summaryrefslogtreecommitdiff
path: root/support/splint/examples/ld/ldman.w
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/examples/ld/ldman.w')
-rw-r--r--support/splint/examples/ld/ldman.w572
1 files changed, 572 insertions, 0 deletions
diff --git a/support/splint/examples/ld/ldman.w b/support/splint/examples/ld/ldman.w
new file mode 100644
index 0000000000..c9551d1b3e
--- /dev/null
+++ b/support/splint/examples/ld/ldman.w
@@ -0,0 +1,572 @@
+% Copyright 2012-2015, Alexander Shibakov
+% Copyright 2002-2014 Free Software Foundation, Inc.
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+@s TeX_ TeX
+\input limbo.sty
+\input ldfrontmatter.sty
+\def\MRI{{\sc MRI}}
+\def\optimization{5}
+\input ldman.sty
+% multi-column output
+\input dcols.sty
+
+\let\oldN\N
+\let\N\textN
+\let\M\textM
+\def\ld{\.{ld}}
+
+\showlastactiontrue
+\immediate\openout\gindex=\jobname.gdx
+@** Introduction.
+\setupfootnotes
+This is a manual documenting the development of a parser that can be
+used to typeset \ld\ files (linker scripts) with or without the help
+of \CWEB. An existing parser for \ld\ has been adopted as a base, with
+appropriately designed actions specific to the task of
+typesetting. The appendix to this manual contains the full source code
+(including the parts written in \Cee) of both the scanner and the parser for \ld,
+used in the original program. Some very minor modifications have been
+made to make the programs more `presentable' in \CWEB\ (in particular, the
+file had to be split into smaller chunks to satisfy \CWEAVE's
+limitations).
+
+Nearly every aspect of the design is discussed, including the
+supporting \TeX\ macros that make both the parser and this
+documentation possible. The \TeX\ macros presented here are collected
+in \.{ldman.sty} which is later included in the \TeX\ file produced by \CWEAVE.
+@<Set up the generic parser machinery@>=
+@G
+\ifx\optimization\UNDEFINED %/* this trick is based on the premise that \.{\\UNDEFINED} */
+ \def\optimization{0} %/* is never defined nor created with \.{\\csname$\ldots$\\endcsname} */
+\fi
+
+\let\nx\noexpand %/* convenient */
+
+\input yycommon.sty %/* general routines for stack and array access */
+\input yymisc.sty %/* helper macros (stack manipulation, table processing, value stack pointers) */
+\input yyinput.sty %/* input functions */
+\input yyparse.sty %/* parser machinery */
+\input flex.sty %/* lexer functions */
+\input yyboth.sty %/* parser initialization, optimization */
+
+\ifnum\optimization>\tw@
+ \input yyfaststack.sty
+\fi
+
+\input yystype.sty %/* scanner auxiliary types and functions */
+\input yyunion.sty %/* parser data structures */
+\input yxunion.sty %/* extended parser data structures */
+@=\input ldunion.sty %@>/* \ld\ parser data structures */@+
+@g
+
+@*1 Bootstrapping.
+To produce a usable parser/scanner duo, several pieces of code must
+be generated. The most important of these are the {\it table files\/}
+(\.{ptab.tex} and \.{ltab.tex}) for the parser and the scanner. These
+consist of the integer tables defining the operation of the parser and
+scanner automata, the values of some constants, and the `action switch'.
+
+Just like in the case of `real' parsers and scanners, in order to
+make the parser and the scanner interact seamlessly, some amount of `glue'
+is required. As an example, a file containing the (numerical)
+definitions of the token values is generated by \bison\ to be used by
+a \flex\ generated scanner. Unfortunately, this file has too little
+structure for our purposes (it contains definitions of token values
+mixed in with other constants making it hard to distinguish one kind of
+definition from another). Therefore, the `glue' is generated by
+parsing our grammar once again, this time with a \bison\ grammar
+designed for typesetting \bison\ files. A special {\it
+bootstrapping\/} mode is used to extract the appropriate
+information. The name `bootstrapping' notwithstanding, the parser and
+lexer used in the bootstrapping phase are not the minimized versions
+used in bootstrapping the \bison\ parser.
+
+The first component generated during the bootstrapping pass is a list
+of `token equivalences' (or `aliases') to be used by the lexer. Every
+token (to be precise, every {\it named token type}) used in
+a \bison\ grammar is declared using one of the
+\prodstyle{\%token}, \prodstyle{\%left}, \prodstyle{\%right},
+\prodstyle{\%precedence}, or \prodstyle{\%nonassoc} declarations. If
+no {\it alias\/} (see below) has been declared using a
+\prodstyle{\%token} declaration, this name ends up in the |yytname|
+array output by \bison\ and can be used by the lexer after associating
+the token names with their numerical values (accomplished by
+\.{\\settokens}). If all tokens are named tokens, no token equivalence
+list is necessary to set up the interaction between the lexer and the
+parser. In this case (the present \ld\ parser is a typical
+example), the token list serves a secondary role: it provides hints
+for the macros that typeset the grammar terms, after the \.{\\tokeneq}
+macro is redefined to serve this purpose.
+
+On the other hand, after a declaration such as `\prodstyle{\%token}
+\.{CHAR} \.{"char"}' the string \.{"char"} becomes an alias
+for the named token \.{CHAR}. Only the string version gets recorded in
+the |yytname| array. Establishing the equivalence between the two
+token forms can now only be accomplished by examining the grammar
+source file and is delegated to the bootstrapping phase parser.
+
+\leavevmode\namedspot{bootstrapstates}The other responsibility of the bootstrapping parser is to extract
+the information about \flex\ {\it states\/} used by the lexer from the
+appropriate source file. As is the case with token names, this
+information is output in a rather chaotic fashion by the scanner
+generator and is all but useless for our purposes. The original
+bootstrapping macros were designed to handle \flex's \prodstyle{\%x}
+and \prodstyle{\%s} state declarations and produce a \Cee\ file with the
+appropriate definitions. This file can later be included by the
+`driver' routine to produce the appropriate table file for the lexer.
+To round off the bootstrapping mode we only need to establish the
+output streams for the tokens and the states, supply the appropriate file
+names for the two lists, flag the bootstrapping mode for the
+bootstrapping macros and inline typesetting (\.{\\prodstyle} macros)
+and input the appropriate machinery.
+
+This is done by the macros
+below. The bootstrap lexer setup (\.{\\bootstraplexersetup}) consists
+of inputting the token equivalence table for the \bison\ parser
+(i.e.~the parser that processes the \bison\ grammar file) and defining
+a robust token output function which simply ignores the token values
+the lexer is not aware of (it should not be necessary in our case
+since we are using full featured lexer and parser).
+@<Define the bootstrapping mode@>=
+@G
+\newwrite\tokendefs %/* token list */
+\newwrite\stlist %/* \flex\ state list */
+\newwrite\gindex %/* index entries */
+
+\def\modebootstrap{%
+ \edef\bstrapparser{dyytab.tex}%
+ \bootstrapmodetrue
+ \def\bootstraplexersetup{%
+ \input bo.tok%
+ \let\yylexreturn\yylexreturnbootstrap /* only return tokens whose value is known */
+ %\let\yylexreturn\yylexreturnregular /* should also work */
+ }%
+ \input yybootstrap.sty%
+}
+@g
+
+@*1 Namespaces and modes.
+Every parser/lexer pair (as well as some other macros) operates
+within a dedicated {\it namespace\/}. This simply means that the macros
+that output token values, switch lexer states and access various
+tables `tack on' the string of characters representing the current
+namespace to the `low level' control sequence name that performs the
+actual output or access. Say, \.{\\yytname} becomes an alias of
+\.{\\yytname[main]} while in the \.{[main]} namespace. When a parser
+or lexer is initialized, the appropriate tables are aliased with a
+generic name in the case of an `unoptimized' parser or lexer. The
+optimized parser or lexer handles the namespace referencing internally.
+
+The mode setup macros for this manual define several separate
+namespaces. The \.{[main]} namespace is established for the parser
+that does the typesetting of the grammar. Every time a term name is
+processed, the token names are looked up in the \.{[ld]}
+namespace. The same namespace is used by the parser that typesets \ld\
+script examples in the manual (i.e.~the parser described here). This
+is done to provide visual consistency between the description of the
+parser and its output. The \.{[small]} namespace is used by the term
+name parser itself. Since we use a customized version of the name parser, we
+dedicate a separate namespace for this purpose, \.{[ldsmall]}.
+The parser based on a subset of the full \bison\
+grammar describing prologue declarations uses the \.{[prologue]}
+namespace. The \.{[index]} namespace is used for typesetting the
+index entries and is not necessarily associated with any parser or
+lexer.
+@<Begin namespace setup@>=
+@G
+\def\indexpseudonamespace{[index]}
+\let\parsernamespace\empty
+@g
+
+@ After all the appropriate tables and `glue' have been generated, the
+typesetting of this manual can be handled by the {\tt normal} mode. Note
+that this requires the \ld\ parser, as well as the \bison\ parser,
+including all the appropriate machinery.
+
+The normal mode is started by including the tables and lists and
+initializing the \bison\ parser (accomplished by inputting
+\.{yyinit.sty}), followed by handling the token typesetting for the
+\ld\ grammar.
+@<Define the normal mode@>=
+@G
+\newtoks\ldcmds
+
+\def\modenormal{%
+ \def\drvname{bo}%
+ \def\appendr##1##2{\edef\appnext{##1{\the##1##2}}\appnext}%
+ \def\appendl##1##2{\edef\appnext{##1{##2\the##1}}\appnext}%
+ \input yyinit.sty%
+ \let\hostparsernamespace\ldnamespace /* the namespace where tokens are looked up for typesetting purposes */
+}
+@g
+
+@ The \ld\ parser initialization requires setting a few global
+variables, as well as entering the \.{INITIAL} state for the \ld\
+lexer. The latter is somewhat counterintuitive and is necessitated by
+the ability of the parser to switch lexer states. Thus, the parser can
+switch the lexer state before the lexer is invoked for the first time
+wreaking havoc on the lexer state stack.
+@<Define the normal mode@>=
+@G
+\def\ldparserinit{%
+ \basicparserinit
+ \includestackptr=\@@ne
+ \versnodenesting=\z@@
+ \ldcmds{}%
+ \yyBEGIN{INITIAL}%
+}
+@g
+
+@ This is the \ld\ parser invocation routine. It is coded according to
+a straightforward sequence initialize-invoke-execute-or-fall back.
+@<Define the normal mode@>=
+@G
+\expandafter\def\csname parserstack[l]\endcsname#1#2{%
+ \toldparser\ldparserinit\yyparse#1\yyeof\yyeof\endparseinput\endparse
+ \ifyyparsefail % /* revert to generic macros if parsing failed */
+ \yybreak{\message{parsing failed ...}#2}%
+ \else % /* stage three, process the parsed table */
+ \yybreak{%
+ \message{commands: \the\ldcmds}%
+ {%
+ \restorecslist{ld-display}\ldunion
+ \the\ldcmds
+ \par
+ \vskip-\baselineskip
+ \the\lddisplay
+ }%
+ }%
+ \yycontinue
+}
+@g
+
+@ @<Initialize the active mode@>=
+@G
+\ifx\modeactive\UNDEFINED
+ \def\modeactive{\modenormal}
+\fi
+
+\modeactive
+
+\ifbootstrapmode\else
+ @>@[@<Initialize \ld\ parsers@>@]@;
+ @>@[@<Modified name parser for \ld\ grammar@>@]@;
+\fi
+@g
+
+@ Unless they are being bootstrapped, the \ld\ parser and its
+term parser are initialized by the normal mode. The token typesetting
+of \ld\ grammar tokens is adjusted at the same time (see the remarks
+above about the mechanism that is responsible for this). Most nonterminals
+(such as keywords, etc.) may be displayed unchanged (provided the
+names used by the lexer agree with their appearance in the script file,
+see below), while the typeseting of others is modified in
+\.{ltokenset.sty}.
+
+In the original \bison-\flex\ interface, token names are
+defined as straightforward macros (a poor choice as will be seen
+shortly) which can sometimes clash with the standard \Cee\ macros.
+This is why \ld\ lexer returns \prodstyle{ASSERT} as
+\prodstyle{ASSERT_K}. The name parser treats \.{K} as a suffix to
+supply a visual reminder of this flaw. Note that the `suffixless' part
+of these tokens (such as \prodstyle{ASSERT}) is never declared and
+thus has to be entered in \.{ltokenset.sty} by hand.
+
+The tokens that never appear as part of the input (such as
+\prodstyle{END} and \prodstyle{UNARY}) or those that do but have no
+fixed appearance (for example, \prodstyle{NAME}) are typeset in a
+style that indicates their origin. The details can be found by
+examining \.{ltokenset.sty}.
+@<Initialize \ld\ parsers@>=
+@G
+\genericparser
+ name: ld,
+ ptables: ptab.tex,
+ ltables: ltab.tex,
+ tokens: {},
+ asetup: {},
+ dsetup: {},
+ rsetup: {},
+ optimization: {};%
+\genericprettytokens
+ namespace: ld,
+ tokens: ldp.tok,
+ correction: ltokenset.sty,
+ host: ld;%
+@g
+
+@ The macros are collected in a single file included at the beginning
+of this documentation.
+@(ldman.stx@>=
+@<Set up the generic parser machinery@>@;
+@<Begin namespace setup@>@;
+@<Define the bootstrapping mode@>@;
+@<Define the normal mode@>@;
+@<Additional macros for the \ld\ lexer/parser@>@;
+@<Initialize the active mode@>@;
+
+@i ldgram.x
+@i ldlex.x
+
+@** Example output. Here is an example output of the \ld\ parser designed in this
+document. The original linker script is presented in the section that
+follows. The same parser can be used to present examples of \ld\ scripts
+in text similar to the one below.
+\beginldprod
+MEMORY
+{
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
+ FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
+ ASH (rx) : ORIGIN = 8000000, LENGTH = 128K
+ CLASH (rx) : ORIGIN = 700000, LENGTH = 128K
+ ASH (rx) : ORIGIN = $8000000, LENGTH = 128K
+ CLASH (rx) : ORIGIN = 700000B, LENGTH = 128K
+ INCLUDE file.mem
+}
+\endprod
+\noindent The syntax of \ld\ is modular enough so there does not seem to be a
+need for a `parser stack' as in the case of the \bison\
+parser. If one must be able to display still smaller segments of \ld\
+code, using `hidden context' tricks (discussed elsewhere) seems to be
+a better approach.
+\iffalse
+\traceparserstatestrue
+\tracestackstrue
+\tracerulestrue
+\traceactionstrue
+\tracelookaheadtrue
+\traceparseresultstrue
+\tracebadcharstrue
+\yyflexdebugtrue
+\tracestatestrue
+\fi
+%
+@<Example \ld\ script@>=
+@G(l)
+INCLUDE file.ld
+
+MEMORY
+{
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
+ FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
+ ASH (rx) : ORIGIN = 8000000, LENGTH = 128K
+ CLASH (rx) : ORIGIN = 700000, LENGTH = 128K
+ ASH (rx) : ORIGIN = $8000000, LENGTH = 128K
+ CLASH (rx) : ORIGIN = 700000B, LENGTH = 128K
+ INCLUDE file.mem
+}
+
+_estack = 0x20005000;
+_bstack = a > 0 ? NEXT(11) : 0x19;
+
+SECTIONS
+{
+ .isr_vector ALIGN(8) (NOLOAD): AT(.) ALIGN(.) ALIGN_WITH_INPUT SUBALIGN(8) SPECIAL
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector))
+ . = ALIGN(4);
+ } > FLASH AT > RAM : FLASH : RAM : OTHER = . + 8
+
+ .text :
+ {
+ /* skip this comment */;
+ . = ALIGN(4);
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ . = ALIGN(4);
+ _etext = . + 8;
+ _sidata = _etext;
+ } >FLASH AT > RAM
+
+ .data : AT ( _sidata )
+ {
+ . = ALIGN(4);
+ _sdata = . ;
+ *(.data)
+ *(.data.*)
+ . = ALIGN(4);
+ _edata = . ;
+ } >RAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = . ;
+ } >RAM
+}
+@g
+
+@ @<The same example of an \ld\ script@>=
+@G(b)
+INCLUDE file.ld
+
+MEMORY
+{
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
+ FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
+ ASH (rx) : ORIGIN = 8000000, LENGTH = 128K
+ CLASH (rx) : ORIGIN = 700000, LENGTH = 128K
+ ASH (rx) : ORIGIN = $8000000, LENGTH = 128K
+ CLASH (rx) : ORIGIN = 700000B, LENGTH = 128K
+ INCLUDE file.mem
+}
+
+_estack = 0x20005000;
+_bstack = a > 0 ? NEXT(11) : 0x19;
+
+SECTIONS
+{
+ .isr_vector ALIGN(8) (NOLOAD): AT(.) ALIGN(.) ALIGN_WITH_INPUT SUBALIGN(8) SPECIAL
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector))
+ . = ALIGN(4);
+ } > FLASH AT > RAM : FLASH : RAM : OTHER = . + 8
+
+ .text :
+ {
+ /* skip this comment */;
+ . = ALIGN(4);
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata*)
+ *(.glue_7)
+ *(.glue_7t)
+ . = ALIGN(4);
+ _etext = . + 8;
+ _sidata = _etext;
+ } >FLASH AT > RAM
+
+ .data : AT ( _sidata )
+ {
+ . = ALIGN(4);
+ _sdata = . ;
+ *(.data)
+ *(.data.*)
+ . = ALIGN(4);
+ _edata = . ;
+ } >RAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ _sbss = .;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = . ;
+ } >RAM
+}
+@g
+
+@
+\traceparserstatesfalse
+\tracestacksfalse
+\tracerulesfalse
+\traceactionsfalse
+\tracelookaheadfalse
+\traceparseresultsfalse
+\tracebadcharsfalse
+\yyflexdebugfalse
+\tracestatesfalse
+
+@i ldnp.x
+
+@** Appendix. The original code of the \ld\ parser and lexer is reproduced below. It
+is mostly left intact and is typeset by the pretty printing parser for
+\bison\ input. The lexer (\flex) input is reproduced verbatim and is
+left mostly unformatted with the exception of spacing and the embedded
+\Cee\ code.
+
+The treatment of comments is a bit more invasive. \CWEB\ silently
+assumes that the comment refers to the preceding statement or a group
+of statements which is reflected in the way the comment is
+typeset. The comments in \ld\ source files use the
+opposite convention. For the sake of consistency, such comments have
+been moved so as to make them fit the \CWEB\ style. The comments meant to refer to a
+sizable portion of the program (such as a whole function or a group
+of functions) are put at the beginning of a \CWEB\ section containing
+the appropriate part of the program.
+
+\CWEB\ treats comments as ordinary \TeX\ so the comments are changed
+to take advantage of \TeX\ formatting and introduce some visual
+cues. The convention of using {\it italics\/} for the original
+comments has been reversed: the italicized comments are the ones
+introduced by the author, {\it not\/} the original
+creators of \ld.
+
+@i ldgramo.x
+@i ldlexo.x
+
+@** Index. This section lists the variable names and (in some cases)
+the keywords used inside the `language sections' of the \CWEB\
+source. It takes advantage of the built-in facility of \CWEB\ to supply
+references for both definitions (set in {\it
+italic}) as well as uses for each \Cee\ identifier in the text.
+
+Special facilities have been added to extend indexing to
+\bison\ grammar terms, \TeX\ control sequences encountered in
+\bison\ actions, and file and section names encountered in \ld\
+scripts. For a detailed description of the various conventions adhered
+to by the index entries the reader is encouraged to consult the
+remarks preceding the index of the document describing the core of
+the \splint\ suite. We will only mention here that (consistent with
+the way \bison\ references are treated) a script example:
+$$
+\vbox{
+\beginldprod
+MEMORY
+{
+ MEMORY1 (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
+ MEMORY2 (rx) : ORIGIN = 0x8000000, LENGTH = 128K
+}
+_var_1 = 0x20005000;
+\endprod
+}%
+$$
+\noindent inside the \TeX\ part of a \CWEB\ section will generate several
+index entries, as well, mimicking \CWEB's behavior for the
+{\it inline \Cee\/} (\.{\yl}$\ldots$\.{\yl}). Such entries are labeled
+with $^\circ$, to provide a reminder of their origin.
+\def\otherlangindexseparator{%
+ \par
+ \vskip.5\baselineskip
+ \centerline{B{\sc ISON}, LD, {\sc AND} \TeX\ {\sc INDICES}}%
+ \vskip.5\baselineskip
+ \par
+}
+\let\currentparsernamespace\parsernamespace
+ \let\parsernamespace\indexpseudonamespace
+ \prettywordpair{emptyrhs}{$\circ$ {\rm(empty rhs)}}%
+ \prettywordpair{inline_action}{$\diamond$ {\rm(inline action)}}%
+\let\parsernamespace\currentparsernamespace
+\closeout\gindex
+\let\inx\inxmod
+\let\fin\finmod
+\let\oldMRL\MRL
+\def\MRL#1{\smash{\oldMRL{#1}}} % a more sophisticated way to handle it woud be to add a \smash whenever we are
+ % in the [index] namespace but this is simpler and works as well
+\def\topofcontents{\null\vskip-3\baselineskip\centerline{C{\sc ONTENTS} (\sc\uppercase\expandafter{\title})}\medskip}