summaryrefslogtreecommitdiff
path: root/support/ltx2x
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/ltx2x
Initial commit
Diffstat (limited to 'support/ltx2x')
-rw-r--r--support/ltx2x/NOSUPPORT58
-rw-r--r--support/ltx2x/README189
-rw-r--r--support/ltx2x/bye.ct33
-rw-r--r--support/ltx2x/detex.ct1234
-rw-r--r--support/ltx2x/fun.ct469
-rw-r--r--support/ltx2x/getopt.c85
-rw-r--r--support/ltx2x/getopt.h10
-rw-r--r--support/ltx2x/html.sty360
-rw-r--r--support/ltx2x/l2h.ct1709
-rw-r--r--support/ltx2x/l2x.l1184
-rw-r--r--support/ltx2x/l2x.y1502
-rw-r--r--support/ltx2x/l2xacts.c631
-rw-r--r--support/ltx2x/l2xacts.h17
-rw-r--r--support/ltx2x/l2xcom.h85
-rw-r--r--support/ltx2x/l2xicmon.h60
-rw-r--r--support/ltx2x/l2xicpr.h38
-rw-r--r--support/ltx2x/l2xidbug.c1295
-rw-r--r--support/ltx2x/l2xidecl.c958
-rw-r--r--support/ltx2x/l2xidftc.h13
-rw-r--r--support/ltx2x/l2xierr.c410
-rw-r--r--support/ltx2x/l2xierr.h65
-rw-r--r--support/ltx2x/l2xiertc.h144
-rw-r--r--support/ltx2x/l2xiexec.h97
-rw-r--r--support/ltx2x/l2xiexpr.c788
-rw-r--r--support/ltx2x/l2xiidbg.c271
-rw-r--r--support/ltx2x/l2xiidbg.h22
-rw-r--r--support/ltx2x/l2xiprse.h49
-rw-r--r--support/ltx2x/l2xirexp.c814
-rw-r--r--support/ltx2x/l2xirexp.h28
-rw-r--r--support/ltx2x/l2xirtne.c651
-rw-r--r--support/ltx2x/l2xiscan.c1215
-rw-r--r--support/ltx2x/l2xiscan.h36
-rw-r--r--support/ltx2x/l2xisctc.h174
-rw-r--r--support/ltx2x/l2xisdcl.c420
-rw-r--r--support/ltx2x/l2xisftc.h24
-rw-r--r--support/ltx2x/l2xistd.c667
-rw-r--r--support/ltx2x/l2xistmt.c719
-rw-r--r--support/ltx2x/l2xistup.c477
-rw-r--r--support/ltx2x/l2xisymt.c416
-rw-r--r--support/ltx2x/l2xisymt.h139
-rw-r--r--support/ltx2x/l2xixref.c204
-rw-r--r--support/ltx2x/l2xixstd.c1233
-rw-r--r--support/ltx2x/l2xixstm.c881
-rw-r--r--support/ltx2x/l2xixutl.c1866
-rw-r--r--support/ltx2x/l2xixxpr.c1234
-rw-r--r--support/ltx2x/l2xlexyy.c2351
-rw-r--r--support/ltx2x/l2xlib.c5629
-rw-r--r--support/ltx2x/l2xlib.h155
-rw-r--r--support/ltx2x/l2xlibtc.h153
-rw-r--r--support/ltx2x/l2xusrlb.c290
-rw-r--r--support/ltx2x/l2xusrlb.h22
-rw-r--r--support/ltx2x/l2xytab.c6405
-rw-r--r--support/ltx2x/l2xytab.h96
-rw-r--r--support/ltx2x/licomsym.h175
-rw-r--r--support/ltx2x/listsetc.c355
-rw-r--r--support/ltx2x/listsetc.h49
-rw-r--r--support/ltx2x/ltx2html.sty38
-rw-r--r--support/ltx2x/ltx2x.ct7
-rw-r--r--support/ltx2x/ltx2x.html8107
-rw-r--r--support/ltx2x/ltx2x.ps14045
-rw-r--r--support/ltx2x/ltx2x.tex7453
-rw-r--r--support/ltx2x/ltx2x.txt7012
-rw-r--r--support/ltx2x/makefile290
-rw-r--r--support/ltx2x/man203
-rw-r--r--support/ltx2x/printct.c1091
-rw-r--r--support/ltx2x/remcom.ct133
-rw-r--r--support/ltx2x/srchenv.c392
-rw-r--r--support/ltx2x/srchenv.h7
-rw-r--r--support/ltx2x/strtypes.h16
l---------support/ltx2x/url.sty1
70 files changed, 77449 insertions, 0 deletions
diff --git a/support/ltx2x/NOSUPPORT b/support/ltx2x/NOSUPPORT
new file mode 100644
index 0000000000..df95634ae6
--- /dev/null
+++ b/support/ltx2x/NOSUPPORT
@@ -0,0 +1,58 @@
+file: NOSUPPORT (for ltx2x)
+
+ When I wrote ltx2x it was in a different century and for a different
+employer.
+
+ At that time I was involved in a project for storing a large series
+of SGML tagged documents in a database. The intention was that queries
+could be made against the database, couched in terms of the
+SGML DTD, to retrieve (portions of) the documents. Some retrievals would
+be for just reading, others would be by the series authors to paste text
+into new documents in the series. There were no restrictions on how the
+documents could be produced, except that they had to be in plain ASCII;
+some authors used LaTeX, others used proprietry word processing systems,
+and others a plain text editor. Camera ready copies of the documents
+were also required for publication.
+
+ I wrote ltx2x to provide an automated means of converting LaTeX tagged
+documents to SGML tagged documents. Someone else wrote a converter from
+SGML to LaTeX as it was determined that LaTeX was the best means of
+generating high quality camera ready copies. This all actually worked!
+
+ At the time I wrote ltx2x I think that there was no other similar
+tool available that could provide a configurable conversion process ---
+I at least configured ltx2x to operate like the detex program, to convert
+to HTML, and to SGML (this was in the days before XML). The major problem
+with the architecture of ltx2x was that it did its own parsing of the
+LaTeX source, and the only robust LaTeX parser is TeX. A new kind of LaTeX
+macro in a document required extending the ltx2x source code and recompiling.
+
+ I am now with another employer and as far as I know the SGML database
+idea has lapsed. Therefore I have no work-related imperitive to maintain
+ltx2x. Also, except for conversion of simple LaTeX into HTML, I no longer
+use it myself.
+
+ Eitan Gurari's TeX4ht system is also a configurable converter and
+uses TeX as the parser, so eliminating any need to keep recompiling
+the basis system. I have effectively retired my use of ltx2x in favour
+of TeX4ht. The homepage for TeX4ht is at:
+http://www.cis.ohio-state.edu/~gurari/TeX4ht
+
+ The bottom line is that I will no longer provide even the minimal support
+for ltx2x that I have done for the past three years or so. I regret having
+to say this but feel it is probably best for any current or future users
+to know what the situation is.
+
+ If anyone wishes to take over support or development of ltx2x I will
+be very pleased. The majority of the code is in the public domain and the
+remainder is available under the LaTeX Project Public License, so anyone can
+make any changes they like. Just let me know if you want to do anything so
+I have a record of what might happen.
+
+Peter Wilson (peter.r.wilson@boeing.com)
+2001/07/01
+
+
+
+
+
diff --git a/support/ltx2x/README b/support/ltx2x/README
new file mode 100644
index 0000000000..7b2601d0f8
--- /dev/null
+++ b/support/ltx2x/README
@@ -0,0 +1,189 @@
+file: README for version 0.92 (November 1999) release of LTX2X ---
+ A LaTeX to X Autotagger
+
+FUNCTION
+
+ The LTX2X program, which is written in C, replaces LaTeX commands
+in a LaTeX document by user-defined strings. In essence, LaTeX tags can
+be replaced by other kinds of document tags (e.g. HTML/SGML or RTF tags),
+or can be removed altogether. The program also has an unsophisticated
+pretty-print capability.
+
+ The replacement strings for the LaTeX commands are specified
+in a command table file, which can be created simply via any text
+editor. For more advanced users an interpreter for the EXPRESS-A
+programming language is also included. EXPRESS-A includes STRING, LIST
+and ENTITY types as as primitives of the language, as well as the
+usual REAL, INTEGER and LOGICAL types. Regular expressions are also
+an integral part of EXPRESS-A. The interpreter also includes an
+interactive source level debugger for EXPRESS-A.
+
+ The supplied command tables include facilities for, among others:
+o deTeXing and pretty-printing
+o Conversion from LaTeX tagging to HTML tagging
+
+ The 100+ page user manual is supplied as LaTeX source, Postscript,
+and in deTeXed and HTML forms, the latter two being automatically
+generated by running LTX2X on the LaTeX source.
+
+ LTX2X is compilable by at least the GNU gcc compiler.
+
+FILES
+
+ Files in this distribution are:
+o README (this file)
+
+o l2xlib.c and l2xlib.h main program and library functions for LTX2X
+o l2xlibtc.h keywords and their string representations
+o l2xcom.h typedefs
+o l2x.l lexer source to be processed by flex
+o l2xlexyy.c lexer code after flex processing
+o l2x.y parser source to be processed by bison
+o l2xytab.c and l2xytab.h parser code after bison processing
+o l2xacts.c and l2xacts.h standard action functions
+o l2xusrlb.c and l2xusrlb.h user-defined action functions
+o srchenv.c and srchenv.h C code for directory searching
+o getopt.c and getpopt.h C code for command line options
+o strtypes.h header file for string proccessing
+
+o l2xistup.c and l2xicmon.h interface for the interpreter
+o l2xirtne.c, l2xistd.c, interpreter parsing routines
+ l2xidecl.c, l2xistmt.c,
+ l2xiexpr.c, l2xiprse.h
+o l2xixutl.c l2xiexec.h interpreter executor utility routines
+o l2xixstd.c l2xixstm.c, routines for interpreter executor module
+ l2xixxpr.c
+o l2xirexp.c, l2xirexp.h routines for processing regular expressions
+o listsetc.c, listsetc.h general list processing routines
+o l2xiscan.c l2xiscan.h interpreter lexing routines
+o l2xisymt.c, l2xisymt.h interpreter symbol table support
+o l2xidbug.c source level debugger for the interpreter
+o l2xierr.c, l2xierr.h EXPRESS-A user focussed error handling
+o l2xiidbg.c l2xiidbg.h, diagnostics for interpreter developer
+ l2xisdcl.c
+o licomsym.h general interpreter header file
+o l2xidftc.h, l2xiertc.h, keywords and their string representations
+ l2xisctc.h, l2xisftc.h
+
+o printct.c C program for command table printing and update
+
+o man manpage
+o makefile makefile for ltx2x
+o ltx2html.sty Package file for ltx2x LaTeX to HTML
+o ltx2x.tex User manual in LaTeX format
+o ltx2x.ps User manual in PostScript format
+o ltx2x.html HTMLed version of ltx2x.tex
+o ltx2x.txt deTeXed version of ltx2x.tex
+o ltx2x.ct Dummy command table file
+o bye.ct Example "Goodbye document" command table file
+o remcom.ct Example decommenter command table file
+o detex.ct Example deTeXing command table file
+o l2h.ct Example command table for LaTeX to HTML conversion
+o fun.ct Example EXPRESS-A code
+and possibly
+o ltx2x.tar.gz Tared and Zipped archive of all the above
+
+Changes in version 0.92 (November 1999)
+o Added -h option to print usage
+o Eliminated known warnings from gcc
+o Changed makefile to handle (not) system supplied getopt
+o Changed makefile to add printct installation
+
+INSTALLATION
+
+ ltx2x is written as a parser for LaTeX. The main source is
+in l2xlib.c. Source for the lexer is in l2x.l which has to be
+processed by flex (or equivalent) and the parser is in l2x.y
+which is intended to be processed by bison (or equivalent).
+Support functions are in files l2xacts.c, l2xusrlb.c, srchenv.c
+and getopt.c. After the lexer and parser files are processed,
+all the code files must be compiled and linked to form the executable.
+
+ The syntax of the command table has been extended and modified.
+The printct program will convert a command table in the original
+syntax to the new syntax.
+
+Via Make
+--------
+
+0. Read the manual
+
+1. Edit the first part of makefile to match your system's configuration.
+
+----- For the ltx2x program
+
+ If you are feeling brave, do `make all'. Otherwise continue as below.
+
+2. Do `make' (processes lexer and parser and compiles and links the program)
+
+3. (Optional) Set the environment variable LTX2XTABLES to the
+ directories where command table files might be located
+
+4. Test the program
+
+5. Do `make install' (moves the binary into its final location)
+
+6. Do `make manpage' (edits the manpage and copies it to its working location)
+
+7. Do `make ctables' (copies the command tables to their working location)
+
+8. Do `make doc' (copies the user manual sources to their final location)
+
+9. Do `make clean' (deletes the object code, yacc output, and edited
+ manpage files)
+
+----- For the printct program, if desired and preferably after installing ltx2x
+
+10. Do `make printct' to compile printct.c.
+
+11. Do `make installprintct' to move the binary to its final destination.
+
+12. Do `make cleanprintct' to delete printct binary and object files
+
+
+By Hand
+-------
+
+0. Read the manual.
+
+ Steps 1 and/or 2 below are only required if changes have been made
+to the files l2x.y and/or l2x.l, respectively.
+
+1. Run bison on l2x.y. Rename y.tab.c to l2xytab.c and rename
+ y.tab.h to l2xytab.h
+
+2. Run flex on l2x.l. Rename lex.yy.c to l2xlexyy.c.
+
+3. Compile all the .c files
+
+4. Link the compiled code to form the final program binary
+
+5. (Optional) Set the environment variable LTX2XTABLES to the
+ directories where command table files might be located
+
+6. Test the program
+
+7. Move the binary to its final destination
+
+8. Edit the manpage file and copy it to its working location, renaming
+ it appropriately
+
+9. Copy the example .ct files to their working location
+
+10. Copy the manual source filers to their final location
+
+11. Compile printct.c and move the binary to its final destination
+
+12. Remove intermediate files
+
+AUTHOR
+
+ LTX2X has been written by Peter Wilson (ex The Catholic University
+of America and NIST). Development of the software upto and including
+version 0.7 (November 1996) was funded by the United States Government
+and is not subject to copyright. This version is released under the
+LaTeX Project Public License.
+
+ Please send any comments to Peter Wilson at peter.r.wilson@boeing.com
+
+29 November 1999 \ No newline at end of file
diff --git a/support/ltx2x/bye.ct b/support/ltx2x/bye.ct
new file mode 100644
index 0000000000..f863303db5
--- /dev/null
+++ b/support/ltx2x/bye.ct
@@ -0,0 +1,33 @@
+ c= bye.ct "Hello World" for ltx2x
+
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \documentstyle
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \documentclass
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+END_CTFILE= end of bye.ct
+
diff --git a/support/ltx2x/detex.ct b/support/ltx2x/detex.ct
new file mode 100644
index 0000000000..fa261d78f7
--- /dev/null
+++ b/support/ltx2x/detex.ct
@@ -0,0 +1,1234 @@
+ c= detex.ct skeleton file for ltx2x to deTeX source
+ c= includes support for packages url, html, hyperref, hyper
+ c= plus additional commands used in the LTX2X.TEX manual
+ c= Author: Peter Wilson (pwilson@cme.nist.gov) August 1996
+
+ c= -----------------------------------escape sequences
+
+ESCAPE_CHAR= ?
+ c= use the default escape characters
+
+ c= ----------------------------------- required built in commands
+ c= most of these could have been omitted as they produce no tags
+TYPE= BEGIN_DOCUMENT
+END_TYPE
+
+TYPE= END_DOCUMENT
+END_TYPE
+
+TYPE= BEGIN_VERB
+END_TYPE
+
+TYPE= END_VERB
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+END_TYPE
+
+TYPE= END_DOLLAR
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= " "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= LBRACE
+ START_TAG= ""
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= ""
+END_TYPE
+
+TYPE= PARAGRAPH
+ START_TAG= "?n?n "
+END_TYPE
+
+ c= -------------------------------------(La)TeX special characters
+
+ c= hash (for use in \def s )
+TYPE= TEX_CHAR
+NAME= #
+END_TYPE
+
+ c= ampersand (table column delimeter)
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " | "
+END_TYPE
+
+ c= twiddle (unbreakable space)
+TYPE= TEX_CHAR
+NAME= ~
+ START_TAG= " "
+END_TYPE
+
+ c= underscore (math subscript)
+TYPE= TEX_CHAR
+NAME= _
+ START_TAG= "_"
+END_TYPE
+
+ c= caret (math superscript)
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "^"
+END_TYPE
+
+ c= percent (start of comment)
+TYPE= TEX_CHAR
+NAME= %
+ START_TAG= ""
+END_TYPE
+
+ c= at
+TYPE= TEX_CHAR
+NAME= @
+ START_TAG= "@"
+END_TYPE
+
+ c= ----------------------------- default single character commands
+
+ c= LaTeX start a new line
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+END_TYPE
+
+ c= small space
+TYPE= CHAR_COMMAND
+NAME= \,
+ START_TAG= " "
+END_TYPE
+
+ c= end of sentence space
+TYPE= CHAR_COMMAND
+NAME= \@
+ START_TAG= " "
+END_TYPE
+
+ c= hash
+TYPE= CHAR_COMMAND
+NAME= \#
+ START_TAG= "#"
+END_TYPE
+
+ c= dollar
+TYPE= CHAR_COMMAND
+NAME= \$
+ START_TAG= "$"
+END_TYPE
+
+ c= ampersand
+TYPE= CHAR_COMMAND
+NAME= \&
+ START_TAG= "&"
+END_TYPE
+
+ c= underscore
+TYPE= CHAR_COMMAND
+NAME= \_
+ START_TAG= "_"
+END_TYPE
+
+ c= percent
+TYPE= CHAR_COMMAND
+NAME= \%
+ START_TAG= "%"
+END_TYPE
+
+ c= optional hyphenation
+TYPE= CHAR_COMMAND
+NAME= \-
+ START_TAG= ""
+END_TYPE
+
+ c= left open brace
+TYPE= CHAR_COMMAND
+NAME= \{
+ START_TAG= "{"
+END_TYPE
+
+ c= right close brace
+TYPE= CHAR_COMMAND
+NAME= \}
+ START_TAG= "}"
+END_TYPE
+
+
+ c= ----------------------------- (re)newstuff
+ c= do no processing
+
+TYPE= COMMAND_POOP
+NAME= \newcommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOP
+NAME= \renewcommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOP
+NAME= \providecommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \newenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \renewenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+
+
+
+
+ c= ----------------------------- General (La)TeX
+
+ c= ----------------------------- document titles, etc
+
+TYPE= COMMAND
+NAME= \mltitle
+ c= special command for HTML document title
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \maketitle
+ c= print contents of \title, \author and \date
+ START_TAG= "?n"
+ STRING: "TITLE: "
+ SOURCE: FILE tit.tmp
+ STRING: "?n?n AUTHOR(S): "
+ SOURCE: BUFFER 2
+ STRING: "?n?n DATE: "
+ SOURCE: BUFFER 3
+ STRING: "?n?n"
+ RESET_BUFFER: 2
+ RESET_BUFFER: 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \title
+ REQPARAMS= 1
+ PRINT_P1= TO_FILE tit.tmp
+END_TYPE
+
+TYPE= COMMAND
+NAME= \author
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 2
+END_TYPE
+
+TYPE= COMMAND
+NAME= \date
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \thanks
+ START_TAG= "?n("
+ END_TAG= ")?n"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= abstract
+ START_TAG= "?nABSTRACT:?n"
+END_TYPE
+
+TYPE= END_ENV
+NAME= abstract
+ START_TAG= "?n"
+END_TYPE
+
+ c= ------------------------------- tables
+
+TYPE= BEGIN_ENV
+NAME= table
+ START_TAG= "?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ END_TAG=
+ SET_MODE: table
+END_TYPE
+
+TYPE= END_ENV
+NAME= table
+ END_TAG= "?n"
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= tabular
+ START_TAG= "?n"
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+END_TYPE
+
+TYPE= END_ENV
+NAME= tabular
+END_TYPE
+
+TYPE= COMMAND
+NAME= \multicolumn
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarray
+ START_TAG= "?n"
+ SET_MODE: eqnarray
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray
+ END_TAG= "?n"
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarray*
+ START_TAG= "?n"
+ SET_MODE: eqnarray
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray*
+ END_TAG= "?n"
+ RESET_MODE:
+END_TYPE
+
+ c= --------------------------------- figures, etc
+
+TYPE= BEGIN_ENV
+NAME= figure
+ START_TAG= "?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ END_TAG=
+ SET_MODE: figure
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+ START_TAG= "?n(**Figure contents are usually not available**)?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \centering
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= center
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_ENV
+NAME= center
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION: "
+ END_TAG= "?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+ c= ------------------------------- lists
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+ START_ITEM= "?n (#) "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "?n"
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+ START_TAG= "?n"
+END_TYPE
+
+ c= fake some \dots commands
+TYPE= COMMAND
+NAME= \ldots
+ START_TAG= "..."
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cdots
+ START_TAG= "..."
+END_TYPE
+
+TYPE= COMMAND
+NAME= \vdots
+ START_TAG= ":"
+END_TYPE
+
+
+ c= replace footnote with parenthesised text
+TYPE= COMMAND
+NAME= \footnote
+ START_TAG= " (Footnote: "
+ END_TAG= ") "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+ c= --------------------------------- quotations
+
+TYPE= BEGIN_ENV
+NAME= quote
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_ENV
+NAME= quote
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= quotation
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_ENV
+NAME= quotation
+ START_TAG= "?n"
+END_TYPE
+
+
+TYPE= COMMAND
+NAME= \TeX
+ START_TAG= "TeX"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \LaTeX
+ START_TAG= "LaTeX"
+END_TYPE
+
+ c= --------------------------- Picture commands
+ c= throw all their contents away
+
+TYPE= BEGIN_PICTURE_CC
+NAME= picture
+ PC_AT_START= NO_PRINT
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CP
+NAME= \put
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CCPP
+NAME= \multiput
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_PCOP
+NAME= \savebox
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCC
+NAME= \graphpaper
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCCC
+NAME= \qbezier
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= END_PICTURE
+NAME= picture
+ PC_AT_END= RESET
+END_TYPE
+
+
+ c= ---------------------------sectioning (keep headers only)
+
+TYPE= SECTIONING
+NAME= \part
+ SECTIONING_LEVEL= PART
+ START_TAG= "?n?nPART: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \chapter
+ SECTIONING_LEVEL= CHAPTER
+ START_TAG= "?n?nCHAPTER: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?nSECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsection
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "?n?nSUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsubsection
+ SECTIONING_LEVEL= SUBSUBSECT
+ START_TAG= "?n?nSUB-SUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \paragraph
+ SECTIONING_LEVEL= PARA
+ START_TAG= "?n?nSUB-SUB-SUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subparagraph
+ SECTIONING_LEVEL= SUBPARA
+ START_TAG= "?n?nSUB-SUB-SUB-SUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+
+TYPE= SECTIONING
+NAME= \part*
+ SECTIONING_LEVEL= PART
+ START_TAG= "?n?nPART: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \chapter*
+ SECTIONING_LEVEL= CHAPTER
+ START_TAG= "?n?nCHAPTER: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \section*
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?nSECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsection*
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "?n?nSUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsubsection*
+ SECTIONING_LEVEL= SUBSUBSECT
+ START_TAG= "?n?nSUB-SUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \paragraph*
+ SECTIONING_LEVEL= PARA
+ START_TAG= "?n?nSUB-SUB-SUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subparagraph*
+ SECTIONING_LEVEL= SUBPARA
+ START_TAG= "?n?nSUB-SUB-SUB-SUB-SECTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \appendix
+ START_TAG= "?n?nAPPENDICES?n"
+END_TYPE
+
+ c= ------------------------------ misc stuff
+
+TYPE= COMMAND
+NAME= \addcontentsline
+ REQPARAMS= 3
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+END_TYPE
+
+TYPE= COMMAND
+NAME= \quad
+ START_TAG= " "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \pagenumbering
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \bibliographystyle
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \bibliography
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+ c= ------------------------------ some math commands
+
+TYPE= COMMAND
+NAME= \leq
+ START_TAG= " <= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \geq
+ START_TAG= " >= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \neq
+ START_TAG= " /= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \subseteq
+ START_TAG= " <= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \subset
+ START_TAG= " < "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \supseteqeq
+ START_TAG= " >= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \supset
+ START_TAG= " > "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cap
+ START_TAG= " * "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cup
+ START_TAG= " + "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \in
+ START_TAG= " in "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \emptyset
+ START_TAG= "{0}"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \forall
+ START_TAG= " forall "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \Rightarrow
+ START_TAG= " => "
+END_TYPE
+
+ c= ------------------------------ font changes
+
+TYPE= COMMAND
+NAME= \texttt
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \emph
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textit
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textbf
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textsl
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textsc
+ REQPARAMS= 1
+END_TYPE
+
+
+
+
+ c= ------------------------------ bibliography and ref commands
+
+TYPE= BEGIN_ENV
+NAME= thebibliography
+ START_TAG= "?n?nREFERENCES?n?n"
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= END_ENV
+NAME= thebibliography
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \bibitem
+ START_TAG= "?n"
+ REQPARAMS= 1
+ START_TAG_1= "["
+ END_TAG_1= "] "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \newblock
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cite
+ START_TAG= "["
+ END_TAG= "]"
+ REQPARAMS= 1
+ OPT_PARAM= FIRST
+ END_OPT= " "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \label
+ START_TAG= " ("
+ END_TAG= ") "
+ REQPARAMS= 1
+IN_MODE= table
+ REQPARAMS= 1
+ START_TAG= " (Table: "
+ END_TAG= ") "
+END_MODE
+IN_MODE= figure
+ REQPARAMS= 1
+ START_TAG= " (Figure: "
+ END_TAG= ") "
+END_MODE
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ref
+ START_TAG= "("
+ END_TAG= ")"
+ REQPARAMS= 1
+END_TYPE
+
+
+ c= --------------------- for the url package
+
+TYPE= VCOMMAND
+NAME= \url
+ REQPARAMS= 1
+END_TYPE
+
+ c= ---------------------- for the html package (as best I understand them)
+ c= (normally used with the latex2html program)
+
+TYPE= COMMAND
+NAME= \htmladdnormallinkfoot
+ REQPARAMS= 2
+ START_TAG_2= " (Footnote: "
+ END_TAG_2= ") "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdnormallink
+ REQPARAMS= 2
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdimg
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \externallabels
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \externalref
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmlrule
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= rawhtml
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= rawhtml
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= htmlonly
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= htmlonly
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= VCOMMAND
+NAME= \html
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= latexonly
+END_TYPE
+
+TYPE= END_ENV
+NAME= latexonly
+END_TYPE
+
+TYPE= COMMAND
+NAME= \latex
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperref
+ REQPARAMS= 4
+ START_TAG=
+ RESET_BUFFER: 4
+ RESET_BUFFER: 5
+ PRINT_P1= NO_PRINT
+ PRINT_P3= TO_BUFFER 4
+ PRINT_P4= TO_BUFFER 5
+ END_TAG= " ("
+ SOURCE: BUFFER 5
+ STRING: ") "
+ SOURCE: BUFFER 4
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmlref
+ REQPARAMS= 2
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmlimage
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdtonavigation
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+
+ c= --------------------- stuff for hyper package (as best I understand it)
+
+TYPE= COMMAND
+NAME= \hyperanchor
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \blindhyperanchor
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperreference
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperURL
+ REQPARAMS= 4
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \labeltext
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \noref
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+ c= renamed to avoid clash with original \ref
+ c= NAME= \ref
+NAME= \Href
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ START_TAG_1= " ("
+ END_TAG_1= ")"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \pageref
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \refcurrent
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \refnext
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+ c= -------------------- stuff for hyperref package (as best I understand)
+
+TYPE= COMMAND
+NAME= \hyperlink
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hypertarget
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \href
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperimage
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperdef
+ OPT_PARAM= FIRST
+ REQPARAMS= 4
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperref
+ OPT_PARAM= FIRST
+ REQPARAMS= 4
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdimg
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdnormallink
+ REQPARAMS= 2
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+ c= -------------------- commands for detexing l2x.tex
+ c= could have been defined via an included file. e.g.
+ c= INCLUDE= detex.l2x
+
+TYPE= BEGIN_VENV
+NAME= htmlverbatim
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= htmlverbatim
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "L2X"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \keyword
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \keytext
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \file
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ST
+ REQPARAMS= 1
+ START_TAG= "<"
+ END_TAG= ">"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ET
+ REQPARAMS= 1
+ START_TAG= "</"
+ END_TAG= ">"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \Amp
+ START_TAG= "&"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \LT
+ START_TAG= "<"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \GT
+ START_TAG= ">"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \HASH
+ START_TAG= "#"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \Express
+ START_TAG= "EXPRESS"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ExpressA
+ START_TAG= "EXPRESS-A"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ExpressG
+ START_TAG= "EXPRESS-G"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ExpressI
+ START_TAG= "EXPRESS-I"
+END_TYPE
+
+
+
+
+ c= ------------------- include extra ct files here
+
+ c= this will give an opportunity tom interactively include a
+ c= ct file, assuming that ZiLcH.ct is not on the search path.
+INCLUDE= ZiLcH.ct
+
+
+END_CTFILE= ------------------ end of detex.ct
+
+
diff --git a/support/ltx2x/fun.ct b/support/ltx2x/fun.ct
new file mode 100644
index 0000000000..b81d3664b3
--- /dev/null
+++ b/support/ltx2x/fun.ct
@@ -0,0 +1,469 @@
+ c= fun.ct Test of CODE ltx2x
+
+CODE_SETUP=
+ ENTITY ent;
+ attr1, attr3 : INTEGER;
+ attr2 : STRING;
+ END_ENTITY;
+
+ TYPE joe = INTEGER;
+ END_TYPE;
+
+ TYPE colour = ENUMERATION OF (red, blue, green);
+ END_TYPE;
+
+
+PROCEDURE easter;
+ LOCAL
+ n, a, b, m, q, w : INTEGER;
+ day : INTEGER;
+ month : STRING;
+ END_LOCAL;
+
+ n := THE_YEAR - 1900;
+ a := n MOD 19;
+ b := (7*a + 1) DIV 19;
+ m := (11*a + 4 - b) MOD 29;
+ q := n DIV 4;
+ w := (n + q + 31 - m) MOD 7;
+ day := 25 - m - w;
+ month := 'April';
+ IF (day < 1) THEN
+ month := 'March';
+ day := day + 31;
+ END_IF;
+ writeln('In ', THE_YEAR:5, ' Easter is on ', month, day:3);
+ println('In ', THE_YEAR:5, ' Easter is on ', month, day:3);
+END_PROCEDURE;
+
+
+FUNCTION magic_square(order:INTEGER): LOGICAL;
+ LOCAL
+ row, col, num : INTEGER;
+ sqr_order : INTEGER;
+ magic : ARRAY[1:15] OF ARRAY[1:15] OF INTEGER;
+ END_LOCAL;
+
+ IF (order > 15) THEN -- only squares up to order 15
+ RETURN(FALSE);
+ ELSE
+ IF (order < 1) THEN -- squares have at least one entry
+ RETURN(FALSE);
+ ELSE
+ IF (NOT ODD(order)) THEN -- squares are odd
+ RETURN(FALSE);
+ END_IF;
+ END_IF;
+ END_IF;
+
+ sqr_order := order**2;
+ row := 1;
+ col := (order + 1) DIV 2;
+ REPEAT num := 1 TO sqr_order;
+ magic[row][col] := num;
+ IF ((num MOD order) <> 0) THEN
+ IF (row = 1) THEN row := order; ELSE row := row - 1; END_IF;
+ IF (col = order) THEN col := 1; ELSE col := col + 1; END_IF;
+ ELSE
+ IF (num <> sqr_order) THEN row := row + 1; END_IF;
+ END_IF;
+ END_REPEAT;
+
+ writeln; println;
+ REPEAT row := 1 TO order;
+ REPEAT col := 1 TO order;
+ write(magic[row][col]:4);
+ print(magic[row][col]:4);
+ END_REPEAT;
+ writeln; println;
+ END_REPEAT;
+ writeln; println;
+
+ RETURN(TRUE);
+END_FUNCTION;
+
+FUNCTION month(mnum:INTEGER) : STRING;
+LOCAL
+ str : STRING;
+END_LOCAL;
+ CASE mnum OF
+ 1 : str := 'January';
+ 2 : str := 'February';
+ 3 : str := 'March';
+ 4 : str := 'April';
+ 5 : str := 'May';
+ 6 : str := 'June';
+ 7 : str := 'July';
+ 8 : str := 'August';
+ 9 : str := 'September';
+ 10 : str := 'October';
+ 11 : str := 'November';
+ 12 : str := 'December';
+ OTHERWISE : str := '';
+ END_CASE;
+RETURN(str);
+END_FUNCTION;
+
+ LOCAL
+ a : array[1:3] of integer;
+ lagg : list [0:5] of integer;
+ bagg : bag [3:6] of real;
+ sagg : set of real;
+ all : array [-3:-1] of bag of list of set of logical;
+ a23 : array[1:2] of array[1:3] of integer;
+ i, n : integer;
+ s1, s2 : string;
+ b : logical;
+ r1, r2 : real;
+ nega : array[-3:-1] of integer;
+ posa : array[3:5] of integer;
+ e : ent;
+ j : joe;
+ END_LOCAL;
+
+ BEGIN
+
+ writeln;
+ println;
+
+ writeln(THE_DAY:1, ' ', month(THE_MONTH), ' ', THE_YEAR:1);
+ println(THE_DAY:1, ' ', month(THE_MONTH), ' ', THE_YEAR:1);
+
+ i := 10;
+ posa[3] := i;
+ i := 20;
+ posa[4] := i;
+ i := 30;
+ posa[5] := i;
+ REPEAT i := LOINDEX(posa) TO HIINDEX(posa);
+ writeln('posa[', i:1, '] = ', posa[i]);
+ println('posa[', i:1, '] = ', posa[i]);
+ END_REPEAT;
+
+ posa[3] := 1;
+ posa[4] := 2;
+ posa[5] := 3;
+ REPEAT i := LOINDEX(posa) TO HIINDEX(posa);
+ writeln('posa[', i:1, '] = ', posa[i]);
+ println('posa[', i:1, '] = ', posa[i]);
+ END_REPEAT;
+
+ nega[-3] := 1;
+ nega[-2] := 2;
+ nega[-1] := 3;
+ REPEAT i := LOINDEX(nega) TO HIINDEX(nega);
+ writeln('nega[', i:1, '] = ', nega[i]);
+ println('nega[', i:1, '] = ', nega[i]);
+ END_REPEAT;
+
+
+ r1 := PI/4;
+ println('r1 = PI/4 (0.78539...)', r1);
+ r2 := cos(r1);
+ println('cos(r1) (0.70710...)', r2);
+ r2 := sin(r1);
+ println('sin(r1) (0.70710...)', r2);
+ r2 := tan(r1);
+ println('tan(r1) (1.0)', r2);
+
+ writeln('r1 = PI/4', r1);
+ writeln('cos(r1)', cos(r1));
+ writeln('sin(r1)', sin(r1));
+ writeln('tan(r1)', tan(r1));
+
+ r1 := CONST_E;
+ println('r1 = CONST_E', r1);
+ r2 := log(4.5);
+ println('log(4.5) (1.504077...)', r2);
+ r2 := log2(8);
+ println('log2(8) (3.00)', r2);
+ r2 := log10(10);
+ println('log10(10) (1.00)', r2);
+
+ writeln('r1 = CONST_E', r1);
+ writeln('log(4.5)', log(4.5));
+ writeln('log2(8)', log2(8));
+ writeln('log10(10)', log10(10));
+
+ r2 := exp(10);
+ println('exp(10) (2.203...e4)', r2);
+ writeln('exp(10) (2.203...e4)', r2);
+
+ r2 := sqrt(121);
+ println('sqrt(121) (11.0)', r2);
+ writeln('sqrt(121) (11.0)', r2);
+
+
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+ println('no. of els in lagg = ', i);
+
+ INSERT(lagg, 10, 0);
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+ println('no. of els in lagg = ', i);
+
+ INSERT(lagg, 20, 0);
+ writeln('no. of els in lagg = ', SIZEOF(lagg));
+ println('no. of els in lagg = ', SIZEOF(lagg));
+
+ i := lagg[1];
+ writeln('first = ', i);
+ println('first = ', i);
+
+ writeln('lagg[2] = ', lagg[2]);
+ println('lagg[2] = ', lagg[2]);
+
+ b := 10 IN lagg;
+ writeln(b);
+ println(b);
+
+ b := 30 IN lagg;
+ writeln(b);
+ println(b);
+
+ REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ writeln('lagg[', i:1, '] = ', lagg[i]);
+ println('lagg[', i:1, '] = ', lagg[i]);
+ END_REPEAT;
+
+
+
+ b := FALSE;
+ b := ?;
+ writeln(b);
+ println(b);
+
+
+END;
+
+ writeln; println;
+ easter;
+
+ writeln; println;
+ magic_square(3);
+
+
+ writeln('Test CASE');
+ println('Test CASE (should be otherwise)');
+ n := 8;
+ CASE n OF
+ OTHERWISE : BEGIN
+ writeln('otherwise');
+ println('otherwise');
+ END;
+ 1, 9 : BEGIN
+ writeln(n);
+ println(n);
+ END;
+ END_CASE;
+
+ writeln('Test CASE');
+ println('Test CASE (should be 9)');
+ n := 9;
+ CASE n OF
+ OTHERWISE : BEGIN
+ writeln('otherwise');
+ println('otherwise');
+ END;
+ 1, 9 : BEGIN
+ writeln(n);
+ println(n);
+ END;
+ END_CASE;
+
+
+
+ writeln('Test REPEAT');
+ println('Test REPEAT (should be -2, -1)');
+ i := -2;
+ REPEAT UNTIL i = 0;
+ writeln(i);
+ println(i);
+-- ESCAPE;
+ i := i + 1;
+ END_REPEAT;
+
+ writeln('Test REPEAT');
+ println('Test REPEAT (should be 1, 2, 3)');
+ REPEAT i := 1 TO 3;
+ writeln(i);
+ println(i);
+ END_REPEAT;
+
+ writeln('Test REPEAT');
+ println('Test REPEAT (should be 3, 2, 1)');
+ REPEAT i := 3 TO 1 BY -1;
+ writeln(i);
+ println(i);
+ END_REPEAT;
+
+
+
+ writeln('Test LIKE');
+ println('Test LIKE');
+ writeln(('A' LIKE 'A'));
+ writeln(('A' LIKE 'b'));
+ writeln(('Page 407' LIKE '$###'));
+ writeln(('Page 23' LIKE '$###'));
+ println('A' LIKE 'A');
+ println('A' LIKE 'B');
+ println('Page 407' LIKE '$###');
+ println('Page 23' LIKE '$###');
+
+
+ writeln('Test rexpr');
+ println('Test rexpr');
+ writeln(rexpr('A', 'A'));
+ writeln(rexpr('A', 'b'));
+ writeln(rexpr('Page 407', '[a-zA-Z]+\ [0-9]+'));
+ writeln(rexpr('Page 23', '[a-zA-Z]+\ [0-9]'));
+ println(rexpr('A', 'A'));
+ println(rexpr('A', 'b'));
+ println(rexpr('Page 407', '[a-zA-Z]+\ [0-9]+'));
+ println(rexpr('Page 23', '[a-zA-Z]+\ [0-9]'));
+
+
+
+ writeln('Test IF THEN ELSE');
+ println('Test IF THEN ELSE');
+ IF TRUE THEN BEGIN
+ writeln('Then branch');
+ println('Then branch');
+ END;
+ ELSE BEGIN
+ writeln('Else branch');
+ println('Else branch');
+ END;
+ END_IF;
+
+ IF FALSE THEN
+ writeln('Then branch');
+ println('Then branch');
+ ELSE
+ writeln('Else branch');
+ println('Else branch');
+ END_IF;
+
+
+
+ a[1] := 10;
+ a[2] := 20;
+ a[3] := 30;
+ i := a[2];
+ writeln('a[2] should be 20', i);
+ println('a[2] should be 20', i);
+ writeln('Test REPEAT (should be 1 10, 1 20, 3 30)');
+ println('Test REPEAT (should be 1 10, 2 20, 3 30)');
+ REPEAT i := 1 TO 3;
+ writeln(i, a[i]);
+ println(i, a[i]);
+ END_REPEAT;
+
+
+ a23[1][1] := 11;
+ a23[1][2] := 12;
+ a23[1][3] := 13;
+ a23[2][1] := 21;
+ a23[2][2] := 22;
+ a23[2][3] := 23;
+
+ writeln('Test REPEAT');
+ println('Test REPEAT (should be 1 1 11, 1 2 12, 1 3 13, 2 1 21, 2 2 22 etc)');
+ REPEAT n := 1 TO 2;
+ REPEAT i := 1 TO 3;
+ writeln(n, i, a23[n][i]);
+ println(n, i, a23[n][i]);
+ END_REPEAT;
+ END_REPEAT;
+
+
+
+ s1 := 'string';
+ writeln(s1);
+ println(s1);
+ s2 := s1[2:4];
+ writeln(s2);
+ println(s2);
+ b := s1 <> s2;
+ writeln(b);
+ println(b);
+ writeln(s2 + s1);
+ println(s2 + s1);
+ writeln('Hello world');
+ println('Hello world');
+
+ i := 2;
+ n := 3*i;
+ writeln(i, n);
+ println(i, n);
+ n := 3*?;
+ writeln(i, n);
+ println(i, n);
+ i := ?;
+ n := 3*i;
+ writeln(i, n);
+ println(i, n);
+
+
+END_CODE
+
+ END_CTFILE= ***********************************************
+
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "Goodbye document"
+ CODE:
+-- BEGIN
+ println('BEGIN_DOCUMENT TAG');
+ writeln(i);
+ writeln(n);
+ writeln('Goodbye world');
+ println(i);
+ println(n);
+ println('Goodbye world');
+-- END
+ END_CODE
+c= PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \documentstyle
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \documentclass
+ START_TAG= "Goodbye document"
+ CODE:
+ BEGIN
+ println('DOCUMENTCLASS TAG');
+ i := 10;
+ n := 20;
+ writeln(i);
+ writeln(n);
+ writeln('Goodbye world');
+ println(i);
+ println(n);
+ println('Goodbye world');
+ b := fun(-9999);
+ println(b);
+ END ;
+ END_CODE
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+END_CTFILE= end of bye.ct
+
diff --git a/support/ltx2x/getopt.c b/support/ltx2x/getopt.c
new file mode 100644
index 0000000000..5131cfa4ff
--- /dev/null
+++ b/support/ltx2x/getopt.c
@@ -0,0 +1,85 @@
+/* file getopt.c */
+/* Author: Peter Wilson */
+/* Catholic University and NIST */
+/* pwilson@cme.nist.gov */
+/* */
+/* getopt() from Don Libes "Obfuscated C" */
+
+
+#include <stdio.h>
+
+/* getopt() -- parse command line arguments */
+/* Original Author: AT&T */
+/* This version from Don Libes "Obfuscated C and Other Mysteries" */
+/* John Wiley & Sons, 1993. Chapter 6 */
+
+
+#define ERR(s, c) if(opterr){\
+ char errbuf[2];\
+ errbuf[0] = c; errbuf[1] = '\n';\
+ fprintf(stderr, argv[0], (unsigned)strlen(argv[0]));\
+ fprintf(stderr, s, (unsigned)strlen(s));\
+ fprintf(stderr, errbuf, 2);}
+
+extern int strcmp();
+extern char *strchr();
+extern int strlen();
+
+int opterr = 1; /* getopt prints errors if this is one */
+int optind = 1; /* token pointer */
+int optopt; /* option character passed back to user */
+char *optarg; /* flag argument (or value) */
+
+int /* return option option character, EOF if no more or ? if problem */
+getopt(argc, argv, opts)
+int argc;
+char **argv;
+char *opts; /* option string */
+{
+ static int sp = 1; /* character index in current token */
+ register char *cp; /* pointer into current token */
+
+ if(sp == 1)
+ /* check for more flag-like tokens */
+ if(optind >= argc ||
+ argv[optind][0] != '-' || argv[optind][1] == '\0')
+ return(EOF);
+ else if(strcmp(argv[optind], "--") == 0) {
+ optind++;
+ return(EOF);
+ }
+ optopt = argv[optind][sp];
+ if(optopt == ':' || (cp=strchr(opts, optopt)) == 0) {
+ ERR(": illegal option -- ", optopt);
+ /* if no chars left in this token, move to next token */
+ if(argv[optind][++sp] == '\0') {
+ optind++;
+ sp = 1;
+ }
+ return('?');
+ }
+
+ if(*++cp == ':') {/* if a value is expected, get it */
+ if(argv[optind][sp+1] != '\0')
+ /* flag value is rest of current token */
+ optarg = &argv[optind++][sp+1];
+ else if(++optind >= argc) {
+ ERR(": option requires an argument -- ", optopt);
+ sp = 1;
+ return('?');
+ } else
+ /* flag value is next token */
+ optarg = argv[optind++];
+ sp = 1;
+ } else {
+ /* set up to look at next char in token, next time */
+ if(argv[optind][++sp] == '\0') {
+ /* no m ore in current token, set up next token */
+ sp = 1;
+ optind++;
+ }
+ optarg = 0;
+ }
+ return(optopt); /* return current flag character found */
+ }
+
diff --git a/support/ltx2x/getopt.h b/support/ltx2x/getopt.h
new file mode 100644
index 0000000000..4761761368
--- /dev/null
+++ b/support/ltx2x/getopt.h
@@ -0,0 +1,10 @@
+/* getopt.h from Don Libes "Obfuscated C" (extended by PRW) */
+#ifndef GETOPT_H
+#define GETOPT_H
+extern int getopt();
+extern char *optarg; /* current argv string */
+extern int optind; /* current argv index */
+extern int optopt; /* option character */
+extern int opterr; /* getopt prints errors if 1 */
+#endif /* GETOPT_H */
+
diff --git a/support/ltx2x/html.sty b/support/ltx2x/html.sty
new file mode 100644
index 0000000000..191bb19f4c
--- /dev/null
+++ b/support/ltx2x/html.sty
@@ -0,0 +1,360 @@
+% LaTeX2HTML Version 95.1 : html.sty
+%
+% WARNING: This file requires LaTeX2e. A LaTeX 2.09 version
+% is also provided, but with restricted functionality.
+%
+% This file contains definitions of LaTeX commands which are
+% processed in a special way by the translator.
+% For example, there are commands for embedding external hypertext links,
+% for cross-references between documents or for including
+% raw HTML.
+% This file includes the comments.sty file v2.0 by Victor Eijkhout
+% In most cases these commands do nothing when processed by LaTeX.
+
+% Modifications:
+%
+% nd = Nikos Drakos <nikos@cbl.leeds.ac.uk>
+% jz = Jelle van Zeijl <jvzeijl@isou17.estec.esa.nl>
+% hs = Herb Swan <dprhws@edp.Arco.com>
+
+% hs 31-JAN-96 - Added support for document segmentation
+% hs 10-OCT-95 - Added \htmlrule command
+% jz 22-APR-94 - Added support for htmlref
+% nd - Created
+%%%%MG added
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{html}
+ [1996/02/01 v1.0 hypertext commands for latex2html (nd, hs)]
+%%%%MG
+% Exit if the style file is already loaded
+% (suggested by Lee Shombert <las@potomac.wash.inmet.com>
+\ifx \htmlstyloaded\relax \endinput\else\let\htmlstyloaded\relax\fi
+
+%%% LINKS TO EXTERNAL DOCUMENTS
+%
+% This can be used to provide links to arbitrary documents.
+% The first argumment should be the text that is going to be
+% highlighted and the second argument a URL.
+% The hyperlink will appear as a hyperlink in the HTML
+% document and as a footnote in the dvi or ps files.
+%
+\newcommand{\htmladdnormallinkfoot}[2]{#1\footnote{#2}}
+
+% This is an alternative definition of the command above which
+% will ignore the URL in the dvi or ps files.
+\newcommand{\htmladdnormallink}[2]{#1}
+
+% This command takes as argument a URL pointing to an image.
+% The image will be embedded in the HTML document but will
+% be ignored in the dvi and ps files.
+%
+\newcommand{\htmladdimg}[1]{}
+
+%%% CROSS-REFERENCES BETWEEN (LOCAL OR REMOTE) DOCUMENTS
+%
+% This can be used to refer to symbolic labels in other Latex
+% documents that have already been processed by the translator.
+% The arguments should be:
+% #1 : the URL to the directory containing the external document
+% #2 : the path to the labels.pl file of the external document.
+% If the external document lives on a remote machine then labels.pl
+% must be copied on the local machine.
+%
+%e.g. \externallabels{http://cbl.leeds.ac.uk/nikos/WWW/doc/tex2html/latex2html}
+% {/usr/cblelca/nikos/tmp/labels.pl}
+% The arguments are ignored in the dvi and ps files.
+%
+\newcommand{\externallabels}[2]{}
+
+%
+% This complements the \externallabels command above. The argument
+% should be a label defined in another latex document and will be
+% ignored in the dvi and ps files.
+%
+\newcommand{\externalref}[1]{}
+
+% This command adds a horizontal rule and is valid even within
+% a figure caption.
+%
+\newcommand{\htmlrule}{}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% The following commands pertain to document segmentation, and
+% were added by Herbert Swan <dprhws@edp.Arco.com> (with help from
+% Michel Goossens <goossens@cern.ch>):
+%
+%
+% This command inputs internal latex2html tables so that large
+% documents can to partitioned into smaller (more manageable)
+% segments.
+%
+\newcommand{\internal}[2][internals]{}
+
+%
+% Define a dummy stub \htmlhead{}. This command causes latex2html
+% to define the title of the start of a new segment. It is not
+% normally placed in the user's document. Rather, it is passed to
+% latex2html via a .ptr file written by \segment.
+%
+\newcommand{\htmlhead}[2]{}
+
+%
+% The dummy command \endpreamble is needed by latex2html to
+% mark the end of the preamble in document segments that do
+% not contain a \begin{document}
+%
+\newcommand{\startdocument}{}
+
+%
+% Allocate a new set of section counters, which will get incremented
+% for "*" forms of sectioning commands, and for a few miscellaneous
+% commands.
+%
+
+\newcounter{lpart}
+\newcounter{lchapter}[part]
+\ifx\chapter\undefined\newcounter{lsection}[part]\else\newcounter{lsection}[chapter]\fi
+\newcounter{lsubsection}[section]
+\newcounter{lsubsubsection}[subsection]
+\newcounter{lparagraph}[subsubsection]
+\newcounter{lsubparagraph}[paragraph]
+\newcounter{lsubsubparagraph}[subparagraph]
+\newcounter{lequation}
+%
+% Redefine "*" forms of sectioning commands to increment their
+% respective counters.
+%
+\let\Hpart=\part
+\let\Hchapter=\chapter
+\let\Hsection=\section
+\let\Hsubsection=\subsection
+\let\Hsubsubsection=\subsubsection
+\let\Hparagraph=\paragraph
+\let\Hsubparagraph=\subparagraph
+\let\Hsubsubparagraph=\subsubparagraph
+
+%
+% The following definitions are specific to LaTeX2e:
+% (They must be commented out for LaTeX 2.09)
+%
+\def\part{\@ifstar{\stepcounter{lpart}\Hpart*}{\Hpart}}
+\def\chapter{\@ifstar{\stepcounter{lchapter}\Hchapter*}{\Hchapter}}
+\def\section{\@ifstar{\stepcounter{lsection}\Hsection*}{\Hsection}}
+\def\subsection{\@ifstar{\stepcounter{lsubsection}\Hsubsection*}{\Hsubsection}}
+\def\subsubsection{\@ifstar{\stepcounter{lsubsubsection}\Hsubsubsection*}{\Hsubsubsection}}
+\def\paragraph{\@ifstar{\stepcounter{lparagraph}\Hparagraph*}{\Hparagraph}}
+\def\subparagraph{\@ifstar{\stepcounter{lsubparagraph}\Hsubparagraph*}{\Hsubparagraph}}
+\def\subsubparagraph{\@ifstar{\stepcounter{lsubsubparagraph}\Hsubsubparagraph*}{\Hsubsubparagraph}}
+%
+% Define a helper macro to dump a single \secounter command to a file.
+%
+\newcommand{\DumpPtr}[2]{%
+\count255=\arabic{#1} \advance\count255 by \arabic{#2}
+\immediate\write\ptrfile{%
+\noexpand\setcounter{#1}{\number\count255}}}
+
+%
+% Define a helper macro to dump all counters to the file.
+% The value for each counter will be the sum of the l-counter
+% actual LaTeX section counter.
+% Also dump an \htmlhead{section-command}{section title} command
+% to the file.
+%
+
+\def\DumpCounters#1#2#3{\newwrite\ptrfile
+\immediate\openout\ptrfile = #1.ptr
+\DumpPtr{part}{lpart}
+\ifx\Hchapter\undefined\relax\else\DumpPtr{chapter}{lchapter}\fi
+\DumpPtr{section}{lsection}
+\DumpPtr{subsection}{lsubsection}
+\DumpPtr{subsubsection}{lsubsubsection}
+\DumpPtr{paragraph}{lparagraph}
+\DumpPtr{subparagraph}{lsubparagraph}
+\DumpPtr{equation}{lequation}
+\immediate\write\ptrfile{\noexpand\htmlhead{#2}{#3}}
+\immediate\closeout\ptrfile}
+
+%
+% Define the \segment{file}{section-command}{section-title} command,
+% and its helper macros. This command does four things:
+% 1) Begins a new LaTeX section;
+% 2) Writes a list of section counters to file.ptr, each
+% of which represents the sum of the LaTeX section
+% counters, and the l-counters, defined above;
+% 3) Write an \htmlhead{section-title} command to file.ptr;
+% 4) Inputs file.tex.
+%
+
+%%%%MG changed
+\def\segment{\@ifstar{\@@htmls}{\@@html}}
+\def\@@htmls#1#2#3{\csname #2\endcsname* {#3}%
+ \DumpCounters{#1}{#2*}{#3}\input{#1}}
+\def\@@html#1#2#3{\csname #2\endcsname {#3}%
+ \DumpCounters{#1}{#2}{#3}\input{#1}}
+%%%%MG
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Comment.sty version 2.0, 19 June 1992
+% selectively in/exclude pieces of text: the user can define new
+% comment versions, and each is controlled separately.
+% This style can be used with plain TeX or LaTeX, and probably
+% most other packages too.
+%
+% Examples of use in LaTeX and TeX follow \endinput
+%
+% Author
+% Victor Eijkhout
+% Department of Computer Science
+% University Tennessee at Knoxville
+% 104 Ayres Hall
+% Knoxville, TN 37996
+% USA
+%
+% eijkhout@cs.utk.edu
+%
+% Usage: all text included in between
+% \comment ... \endcomment
+% or \begin{comment} ... \end{comment}
+% is discarded. The closing command should appear on a line
+% of its own. No starting spaces, nothing after it.
+% This environment should work with arbitrary amounts
+% of comment.
+%
+% Other 'comment' environments are defined by
+% and are selected/deselected with
+% \includecomment{versiona}
+% \excludecoment{versionb}
+%
+% These environments are used as
+% \versiona ... \endversiona
+% or \begin{versiona} ... \end{versiona}
+% with the closing command again on a line of its own.
+%
+% Basic approach:
+% to comment something out, scoop up every line in verbatim mode
+% as macro argument, then throw it away.
+% For inclusions, both the opening and closing comands
+% are defined as noop
+%
+% Changed \next to \html@next to prevent clashes with other sty files
+% (mike@emn.fr)
+% Changed \html@next to \htmlnext so the \makeatletter and
+% \makeatother commands could be removed (they were causing other
+% style files - changebar.sty - to crash) (nikos@cbl.leeds.ac.uk)
+% Changed \htmlnext back to \html@next...
+
+\makeatletter
+\def\makeinnocent#1{\catcode`#1=12 }
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+
+\def\ThrowAwayComment#1{\begingroup
+ \def\CurrentComment{#1}%
+ \let\do\makeinnocent \dospecials
+ \makeinnocent\^^L% and whatever other special cases
+ \endlinechar`\^^M \catcode`\^^M=12 \xComment}
+{\catcode`\^^M=12 \endlinechar=-1 %
+ \gdef\xComment#1^^M{\def\test{#1}
+ \csarg\ifx{PlainEnd\CurrentComment Test}\test
+ \let\html@next\endgroup
+ \else \csarg\ifx{LaLaEnd\CurrentComment Test}\test
+ \edef\html@next{\endgroup\noexpand\end{\CurrentComment}}
+ \else \let\html@next\xComment
+ \fi \fi \html@next}
+}
+\makeatother
+
+\def\includecomment
+ #1{\expandafter\def\csname#1\endcsname{}%
+ \expandafter\def\csname end#1\endcsname{}}
+\def\excludecomment
+ #1{\expandafter\def\csname#1\endcsname{\ThrowAwayComment{#1}}%
+ {\escapechar=-1\relax
+ \csarg\xdef{PlainEnd#1Test}{\string\\end#1}%
+ \csarg\xdef{LaLaEnd#1Test}{\string\\end\string\{#1\string\}}%
+ }}
+
+\excludecomment{comment}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%% RAW HTML
+%
+% Enclose raw HTML between a \begin{rawhtml} and \end{rawhtml}.
+% The html environment ignores its body
+%
+\excludecomment{rawhtml}
+
+%%% HTML ONLY
+%
+% Enclose LaTeX constructs which will only appear in the
+% HTML output and will be ignored by LaTeX with
+% \begin{htmlonly} and \end{htmlonly}
+%
+\excludecomment{htmlonly}
+% Shorter version
+\newcommand{\html}[1]{}
+
+
+%%% LaTeX ONLY
+% Enclose LaTeX constructs which will only appear in the
+% DVI output and will be ignored by latex2html with
+%\begin{latexonly} and \end{latexonly}
+%
+\newenvironment{latexonly}{}{}
+% Shorter version
+\newcommand{\latex}[1]{#1}
+
+%%% HYPERREF
+% Suggested by Eric M. Carol <eric@ca.utoronto.utcc.enfm>
+% Similar to \ref but accepts conditional text.
+% The first argument is HTML text which will become ``hyperized''
+% (underlined).
+% The second and third arguments are text which will appear only in the paper
+% version (DVI file), enclosing the fourth argument which is a reference to a label.
+%
+%e.g. \hyperref{using the tracer}{using the tracer (see Section}{)}{trace}
+% where there is a corresponding \label{trace}
+%
+\newcommand{\hyperref}[4]{#2\ref{#4}#3}
+
+%%% HTMLREF
+% Reference in HTML version only.
+% Mix between \htmladdnormallink and \hyperref.
+% First arg is text for in both versions, second is label for use in HTML
+% version.
+\newcommand{\htmlref}[2]{#1}
+
+%%% HTMLIMAGE
+% This command can be used inside any environment that is converted
+% into an inlined image (eg a "figure" environment) in order to change
+% the way the image will be translated. The argument of \htmlimage
+% is really a string of options separated by commas ie
+% [scale=<scale factor>],[external],[thumbnail=<reduction factor>
+% The scale option allows control over the size of the final image.
+% The ``external'' option will cause the image not to be inlined
+% (images are inlined by default). External images will be accessible
+% via a hypertext link.
+% The ``thumbnail'' option will cause a small inlined image to be
+% placed in the caption. The size of the thumbnail depends on the
+% reduction factor. The use of the ``thumbnail'' option implies
+% the ``external'' option.
+%
+% Example:
+% \htmlimage{scale=1.5,external,thumbnail=0.2}
+% will cause a small thumbnail image 1/5th of the original size to be
+% placed in the final document, pointing to an external image 1.5
+% times bigger than the original.
+%
+\newcommand{\htmlimage}[1]{}
+
+%%% HTMLADDTONAVIGATION
+% This command appends its argument to the buttons in the navigation
+% panel. It is ignored by LaTeX.
+%
+% Example:
+% \htmladdtonavigation{\htmladdnormallink
+% {\htmladdimg{http://server/path/to/gif}}
+% {http://server/path}}
+\newcommand{\htmladdtonavigation}[1]{}
+
+\endinput \ No newline at end of file
diff --git a/support/ltx2x/l2h.ct b/support/ltx2x/l2h.ct
new file mode 100644
index 0000000000..00a52369f5
--- /dev/null
+++ b/support/ltx2x/l2h.ct
@@ -0,0 +1,1709 @@
+ c= l2h.ct CT file for ltx2x to convert typical document to HTML
+ c= includes support for packages url, html, hyperref, hyper
+ c= plus the new commands specified for the LTX2X manual
+ c= Author: Peter Wilson (pwilson@cme.nist.gov) August 1996
+
+ c= -------------------- escape sequences
+
+ESCAPE_CHAR= ?
+
+ c= -------------------- required built in commands
+
+TYPE= BEGIN_DOCUMENT
+ c= ( \begin{document} --> <html>
+ c= <head>
+ c= <title>Contents of \mltitle</title>
+ c= </head>
+ c= <body>
+ c= (This document ... program.)
+ c= <a name="HtMlSoD"></a><a href="#HtMlEoD">To the end</a> )
+ START_TAG= "<html>?n<head>?n<title>"
+ SOURCE: BUFFER 1
+ STRING: "</title>?n</head>?n<body>?n"
+ STRING: "(This document was automatically generated from LaTeX source "
+ STRING: "by the ltx2x program.)?n"
+ STRING: "<a name="HtMlSoD"></a><a href="#HtMlEoD">To the end</a>?n"
+ RESET_BUFFER: 1
+END_TYPE
+
+TYPE= END_DOCUMENT
+ c= ( \end{document} --> <a name="HtMlEoD"></a><a href="#HtMlSoD">To the start</a>
+ c= </body>
+ c= <html> )
+ START_TAG= "<a name="HtMlEoD"></a><a href="#HtMlSoD">To the start</a>?n"
+ STRING: "</body>?n</html>?n"
+END_TYPE
+
+TYPE= BEGIN_VERB
+ c= ( \verb| --> <samp> )
+ START_TAG= "<samp>"
+END_TYPE
+
+TYPE= END_VERB
+ START_TAG= "</samp>"
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ c= ( \begin{verbatim} --> <pre> )
+ START_TAG= "<pre>"
+END_TYPE
+
+TYPE= END_VERBATIM
+ c= ( \end{verbatim} --> </pre> )
+ START_TAG= "</pre>"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+END_TYPE
+
+TYPE= END_DOLLAR
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= " "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= LBRACE
+ START_TAG= ""
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= ""
+END_TYPE
+
+TYPE= PARAGRAPH
+ START_TAG= "?n<p>"
+END_TYPE
+
+ c= ---------------------- (La)TeX special characters
+
+ c= hash (for use in \def s )
+TYPE= TEX_CHAR
+NAME= #
+END_TYPE
+
+ c= twiddle (unbreakable space)
+TYPE= TEX_CHAR
+NAME= ~
+ START_TAG= " "
+END_TYPE
+
+ c= underscore (math subscript)
+ c= require a parameter
+TYPE= TEX_CHAR
+NAME= _
+ c= ( _{text} --> <sub>text</sub> )
+ START_TAG_1= "<sub>"
+ END_TAG_1= "</sub>"
+ REQPARAMS= 1
+END_TYPE
+
+ c= caret (math superscript)
+ c= require a parameter
+TYPE= TEX_CHAR
+NAME= ^
+ c= ( ~{text} --> <sup>text</sup> )
+ START_TAG_1= "<sup>"
+ END_TAG_1= "</sup>"
+ REQPARAMS= 1
+END_TYPE
+
+ c= percent (start of comment)
+TYPE= TEX_CHAR
+NAME= %
+ START_TAG= ""
+END_TYPE
+
+ c= at
+TYPE= TEX_CHAR
+NAME= @
+ START_TAG= "@"
+END_TYPE
+
+ c= ----------------------- default single character commands
+
+ c= LaTeX start a new line
+TYPE= CHAR_COMMAND
+NAME= \\
+ c= ( \\ --> <br> )
+ START_TAG= "<br>"
+IN_MODE= tabular
+ c= ( \\ --> BUFFER 8">BUFFER 9</tr>
+ c= <tr><td )
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "> "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= "</tr>?n<tr><td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_MODE
+IN_MODE= eqnarray
+ c= ( \\ --> </td></tr>
+ c= <tr align=center><td nowrap> )
+ START_TAG= "</td></tr>?n<tr align=center><td nowrap>"
+END_MODE
+END_TYPE
+
+ c= small space
+TYPE= CHAR_COMMAND
+NAME= \,
+ START_TAG= " "
+END_TYPE
+
+ c= end of sentence space
+TYPE= CHAR_COMMAND
+NAME= \@
+ START_TAG= " "
+END_TYPE
+
+ c= hash
+TYPE= CHAR_COMMAND
+NAME= \#
+ START_TAG= "#"
+END_TYPE
+
+ c= dollar
+TYPE= CHAR_COMMAND
+NAME= \$
+ START_TAG= "$"
+END_TYPE
+
+ c= ampersand
+TYPE= CHAR_COMMAND
+NAME= \&
+ START_TAG= "&amp;"
+END_TYPE
+
+ c= underscore
+TYPE= CHAR_COMMAND
+NAME= \_
+ START_TAG= "_"
+END_TYPE
+
+ c= percent
+TYPE= CHAR_COMMAND
+NAME= \%
+ START_TAG= "%"
+END_TYPE
+
+ c= optional hyphenation
+TYPE= CHAR_COMMAND
+NAME= \-
+ START_TAG= ""
+END_TYPE
+
+ c= left brace
+TYPE= CHAR_COMMAND
+NAME= \{
+ START_TAG= "{"
+END_TYPE
+
+ c= right brace
+TYPE= CHAR_COMMAND
+NAME= \}
+ START_TAG= "}"
+END_TYPE
+
+ c= ----------------------------- (re)newstuff
+ c= do no processing
+
+TYPE= COMMAND_POOP
+NAME= \newcommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOP
+NAME= \renewcommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOP
+NAME= \providecommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \newenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \renewenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+
+ c= ------------------------- General (La)TeX
+
+ c= ------------------------- document title, author, etc
+
+TYPE= COMMAND
+NAME= \documentclass
+ c= empty buffer 1 in case \mltitle not used in document
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+ PRINT_OPT= NO_PRINT
+ END_TAG=
+ RESET_BUFFER: 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \documentstyle
+ c= empty buffer 1 in case \mltitle not used in document
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+ PRINT_OPT= NO_PRINT
+ END_TAG=
+ RESET_BUFFER: 1
+END_TYPE
+
+ c= special latex tag for html title
+TYPE= COMMAND
+NAME= \mltitle
+ c= ( newcommand{\mltitle}[1]{} )
+ c= ( \mltitle{text} --> BUFFER 1 )
+ REQPARAMS= 1
+ START_TAG=
+ RESET_BUFFER: 1
+ PRINT_P1= TO_BUFFER 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \maketitle
+ c= ( \maketitle --> <h1 align=center>
+ c= contents of \title command
+ c= </h1>
+ c= <h3 align=center>
+ c= contents of \author command
+ c= </h3>
+ c= <h3 align=center>
+ c= contents of \date command
+ c= </h3> )
+ START_TAG= "?n"
+ STRING: "<h1 align=center>?n"
+ SOURCE: FILE tit.tmp
+ STRING: "?n</h1>?n<h3 align=center>?n"
+ SOURCE: BUFFER 2
+ STRING: "?n</h3>?n<h3 align=center>?n"
+ SOURCE: BUFFER 3
+ STRING: "?n</h3>?n"
+ RESET_BUFFER: 2
+ RESET_BUFFER: 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \title
+ REQPARAMS= 1
+ PRINT_P1= TO_FILE tit.tmp
+END_TYPE
+
+TYPE= COMMAND
+NAME= \author
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 2
+END_TYPE
+
+TYPE= COMMAND
+NAME= \date
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \thanks
+ c= ( \thanks{text} --> <br><font size=-1>(text)</font><br> )
+ START_TAG= "<br><font size=-1>("
+ END_TAG= ")</font><br>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= abstract
+ c= ( \begin{abstract} --> <h4>Abstract</h4>
+ c= <blockquote> )
+ START_TAG= "<h4>Abstract</h4>?n<blockquote>?n"
+END_TYPE
+
+TYPE= END_ENV
+NAME= abstract
+ c= ( \end{abstract} --> </blockquote> )
+ START_TAG= "</blockquote>?n"
+END_TYPE
+
+ c= ---------------------- tables
+
+TYPE= BEGIN_ENV
+NAME= table
+ c= ( \begin{table}[opt] --> <center><table border> )
+ START_TAG= "<center><table border>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ END_TAG=
+ SET_MODE: table
+END_TYPE
+
+TYPE= END_ENV
+NAME= table
+ c= ( \end{table} --> </table></center> )
+ START_TAG= "</table></center>"
+ END_TAG=
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= tabular
+ c= ( \begin{tabular}{pream} --> <tr><td )
+ START_TAG= "?n<tr><td"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ END_TAG= ""
+ SET_MODE: tabular
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+
+TYPE= COMMAND
+NAME= \multicolumn
+ c= ( \multicolumn{num}{pream} --> colspan=num )
+ PC_AT_START= TO_BUFFER 8
+ REQPARAMS= 2
+ START_TAG_1= " colspan="
+ PRINT_P2= NO_PRINT
+ PC_AT_END= RESET
+END_TYPE
+
+ c= ampersand (table column delimeter)
+TYPE= TEX_CHAR
+NAME= &
+ c= ( & --> BUFFER 8 > BUFFER 9 </td><td )
+ PC_AT_START= RESET
+ START_TAG= ""
+ SOURCE: BUFFER 8
+ STRING: "> "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= " </td><td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+IN_MODE= eqnarray
+ c= ( & --> </td><td nowrap> )
+ START_TAG= "</td><td nowrap>"
+END_MODE
+END_TYPE
+
+TYPE= END_ENV
+NAME= tabular
+ c= ( \end{tabular} --> > )
+ PC_AT_START= RESET
+ START_TAG= ">"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ RESET_MODE:
+END_TYPE
+
+ c= -------------------------------- EQNARRYs (a simple "table" format)
+
+TYPE= BEGIN_ENV
+NAME= eqnarray
+ c= ( \begin{eqnarray} --> <center><table>
+ c= <tr align=center><td nowrap> )
+ START_TAG= "?n<center><table>?n<tr align=center><td nowrap>"
+ SET_MODE: eqnarray
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarray*
+ c= as for eqnarray
+ START_TAG= "?n<center><table>?n<tr align=center><td nowrap>"
+ SET_MODE: eqnarray
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray
+ c= ( \end{eqnarray} --> </table></center> )
+ START_TAG= "</table></center>"
+ RESET_MODE:
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray*
+ c= as for eqnarray*
+ START_TAG= "</table></center>"
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= figure
+ c= ( \begin{figure}[opt] --> <h4 align=center>FIGURE</h4> )
+ START_TAG= "?n<h4 align=center>FIGURE</h4>?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ END_TAG=
+ SET_MODE: figure
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+ c= ( \end{figure} --> <h5 align=center>Figures ... available!</h5> )
+ START_TAG= "?n"
+ STRING: "<h5 align=center>Figures are not yet available!</h5>"
+ END_TAG=
+ RESET_MODE:
+END_TYPE
+
+TYPE= COMMAND
+NAME= \centering
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= center
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_ENV
+NAME= center
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \caption
+ c= ( \caption[opt]{text} --> <caption>text</caption> )
+ START_TAG= "<caption>"
+ END_TAG= "</caption>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+ c= --------------------------- lists
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ c= ( \begin{itemize} --> <ul> )
+ c= ( \item --> <li> )
+ START_TAG= "<ul>?n"
+ START_ITEM= "?n <li> "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ c= ( \end{itemize} --> </ul> )
+ START_TAG= "</ul>?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ c= ( \begin{enumerate} --> <ol> )
+ c= ( \item --> <li> )
+ START_TAG= "<ol>?n"
+ START_ITEM= "?n <li> "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ c= ( \end{enumerate} --> </ol> )
+ START_TAG= "</ol>?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ c= ( \begin{description} --> <dl> )
+ c= ( \item[text] --> <dt>text
+ c= <dd> )
+ START_TAG= "<dl>"
+ START_ITEM= "<dt>"
+ END_ITEM_PARAM= "?n<dd>"
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+ c= ( \end{description} --> </dl> )
+ START_TAG= "</dl>"
+END_TYPE
+
+ c= fake some \dots commands
+TYPE= COMMAND
+NAME= \ldots
+ START_TAG= "..."
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cdots
+ START_TAG= "..."
+END_TYPE
+
+TYPE= COMMAND
+NAME= \vdots
+ START_TAG= ":"
+END_TYPE
+
+
+ c= replace footnote with parenthesised text
+TYPE= COMMAND
+NAME= \footnote
+ c= ( \footnote[opt]{text} --> (Footnote: text) )
+ START_TAG= " (Footnote: "
+ END_TAG= ") "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+
+ c= -------------------------- quotations
+TYPE= BEGIN_ENV
+NAME= quote
+ c= ( \begin{quote} --> <blockquote> )
+ START_TAG= "<blockquote>"
+END_TYPE
+
+TYPE= END_ENV
+NAME= quote
+ c= ( \end{quote} --> </blockquote> )
+ START_TAG= "</blockquote>"
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= quotation
+ c= as per quote
+ START_TAG= "<blockquote>"
+END_TYPE
+
+TYPE= END_ENV
+NAME= quotation
+ c= as per quote
+ START_TAG= "</blockquote>"
+END_TYPE
+
+
+
+TYPE= COMMAND
+NAME= \TeX
+ START_TAG= "TeX"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \LaTeX
+ START_TAG= "LaTeX"
+END_TYPE
+
+ c= --------------------------- Picture commands
+ c= throw all their contents away
+
+TYPE= BEGIN_PICTURE_CC
+NAME= picture
+ PC_AT_START= NO_PRINT
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CP
+NAME= \put
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CCPP
+NAME= \multiput
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_PCOP
+NAME= \savebox
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCC
+NAME= \graphpaper
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCCC
+NAME= \qbezier
+ PRINT_P1= NO_PRINT
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= END_PICTURE
+NAME= picture
+ PC_AT_END= RESET
+END_TYPE
+
+
+ c= -------------------------- sectioning (keep headers only)
+
+TYPE= SECTIONING
+NAME= \part
+ c= ( \part[opt]{text} --> <h1>text</h1> )
+ SECTIONING_LEVEL= PART
+ START_TAG= "<h1>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h1>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \chapter
+ c= similar to part
+ SECTIONING_LEVEL= CHAPTER
+ START_TAG= "<h2>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h2>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \section
+ c= similar to part
+ SECTIONING_LEVEL= SECT
+ START_TAG= "<h2>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h2>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsection
+ c= similar to part
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "<h3>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h3>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsubsection
+ c= similar to part
+ SECTIONING_LEVEL= SUBSUBSECT
+ START_TAG= "<h4>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h4>"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \paragraph
+ c= similar to part
+ SECTIONING_LEVEL= PARA
+ START_TAG= "<h5>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h5>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subparagraph
+ c= similar to part
+ SECTIONING_LEVEL= SUBPARA
+ START_TAG= "<h6>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h6>?n"
+END_TYPE
+
+
+TYPE= SECTIONING
+NAME= \part*
+ c= similar to part
+ SECTIONING_LEVEL= PART
+ START_TAG= "<h1>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h1>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \chapter*
+ c= similar to part
+ SECTIONING_LEVEL= CHAPTER
+ START_TAG= "<h2>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h2>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \section*
+ c= similar to part
+ SECTIONING_LEVEL= SECT
+ START_TAG= "<h2>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h2>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsection*
+ c= similar to part
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "<h3>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h3>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subsubsection*
+ c= similar to part
+ SECTIONING_LEVEL= SUBSUBSECT
+ START_TAG= "<h4>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h4>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \paragraph*
+ c= similar to part
+ SECTIONING_LEVEL= PARA
+ START_TAG= "<h5>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h5>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \subparagraph*
+ c= similar to part
+ SECTIONING_LEVEL= SUBPARA
+ START_TAG= "<h6>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "</h6>?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \appendix
+ c= ( \appendix --> <h2>APPENDICES</h2> )
+ START_TAG= "?n<h2>APPENDICES</h2>?n"
+END_TYPE
+
+ c= --------------------------------- misc stuff
+
+TYPE= COMMAND
+NAME= \quad
+ START_TAG= " "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \tableofcontents
+END_TYPE
+
+TYPE= COMMAND
+NAME= \listoffigures
+END_TYPE
+
+TYPE= COMMAND
+NAME= \listoftables
+END_TYPE
+
+TYPE= COMMAND
+NAME= \clearpage
+END_TYPE
+
+TYPE= COMMAND
+NAME= \pagenumbering
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \bibliographystyle
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \bibliography
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+ c= --------------------------------- special characters LaTeX -> HTML
+
+TYPE= TEX_CHAR
+NAME= <
+ c= ( < --> &lt; )
+ START_TAG= "&lt;"
+END_TYPE
+
+TYPE= TEX_CHAR
+NAME= >
+ c= ( > --> &gt; )
+ START_TAG= "&gt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \dag
+ START_TAG= "&#134;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ddag
+ START_TAG= "&#135;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \OE
+ START_TAG= "&#140;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \oe
+ START_TAG= "&#156;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \pounds
+ START_TAG= "&pound;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \S
+ START_TAG= "&sect;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \copyright
+ START_TAG= "&copy;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \neg
+ START_TAG= "&not;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \pm
+ START_TAG= "&plusmn;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \mu
+ START_TAG= "&micro;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \P
+ START_TAG= "&para;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \AA
+ START_TAG= "&Aring;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \AE
+ START_TAG= "&AElig;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \times
+ START_TAG= "&times;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \O
+ START_TAG= "&Oslash;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ss
+ START_TAG= "&szlig;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \aa
+ START_TAG= "&aring;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ae
+ START_TAG= "&aelig;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \div
+ START_TAG= "&divide;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \o
+ START_TAG= "&oslash;"
+END_TYPE
+
+
+ c= ---------------------------- some math commands
+
+TYPE= COMMAND
+NAME= \mathcal
+ c= ( \mathcal{text} --> <i>text</i> )
+ REQPARAMS= 1
+ START_TAG_1= "<i>"
+ END_TAG_1= "</i>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \leq
+ START_TAG= " &lt;= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \geq
+ START_TAG= " &gt;= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \neq
+ START_TAG= " /= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \subseteq
+ START_TAG= " &lt;= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \subset
+ START_TAG= " &lt; "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \supseteq
+ START_TAG= " &gt;= "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \supset
+ START_TAG= " &gt; "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cap
+ START_TAG= " * "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cup
+ START_TAG= " + "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \in
+ START_TAG= " <i>in</i> "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \emptyset
+ START_TAG= "&Oslash;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \forall
+ START_TAG= " <i>forall</i> "
+END_TYPE
+
+TYPE= COMMAND
+NAME= \Rightarrow
+ START_TAG= " =&gt; "
+END_TYPE
+
+ c= ----------------------------- font changes
+
+TYPE= COMMAND
+NAME= \texttt
+ c= ( \texttt{text} --> <tt>text</tt> )
+ START_TAG= "<tt>"
+ END_TAG= "</tt>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \emph
+ START_TAG= "<em>"
+ END_TAG= "</em>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textit
+ START_TAG= "<i>"
+ END_TAG= "</i>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textbf
+ START_TAG= "<b>"
+ END_TAG= "</b>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \textsl
+ START_TAG= "<i>"
+ END_TAG= "</i>"
+ REQPARAMS= 1
+END_TYPE
+
+
+
+
+
+ c= ------------------------------ bibliography and ref commands
+
+TYPE= BEGIN_ENV
+NAME= thebibliography
+ c= ( \begin{thebibliography}{text} --> <h2>REFERENCES</h2>
+ c= <dl>
+ c= )
+ START_TAG= "<h2>REFERENCES</h2>?n<dl>?n"
+ REQPARAMS= 1
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= END_ENV
+NAME= thebibliography
+ c= ( \end{thebibliography} --> </dl>
+ START_TAG= "</dl>?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \bibitem
+ c= ( \bibitem[opt]{text} --> [<a name="text">text</a>]<dd> )
+ START_TAG= "?n<dt>"
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 1
+ END_TAG_1= "[<a name=""
+ SOURCE: BUFFER 1
+ STRING: "">"
+ SOURCE: BUFFER 1
+ STRING: "</a>]<dd> "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \newblock
+END_TYPE
+
+TYPE= COMMAND
+NAME= \cite
+ c= ( \cite[opt]{text} --> opt[<a href="#text">text</a>] )
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 1
+ END_TAG= "[<a href="#"
+ SOURCE: BUFFER 1
+ STRING: "">"
+ SOURCE: BUFFER 1
+ STRING: "</a>]"
+ OPT_PARAM= FIRST
+ END_OPT= ""
+END_TYPE
+
+TYPE= COMMAND
+NAME= \label
+ c= ( \label{text} --> <a name="text"></a> )
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 6
+ END_TAG= "<a name=""
+ SOURCE: BUFFER 6
+ STRING: "">"
+ STRING: "</a>"
+IN_MODE= table
+ c= ( \label{text} --> <a name="text">(Table text)</a> )
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 6
+ END_TAG= "<a name=""
+ SOURCE: BUFFER 6
+ STRING: "">"
+ STRING: "(Table "
+ SOURCE: BUFFER 6
+ STRING: ")"
+ STRING: "</a>"
+END_MODE
+IN_MODE= figure
+ c= ( \label{text} --> <a name="text">(Figure text)</a> )
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 6
+ END_TAG= "<a name=""
+ SOURCE: BUFFER 6
+ STRING: "">"
+ STRING: "(Figure "
+ SOURCE: BUFFER 6
+ STRING: ")"
+ STRING: "</a>"
+END_MODE
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ref
+ c= ( \ref{text} --> <a href="#text">text</a> )
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 6
+ END_TAG= "<a href="#"
+ SOURCE: BUFFER 6
+ STRING: "">"
+ SOURCE: BUFFER 6
+ STRING: "</a>"
+END_TYPE
+
+ c= ----------------------------- for the url package
+
+TYPE= VCOMMAND
+NAME= \url
+ c= ( \url{text} --> <a href="text">text</a> )
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 7
+ START_TAG= ""
+ RESET_BUFFER: 7
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 7
+ STRING: "">"
+ SOURCE: BUFFER 7
+ STRING: "</a>"
+ RESET_BUFFER: 7
+END_TYPE
+
+ c= ----------------------------- commands from html.sty (as best I understand)
+ c= (normally used with program latex2html)
+
+TYPE= COMMAND
+NAME= \htmladdnormallinkfoot
+ REQPARAMS= 2
+ c= first argument is html highlighted text
+ c= second argument is a corresponding URL to be put in a LaTeX footnote
+ c= (e.g., newcommand{\htmladdnormallinkfoot}[2]{#1\footnote{#2}} )
+ c= ( \htmladdnormallinkfoot{first}{second} --> <a href="second">first</a> )
+ START_TAG=
+ RESET_BUFFER: 4
+ RESET_BUFFER: 5
+ PRINT_P1= TO_BUFFER 4
+ PRINT_P2= TO_BUFFER 5
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 5
+ STRING: "">"
+ SOURCE: BUFFER 4
+ STRING: "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdnormallink
+ REQPARAMS= 2
+ c= first argument is html highlighted text
+ c= second argument is a LaTeX ignored URL not to be put in a LaTeX footnote
+ c= (e.g., newcommand{\htmladdnormallink}[2]{#1} )
+ c= ( \htmladdnormallink{first}{second} --> <a href="second">first</a> )
+ START_TAG=
+ RESET_BUFFER: 4
+ RESET_BUFFER: 5
+ PRINT_P1= TO_BUFFER 4
+ PRINT_P2= TO_BUFFER 5
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 5
+ STRING: "">"
+ SOURCE: BUFFER 4
+ STRING: "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdimg
+ REQPARAMS= 1
+ c= argument is URL pointing to an image for embedding in HTML doc
+ c= ( \htmladdimg{first} --> <img src="first"> )
+ START_TAG= "<img src=""
+ END_TAG= "">"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \externallabels
+ REQPARAMS= 2
+ c= first arg is URL to directory containing external document
+ c= second arg is the path to the labels.pl file of the external document
+ c= (e.g., newcommand{\externallabels}[2]{} )
+END_TYPE
+
+TYPE= COMMAND
+NAME= \externalref
+ REQPARAMS= 1
+ c= first arg is a label defined in an external document.
+ c= (e.g., newcommand{\externalref}[1]{} )
+ c= ( \externalref{first} --> <a href="first"></a>
+ START_TAG= "<a href=""
+ END_TAG= ""></a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmlrule
+ c= adds a horizontal rule
+ c= ( \htmlrule --> <hr> )
+ START_TAG= "<hr>"
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= rawhtml
+ c= html stuff only --- to be ignored by LaTeX
+END_TYPE
+
+TYPE= END_VENV
+NAME= rawhtml
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= htmlonly
+ c= processed body appears in HTML output but ignored by LaTeX
+END_TYPE
+
+TYPE= END_VENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= VCOMMAND
+NAME= \html
+ REQPARAMS= 1
+ c= Short version of htmlonly environment.
+ c= First argument is ignored by LaTeX (e.g. \newcommand{\html}[1]{}.
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= latexonly
+ c= body appears only in LaTeX output
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= latexonly
+ PC_AT_START= RESET
+END_TYPE
+
+TYPE= COMMAND
+NAME= \latex
+ REQPARAMS= 1
+ c= command version of latexonly environment (e.g., \newcommand{\latex}[1]{#1})
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperref
+ REQPARAMS= 4
+ c= first arg is text for HTML hyperizing (underlined)
+ c= second arg and third args are text for LaTeXing only
+ c= fourth arg is name of a label (\ref{#4}) appears as #2\ref{#4}#3
+ c= ( e.g., newcommand{\hyperref}[4]{#2\ref{#4}#3} )
+ c= ( \hyperref{first}{second}{third}{fourth} --> <a href="fourth">first</a> )
+ START_TAG=
+ RESET_BUFFER: 4
+ RESET_BUFFER: 5
+ PRINT_P1= TO_BUFFER 4
+ PRINT_P2= NO_PRINT
+ PRINT_P3= NO_PRINT
+ PRINT_P4= TO_BUFFER 5
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 5
+ STRING: "">"
+ SOURCE: BUFFER 4
+ STRING: "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmlref
+ REQPARAMS= 2
+ c= mix between \htmladdnormallink and \hyperref
+ c= first arg is text for both LaTeX and HTML
+ c= second arg is label for use in HTML only
+ c= ( e.g., \newcommand{\htmlref}[2]{#1} )
+ c= ( \htmlref{first}{second} --> <a href="second">first</a> )
+ START_TAG=
+ RESET_BUFFER: 4
+ RESET_BUFFER: 5
+ PRINT_P1= TO_BUFFER 4
+ PRINT_P2= TO_BUFFER 5
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 5
+ STRING: "">"
+ SOURCE: BUFFER 4
+ STRING: "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmlimage
+ REQPARAMS= 1
+ c= (e.g., newcommand{\htmlimage}[1]{} )
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdtonavigation
+ REQPARAMS= 1
+ c= (e.g., newcommand{\htmladdtonavigation}[1]{} )
+ PRINT_P1= NO_PRINT
+END_TYPE
+
+ c= ------------------------- stuff for hyper package (as best I understand)
+
+TYPE= COMMAND
+NAME= \hyperanchor
+ REQPARAMS= 2
+ c= first arg is the hypertext anchor for #2
+ c= second arg
+ c= (e.g., newcommand{\hyperanchor}[2]{#2} )
+ c= ( \hyperanchor{first}{second} --> <a name ="first">second</a> )
+ START_TAG_1= "<a name=""
+ END_TAG_1= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \blindhyperanchor
+ REQPARAMS= 1
+ c= first arg a hypertext anchor
+ c= (e.g., newcommand{\blindhyperanchor}[1]{} )
+ c= ( \blindhyperanchor{first} --> <a name="first"></a> )
+ START_TAG_1= "<a name=""
+ END_TAG= ""></a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperreference
+ REQPARAMS= 2
+ c= first arg an anchor
+ c= second arg a reference to anchor #1
+ c= ( newcommand{\hyperreference}[2]{#2} )
+ c= ( \hyperreference{first}{second} --> <a href="#first">second</a> )
+ START_TAG_1= "<a href="#"
+ END_TAG_1= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperURL
+ REQPARAMS= 4
+ c= first arg URL type
+ c= second arg URL domain
+ c= third arg URL document
+ c= fourth arg is reference to URL #1://#2/#3
+ c= ( newcommand{\hyperURL}[4]{#4} )
+ c= ( \hyperURL{first}{second}{third}{fourth} --> <a href="first://second/third">fourth</a> )
+ START_TAG_1= "<a href=""
+ START_TAG_2= "://"
+ START_TAG_3= "/"
+ START_TAG_4= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \labeltext
+ REQPARAMS= 2
+ c= first arg reference to text #2
+ c= second arg #2 is printed
+ c= ( newcommand{\labeltext}[2]{#2} )
+ c= ( \labeltext{first}{second} --> <a name="N">second</a> )
+END_TYPE
+
+TYPE= COMMAND
+NAME= \noref
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ c= first arg hypertext ref to anchor #2 (optional arg is NOT optional)
+ c= second arg
+END_TYPE
+
+TYPE= COMMAND
+ c= This clashes with "normal" \ref command, so changed name
+ c= NAME= \ref
+NAME= \Href
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ c= like LaTeX #1~\ref{#2} except that hypertext ref is provided from both args
+ c= ( \ref[opt]{first} --> ?????? )
+END_TYPE
+
+TYPE= COMMAND
+NAME= \pageref
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ c= like \ref, except for page number ref
+ c= ( \pageref[opt]{first} --> ??????? )
+END_TYPE
+
+TYPE= COMMAND
+NAME= \refcurrent
+ REQPARAMS= 1
+ c= first arg hypertext ref to actual anchor
+ c= ( \refcurrent{first} --> ??????? )
+END_TYPE
+
+TYPE= COMMAND
+NAME= \refnext
+ REQPARAMS= 1
+ c= first arg hypertext ref to the next anchor that will be generated
+ c= ( \refnext{first} --> ??????? )
+END_TYPE
+
+ c= ------------------- stuff for hyperref package (as best I understand)
+
+TYPE= COMMAND
+NAME= \hyperlink
+ REQPARAMS= 2
+ c= \hyperlink{linkname}{text}
+ c= ( newcommand{\hyperlink}[2]{#2} )
+ c= ( \hyperlink{first}{second} --> <a href="#first">second</a> )
+ START_TAG_1= "<a href="#"
+ END_TAG_1= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hypertarget
+ REQPARAMS= 2
+ c= \hypertarget{anchorname}{text}
+ c= ( newcommand{\hypertarget}[2]{#2} )
+ c= ( \hypertarget{first}{second} --> <a name="first"></a>second )
+ START_TAG_1= "<a name=""
+ END_TAG_1= ""></a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \href
+ REQPARAMS= 2
+ c= \href{URL}{anchor}
+ c= ( newcommand{\href}[2]{#2} )
+ c= ( \href{first}{second} --> <a href="first">second</a> )
+ START_TAG_1= "<a href=""
+ END_TAG_1= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperimage
+ REQPARAMS= 1
+ c= \hyperimage{imageURL}
+ c= points to a graphic
+ c= ( newcommand{\hyperimage}[1]{} )
+ c= ( \hyperimage{first} --><img src="first"> )
+ START_TAG= "<img src=""
+ END_TAG= "">"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperdef
+ REQPARAMS= 4
+ OPT_PARAM= FIRST
+ c= \hyperdef[label]{URL}{category}{name}{text}
+ c= ( newcommand{\hyperdef}[4]{#4}
+ c= ( \hyperdef[opt]{first}{second}{third}{fourth} --> <a name="firstsecond.third"></a>fourth )
+ START_TAG= "<a name=""
+ START_TAG_3= "."
+ START_TAG_4= ""></a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \hyperref
+ REQPARAMS= 4
+ c= \hyperref{URL}{category}{name}{anchor}
+ c= \hyperref[label]{anchor}
+ c= ( newcommand{\hyperref}[4]{#4} )
+ c= ( \hyperref{first}{second}{third}{fourth} --> <a href="first#second.third">fourth</a> )
+ START_TAG_1= "<a href=""
+ START_TAG_2= "#"
+ START_TAG_3= "."
+ START_TAG_4= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdimg
+ REQPARAMS= 1
+ c= same as \hyperimage
+ START_TAG= "<img src=""
+ END_TAG= "">"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \htmladdnormallink
+ REQPARAMS= 2
+ c= same as \href
+ START_TAG_1= "<a href=""
+ END_TAG_1= "">"
+ END_TAG= "</a>"
+END_TYPE
+
+
+ c= -------------------- commands for html-ing ltx2x.tex
+ c= could have been defined via an included file. e.g.
+ c= INCLUDE= html.l2x
+
+TYPE= BEGIN_ENV
+NAME= htmlverbatim
+ START_TAG= "?n<pre>"
+END_TYPE
+
+TYPE= END_ENV
+NAME= htmlverbatim
+ END_TAG= "</pre>?n"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \keyword
+ c= ( \keyword{first} --> <samp>first</samp> )
+ START_TAG= "<samp>"
+ END_TAG= "</samp>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \keytext
+ c= ( \keytext{first} --> <samp>first</samp> )
+ START_TAG= "<samp>"
+ END_TAG= "</samp>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \file
+ c= ( \file{first} --> <tt>first</tt> )
+ START_TAG= "<tt>"
+ END_TAG= "</tt>"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ST
+ c= ( \ST{first} --> &lt;first&gt; )
+ START_TAG= "&lt;"
+ END_TAG= "&gt;"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ET
+ c= ( \ET{first} --> &lt;/first&gt; )
+ START_TAG= "&lt;/"
+ END_TAG= "&gt;"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \Amp
+ START_TAG= "&amp;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \LT
+ START_TAG= "&lt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \GT
+ START_TAG= "&gt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \HASH
+ START_TAG= "&#035;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \Express
+ START_TAG= "EXPRESS"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ExpressA
+ START_TAG= "EXPRESS-A"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ExpressG
+ START_TAG= "EXPRESS-G"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ExpressI
+ START_TAG= "EXPRESS-I"
+END_TYPE
+
+
+
+ c= ------------------- include extra ct files here
+
+ c= this will give an opportunity to interactively include a
+ c= ct file, assuming that ZiLcH.ct is not on the search path.
+INCLUDE= ZiLcH.ct
+
+
+
+END_CTFILE= --------------------- end of l2h.ct
+
+
diff --git a/support/ltx2x/l2x.l b/support/ltx2x/l2x.l
new file mode 100644
index 0000000000..2b748b61ac
--- /dev/null
+++ b/support/ltx2x/l2x.l
@@ -0,0 +1,1184 @@
+%{
+/*
+ * l2x.l --- (flex) lexer for converting a LaTeX file to X
+ * Written by Peter Wilson (Catholic University and NIST)
+ * Version 0.2, January 1995
+ * Revised July 1996
+ * -- replace myprint(tag) by tag_print(tag)
+ * -- added verb(atim) like capability
+ */
+
+/* Development of this software was funded by the United States Government,
+ * and is not subject to copyright.
+ */
+
+#include <string.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xytab.h" /* token codes from parser */
+#include "l2xlib.h" /* functions and global variables */
+#include "l2xusrlb.h" /* possibly useful strings and user-defined functions */
+
+
+extern int opt_param;
+extern int all_opt;
+extern int opt_coord;
+int got_opt_item = FALSE;
+int got_a_dollar = FALSE;
+int got_opt_param = FALSE;
+int got_all_opt = FALSE;
+int got_opt_coord = FALSE;
+
+
+char verb_char; /* delimeter for \verb command */
+int result;
+int kind;
+int special_kind;
+PSENTRY ptr; /* pointer to sym entry */
+int nl_count = 0; /* number of consecutive new lines */
+char a_newline[] = "\n";
+char a_space[] = " ";
+char vlenv[80]; /* name of verbatim-like environment */
+int nopen_vbrace = 0; /* no of unmatched open braces after verb-like command */
+
+int nopen_noop = 0; /* no of unmatched openers for no_op argument */
+#define NOOPLBRAK 1
+#define NOOPRBRAK 1
+#define NOOPLBRACE 2
+#define NOOPRBRACE 2
+int noop_openc; /* noop argument opening character ( [ or { )*/
+
+#define LDA -1
+#define LD0 0
+#define LD1 1
+#define LD2 2
+#define LD3 3
+#define LD4 4
+#define LD5 5
+#define LD6 6
+/*
+ * LDEBUG > LDA: error prints:
+ * > LD0: names not in command table
+ * > LD1: newlines, returned useful tokens
+ * > LD2: general tokens
+ * > LD3: text dealt with in lexer
+ * > LD4: comments
+ * > LD5: stuff within verbatims
+ * > LD6:
+ *
+ */
+
+%}
+
+ /* whitespace and comments */
+ws ([ \t])
+newline (\n)
+ /* TeX comments from % through eol + any following whitespace */
+tex_comment (%.*\n[ \t]*)
+ /* general REs */
+lbrace (\{)
+rbrace (\})
+lbrak (\[)
+rbrak (\])
+lparen (\()
+rparen (\))
+backslash (\\)
+comma (",")
+name ([a-zA-Z]+\*?)
+integer (-?[0-9]+)
+real (-?(([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)))
+hash (#)
+dollar ($)
+ampersand (&)
+twiddle (~)
+underscore (_)
+caret (^)
+percent (%)
+at (@)
+slashspace (\\ )
+ /* (La)TeX literals */
+ /* general LaTeX commands */
+
+verbatim (verbatim\*?)
+command (\\[a-zA-Z]+\*?)
+char_command (\\[^a-zA-Z\n])
+begin_c (\\begin[ \t]*)
+end_c (\\end[ \t]*)
+verb (\\verb\*?)
+ /* list items */
+item (\\item[ \t]*)
+
+
+
+%x VERBATIM_STATE
+%x VERB_STATE
+%x VERBATIM_LIKE
+%x VERB_LIKE
+%x NOOP
+%%
+
+ /*------------ Comments plus start and end document ---------------*/
+
+{tex_comment} {
+ if (LDEBUG > LD4) {
+ print_debug_2s("(tex_comment):", yytext);
+ }
+ catl(yyleng, yytext);
+ do_newline();
+ if (leave_comments) { /* leave in comments */
+ myprint(yytext);
+ }
+ }
+
+
+ /* \begin{document} */
+{begin_c}{lbrace}{ws}*document{ws}*{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_BEGIN_DOCUMENT):", yytext);
+ }
+ yylval.pos = get_mode_sym(pos_bdoc);
+ return(BEGIN_DOCUMENT);
+ }
+
+ /* end of document \end{document} */
+{end_c}{lbrace}{ws}*document{ws}*{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_END_DOCUMENT):", yytext);
+ }
+ yylval.pos = get_mode_sym(pos_edoc);
+ return(END_DOCUMENT);
+ }
+
+
+
+
+ /*----------------- verbatims -----------------------------------------*/
+ /* Do most of the processing in the lexer */
+ /* but pass token back to parser anyway */
+
+ /* \begin{verbatim} */
+{begin_c}{lbrace}{ws}*{verbatim}{ws}*{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(begin{verbatim}):", yytext);
+ }
+ BEGIN VERBATIM_STATE;
+ yylval.pos = get_mode_sym(pos_bvbm);
+ bverb = TRUE;
+ return(BEGIN_VERBATIM);
+ }
+ /* newline */
+<VERBATIM_STATE>{newline} { catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in verbatim):", yytext);
+ }
+ verbatim_print(yytext);
+ }
+ /* backslash */
+<VERBATIM_STATE>{backslash} { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+ /* any characters other than newline and backslash */
+<VERBATIM_STATE>[^\n\\]+ { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+ /* \end{verbatim} */
+<VERBATIM_STATE>{end_c}{lbrace}{ws}*{verbatim}{ws}*{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(end{verbatim}):", yytext);
+ }
+ BEGIN 0;
+ yylval.pos = get_mode_sym(pos_evbm);
+ return(END_VERBATIM);
+ }
+
+ /* \verb (and its trailing character) */
+{verb}. { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(verb):", yytext);
+ }
+ BEGIN VERB_STATE;
+ verb_char = yytext[yyleng-1];
+ yylval.pos = get_mode_sym(pos_bv);
+ return(BEGIN_VERB);
+ }
+
+ /* chars inside \verb */
+<VERB_STATE>. { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (verb_char != yytext[0] ) {
+ myprint(yytext);
+ }
+ else { /* end of verb environment */
+ BEGIN 0;
+ yylval.pos = get_mode_sym(pos_ev);
+ return(END_VERB);
+ }
+ }
+
+ /* newlines not allowed within verb */
+<VERB_STATE>{newline} { catl(yyleng, yytext);
+ nl_count++;
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ BEGIN 0;
+ yyerror("Error: \"verb\" ended by a newline");
+ do_newline();
+ myprint(a_newline);
+ yylval.pos = get_mode_sym(pos_ev);
+ return(END_VERB);
+ }
+
+ /* VERB LIKE command stuff */
+ /* { (open brace) */
+<VERB_LIKE>{lbrace} { catl(yyleng, yytext);
+ nopen_vbrace++;
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (nopen_vbrace == 1) { /* start of argument */
+ yylval.pos = get_mode_sym(pos_lbrace);
+ return(LBRACE);
+ }
+ else { /* part of argument */
+ verbatim_print(yytext);
+ }
+ }
+
+ /* } (close brace) */
+<VERB_LIKE>{rbrace} { catl(yyleng, yytext);
+ nopen_vbrace--;
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (nopen_vbrace == 0) { /* end of argument */
+ BEGIN 0; /* change state */
+ yylval.pos = get_mode_sym(pos_rbrace);
+ return(RBRACE);
+ }
+ else { /* part of argument */
+ verbatim_print(yytext);
+ }
+ }
+
+ /* newline */
+<VERB_LIKE>{newline} { catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in verb-like):", yytext);
+ }
+ verbatim_print(yytext);
+ }
+
+ /* any other character */
+<VERB_LIKE>. { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+
+
+ /* VERBATIM LIKE environment stuff */
+
+ /* \end{something} */
+<VERBATIM_LIKE>{end_c}{lbrace}{ws}*{name}{ws}*{rbrace} { catl (yyleng, yytext);
+ nl_count = 0;
+ get_env_name(yytext);
+ if (strcmp(vlenv, env_name) == 0) { /* close verbatim like */
+ if (LDEBUG > LD1) {
+ print_debug_2s("(end):", yytext);
+ print_debug_2s("env_name= ", env_name);
+ }
+ result = lookup_entry(env_name, END_VENV);
+ if (result > 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ BEGIN 0;
+ return(kind);
+ }
+ else { /* got problems, end env name not in table */
+ warning_3s("END_VENV",env_name,"not in command table. Expect input/output errors from now on");
+ BEGIN 0;
+ verbatim_print(yytext);
+ }
+ }
+ else { /* not end of verbatim-like env */
+ verbatim_print(yytext);
+ }
+ }
+
+ /* newline */
+<VERBATIM_LIKE>{newline} { catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in verbatim-like):", yytext);
+ }
+ verbatim_print(yytext);
+ }
+
+ /* any other character */
+<VERBATIM_LIKE>. { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+
+ /*---------------------------No Op processing---------------------------*/
+
+ /* open brace */
+<NOOP>{lbrace} { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRACE) {
+ nopen_noop++;
+ }
+ }
+
+ /* open bracket */
+<NOOP>{lbrak} { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRAK) {
+ nopen_noop++;
+ }
+ }
+
+ /* close brace */
+<NOOP>{rbrace} { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRACE) {
+ nopen_noop--;
+ if (nopen_noop <= 0) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Closing NO_OP on brace)");
+ }
+ nopen_noop = 0;
+ in_noop = FALSE;
+ start_noop = FALSE;
+ BEGIN 0;
+ yylval.pos = get_mode_sym(pos_rbrace);
+ return(RBRACE);
+ }
+ }
+ }
+
+ /* close bracket */
+<NOOP>{rbrak} { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRAK) {
+ nopen_noop--;
+ if (nopen_noop <= 0) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Closing NO_OP on bracket)");
+ }
+ nopen_noop = 0;
+ in_noop = FALSE;
+ start_noop = FALSE;
+ BEGIN 0;
+ got_opt_param = FALSE;
+ return(END_ANOPT);
+ }
+ }
+ }
+
+
+ /* newline */
+<NOOP>{newline} { catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in a no op):", yytext);
+ }
+ }
+
+ /* any other character */
+<NOOP>. { catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ }
+
+ /*----------------------------Default processing------------------------*/
+
+ /*----------------------- list items ---------------------------*/
+
+ /* item */
+{item} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_ITEM):", yytext);
+ }
+ return(ITEM);
+ }
+
+ /* item[ */
+{item}{lbrak} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_ITEM_AND_BRAK):", yytext);
+ }
+ got_opt_item = TRUE;
+ return(ITEM_AND_BRAK);
+ }
+
+
+ /*------------------------------ commands ------------------------------*/
+
+ /* (La)TeX backslash followed by a single space */
+{backslash}[ ] { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD4) {
+ print_debug_2s("(slashspace):", yytext);
+ } /* 6/96 change myprint to tag_print */
+ ptr = get_mode_sym(pos_bss);
+ tag_print(get_t(ptr));
+ tag_print(get_et(ptr));
+ }
+
+ /* (La)TeX backslash followed by a newline */
+{backslash}[\n] { catl(yyleng, yytext);
+ nl_count++;
+ yylval.string = strsave(yytext);
+ do_newline();
+ if (LDEBUG > LD1) {
+ fprintf(filerr, "\n LD(slashnewline): next line is %d\n", lineno);
+ fflush(filerr);
+ }
+ ptr = get_mode_sym(pos_bss);
+ tag_print(get_t(ptr));
+ tag_print(get_et(ptr));
+ if (!pretty_print) {
+ myprint(a_newline);
+ }
+ }
+
+ /* \one non-alphabetic character */
+{char_command} {catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(char_command):", yytext);
+ }
+ result = lookup_entry(yytext, CHAR_COMMAND);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_COMMAND)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as CHAR_COMMAND)");
+ }
+ return(OTHER_COMMAND);
+ }
+ }
+
+ /* special processing for \\* command */
+{backslash}{backslash}[ \t]*\* { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(char_command):", yytext);
+ }
+ result = lookup_entry("\\\\", CHAR_COMMAND);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_COMMAND)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as CHAR_COMMAND)");
+ }
+ return(OTHER_COMMAND);
+ }
+ }
+
+
+
+ /* a command \something or \something* */
+{command} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(command):", yytext);
+ }
+ result = lookup_entry(yytext, DONT_CARE);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ switch (get_user_type(ptr)) {
+ case SPECIAL_COMMAND: {
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_COMMAND",yytext,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(kind);
+ }
+ else {
+ return(special_kind);
+ }
+ break;
+ }
+ case SPECIAL_SECTIONING: {
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_SECTIONING",yytext,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(kind);
+ }
+ else {
+ return(special_kind);
+ }
+ break;
+ }
+ case VCOMMAND: { /* verb-like */
+ BEGIN VERB_LIKE;
+ nopen_vbrace = 0;
+ break;
+ }
+ } /* end switch */
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_COMMAND)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a command type)");
+ }
+ return(OTHER_COMMAND);
+ }
+ }
+
+
+ /*-------------------- Environments ---------------------------*/
+
+ /* \begin{something} */
+{begin_c}{lbrace}{ws}*{name}{ws}*{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(begin):", yytext);
+ }
+ get_env_name(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_2s("env_name= ", env_name);
+ }
+ result = lookup_entry(env_name, BEGIN_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, BEGIN_LIST_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, BEGIN_PICTURE_CC);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, BEGIN_VENV);
+ if (result >= 0) { /* found it */
+ BEGIN VERBATIM_LIKE; /* switch into verbatim-like mode */
+ bverb = TRUE;
+ strcpy(vlenv, env_name); /* remember environment name */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, SPECIAL_BEGIN_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_BEGIN_ENV",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ result = lookup_entry(env_name, SPECIAL_BEGIN_LIST);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_BEGIN_LIST",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_BEGIN)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as begin something)");
+ }
+ return(OTHER_BEGIN);
+ }
+
+ /* \end{something} */
+{end_c}{lbrace}{ws}*{name}{ws}*{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(end):", yytext);
+ }
+ get_env_name(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_2s("env_name= ", env_name);
+ }
+ result = lookup_entry(env_name, END_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, END_LIST_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, END_PICTURE);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, SPECIAL_END_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_END_ENV",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ result = lookup_entry(env_name, SPECIAL_END_LIST);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_END_ENV",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_END)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as end something)");
+ }
+ return(OTHER_END);
+ }
+
+
+ /*--------------------- Miscellaneous stuff -----------------------*/
+
+
+ /* an open brace { */
+{lbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_LBRACE):", yytext);
+ }
+ if (start_noop) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Starting NO_OP on brace)");
+ }
+ start_noop = FALSE;
+ in_noop = TRUE;
+ nopen_noop = 1;
+ noop_openc = NOOPLBRACE;
+ BEGIN NOOP;
+ }
+ yylval.pos = get_mode_sym(pos_lbrace);
+ return(LBRACE);
+ }
+
+ /* a close brace } */
+{rbrace} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_RBRACE):", yytext);
+ }
+ yylval.pos = get_mode_sym(pos_rbrace);
+ return(RBRACE);
+ }
+
+ /* an open bracket [ */
+{lbrak} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_LBRAK):", yytext);
+ }
+ if (opt_param) {
+ got_opt_param = TRUE;
+ opt_param = FALSE;
+ if (start_noop) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Starting NO_OP on bracket)");
+ }
+ start_noop = FALSE;
+ in_noop = TRUE;
+ noop_openc = NOOPLBRAK;
+ BEGIN NOOP;
+ }
+ return(START_ANOPT);
+ }
+ else if (all_opt) {
+ got_all_opt = TRUE;
+ all_opt = FALSE;
+ return(START_ALLOPT);
+ }
+ else {
+ return(LBRAK);
+ }
+ }
+
+ /* a close bracket ] */
+{rbrak} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_RBRAK):", yytext);
+ }
+ if (got_opt_item) {
+ got_opt_item = FALSE;
+ return(END_ITEM_BRAK);
+ }
+ else if (got_opt_param) {
+ got_opt_param = FALSE;
+ return(END_ANOPT);
+ }
+ else if (got_all_opt) {
+ got_all_opt = FALSE;
+ return(END_ALLOPT);
+ }
+ else {
+ return(RBRAK);
+ }
+ }
+
+ /*------------------- Special characters ----------------------*/
+
+ /* a naked hash # */
+{hash} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(hash):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+ /* a naked dollar $ */
+{dollar} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(dollar):", yytext);
+ if (got_a_dollar) { print_debug_1s("(as t_END_DOLLAR)"); }
+ else { print_debug_1s("(as t_BEGIN_DOLLAR)"); }
+ }
+ if (got_a_dollar) { /* a 'closing' $ */
+ got_a_dollar = FALSE;
+ yylval.pos = get_mode_sym(pos_edol);
+ return(END_DOLLAR);
+ }
+ else { /* an 'opening' $ */
+ got_a_dollar = TRUE;
+ yylval.pos = get_mode_sym(pos_bdol);
+ return(BEGIN_DOLLAR);
+ }
+ }
+
+ /* a naked ampersand & */
+{ampersand} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(ampersand):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+
+ /* a naked twiddle ~ */
+{twiddle} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(twiddle):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+ /* a naked underscore _ */
+{underscore} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(underscore):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+ /* a naked caret ^ */
+{caret} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(caret):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+ /* a naked percent % */
+{percent} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(percent):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+ /* a naked at @ */
+{at} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(at):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+
+
+
+ /* name (alphabetic string(*) ) */
+{name} { catl(yyleng, yytext);
+ nl_count = 0;
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_NAME):", yytext);
+ }
+ return(NAME);
+ }
+
+ /* integer (digit string) */
+{integer} { catl(yyleng, yytext);
+ nl_count = 0;
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_INTEGER):", yytext);
+ }
+ return(INTEGER);
+ }
+
+ /* real (digits with one period) */
+{real} { catl(yyleng, yytext);
+ nl_count = 0;
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_REAL):", yytext);
+ }
+ return(REAL);
+ }
+
+
+ /* a comma */
+{comma} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_COMMA):", yytext);
+ }
+ return(COMMA);
+ }
+
+ /* left parenthesis */
+{lparen} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_LPAREN):", yytext);
+ }
+ if (opt_coord) {
+ got_opt_coord = TRUE;
+ opt_coord = FALSE;
+ return(START_COORD);
+ }
+ else {
+ return(LPAREN);
+ }
+ }
+
+ /* right parenthesis */
+{rparen} { catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_RPAREN):", yytext);
+ }
+ if (got_opt_coord) {
+ got_opt_coord = FALSE;
+ return(END_COORD);
+ }
+ else {
+ return(RPAREN);
+ }
+ }
+
+
+
+ /* whitespace (except newline) print it out */
+[ \t]+ { catl(yyleng, yytext);
+ if (LDEBUG > LD4) {
+ print_debug_2s("(ws):", yytext);
+ }
+ if (collapse_ws) { /* collapse whitespace */
+ myprint(a_space);
+ }
+ else {
+ myprint(yytext);
+ }
+ }
+
+ /* newline with leading and trailing spaces */
+ /* 7/96 changed to enable paragraphs outside pretty mode */
+{ws}*{newline}{ws}* { catl(yyleng, yytext);
+ nl_count++;
+ /* yylval.string = strsave(yytext); */
+ do_newline();
+ if (LDEBUG > LD1) {
+ fprintf(filerr, "\n LD(newline): next line is %d\n", lineno);
+ fflush(filerr);
+ }
+ if (!pretty_print) { /* not pretty printing */
+ myprint(yytext);
+ if (nl_count == 2) { /* 6/96 added this */
+ yylval.pos = get_mode_sym(pos_para);
+ return(PARAGRAPH);
+ }
+ }
+ else {
+ if (nl_count == 2) { /* (6/96 changed from >= 2 to == 2) a paragraph break */
+ yylval.pos = get_mode_sym(pos_para);
+ return(PARAGRAPH);
+ }
+ else { /* treat as space */
+ myprint(a_space);
+ }
+ }
+ }
+
+
+
+ /*----------- WHEN ALL ELSE FAILS --------------------*/
+
+ /* end of file */
+<<EOF>> { catl(yyleng, yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(end of file):\n");
+ }
+ yyerror("Lexer: Unexpected end of file");
+ return(END_OF_FILE);
+ }
+
+ /* anything else */
+. { catl(yyleng, yytext);
+ nl_count = 0;
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ if (LDEBUG > LD1) {
+ print_debug_2s("(tex_char):", yytext);
+ }
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD4) {
+ print_debug_2s("(catch_all):", yytext);
+ }
+ return(OTHER);
+ }
+ }
+
+%%
+
+
diff --git a/support/ltx2x/l2x.y b/support/ltx2x/l2x.y
new file mode 100644
index 0000000000..a68c0ff40c
--- /dev/null
+++ b/support/ltx2x/l2x.y
@@ -0,0 +1,1502 @@
+%{
+/*
+ * l2x.y A (bison) parser to convert LaTeX source to X
+ * Written by Peter Wilson (Catholic University and NIST)
+ * Version 0.2, January 1995
+ * revised 6/96 replacing myprint(tag) by tag_print(tag)
+ */
+
+/* Development of this software was funded by the United States Government,
+ * and is not subject to copyright.
+ */
+
+/****************************************************************************/
+/* WARNING: This file is intended to be processed by bison. If it is so */
+/* processed, then the resulting output is subject to the Free */
+/* Software Foundation GNU "copyleft" software license. */
+/* A copy of this license can be obtained by writing to: */
+/* Free Software Foundation, Inc. */
+/* 675 Massachusetts Avenue */
+/* Cambridge, MA 02139 */
+/* +1 (617) 876-3296 */
+/****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xacts.h" /* system provided action functions */
+#include "l2xusrlb.h" /* user defined action functions, etc */
+#include "l2xlib.h" /* functions and global variables */
+
+
+ /* lexer communication */
+int opt_param = FALSE;
+int all_opt = FALSE;
+int opt_coord = FALSE;
+
+ /* parser variables */
+int yacresult;
+int yackind;
+PSENTRY sym;
+char grammbuf[80]; /* for example grammar-based special */
+
+%}
+
+%union {
+ char *string; /* string buffer */
+ /* int pos; command table position */
+ PSENTRY pos; /* pointer to sym entry */
+}
+
+%token END_OF_FILE
+ /* TeX special chars */
+%token <pos> TEX_CHAR
+ /* special character command */
+%token <pos> CHAR_COMMAND
+ /* begin and end document */
+%token <pos> BEGIN_DOCUMENT END_DOCUMENT
+ /* begin and end verbatims */
+%token <pos> BEGIN_VERBATIM END_VERBATIM BEGIN_VERB END_VERB
+ /* begin and end dollar math */
+%token <pos> BEGIN_DOLLAR END_DOLLAR
+ /* alpahabetic commands & environments */
+%token <pos> COMMAND COMMAND_OPT
+%token <pos> COMMAND_1 COMMAND_2 COMMAND_3 COMMAND_4 COMMAND_5
+%token <pos> COMMAND_6 COMMAND_7 COMMAND_8 COMMAND_9
+%token <pos> COMMAND_1_OPT COMMAND_2_OPT COMMAND_3_OPT COMMAND_4_OPT COMMAND_5_OPT
+%token <pos> COMMAND_6_OPT COMMAND_7_OPT COMMAND_8_OPT
+ /* begin environments */
+%token <pos> BEGIN_ENV
+ /* end environment */
+%token <pos> END_ENV
+ /* begin lists */
+%token <pos> BEGIN_LIST_ENV
+ /* end lists */
+%token <pos> END_LIST_ENV
+ /* sectioning */
+%token <pos> SECTIONING
+ /* picture commands */
+%token <pos> BEGIN_PICTURE_CC END_PICTURE
+%token <pos> PICTURE_CCPP PICTURE_CO PICTURE_COP PICTURE_CP
+%token <pos> PICTURE_OCC PICTURE_OCCC PICTURE_OCO PICTURE_PCOP
+ /* a special something */
+%token <pos> SPECIAL SPECIAL_COMMAND SPECIAL_BEGIN_ENV SPECIAL_END_ENV
+%token <pos> SPECIAL_BEGIN_LIST SPECIAL_END_LIST SPECIAL_SECTIONING
+ /* verb(atim) like stuff */
+%token <pos> BEGIN_VENV END_VENV VCOMMAND
+ /* commands with odd optionals */
+%token <pos> COMMAND_OOP COMMAND_OOOPP COMMAND_OPO
+%token <pos> COMMAND_POOOP COMMAND_POOP COMMAND_POOPP
+ /* default stuff */
+%token <pos> OTHER_COMMAND OTHER_BEGIN OTHER_END
+%token <pos> PRINT_CONTROLLED_COMMAND
+ /* uninteresting and built-in stuff */
+%token <string> NAME INTEGER REAL OTHER
+%type <string> Words Numbers
+%type <pos> l2xNoOps
+%type <pos> ReqParam
+%token ITEM ITEM_AND_BRAK END_ITEM_BRAK
+%token <pos> LBRACE RBRACE
+%token <pos> PARAGRAPH
+%token <pos> SLASH_SPACE
+%token LBRAK RBRAK
+%token COMMA LPAREN RPAREN
+%token START_ANOPT START_COORD START_ALLOPT
+%token END_ANOPT END_COORD END_ALLOPT
+
+ /* specials */
+%token <pos> GRAMMSPECIAL 32767
+
+ /* precedences */
+
+%%
+Document: StuffList
+ ;
+
+StuffList: Stuff
+ | StuffList Stuff
+ ;
+
+Stuff: AnItem
+ | StartDoc
+ | EndDoc
+ | Words { myprint($1);
+ free($1);
+ }
+ | Numbers { myprint($1);
+ free($1);
+ }
+ | BracedStuff
+ | l2xSpecialChar
+ | l2xCharCommand
+ | l2xCommands
+ | l2xSpecials
+ | l2xOthers
+ | l2xPictures
+ ;
+
+ /*---------- Start and End the document --------------*/
+
+StartDoc: BEGIN_DOCUMENT
+ {
+ action_no_param($1);
+ }
+ ;
+
+EndDoc: END_DOCUMENT { action_no_param($1);
+ close_down(" (at end of document)");
+ exit(0); }
+ | END_OF_FILE { close_down(" (at unexpected end of file)");
+ exit(1); }
+ ;
+
+
+ /*------------------- List Items -----------------------*/
+
+AnItem: DescItem
+ | NdItem
+ ;
+
+DescItem: ITEM_AND_BRAK
+ {
+ print_end_item();
+ num_items[list_level]++;
+ tag_print(list_item_start[list_level]);
+ tag_print(list_descitemp_start[list_level]);
+ }
+ END_ITEM_BRAK
+ {
+ tag_print(list_descitemp_end[list_level]);
+ }
+ | ITEM_AND_BRAK
+ {
+ print_end_item();
+ num_items[list_level]++;
+ tag_print(list_item_start[list_level]);
+ tag_print(list_descitemp_start[list_level]);
+ }
+ StuffList END_ITEM_BRAK
+ {
+ tag_print(list_descitemp_end[list_level]);
+ }
+ ;
+
+NdItem: ITEM
+ {
+ print_end_item();
+ num_items[list_level]++;
+ tag_print(list_item_start[list_level]);
+ }
+ ;
+
+
+
+
+ /*----------- Special Characters -----------------*/
+l2xSpecialChar: TEX_CHAR
+ {
+ action_no_param($1);
+ }
+ ;
+
+ /*---------- Character Command ---------------------*/
+l2xCharCommand: CHAR_COMMAND
+ {
+ action_no_param($1);
+ }
+ ;
+
+ /*----------- Regular Commands & Environments ----------------*/
+
+l2xCommands: l2xCommand
+ | l2xComm1
+ | l2xComm2
+ | l2xComm3
+ | l2xComm4
+ | l2xComm5
+ | l2xComm6
+ | l2xComm7
+ | l2xComm8
+ | l2xComm9
+ | l2xCommandOpt
+ | l2xComm1Opt
+ | l2xComm2Opt
+ | l2xComm3Opt
+ | l2xComm4Opt
+ | l2xComm5Opt
+ | l2xComm6Opt
+ | l2xComm7Opt
+ | l2xComm8Opt
+ | l2xCommOddP
+ ;
+
+ReqParam: LBRACE RBRACE
+ | LBRACE StuffList RBRACE
+ | error
+ {yyerror("Syntax error: Required parameter expected");}
+ ;
+
+ /*-------------Regular commands without trailing opt --------*/
+l2xComm9: COMMAND_9
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_p_p1($1,6);
+ }
+ ReqParam
+ {
+ action_p_p1($1,7);
+ }
+ ReqParam
+ {
+ action_p_p1($1,8);
+ }
+ ReqParam
+ {
+ action_last_p($1,9);
+ }
+ ;
+
+l2xComm8: COMMAND_8
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_p_p1($1,6);
+ }
+ ReqParam
+ {
+ action_p_p1($1,7);
+ }
+ ReqParam
+ {
+ action_last_p($1,8);
+ }
+ ;
+
+l2xComm7: COMMAND_7
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_p_p1($1,6);
+ }
+ ReqParam
+ {
+ action_last_p($1,7);
+ }
+ ;
+
+l2xComm6: COMMAND_6
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_last_p($1,6);
+ }
+ ;
+
+l2xComm5: COMMAND_5
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_last_p($1,5);
+ }
+ ;
+
+l2xComm4: COMMAND_4
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_last_p($1,4);
+ }
+ ;
+
+l2xComm3: COMMAND_3
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_last_p($1,3);
+ }
+ ;
+
+l2xComm2: COMMAND_2
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_last_p($1,2);
+ }
+ ;
+
+l2xComm1: COMMAND_1
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_last_p($1,1);
+ }
+ ;
+
+
+l2xCommand: COMMAND
+ {
+ action_no_param($1);
+ }
+ ;
+
+ /*-------------- Regular commands with trailing opt --------*/
+
+l2xComm8Opt: COMMAND_8_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_p_p1($1,6);
+ }
+ ReqParam
+ {
+ action_p_p1($1,7);
+ }
+ ReqParam
+ {
+ action_p_opt($1,8);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm7Opt: COMMAND_7_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_p_p1($1,6);
+ }
+ ReqParam
+ {
+ action_p_opt($1,7);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm6Opt: COMMAND_6_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_p1($1,5);
+ }
+ ReqParam
+ {
+ action_p_opt($1,6);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm5Opt: COMMAND_5_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_p1($1,4);
+ }
+ ReqParam
+ {
+ action_p_opt($1,5);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm4Opt: COMMAND_4_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_p1($1,3);
+ }
+ ReqParam
+ {
+ action_p_opt($1,4);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm3Opt: COMMAND_3_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,2);
+ }
+ ReqParam
+ {
+ action_p_opt($1,3);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm2Opt: COMMAND_2_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_opt($1,2);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xComm1Opt: COMMAND_1_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_opt($1,1);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+l2xCommandOpt: COMMAND_OPT
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+OptParam: START_ANOPT END_ANOPT
+ | START_ANOPT StuffList END_ANOPT
+ | /* empty */
+ ;
+
+ /*---------------Picture Stuff -------------------*/
+
+l2xPictures: BeginPicCC
+ | EndPic
+ | PicCCPP
+ | PicCO
+ | PicCOP
+ | PicCP
+ | PicOCC
+ | PicOCCC
+ | PicOCO
+ | PicPCOP
+ ;
+
+BeginPicCC: BEGIN_PICTURE_CC
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_coord = TRUE;
+ }
+ OptCoord
+ {
+ opt_coord = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ end_it($1);
+ }
+ ;
+
+EndPic: END_PICTURE
+ {
+ start_it($1);
+ end_it($1);
+ }
+ ;
+
+PicCCPP: PICTURE_CCPP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ end_it($1);
+ }
+ ;
+
+PicCO: PICTURE_CO
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ end_it($1);
+ }
+ ;
+
+PicCOP: PICTURE_COP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ end_it($1);
+ }
+ ;
+
+PicCP: PICTURE_CP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ end_it($1);
+ }
+ ;
+
+PicOCC: PICTURE_OCC
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ end_it($1);
+ }
+ ;
+
+PicOCCC: PICTURE_OCCC
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ end_it($1);
+ }
+ ;
+
+PicOCO: PICTURE_OCO
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ end_it($1);
+ }
+ ;
+
+PicPCOP: PICTURE_PCOP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ Coord
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ end_it($1);
+ }
+ ;
+
+ /* -------------Odd Optionals-------------------*/
+
+l2xCommOddP : ltxCommandOOP
+ | ltxCommandOOOPP
+ | ltxCommandOPO
+ | ltxCommandPOOOP
+ | ltxCommandPOOP
+ | ltxCommandPOOPP
+ ;
+
+ltxCommandOOP : COMMAND_OOP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ end_it($1);
+ }
+ ;
+
+ltxCommandOOOPP : COMMAND_OOOPP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ tag_print(get_tag_t($1,5));
+ set_print(get_param_print($1,5));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,5));
+ end_it($1);
+ }
+ ;
+
+ltxCommandOPO : COMMAND_OPO
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ end_it($1);
+ }
+ ;
+
+ltxCommandPOOOP : COMMAND_POOOP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ tag_print(get_tag_t($1,5));
+ set_print(get_param_print($1,5));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,5));
+ end_it($1);
+ }
+ ;
+
+ltxCommandPOOP : COMMAND_POOP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ end_it($1);
+ }
+ ;
+
+ltxCommandPOOPP : COMMAND_POOPP
+ {
+ start_it($1);
+ tag_print(get_tag_t($1,1));
+ set_print(get_param_print($1,1));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,1));
+ tag_print(get_tag_t($1,2));
+ set_print(get_param_print($1,2));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,2));
+ tag_print(get_tag_t($1,3));
+ set_print(get_param_print($1,3));
+ opt_param = TRUE;
+ }
+ OptParam
+ {
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et($1,3));
+ tag_print(get_tag_t($1,4));
+ set_print(get_param_print($1,4));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,4));
+ tag_print(get_tag_t($1,5));
+ set_print(get_param_print($1,5));
+ }
+ ReqParam
+ {
+ reset_print();
+ tag_print(get_tag_et($1,5));
+ end_it($1);
+ }
+ ;
+
+
+ /*----------- "Uninteresting" stuff ---------------*/
+Words: NAME { $$ = $1; }
+ | OTHER { $$ = $1; }
+ ;
+
+Numbers: INTEGER { $$ = $1; }
+ | REAL { $$ = $1; }
+ ;
+
+l2xOthers: l2xOtherCommand
+ | l2xOtherBegin
+ | l2xOtherEnd
+ | l2xDollars
+ | CoordStuff { ; }
+ | l2xNoOps
+ {
+ start_it($1);
+ end_it($1);
+ }
+ ;
+
+l2xOtherCommand: OTHER_COMMAND
+ {
+ sym = get_mode_sym(pos_oc);
+ tag_print(get_t(sym));
+ set_print(get_com_print(sym));
+ myprint($1);
+ }
+ AllParameters
+ {
+ reset_print();
+ free($1);
+ sym = get_mode_sym(pos_oc);
+ tag_print(get_et(sym));
+ }
+ ;
+
+l2xOtherBegin: OTHER_BEGIN
+ {
+ sym = get_mode_sym(pos_ob);
+ tag_print(get_t(sym));
+ set_print(get_com_print(sym));
+ myprint($1);
+ }
+ AllParameters
+ {
+ reset_print();
+ free($1);
+ sym = get_mode_sym(pos_ob);
+ tag_print(get_et(sym));
+ }
+ ;
+
+l2xOtherEnd: OTHER_END
+ {
+ sym = get_mode_sym(pos_oe);
+ tag_print(get_t(sym));
+ set_print(get_com_print(sym));
+ myprint($1);
+ }
+ AllParameters
+ {
+ reset_print();
+ free($1);
+ sym = get_mode_sym(pos_oe);
+ tag_print(get_et(sym));
+ }
+ ;
+
+l2xNoOps: BEGIN_VERBATIM
+ | END_VERBATIM
+ | BEGIN_VERB
+ | END_VERB
+ | PARAGRAPH
+ ;
+
+Coord: LPAREN Numbers COMMA Numbers RPAREN
+ {
+ myprint("(");
+ myprint($2);
+ free($2);
+ myprint(",");
+ myprint($4);
+ free($4);
+ myprint(")");
+ }
+ ;
+
+OptCoord: /* empty */
+ | START_COORD Numbers COMMA Numbers END_COORD
+ {
+ myprint("(");
+ myprint($2);
+ free($2);
+ myprint(",");
+ myprint($4);
+ free($4);
+ myprint(")");
+ }
+ ;
+
+CoordStuff: COMMA { myprint(","); }
+ | LPAREN { myprint("("); }
+ | RPAREN { myprint(")"); }
+ | LBRAK { myprint("["); }
+ | RBRAK { myprint("]"); }
+ ;
+
+AllParameters: {all_opt = TRUE;} OptBracketedStuff {all_opt = FALSE;}
+ ParamList
+ {all_opt = TRUE;} OptBracketedStuff {all_opt = FALSE;}
+ ;
+
+ParamList: /* empty */
+ | BracedStuff
+ | ParamList BracedStuff
+ ;
+
+BracedStuff: Lbrace Rbrace
+ | Lbrace StuffList Rbrace
+ ;
+
+BracketedStuff: START_ALLOPT {myprint("[");} END_ALLOPT {myprint("]");}
+ | START_ALLOPT {myprint("[");} StuffList END_ALLOPT {myprint("]");}
+ ;
+
+OptBracketedStuff: /* empty */
+ | BracketedStuff
+ ;
+
+Lbrace: LBRACE
+ {
+ sym = get_mode_sym(pos_lbrace);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ }
+ ;
+
+Rbrace: RBRACE
+ {
+ sym = get_mode_sym(pos_rbrace);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ }
+ ;
+
+l2xDollars: BEGIN_DOLLAR
+ {
+ sym = get_mode_sym(pos_bdol);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ }
+ | END_DOLLAR
+ {
+ sym = get_mode_sym(pos_edol);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ }
+ ;
+
+ /*-------------Specials-----------------*/
+
+l2xSpecials: GrammSpecial
+ ;
+
+
+ /*----------- \GRAMMspecial{param text} -----------------*/
+/* start new section, save param text, start description environment */
+GrammSpecial: GRAMMSPECIAL
+ {
+ start_section($1);
+ tag_print(get_t($1));
+ tag_print(get_tag_t($1,1));
+ initialise_sysbuf();
+ set_print(p_print_to_sysbuf);
+ }
+ LBRACE StuffList RBRACE
+ {
+ initialise_string(grammbuf);
+ copy_sysbuf(grammbuf);
+ reset_print();
+ prwboiler1();
+ print_sysbuf();
+ prwboiler2();
+ myprint(grammbuf);
+ prwboiler3();
+ start_list($1);
+ }
+ ;
+
+
+%%
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xacts.c b/support/ltx2x/l2xacts.c
new file mode 100644
index 0000000000..5dd7687345
--- /dev/null
+++ b/support/ltx2x/l2xacts.c
@@ -0,0 +1,631 @@
+/* l2xacts.c Grammer actions for l2x */
+/* 6/96 replaced myprint(tag) by tag_print(tag) */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xusrlb.h" /* user defined action functions */
+#include "l2xlib.h" /* functions and global variables */
+#include "l2xytab.h" /* parser communication */
+
+
+/* functions defined herein */
+void default_start_with_opt();
+void default_end_start_opt();
+void start_it();
+void end_it();
+void start_section();
+void start_list();
+void end_list();
+void start_with_req();
+void action_p_p1();
+void action_last_p();
+void start_with_opt();
+void action_opt_first();
+void action_p_opt();
+void action_last_opt();
+void action_no_param();
+void do_start_pc();
+void do_end_pc();
+int not_ok_sym();
+
+
+ /* lexer/parser communication */
+extern int opt_param;
+
+
+ /* 6/96 changed int pos to PSENTRY pos */
+
+/* DEFAULT_START_WITH_OPT default action before an initial opt param */
+void default_start_with_opt(pos)
+PSENTRY pos; /* ptr to sym entry */
+{
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ tag_print(get_opttag_t(pos)); /* print start tag for opt param */
+ set_print(get_opt_print(pos)); /* set parameter printing */
+ opt_param = TRUE; /* processing optional */
+} /* end DEFAULT_START_WITH_OPT */
+
+
+/* DEFAULT_END_START_OPT defaults action after an initial opt param */
+void default_end_start_opt(pos)
+PSENTRY pos; /* command position in table */
+{
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ opt_param = FALSE; /* not processing optional */
+ reset_print(); /* set printing on */
+ tag_print(get_opttag_et(pos)); /* print opt param end tag */
+} /* end DEFAULT_END_START_OPT */
+
+
+/* START_IT starts a grammar rule */
+void start_it(pos) /* command position in table */
+PSENTRY pos;
+{
+ int ut;
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+ do_start_pc(pos); /* added 6/96 */
+ ut = get_user_type(pos);
+ switch (ut) { /* switch on user type */
+ case SECTIONING: {
+ start_section(pos);
+ break;
+ }
+ case BEGIN_LIST_ENV: {
+ start_list(pos);
+ break;
+ }
+ case END_LIST_ENV: {
+ end_list();
+ break;
+ }
+ }
+ tag_print(get_t(pos)); /* print command start tag */
+} /* end START_IT */
+
+
+/* END_IT ends a grammar rule */
+void end_it(pos) /* position in command table */
+PSENTRY pos;
+{
+ int ut;
+
+ if (not_ok_sym(pos)) { /* out of range */
+ return;
+ }
+ ut = get_user_type(pos);
+ switch (ut) { /* switch on user type */
+ case SECTIONING: { /* end tag printed via start-section */
+ break;
+ }
+ default: {
+ tag_print(get_et(pos)); /* print command end tag */
+ break;
+ }
+ } /* end switch */
+ do_end_pc(pos); /* added 6/96 */
+} /* end END_IT */
+
+
+
+/* START_SECTION sets up sectioning stuff */
+void start_section(pos) /* position in command table */
+PSENTRY pos;
+{
+ int this_level; /* sectioning level */
+
+ if (not_ok_sym(pos)) { /* out of range */
+ return;
+ }
+ this_level = get_level(pos);
+ close_doc_divs(this_level); /* close prior levels */
+ current_level = this_level; /* set current level */
+ set_clause_stack(current_level, get_et(pos) );
+} /* end START_SECTION */
+
+
+/* START_LIST sets up item list stuff */
+void start_list(pos) /* position in command table */
+PSENTRY pos;
+{
+ if (not_ok_sym(pos)) { /* out of range */
+ return;
+ }
+ /* push tags onto list stack */
+ set_list_stack(get_item_t(pos), get_item_et(pos),
+ get_itemopt_t(pos), get_itemopt_et(pos) );
+} /* end START_LIST */
+
+
+
+/* END_LIST finishes a list environment */
+void end_list()
+{
+ if (list_level >= LIST_STACK_SIZE) {
+ yyerror("Somethings wrong (end_list): overflow");
+ list_level = LIST_STACK_SIZE - 1;
+ }
+ else if (list_level < 0) {
+ yyerror("Somethings wrong (end_list): underflow");
+ list_level = 0;
+ }
+ else if (num_items[list_level] > 0) { /* close off last item */
+ tag_print(list_str_stack[list_level]);
+ }
+ num_items[list_level] = 0;
+ list_level--;
+} /* end END_LIST */
+
+
+
+/* START_WITH_REQ action at start of command with req param */
+void start_with_req(pos)
+PSENTRY pos; /* command position in table */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ start_it(pos); /* command start action */
+ tag_print(get_tag_t(pos,1)); /* print start tag for 1st param */
+ set_print(get_param_print(pos,1)); /* set parameter printing */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_start_with_req(pos);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(start_with_req) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end START_WITH_REQ */
+
+
+/* ACTION_P_P1 action between p'th and p+1'th req params */
+void action_p_p1(pos,p)
+PSENTRY pos; /* position of command in table */
+int p; /* number of p'th parameter */
+{
+ int p1;
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ p1 = p + 1;
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ reset_print(); /* set printing on */
+ tag_print(get_tag_et(pos,p)); /* print end tag for parameter p */
+ tag_print(get_tag_t(pos,p1)); /* print start tag for p+1 */
+ set_print(get_param_print(pos,p1)); /* set parameter printing */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_action_p_p1(pos,p);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(action_p_p1) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end ACTION_P_P1 */
+
+
+/* ACTION_LAST_P action after last req parameter */
+void action_last_p(pos,p)
+PSENTRY pos; /* position of command in table */
+int p; /* number of last parameter */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ reset_print();
+ tag_print(get_tag_et(pos,p)); /* print end tag for parameter p */
+ end_it(pos); /* final action for command */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_action_last_p(pos,p);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(action_last_p) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end ACTION_LAST_P */
+
+
+/* START_WITH_OPT start action for command with optional param */
+void start_with_opt(pos)
+PSENTRY pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ start_it(pos); /* command start action */
+ default_start_with_opt(pos); /* start optional param */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_start_with_opt(pos);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(start_with_opt) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end START_WITH_OPT */
+
+
+/* ACTION_OPT_FIRST action between opt and 1st param */
+void action_opt_first(pos)
+PSENTRY pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ default_end_start_opt(pos); /* end opt param */
+ tag_print(get_tag_t(pos,1)); /* print start tag for 1st param */
+ set_print(get_param_print(pos,1)); /* set parameter printing */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_action_opt_first(pos);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(action_opt_first) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end ACTION_OPT_FIRST */
+
+
+/* ACTION_P_OPT action between param p and opt */
+void action_p_opt(pos,p)
+PSENTRY pos; /* position of command in table */
+int p; /* number of p'th parameter */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ reset_print(); /* set printing on */
+ tag_print(get_tag_et(pos,p)); /* print end tag for parameter p */
+ tag_print(get_opttag_t(pos)); /* print start tag for opt param */
+ set_print(get_opt_print(pos)); /* set parameter printing */
+ opt_param = TRUE; /* processing optional */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_action_p_opt(pos,p);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(action_p_opt) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end ACTION_P_OPT */
+
+
+/* ACTION_LAST_OPT action after last opt param */
+void action_last_opt(pos)
+PSENTRY pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ opt_param = FALSE; /* not processing optional */
+ reset_print();
+ tag_print(get_opttag_et(pos)); /* print end tag for opt parameter */
+ end_it(pos); /* final action for command */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_action_last_opt(pos);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(action_last_opt) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end ACTION_LAST_OPT */
+
+
+/* ACTION_NO_PARAM command with no params */
+void action_no_param(pos)
+PSENTRY pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ case BEGIN_DOCUMENT:
+ case END_DOCUMENT:
+ case VCOMMAND:
+ case BEGIN_VENV:
+ case END_VENV: {
+ start_it(pos); /* start action for command */
+ end_it(pos); /* final action for command */
+ break;
+ }
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING: {
+ special_action_no_param(pos);
+ break;
+ }
+ default: { /* should not be here! */
+ warning("(action_no_param) Unrecognized command type");
+ break;
+ }
+ } /* end switch on user_kind */
+} /* end ACTION_NO_PARAM */
+
+
+/* DO_START_PC sets the starting print control */
+void do_start_pc(pos)
+PSENTRY pos; /* position in command table */
+{
+ int pc;
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ pc = get_pc_enum(get_start_pc(pos));
+ switch (pc) {
+ case DEFAULT_PRINT : { /* do nothing */
+ break;
+ }
+ case RESET : { /* reset print control */
+ reset_print();
+ break;
+ }
+ default : { /* anything else changes the setting */
+ set_print(get_start_pc(pos));
+ break;
+ }
+ } /* end switch */
+ return;
+} /* end DO_START_PC */
+
+
+/* DO_END_PC sets the ending print control */
+void do_end_pc(pos)
+PSENTRY pos; /* position in command table */
+{
+ int pc;
+
+ if (not_ok_sym(pos)) {
+ return;
+ }
+
+ pc = get_pc_enum(get_end_pc(pos));
+ switch (pc) {
+ case DEFAULT_PRINT : { /* do nothing */
+ break;
+ }
+ case RESET : { /* reset print control */
+ reset_print();
+ break;
+ }
+ default : { /* anything else changes the setting */
+ set_print(get_end_pc(pos));
+ break;
+ }
+ } /* end switch */
+ return;
+} /* end DO_END_PC */
+
+
+/* NOT_OK_SYM returns TRUE if sym entry not found */
+int not_ok_sym(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) {
+ yyerror("symbol table entry not found");
+ return(TRUE);
+ }
+ return(FALSE);
+} /* end NOT_OK_SYM */
+
+
+
diff --git a/support/ltx2x/l2xacts.h b/support/ltx2x/l2xacts.h
new file mode 100644
index 0000000000..04eaab3ffd
--- /dev/null
+++ b/support/ltx2x/l2xacts.h
@@ -0,0 +1,17 @@
+/* l2xacts.h .h file for l2xacts.c */
+
+extern void default_start_with_opt();
+extern void default_end_start_opt();
+extern void start_it();
+extern void end_it();
+extern void start_section();
+extern void start_list();
+extern void end_list();
+extern void start_with_req();
+extern void action_p_p1();
+extern void action_last_p();
+extern void start_with_opt();
+extern void action_opt_first();
+extern void action_p_opt();
+extern void action_last_opt();
+extern void action_no_param();
diff --git a/support/ltx2x/l2xcom.h b/support/ltx2x/l2xcom.h
new file mode 100644
index 0000000000..138482231f
--- /dev/null
+++ b/support/ltx2x/l2xcom.h
@@ -0,0 +1,85 @@
+/* l2xcom.h typedefs, etc for ltx2x */
+
+#ifndef L2XCOM_H
+#define L2XCOM_H
+
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+
+#ifndef common_h
+typedef int ICT; /* from inter code common.h */
+#endif
+
+typedef union u_rwc{
+ int bfnum; /* buffer or file number */
+ FILE *uf; /* file */
+ STRING defstr; /* string in CT */
+ ICT *bytecode; /* pointer to a compiled code segment */
+ } URWC ;
+
+typedef struct st_rwc{
+ struct st_rwc *next; /* pointer to next in list */
+ int cmd; /* command keyword enum */
+ int pcenum; /* print_control enum */
+ URWC rwcode; /* print_control value */
+ } STRWC, *PSTRWC ;
+
+
+typedef struct st_entry { /* symbol table entry */
+ STRING command; /* user defined command string */
+ int kind; /* user defined kind of command */
+ int parse_kind; /* system defined kind of command */
+ int mode; /* mode for this command (if any) */
+ struct st_entry *next_mode; /* pointer to next mode */
+ PSTRWC printing; /* print control (changed 6/96 from int) */
+ PSTRWC command_t; /* command tag */
+ PSTRWC command_et; /* end of command tag */
+ int numparams; /* user defined no. of required params */
+ PSTRWC param_t[9]; /* parameter begin tags */
+ PSTRWC param_et[9]; /* parameter end tags */
+ PSTRWC print_param[9]; /* param text print control (changed 6/96 from int) */
+ int opt_param_pos; /* position (if any) of optional param */
+ PSTRWC opt_param_t; /* opt param begin tag */
+ PSTRWC opt_param_et; /* opt param end tag */
+ PSTRWC popt_param_t[2]; /* (SD) first and last opt param begin tag */
+ PSTRWC popt_param_et[2]; /* (SD) first and last opt param end tags */
+ PSTRWC print_opt[2]; /* opt param text print control (changed 6/96 from int) */
+ PSTRWC start_pc; /* starting print control (added 6/96) */
+ PSTRWC end_pc; /* ending print control (added 6/96) */
+ int sectioning_level; /* user specified sectioning level */
+ int special_token; /* user defined special token for/from yac */
+} STENTRY, *PSENTRY;
+
+#define IERR -1
+
+enum print_control{
+#define kwtc(a, b)
+#define lctc(a, b)
+#define pctc(a, b) a,
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+/*
+enum print_control{BUFFER,
+ DEFAULT_PRINT,
+ FFILE,
+ FIRST_STRING,
+ MODE,
+ NO_OP,
+ NO_PRINT,
+ PRINT_UNDERFLOW,
+ RESET,
+ SOURCE_STRING,
+ SYSBUF,
+ TO_BUFFER,
+ TO_FILE,
+ TO_SYSBUF,
+ UNKNOWN_PRINT,
+ MAX_PCSTR};
+*/
+
+#endif
diff --git a/support/ltx2x/l2xicmon.h b/support/ltx2x/l2xicmon.h
new file mode 100644
index 0000000000..5ff228c876
--- /dev/null
+++ b/support/ltx2x/l2xicmon.h
@@ -0,0 +1,60 @@
+/* l2xicmon.h for LTX2X interpreter */
+/* BASED ON: common.h (unaltered) */
+
+#ifndef common_h
+#define common_h
+
+#define FORM_FEED_CHAR '\f'
+#define MAX_FILE_NAME_LENGTH 32
+#define MAX_SOURCE_LINE_LENGTH 256
+#define MAX_PRINT_LINE_LENGTH 80
+#define MAX_LINES_PER_PAGE 50
+#define DATE_STRING_LENGTH 26
+#define MAX_TOKEN_STRING_LENGTH MAX_SOURCE_LINE_LENGTH
+#define MAX_CODE_BUFFER_SIZE 4096
+#define MAX_NESTING_LEVEL 16
+#define MAX_STACK_SIZE 1024
+#define STACK_FRAME_HEADER_SIZE 4
+#define MAX_EXPRESS_STRING 2048
+#define MAX_AGG_SIZE 1024
+
+/* typedef enum { FALSE, TRUE, } BOOLEAN; */
+typedef int BOOLEAN;
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+/* PRW change ADDRESS */
+/* typedef char *ADDRESS; */
+#ifndef L2XCOM_H
+typedef int ICT; /* intermediate code segment type */
+#endif
+typedef ICT *ADDRESS; /* ptr into code segment */
+
+/* macros for memory allocation */
+#define alloc_struct(type) (type *) malloc(sizeof(type))
+#define alloc_array(type, count) (type *) malloc(count*sizeof(type))
+#define alloc_bytes(length) (char *) malloc(length)
+
+ /* PW additions */
+#define EOS '\0'
+
+extern FILE *ferr; /* error o/p file */
+extern FILE *fcodeseg; /* code segment o/p file */
+extern FILE *filout; /* result output file */
+
+extern int SLD_OFF; /* TRUE if source level debugger disabled */
+
+ /* for numbers */
+typedef long int XPRSAINT; /* C type for INTEGER */
+typedef double XPRSAREAL; /* C type for REAL */
+
+#define MAX_INTEGER 2147483647
+#define MAX_DIGIT_COUNT 20
+#define MAX_EXPONENT 37
+
+#endif
diff --git a/support/ltx2x/l2xicpr.h b/support/ltx2x/l2xicpr.h
new file mode 100644
index 0000000000..4a687fd804
--- /dev/null
+++ b/support/ltx2x/l2xicpr.h
@@ -0,0 +1,38 @@
+/* l2xicpr.h before/after token codes for parser */
+
+#ifndef l2xicpr_h
+#define l2xicpr_h
+
+#ifndef licomsym_h
+#include "licomsym.h" /* this includes the definition of token codes */
+#endif
+
+/* here are the before/after token code lists */
+extern TOKEN_CODE statement_start_list[];
+extern TOKEN_CODE statement_end_list[];
+extern TOKEN_CODE declaration_start_list[];
+extern TOKEN_CODE follow_indexes_list[];
+extern TOKEN_CODE follow_header_list[];
+extern TOKEN_CODE follow_parms_list[];
+extern TOKEN_CODE follow_proc_id_list[];
+extern TOKEN_CODE follow_func_id_list[];
+extern TOKEN_CODE follow_parm_list[];
+extern TOKEN_CODE follow_decls_list[];
+extern TOKEN_CODE follow_expr_list[];
+extern TOKEN_CODE case_label_start_list[];
+extern TOKEN_CODE follow_case_label_list[];
+extern TOKEN_CODE ltx2x_follow_decls_list[];
+extern TOKEN_CODE follow_attributes_list[];
+extern TOKEN_CODE follow_min_bound_list[];
+
+ /* lists of operators */
+extern TOKEN_CODE rel_op_list[];
+extern TOKEN_CODE add_op_list[];
+extern TOKEN_CODE mult_op_list[];
+
+ /* lists of types, constants, ... */
+extern TOKEN_CODE simple_type_list[];
+extern TOKEN_CODE constant_list[];
+extern TOKEN_CODE aggregation_type_list[];
+
+#endif
diff --git a/support/ltx2x/l2xidbug.c b/support/ltx2x/l2xidbug.c
new file mode 100644
index 0000000000..e909a7399c
--- /dev/null
+++ b/support/ltx2x/l2xidbug.c
@@ -0,0 +1,1295 @@
+/* l2xidbug.c Interactive SLD debugging routines for LTX2X interpreter */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiexec.h"
+#include "l2xiidbg.h"
+
+#define MAX_BREAKS 16
+#define MAX_WATCHES 16
+#define COMMAND_QUERY "Command? "
+
+/* EXTERNALS */
+
+extern int level;
+extern SYMTAB_NODE_PTR symtab_display[];
+extern STACK_ITEM_PTR tos;
+
+extern int line_number;
+extern int buffer_offset;
+extern BOOLEAN print_flag;
+
+extern ICT *code_segmentp;
+extern ICT *statement_startp;
+extern int ctoken;
+extern int exec_line_number;
+extern int isynt_error_count;
+
+extern char *bufferp;
+extern int ch;
+extern char source_buffer[];
+extern char word_string[];
+extern int token;
+extern LITERAL literal;
+extern BOOLEAN block_flag;
+
+extern ICT *code_buffer;
+extern ICT *code_bufferp;
+extern ICT *code_segmentp;
+
+extern BOOLEAN is_value_undef();
+
+/* GLOBALS */
+
+FILE *console;
+
+BOOLEAN debugger_command_flag, /* TRUE during debug command */
+ halt_flag, /* TRUE to pause for debug command */
+ trace_flag, /* TRUE to trace statement */
+ step_flag, /* TRUE to single-step */
+ entry_flag, /* TRUE to trace routine entry */
+ exit_flag, /* TRUE to trace routine exit */
+ traceall_flag, /* TRUE to trace everything */
+ stack_flag; /* TRUE to watch the stack */
+
+int break_count; /* count of breakpoints */
+int break_list[MAX_BREAKS]; /* list of breakpoints */
+
+int watch_count; /* count of watches */
+SYMTAB_NODE_PTR watch_list[MAX_WATCHES]; /* list of watches */
+
+typedef struct { /* watch structure */
+ SYMTAB_NODE_PTR watch_idp; /* id node watched variable */
+ BOOLEAN store_flag; /* TRUE to trace stores */
+ BOOLEAN fetch_flag; /* TRUE to trace fetches */
+} WATCH_STRUCT, *WATCH_STRUCT_PTR;
+
+/* char *symbol_strings[EOTC]; */
+/* array of the strings which form tokens */
+char *symbol_strings[] = {
+#define sctc(a, b, c) c,
+#include "l2xisctc.h"
+#undef sctc
+};
+
+/* array of strings which corresponding to form types */
+char *form2str[] = {
+#define fotc(a, b, c, d) d,
+#define sotc(a, b, c, d)
+#define sftc(a, b, c, d) d,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+};
+
+/* array of strings which corresponding to stack types */
+char *stack2str[] = {
+#define fotc(a, b, c, d)
+#define sotc(a, b, c, d) b,
+#define sftc(a, b, c, d) b,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+};
+
+/********************************************************************/
+/* init_debugger() Initialise interactive debugger */
+
+init_debugger()
+{
+ int i;
+
+ if (SLD_OFF) return;
+
+ /* initialise the globals */
+/* console = fopen("CON", "r"); */
+ console = stdin;
+ /* init_symbol_strings(); */
+ /* code_buffer = alloc_bytes(MAX_SOURCE_LINE_LENGTH + 1); */
+
+ print_flag = FALSE;
+ halt_flag = block_flag = TRUE;
+ debugger_command_flag = trace_flag = step_flag
+ = entry_flag = exit_flag
+ = FALSE;
+ traceall_flag = stack_flag = FALSE;
+
+ break_count = 0;
+ for (i = 0; i <MAX_BREAKS; i++) break_list[i] = 0;
+
+ watch_count = 0;
+ for (i = 0; i <MAX_WATCHES; i++) watch_list[i] = NULL;
+
+ } /* end init_debugger */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* read_debugger_command() Read and process a user's debug command */
+
+ read_debugger_command()
+ {
+ BOOLEAN done = FALSE;
+ entry_debug("read_debugger_command");
+
+ do {
+ printf("\n%s", COMMAND_QUERY);
+
+ /* read in comand and replace final \nEOS with ;;EOS */
+ bufferp = fgets(source_buffer, MAX_SOURCE_LINE_LENGTH, console);
+ strcpy(&source_buffer[strlen(source_buffer) - 1], ";;\0");
+
+ buffer_offset = 0;
+ ch = *bufferp++;
+ buffer_offset++;
+ code_bufferp = code_buffer;
+ isynt_error_count = 0;
+
+ get_token();
+
+ /* process the command */
+ switch (token) {
+ case SEMICOLON: {
+ done = TRUE;
+ break;
+ }
+ case IDENTIFIER: {
+ execute_debugger_command();
+ break;
+ }
+ }
+ if (token != SEMICOLON) {
+ error(UNEXPECTED_TOKEN);
+ }
+ } while (!done); /* end do */
+
+ debugger_command_flag = FALSE;
+ exit_debug("read_debugger_command");
+
+ } /* end read_debugger_command */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* execute_debugger_command() Execute a debugger command */
+
+ execute_debugger_command()
+ {
+ WATCH_STRUCT_PTR wp;
+ WATCH_STRUCT_PTR allocate_watch();
+
+ if (strcmp(word_string, "trace") == 0) {
+ trace_flag = TRUE;
+ step_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "untrace") == 0) {
+ trace_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "step") == 0) {
+ step_flag = TRUE;
+ trace_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "unstep") == 0) {
+ step_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "break") == 0) {
+ set_breakpoint();
+ }
+ else if (strcmp(word_string, "unbreak") == 0) {
+ remove_breakpoint();
+ }
+ else if (strcmp(word_string, "entry") == 0) {
+ entry_flag = TRUE;
+ get_token();
+ }
+ else if (strcmp(word_string, "unentry") == 0) {
+ entry_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "exit") == 0) {
+ exit_flag = TRUE;
+ get_token();
+ }
+ else if (strcmp(word_string, "unexit") == 0) {
+ exit_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "watch") == 0) {
+ wp = allocate_watch();
+ if (wp != NULL) {
+ wp->store_flag = TRUE;
+ wp->fetch_flag = TRUE;
+ }
+ }
+ else if (strcmp(word_string, "unwatch") == 0) {
+ remove_watch();
+ }
+ else if (strcmp(word_string, "store") == 0) {
+ wp = allocate_watch();
+ if (wp != NULL) {
+ wp->store_flag = TRUE;
+ }
+ }
+ else if (strcmp(word_string, "fetch") == 0) {
+ wp = allocate_watch();
+ if (wp != NULL) {
+ wp->fetch_flag = TRUE;
+ }
+ }
+ else if (strcmp(word_string, "show") == 0) {
+ show_value();
+ }
+ else if (strcmp(word_string, "assign") == 0) {
+ assign_variable();
+ }
+ else if (strcmp(word_string, "where") == 0) {
+ print_statement();
+ get_token();
+ }
+ else if (strcmp(word_string, "kill") == 0) {
+ printf("Program killed.\n");
+ exit(0);
+ }
+
+ else if (strcmp(word_string, "traceall") == 0) {
+ traceall_flag = TRUE;
+ get_token();
+ }
+ else if (strcmp(word_string, "untraceall") == 0) {
+ traceall_flag = FALSE;
+ get_token();
+ }
+ else if (strcmp(word_string, "stack") == 0) {
+ stack_flag = TRUE;
+ stack_debug();
+ get_token();
+ }
+ else if (strcmp(word_string, "unstack") == 0) {
+ stack_flag = FALSE;
+ get_token();
+ }
+ return;
+ } /* end execute_debugger_command */
+ /********************************************************************/
+
+
+ /* TRACING ROUTINES */
+
+
+
+ /********************************************************************/
+ /* trace_statement_execution() Called just before the execution */
+ /* of each statement */
+
+ trace_statement_execution()
+ {
+ if (SLD_OFF) return;
+
+ if (traceall_flag) {
+ sprintf(dbuffer, ">> Stmt %d\n", exec_line_number);
+ log_print(dbuffer);
+ }
+
+ if (break_count > 0) {
+ int i;
+
+ /* check if this statement is a breakpoint */
+ for (i = 0; i < break_count; i++) {
+ if (exec_line_number == break_list[i]) {
+ printf("\nBreakpoint");
+ print_statement();
+ halt_flag = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* pause to read debugger command */
+ if (halt_flag) {
+ read_debugger_command();
+ halt_flag = step_flag;
+ }
+
+ /* if single stepping, print the current statement */
+ /* if tracing, print the current line number */
+ if (step_flag) print_statement();
+ if (trace_flag && !traceall_flag) print_line_number();
+
+ } /* end trace_statement_execution */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* trace_routine_entry(idp) Called at entry to a routine */
+
+ trace_routine_entry(idp)
+ SYMTAB_NODE_PTR idp; /* routine id */
+ {
+ if (SLD_OFF) return;
+
+ if (traceall_flag) {
+ sprintf(dbuffer, ">> Entering routine %s\n", idp->name);
+ log_print(dbuffer);
+ }
+ else if (entry_flag) {
+ printf("\nEntering %s\n", idp->name);
+ }
+
+ } /* end trace_routine_entry */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* trace_routine_exit(idp) Called at exit from a routine */
+
+ trace_routine_exit(idp)
+ SYMTAB_NODE_PTR idp; /* routine id */
+ {
+ if (SLD_OFF) return;
+
+ if (traceall_flag) {
+ sprintf(dbuffer, ">> Exiting routine %s\n", idp->name);
+ log_print(dbuffer);
+ }
+ else if (exit_flag) {
+ printf("\nExiting %s\n", idp->name);
+ }
+
+ } /* end trace_routine_exit */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* trace_data_store(idp, idp_tp, targetp, target_tp) Called just */
+ /* before storing data in a variable */
+
+ trace_data_store(idp, idp_tp, targetp, target_tp)
+ SYMTAB_NODE_PTR idp; /* id of target variable */
+ TYPE_STRUCT_PTR idp_tp; /* ptr to idp's type */
+ STACK_ITEM_PTR targetp; /* ptr to target location */
+ TYPE_STRUCT_PTR target_tp; /* ptr to target's type */
+ {
+ if (SLD_OFF) return;
+
+ if (traceall_flag) {
+ sprintf(dbuffer, ">> %s", idp->name);
+ log_print(dbuffer);
+ if (idp_tp->form == ARRAY_FORM ||
+ idp_tp->form == BAG_FORM ||
+ idp_tp->form == LIST_FORM ||
+ idp_tp->form == SET_FORM ) {
+ log_print("[*]");
+ }
+ else if (idp_tp->form == ENTITY_FORM) {
+ log_print(".*");
+ }
+ print_data_value_debug(targetp, target_tp, ":=");
+ }
+
+ /* check if variable is being watched for stores */
+ else if ((idp->info != NULL) && ((WATCH_STRUCT_PTR) idp->info)->store_flag) {
+ printf("\nAt %d: Store %s", exec_line_number, idp->name);
+ if (idp_tp->form == ARRAY_FORM ||
+ idp_tp->form == BAG_FORM ||
+ idp_tp->form == LIST_FORM ||
+ idp_tp->form == SET_FORM ) {
+ printf("[*]");
+ }
+ else if (idp_tp->form == ENTITY_FORM) {
+ printf(".*");
+ }
+ print_data_value(targetp, target_tp, ":=");
+ }
+
+ return;
+ } /* end trace_data_store */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* trace_data_fetch(idp, tp, datap) Called just */
+ /* before fetching data from a variable */
+
+ trace_data_fetch(idp, tp, datap)
+ SYMTAB_NODE_PTR idp; /* id of target variable */
+ TYPE_STRUCT_PTR tp; /* ptr to idp's type */
+ STACK_ITEM_PTR datap; /* ptr to data */
+ {
+ TYPE_STRUCT_PTR idp_tp = idp->typep;
+
+ if (SLD_OFF) return;
+
+
+ if (traceall_flag) {
+ sprintf(dbuffer, ">> %s", idp->name);
+ log_print(dbuffer);
+ if (idp_tp->form == ARRAY_FORM ||
+ idp_tp->form == BAG_FORM ||
+ idp_tp->form == LIST_FORM ||
+ idp_tp->form == SET_FORM ) {
+ log_print("[*]");
+ }
+ else if (idp_tp->form == ENTITY_FORM) {
+ log_print(".*");
+ }
+ print_data_value_debug(datap, tp, "=");
+ }
+
+ /* check if variable is being watched for fetches */
+ else if ((idp->info != NULL) && ((WATCH_STRUCT_PTR) idp->info)->fetch_flag) {
+ printf("\nAt %d: Fetch %s", exec_line_number, idp->name);
+ if (idp_tp->form == ARRAY_FORM ||
+ idp_tp->form == BAG_FORM ||
+ idp_tp->form == LIST_FORM ||
+ idp_tp->form == SET_FORM ) {
+ printf("[*]");
+ }
+ else if (idp_tp->form == ENTITY_FORM) {
+ printf(".*");
+ }
+ print_data_value(datap, tp, "=");
+ }
+
+ return;
+ } /* end trace_data_fetch */
+ /********************************************************************/
+
+
+ /* PRINTING ROUTINES */
+
+
+ /********************************************************************/
+ /* print_statement() Uncrunch and print a statement */
+
+ print_statement()
+ {
+ int tk; /* token code */
+ BOOLEAN done = FALSE;
+ ICT *csp = statement_startp;
+/* entry_debug("print_statement"); */
+
+ printf("\nAt %3d:", exec_line_number);
+
+ do {
+ switch (tk = *csp++) {
+ case SEMICOLON:
+ case END:
+ case ELSE:
+ case THEN:
+ case UNTIL:
+ case BEGIN:
+ case OF:
+ case STATEMENT_MARKER: {
+ done = TRUE;
+ break;
+ }
+ default: {
+ done = FALSE;
+ switch(tk) {
+ case ADDRESS_MARKER: {
+ csp++;
+ break;
+ }
+ case IDENTIFIER:
+ case NUMBER_LITERAL:
+ case STRING_LITERAL: {
+ SYMTAB_NODE_PTR np = *((SYMTAB_NODE_PTR *) csp);
+ printf(" %s", np->name);
+ csp++;
+ break;
+ }
+ default: {
+ printf(" %s", symbol_strings[tk]);
+ break;
+ }
+ } /* end switch */
+ }
+ } /* end switch */
+ } while (!done); /* end do */
+
+ printf("\n");
+/* exit_debug("print_statement"); */
+
+ } /* end print_statement */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* print_line_number() Print the current line number */
+
+ print_line_number()
+ {
+
+ printf("<%d>", exec_line_number);
+
+ } /* end print_line_number */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* print_data_value(datap, tp, str) Print a data value */
+
+ print_data_value(datap, tp, str)
+ STACK_ITEM_PTR datap; /* ptr to data value */
+ TYPE_STRUCT_PTR tp; /* ptr to type of stack item */
+ char *str; /* " = " or " := " */
+ {
+ STACK_TYPE stype;
+ LOGICAL_REP log;
+ TYPE_FORM form;
+
+ form = tp->form;
+
+ if (form == ARRAY_FORM ||
+ form == BAG_FORM ||
+ form == LIST_FORM ||
+ form == SET_FORM ||
+ form == ENTITY_FORM ) {
+ printf(" %s <%s>\n", str, form2str[form]);
+ return;
+ }
+
+ stype = get_stackval_type(datap);
+
+ if (stype == STKUDF) {
+ printf(" %s %c\n", str, get_undef(datap));
+ }
+
+ else if (stype == STKINT) {
+ printf(" %s %d\n", str, get_integer(datap));
+ }
+ else if (stype == STKREA) {
+ printf(" %s %0.6g\n", str, get_real(datap));
+ }
+ else if (stype == STKLOG) {
+ log = get_logical(datap);
+ if (log == TRUE_REP) {
+ printf(" %s %s\n", str, "TRUE");
+ }
+ else if (log == FALSE_REP) {
+ printf(" %s %s\n", str, "FALSE");
+ }
+ else {
+ printf(" %s %s\n", str, "UNKNOWN");
+ }
+ }
+ else if (stype == STKSTR) {
+ printf(" %s %s\n", str, get_stacked_string(datap));
+ }
+
+ return;
+
+
+ } /* end print_data_value */
+ /********************************************************************/
+
+
+ /********************************************************************/
+ /* print_data_value_debug(datap, tp, str) Print a data value */
+
+ print_data_value_debug(datap, tp, str)
+ STACK_ITEM_PTR datap; /* ptr to data value */
+ TYPE_STRUCT_PTR tp; /* ptr to type of stack item */
+ char *str; /* " = " or " := " */
+ {
+ STACK_TYPE stype;
+ LOGICAL_REP log;
+ TYPE_FORM form;
+
+ form = tp->form;
+
+ if (form == ARRAY_FORM ||
+ form == BAG_FORM ||
+ form == LIST_FORM ||
+ form == SET_FORM ||
+ form == ENTITY_FORM ) {
+ sprintf(dbuffer, " %s <%s>\n", str, form2str[form]);
+ log_print(dbuffer);
+ return;
+ }
+
+ stype = get_stackval_type(datap);
+
+ if (stype == STKUDF) {
+ sprintf(dbuffer, " %s %c\n", str, get_undef(datap));
+ log_print(dbuffer);
+ }
+
+ else if (stype == STKINT) {
+ sprintf(dbuffer, " %s %d\n", str, get_integer(datap));
+ log_print(dbuffer);
+ }
+ else if (stype == STKREA) {
+ sprintf(dbuffer, " %s %0.6g\n", str, get_real(datap));
+ log_print(dbuffer);
+ }
+ else if (stype == STKLOG) {
+ log = get_logical(datap);
+ if (log == TRUE_REP) {
+ sprintf(dbuffer, " %s %s\n", str, "TRUE");
+ }
+ else if (log == FALSE_REP) {
+ sprintf(dbuffer, " %s %s\n", str, "FALSE");
+ }
+ else {
+ sprintf(dbuffer, " %s %s\n", str, "UNKNOWN");
+ }
+ log_print(dbuffer);
+ }
+ else if (stype == STKSTR) {
+ sprintf(dbuffer, " %s %s\n", str, get_stacked_string(datap));
+ log_print(dbuffer);
+ }
+
+ return;
+
+ } /* end print_data_value_debug */
+ /********************************************************************/
+
+
+ /* BREAKPOINTS AND WATCHES */
+
+
+ /********************************************************************/
+ /* set_breakpoint() Set a breakpoint, or print all breakpoints in */
+ /* the break list */
+
+ set_breakpoint()
+ {
+ int i, number;
+
+ get_token();
+
+ switch (token) {
+ case SEMICOLON: { /* no line number --- list all breakpoints */
+
+ printf("Statement breakpoints at:\n");
+ for (i = 0; i < break_count; i++) {
+ printf("%5d\n", break_list[i]);
+ }
+ break;
+ }
+
+ case NUMBER_LITERAL: { /* set breakpoint by appending to list */
+
+ if (literal.type == INTEGER_LIT) {
+ number = literal.value.integer;
+ if ((number > 0) && (number <= line_number)) {
+ if (break_count < MAX_BREAKS) {
+ break_list[break_count] = number;
+ ++break_count;
+ }
+ else {
+ printf("Break list is full.\n");
+ }
+ }
+ else {
+ error(VALUE_OUT_OF_RANGE);
+ }
+ }
+ else {
+ error(UNEXPECTED_TOKEN);
+ }
+ get_token();
+ break;
+ }
+ } /* end switch */
+
+ } /* end set_breakpoint */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* remove_breakpoint() Remove a specified breakpoint, or all */
+
+ remove_breakpoint()
+ {
+ int i, j, number;
+
+ get_token();
+
+ switch (token) {
+ case SEMICOLON: { /* no line number --- remove all breakpoints */
+
+ for (i = 0; i < break_count; i++) {
+ break_list[i] = 0;
+ }
+ break_count = 0;
+ break;
+ }
+
+ case NUMBER_LITERAL: { /* remove breakpoint from list, and move others up */
+
+ if (literal.type == INTEGER_LIT) {
+ number = literal.value.integer;
+ if (number > 0) {
+ for (i = 0; i < break_count; i++) {
+ if (break_list[i] == number) {
+ break_list[i] = 0;
+ --break_count;
+
+ for (j = i; j < break_count; j++) {
+ break_list[j] = break_list[j+1];
+ }
+ }
+ }
+ }
+ }
+ else {
+ error(VALUE_OUT_OF_RANGE);
+ }
+ get_token();
+ break;
+ }
+ } /* end switch */
+
+ } /* end remove_breakpoint */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* allocate_watch() Return a pointer to a watch structure, */
+ /* or print all variables being watched */
+
+ WATCH_STRUCT_PTR allocate_watch()
+ {
+ int i;
+ SYMTAB_NODE_PTR idp;
+ WATCH_STRUCT_PTR wp;
+
+ get_token();
+
+ switch (token) {
+ case SEMICOLON: { /* no variable, print them all */
+ printf("Variables being watched:\n");
+
+ for (i = 0; i < watch_count; i++) {
+ idp = watch_list[i];
+ if (idp != NULL) {
+ wp = (WATCH_STRUCT_PTR) idp->info;
+ printf("%16s ", idp->name);
+ if (wp->store_flag) printf(" (store)");
+ if (wp->fetch_flag) printf(" (fetch)");
+ printf("\n");
+ }
+ }
+ return(NULL);
+ }
+
+ case IDENTIFIER: {
+ search_and_find_all_symtab(idp);
+ get_token();
+
+ switch (idp->defn.key) {
+ case UNDEFINED: {
+ return(NULL);
+ }
+ case CONST_DEFN:
+ case VAR_DEFN:
+ case ATTRIBUTE_DEFN:
+ case VALPARM_DEFN:
+ case VARPARM_DEFN: {
+ if (idp->info != NULL) { /* being watched, return ptr to structure */
+ return((WATCH_STRUCT_PTR) idp->info);
+ }
+ else if (watch_count < MAX_WATCHES) { /* a new structure */
+ wp = alloc_struct(WATCH_STRUCT);
+ wp->store_flag = FALSE;
+ wp->fetch_flag = FALSE;
+
+ idp->info = (char *) wp;
+ watch_list[watch_count] = idp;
+ watch_count++;
+ return(wp);
+ }
+ else {
+ printf("Watch list is full.\n");
+ return(NULL);
+ }
+ }
+ default: {
+ error(INVALID_IDENTIFIER_USAGE);
+ return(NULL);
+ }
+ } /* end switch */
+ break;
+ }
+ } /* end switch */
+
+ } /* end allocate_watch */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* remove_watch() Remove a variable from the watch list, */
+ /* or remove all variables being watched */
+
+ remove_watch()
+ {
+ int i, j;
+ SYMTAB_NODE_PTR idp;
+ WATCH_STRUCT_PTR wp;
+
+ get_token();
+
+ switch (token) {
+ case SEMICOLON: { /* no variable, remove them all */
+
+ for (i = 0; i < watch_count; i++) {
+ if ((idp = watch_list[i]) != NULL) {
+ wp = (WATCH_STRUCT_PTR) idp->info;
+ watch_list[i] = NULL;
+ idp->info = NULL;
+ free(wp);
+ }
+ }
+ watch_count = 0;
+ break;
+ }
+
+ case IDENTIFIER: { /* remove it from the list and move other up */
+ search_and_find_all_symtab(idp);
+ get_token();
+
+ if ((idp != NULL) && (idp->info != NULL)) {
+ wp = (WATCH_STRUCT_PTR) idp->info;
+ for (i = 0; i < watch_count; i++) {
+ if (watch_list[i] == idp) {
+ watch_list[i] = NULL;
+ idp->info = NULL;
+ free(wp);
+ --watch_count;
+ for (j = i; j < watch_count; j++) {
+ watch_list[j] = watch_list[j + 1];
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ } /* end switch */
+
+ } /* end remove_watch */
+ /********************************************************************/
+
+
+ /* SHOW and ASSIGN */
+
+
+ /********************************************************************/
+ /* show-value() Print the value of an expression */
+
+ show_value()
+ {
+
+ get_token();
+
+ switch (token) {
+ case SEMICOLON: {
+ error(INVALID_EXPRESSION);
+ break;
+ }
+ default: { /* parse and execute expression from code buffer */
+ TYPE_STRUCT_PTR expression();
+ TYPE_STRUCT_PTR tp = expression(); /* parse */
+ ICT *save_code_segmentp = code_segmentp;
+ int save_ctoken = ctoken;
+
+ if (isynt_error_count > 0) break;
+
+ /* switch to the code buffer */
+ code_segmentp = code_buffer + 1;
+ get_ctoken();
+ exec_expression(); /* execute */
+
+ /* print and then pop the value */
+ if ((tp->form == ARRAY_FORM) ||
+ (tp->form == BAG_FORM) ||
+ (tp->form == LIST_FORM) ||
+ (tp->form == SET_FORM) ||
+ (tp->form == ENTITY_FORM)) {
+ print_data_value(get_address(tos), tp, " ");
+ }
+ else {
+ print_data_value(tos, tp, " ");
+ }
+ pop();
+
+ /* resume the code segment */
+ code_segmentp = save_code_segmentp;
+ ctoken = save_ctoken;
+ break;
+ }
+ } /* end switch */
+
+ } /* end show_value */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* assign_variable() Exexcute an assignment statement */
+
+ assign_variable()
+ {
+
+ get_token();
+
+ switch (token) {
+ case SEMICOLON: {
+ error(MISSING_VARIABLE);
+ break;
+ }
+ case IDENTIFIER : { /* parse and execute the assignment statement from code buffer */
+ SYMTAB_NODE_PTR idp;
+ ICT *save_code_segmentp = code_segmentp;
+ int save_ctoken = ctoken;
+
+ search_and_find_all_symtab(idp);
+
+ assignment_statement(idp); /* parse */
+ if (isynt_error_count > 0) break;
+
+ /* switch to the code buffer */
+ code_segmentp = code_buffer + 1;
+ get_ctoken();
+ idp = get_symtab_cptr();
+ exec_assignment_statement(idp); /* execute */
+
+ /* resume the code segment */
+
+ code_segmentp = save_code_segmentp;
+ ctoken = save_ctoken;
+ break;
+ }
+ } /* end switch */
+
+ } /* end assign_variable */
+ /********************************************************************/
+
+
+ /* STACK */
+
+
+ /********************************************************************/
+ /* stack_debug() Print runtime stack */
+
+ extern STACK_ITEM *stack; /* runtime stack */
+ extern STACK_ITEM_PTR tos; /* top of stack */
+ extern STACK_ITEM_PTR stack_frame_basep; /* ptr to stack frame base */
+ extern STACK_ITEM_PTR maxtos; /* current max top of stack */
+
+ stack_debug()
+ {
+ STACK_ITEM_PTR basep = stack; /* base of stack */
+ STACK_ITEM_PTR i;
+
+ if (!stack_flag) return;
+
+ log_print("\n The runtime stack with: ");
+ stack_frame_debug();
+ for (i = basep; i <= tos; i++) {
+ stack_item_debug(i);
+ }
+
+ return;
+ } /* end stack_debug */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* tos_debug() Print top of runtime stack */
+
+ tos_debug()
+ {
+
+ if (!stack_flag) return;
+
+ log_print(" Top of runtime stack.");
+ stack_item_debug(tos);
+ return;
+ } /* end tos_debug */
+ /********************************************************************/
+
+
+ /********************************************************************/
+ /* stack_access_debug(s, sptr) Print stack access kind */
+
+ stack_access_debug(s, sptr)
+ char s[]; /* access kind */
+ STACK_ITEM_PTR sptr; /* stack position */
+ {
+
+ if (!stack_flag) return;
+
+ sprintf(dbuffer, " %-7s ==>", s);
+ log_print(dbuffer);
+ stack_item_debug(sptr);
+
+ if (sptr > maxtos) { /* probably looking at data area */
+ log_print(" Accessed data area:\n");
+ data_item_debug(sptr);
+ }
+
+ return;
+ } /* end stack_access_debug */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* stack_item_debug(sptr) Print a runtime stack item */
+
+ stack_item_debug(sptr)
+ STACK_ITEM_PTR sptr; /* ptr to stack item */
+ {
+ STACK_TYPE stype;
+ if (!stack_flag) return;
+
+ if ((sptr < stack) || (sptr > maxtos)) { /* out of stack range */
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+
+ stype = sptr->type;
+ switch (stype) {
+ case STKINT: {
+ sprintf(dbuffer, " (Entry %d : %s is %d)\n",
+ sptr, stack2str[stype], sptr->value.integer);
+ log_print(dbuffer);
+ break;
+ }
+ case STKREA: {
+ sprintf(dbuffer, " (Entry %d : %s is %f)\n",
+ sptr, stack2str[stype], sptr->value.real);
+ log_print(dbuffer);
+ break;
+ }
+ case STKLOG: {
+ sprintf(dbuffer, " (Entry %d : %s is ",
+ sptr, stack2str[stype]);
+ log_print(dbuffer);
+ if (sptr->value.integer == FALSE_REP) sprintf(dbuffer, "FALSE)\n");
+ else if (sptr->value.integer == TRUE_REP) sprintf(dbuffer, "TRUE)\n");
+ else sprintf(dbuffer, "UNKNOWN)\n");
+ log_print(dbuffer);
+ break;
+ }
+ case STKSTR: {
+ sprintf(dbuffer, " (Entry %d : %s is %d)\n",
+ sptr, stack2str[stype], sptr->value.string);
+ log_print(dbuffer);
+ break;
+ }
+ case STKARY:
+ case STKADD: {
+ sprintf(dbuffer, " (Entry %d : %s is %d)\n",
+ sptr, stack2str[stype], sptr->value.address);
+ log_print(dbuffer);
+ break;
+ }
+ case STKUDF: { /* undefined */
+ sprintf(dbuffer, " (Entry %d : %s is '%c')\n",
+ sptr, stack2str[stype], sptr->value.integer);
+ log_print(dbuffer);
+ break;
+ }
+ case STKBAG:
+ case STKLST:
+ case STKSET: {
+ sprintf(dbuffer, " (Entry %d : %s is %d)\n",
+ sptr, stack2str[stype], sptr->value.head);
+ log_print(dbuffer);
+ break;
+ }
+ case STKENT: {
+ sprintf(dbuffer, " (Entry %d : %s is %d)\n",
+ sptr, stack2str[stype], sptr->value.address);
+ log_print(dbuffer);
+ break;
+ }
+ default: {
+ sprintf(dbuffer, " (Entry %d : unknown type (%d))\n",
+ sptr, sptr->type);
+ log_print(dbuffer);
+ break;
+ }
+ }
+ return;
+ } /* end stack_item_debug */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* data_item_debug(sptr) Print data of array/entity item */
+
+ data_item_debug(sptr)
+ STACK_ITEM_PTR sptr; /* ptr to 'start' of data item */
+ {
+ STACK_TYPE kind;
+ STACK_ITEM_PTR aptr = sptr;
+ int n = 1;
+ int maxn = 20; /* max number of elements to be printed */
+
+ if (!stack_flag) return;
+
+ kind = aptr->type;
+ while ( (kind >= STKINT) && (kind <= STKADD) && (n <= maxn) ) {
+ stack_item_debug(aptr);
+ aptr++;
+ n++;
+ kind = aptr->type;
+ }
+
+ return;
+ } /* end data_item_debug */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* stack_frame_debug() print the stack frame base pointer */
+
+ stack_frame_debug()
+ {
+
+ if (!stack_flag) return;
+
+ sprintf(dbuffer, " (Stack frame base at %d)\n", stack_frame_basep);
+ log_print(dbuffer);
+ return;
+ } /* end stack_frame_debug */
+ /********************************************************************/
+
+
+
+ /********************************************************************/
+ /* expression_type_debug(tptr) print type of type */
+
+ extern TYPE_STRUCT_PTR integer_typep, real_typep,
+ boolean_typep;
+ extern TYPE_STRUCT_PTR logical_typep, string_typep, binary_typep,
+ generic_typep, any_typep;
+
+ expression_type_debug(tptr)
+ TYPE_STRUCT_PTR tptr; /* pointer to type structure */
+ {
+
+
+ if (!stack_flag) return;
+
+ if (tptr == integer_typep) {
+ log_print(" Type is: INTEGER TYPE\n");
+ return;
+ }
+ else if (tptr == real_typep) {
+ log_print(" Type is: REAL TYPE\n");
+ return;
+ }
+ else if (tptr == boolean_typep) {
+ log_print(" Type is: BOOLEAN TYPE\n");
+ return;
+ }
+ else if (tptr == logical_typep) {
+ log_print(" Type is: LOGICAL TYPE\n");
+ return;
+ }
+ else if (tptr == string_typep) {
+ log_print(" Type is: STRING TYPE\n");
+ return;
+ }
+ else if (tptr == binary_typep) {
+ log_print(" Type is: BINARY TYPE\n");
+ return;
+ }
+ else if (tptr == generic_typep) {
+ log_print(" Type is: GENERIC TYPE\n");
+ return;
+ }
+ else if (tptr == any_typep) {
+ log_print(" Type is: INDETERMINATE TYPE\n");
+ return;
+ }
+
+ switch (tptr->form) {
+ case NO_FORM: {
+ log_print(" Type is: NO FORM\n");
+ return;
+ }
+ case SCALAR_FORM: {
+ log_print(" Type is: SCALAR FORM\n");
+ return;
+ }
+ case ENUM_FORM: {
+ log_print(" Type is: ENUM FORM\n");
+ return;
+ }
+ case SUBRANGE_FORM: {
+ log_print(" Type is: SUBRANGE FORM\n");
+ return;
+ }
+ case ARRAY_FORM: {
+ log_print(" Type is: ARRAY of ");
+ expression_type_debug(tptr->info.array.elmt_typep);
+ return;
+ }
+ case BAG_FORM: {
+ log_print(" Type is: BAG of ");
+ expression_type_debug(tptr->info.dynagg.elmt_typep);
+ return;
+ }
+ case LIST_FORM: {
+ log_print(" Type is: LIST of ");
+ expression_type_debug(tptr->info.dynagg.elmt_typep);
+ return;
+ }
+ case SET_FORM: {
+ log_print(" Type is: SET of ");
+ expression_type_debug(tptr->info.dynagg.elmt_typep);
+ return;
+ }
+ case ENTITY_FORM: {
+ log_print(" Type is: ENTITY FORM\n");
+ return;
+ }
+ case STRING_FORM: {
+ log_print(" Type is: STRING FORM\n");
+ return;
+ }
+ default: {
+ log_print(" Type is: UNKNOWN\n");
+ return;
+ }
+
+
+ } /* end switch */
+
+ } /* end expression_type_debug */
+ /********************************************************************/
+
+
diff --git a/support/ltx2x/l2xidecl.c b/support/ltx2x/l2xidecl.c
new file mode 100644
index 0000000000..8777516b0a
--- /dev/null
+++ b/support/ltx2x/l2xidecl.c
@@ -0,0 +1,958 @@
+/* l2xidecl.c LTX2X interpreter parsing routines for declarations */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+#ifndef l2xicpr_h
+#include "l2xicpr.h"
+#endif
+
+#include "listsetc.h"
+
+
+/* EXTERNALS */
+
+extern TOKEN_CODE token;
+extern char word_string[];
+extern LITERAL literal;
+extern SYMTAB_NODE_PTR symtab_display[];
+extern int level;
+
+extern SYMTAB_NODE_PTR string_idp;
+
+/* FORWARDS */
+
+TYPE_STRUCT_PTR identifier_type(), enumeration_type(),
+ subrange_type(), array_type();
+
+TYPE_STRUCT_PTR get_type(), get_array_type(), get_bound_spec_type();
+
+TYPE_STRUCT_PTR an_entity(), a_type(), get_bls_type();
+
+TOKEN_CODE express_decl_list[] = {XENTITY, TYPE, XRULE,
+ FUNCTION, PROCEDURE, 0};
+
+
+/***************************************************************************/
+/* declarations(rtn_idp) Call routines to process constant definitions, */
+/* type definitions, variable declarations, */
+/* procedure definitions, function definitions. */
+/* at entry, token is one of declaration_start_list bag */
+/* at exit, token is the one following all declarations (e.g., start */
+/* of assignment statement) */
+
+declarations(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* program or routine id */
+{
+ entry_debug("declarations");
+
+ /* for EXPRESS */
+ /* loop for general declarations */
+ while (token_in(express_decl_list)) {
+ switch (token) {
+ case XENTITY: {
+ an_entity();
+ break;
+ }
+ case TYPE: {
+ a_type();
+ break;
+ }
+ case XRULE: {
+ a_rule();
+ break;
+ }
+ case PROCEDURE: {
+ a_procedure();
+ break;
+ }
+ case FUNCTION: {
+ a_function();
+ break;
+ }
+ default: {
+ error(UNIMPLEMENTED_FEATURE);
+ break;
+ }
+ } /* end switch */
+ } /* end while over general declarations */
+
+ if (token == XCONSTANT) {
+ get_token();
+ constant_block();
+ }
+ if (token == XLOCAL) {
+ get_token();
+ local_block(rtn_idp);
+ }
+
+ exit_debug("declarations");
+ return;
+
+} /* end declarations */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* skip_declarations(rtn_idp) Skip declaration parsing */
+
+skip_declarations(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* program id */
+{
+ SYMTAB_NODE_PTR const_idp; /* constant id */
+ char tmp_buff[MAX_SOURCE_LINE_LENGTH];
+ entry_debug("skip_declarations");
+
+ strcpy(tmp_buff, word_string);
+ strcpy(word_string, "_ZeRo");
+
+ search_and_enter_local_symtab(const_idp);
+ strcpy(word_string, tmp_buff);
+ const_idp->defn.key = CONST_DEFN;
+
+ const_idp->defn.info.constant.value.integer = 0;
+ const_idp->typep = integer_typep;
+
+ analyze_const_defn(const_idp);
+
+ exit_debug("skip_declarations");
+ return;
+} /* end SKIP_DECLARATIONS */
+/***************************************************************************/
+
+
+/* EXPRESS CONSTANTS and LOCALS */
+
+/***************************************************************************/
+/* constant_block() Process EXPRESS constant block */
+/* CONSTANT { <constant_definition> } END_CONSTANT ; */
+/* at entry, current token is CONSTANT */
+/* at exit, current token is after the semicolon */
+
+constant_block()
+{
+ entry_debug("constant_block");
+
+ error(UNIMPLEMENTED_FEATURE);
+
+ while (token != XEND_CONSTANT) {
+ get_token();
+ }
+
+ get_token();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ exit_debug("constant_block");
+ return;
+} /* end CONSTANT_BLOCK */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* a_constant_definition() Process EXPRESS constant */
+/* <constant_id> : <type> := <expression> ; */
+/* at entry, current token is <constant_id> */
+/* at exit, current token is after closing semicolon */
+
+a_constant_definition()
+{
+ SYMTAB_NODE_PTR type_idp; /* constant id */
+
+ if (token != IDENTIFIER) {
+ error(UNEXPECTED_TOKEN);
+ return;
+ }
+
+ search_and_enter_local_symtab(type_idp);
+ type_idp->defn.key = TYPE_DEFN;
+
+ get_token();
+ if_token_get_else_error(COLON, MISSING_COLON);
+
+ /* process the type */
+ type_idp->typep = get_type();
+ if (type_idp->typep->type_idp == NULL) {
+ type_idp->typep->type_idp = type_idp;
+ }
+
+ get_token();
+ if_token_get_else_error(COLONEQUAL, MISSING_COLONEQUAL);
+
+ /* process the expression */ /* SKIP THIS FOR NOW */
+ while (token != SEMICOLON) {
+ get_token();
+ }
+ get_token();
+
+ return;
+
+} /* end A_CONSTANT_DEFINITION */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* local_block(rtn_idp) Process EXPRESS local block */
+/* LOCAL { <local_definition> } END_LOCAL ; */
+/* at entry, current token is the one after LOCAL */
+/* at exit, current token is after closing semicolon */
+
+local_block(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* id of routine */
+{
+ entry_debug("local_block");
+
+ local_decls(rtn_idp,
+ STACK_FRAME_HEADER_SIZE + rtn_idp->defn.info.routine.parm_count);
+
+ exit_debug("local_block");
+ return;
+} /* end LOCAL_BLOCK */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* local_decls(rtn_idp, record_tp, offset) Process EXPRESS local variables */
+/* at entry, current token is <var_id> */
+/* at exit, current token is after closing END_LOCAL ; */
+
+local_decls(rtn_idp, offset)
+SYMTAB_NODE_PTR rtn_idp;
+int offset;
+{
+ SYMTAB_NODE_PTR idp, first_idp, last_idp; /* variable ids */
+ SYMTAB_NODE_PTR prev_last_idp = NULL; /* last id of a list */
+ TYPE_STRUCT_PTR tp; /* type */
+ int size;
+ int total_size = 0;
+
+ entry_debug("local_decls");
+
+ /* loop to process sublist, each of a single type */
+ while (token == IDENTIFIER) { /* loop over semicolon seperated list */
+ first_idp = NULL;
+
+ /* loop to process each var in a list */
+ while (token == IDENTIFIER) { /* loop over comma seperated list */
+ search_and_enter_local_symtab(idp);
+ idp->defn.key = VAR_DEFN;
+ idp->label_index = 0;
+
+ /* link ids into a sublist */
+ if (first_idp == NULL) {
+ first_idp = last_idp = idp;
+ if (rtn_idp->defn.info.routine.locals == NULL) {
+ rtn_idp->defn.info.routine.locals = idp;
+ }
+ }
+ else {
+ last_idp->next = idp;
+ last_idp = idp;
+ }
+ get_token();
+ if_token_get(COMMA);
+ } /* end while over a comma seperated list */
+
+ /* Process the sublist's type */
+ if_token_get_else_error(COLON, MISSING_COLON);
+ tp = get_type();
+ size = tp->size;
+
+ /* Assign the offset and the type to all ids in the list */
+ for (idp = first_idp; idp != NULL; idp = idp->next) {
+ idp->typep = tp;
+ total_size += size;
+ idp->defn.info.data.offset = offset++;
+ analyze_var_decl(idp);
+ } /* end for */
+
+ /* link this sublist to previous sublist */
+ if (prev_last_idp != NULL) prev_last_idp->next = first_idp;
+ prev_last_idp = last_idp;
+
+ /* optional expression here SKIP FOR NOW */
+ get_token();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ } /* end while over semicolon seperated list */
+
+ if_token_get_else_error(XEND_LOCAL, MISSING_END);
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ rtn_idp->defn.info.routine.total_local_size = total_size;
+
+ exit_debug("local_decls");
+ return;
+} /* end LOCAL_DECLS */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* an_entity() Process an EXPRESS entity */
+/* ENTITY <entity_body> END_ENTITY ; */
+/* at entry, current token = ENTITY */
+/* at exit, current token is after END_ENTITY ; */
+
+TYPE_STRUCT_PTR an_entity()
+{
+ SYMTAB_NODE_PTR idp; /* entity id */
+ TYPE_STRUCT_PTR entity_tp = alloc_struct(TYPE_STRUCT);
+ entry_debug("an_entity (l2xidecl.c)");
+
+ entity_tp->form = ENTITY_FORM;
+ entity_tp->type_idp = NULL;
+ entity_tp->info.entity.attribute_symtab = NULL;
+
+ get_token(); /* name of the entity */
+ if (token != IDENTIFIER) {
+ error(UNEXPECTED_TOKEN);
+ }
+ search_and_enter_local_symtab(idp);
+ idp->defn.key = TYPE_DEFN;
+ idp->label_index = 0;
+ idp->typep = entity_tp;
+
+ get_token(); /* semicolon */
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ attribute_declarations(NULL, entity_tp, 0);
+
+ analyze_type_defn(idp);
+ /* skip to the end */
+ while (token != XEND_ENTITY) {
+ get_token();
+ }
+
+ get_token();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ exit_debug("an_entity");
+ return(entity_tp);
+} /* end AN_ENTITY */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* a_type() Process an EXPRESS type */
+/* TYPE <type_body> END_TYPE ; */
+/* at entry, current token = TYPE */
+/* at exit, current token is after END_TYPE ; */
+
+TYPE_STRUCT_PTR a_type()
+{
+ SYMTAB_NODE_PTR type_idp; /* the TYPE id */
+ TYPE_STRUCT_PTR tsp; /* type structure pointer */
+ entry_debug("a_type (l2xidecl.c)");
+
+ get_token(); /* the type id */
+ if (token != IDENTIFIER) {
+ error(UNEXPECTED_TOKEN);
+ exit_debug("a_type");
+ return(&dummy_type);
+ }
+ search_and_enter_local_symtab(type_idp);
+ type_idp->defn.key = TYPE_DEFN;
+
+ get_token();
+ if_token_get_else_error(EQUAL, MISSING_EQUAL);
+
+ /* process the type */
+ if (token == XENUMERATION) { /* an ENUMERATION type */
+ get_token();
+ if_token_get_else_error(OF, MISSING_OF);
+ if (token != LPAREN) {
+ error(MISSING_LPAREN);
+ }
+ /* process the enumeration */
+ type_idp->typep = enumeration_type();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+ }
+ else { /* an ordinary type */
+ type_idp->typep = get_type();
+ get_token();
+ if (token != SEMICOLON) error(MISSING_SEMICOLON);
+ }
+ if (type_idp->typep->type_idp == NULL) type_idp->typep->type_idp = type_idp;
+ analyze_type_defn(type_idp);
+
+ /* skip to end of definition */
+ while (token != XEND_TYPE) {
+ get_token();
+ }
+
+ get_token();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ exit_debug("a_type");
+ return(type_idp->typep);
+} /* end A_TYPE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* a_rule() Process an EXPRESS rule */
+/* RULE <rule_body> END_RULE ; */
+/* at entry, current token = RULE */
+/* at exit, current token is after END_RULE ; */
+
+a_rule()
+{
+
+ error(UNIMPLEMENTED_FEATURE);
+
+ while (token != XEND_RULE) {
+ get_token();
+ }
+
+ get_token();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ return;
+} /* end A_RULE */
+/***************************************************************************/
+
+
+
+
+
+
+/* CONSTANTS */
+
+
+
+
+
+/* TYPES */
+
+
+/***************************************************************************/
+/* get_type() Process a type identifier. Call the function to make the */
+/* type structure, and return pointer to it. */
+/* at entry, token is the id */
+/* at exit, token is unaltered */
+
+TYPE_STRUCT_PTR get_type()
+{
+ TYPE_STRUCT_PTR tsp;
+ entry_debug("get_type");
+
+ if (token_in(simple_type_list)) { /* predefined simple type */
+ switch (token) {
+ case XINTEGER : {
+ tsp = integer_typep;
+ break;
+ }
+ case XREAL : {
+ tsp = real_typep;
+ break;
+ }
+ case XBOOLEAN : {
+ tsp = boolean_typep;
+ break;
+ }
+ case XLOGICAL : {
+ tsp = logical_typep;
+ break;
+ }
+ case XSTRING : {
+ tsp = make_string_typep(0);
+ break;
+ }
+ default : {
+ error(UNIMPLEMENTED_SIMPLE_TYPE);
+ tsp = &dummy_type;
+ break;
+ }
+ } /* end switch */
+ exit_debug("get_type");
+ return(tsp);
+ } /* end predefined simple types */
+
+ if (token_in(aggregation_type_list)) { /* predefined aggregation type */
+ switch (token) {
+ case ARRAY : {
+ return(get_array_type());
+ break;
+ }
+ case XBAG:
+ case XLIST:
+ case SET: {
+ return(get_bls_type());
+ break;
+ }
+ default : {
+ error(UNIMPLEMENTED_AGGREGATION_TYPE);
+ tsp = &dummy_type;
+ break;
+ }
+ } /* end switch */
+ exit_debug("get_type");
+ return(tsp);
+ } /* end predefined aggregation types */
+
+
+
+
+ switch (token) {
+ case IDENTIFIER: {
+ SYMTAB_NODE_PTR idp;
+
+ search_all_symtab(idp);
+
+ if (idp == NULL) {
+ error(UNDEFINED_IDENTIFIER);
+ exit_debug("get_type");
+ return(&dummy_type);
+ }
+ else if (idp->defn.key == TYPE_DEFN) {
+ exit_debug("get_type");
+ return(identifier_type(idp));
+ }
+/* else if (idp->defn.key == CONST_DEFN) {
+ exit_debug("get_type");
+ return(subrange_type(idp));
+ } */
+ else {
+ error(NOT_A_TYPE_IDENTIFIER);
+ exit_debug("get_type");
+ return(&dummy_type);
+ }
+ }
+
+ default : {
+ error(INVALID_TYPE);
+ exit_debug("get_type");
+ return(&dummy_type);
+ }
+ } /* end switch */
+} /* end get_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* identifier_type(idp) Process an identifier type (the identifier at the */
+/* LHS of an assignment). */
+/* return pointer to the type structure. */
+
+TYPE_STRUCT_PTR identifier_type(idp)
+SYMTAB_NODE_PTR idp; /* type id */
+{
+ TYPE_STRUCT_PTR tp = NULL;
+
+ tp = idp->typep;
+/* get_token(); */
+ return(tp);
+} /* end identifier_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* enumeration_type() Process an enumeration type. */
+/* ( <id>, <id>, ... ) */
+/* Make and return a type structure. */
+/* at entry: token is opening ( */
+/* at exit: token is after closing ) */
+
+TYPE_STRUCT_PTR enumeration_type()
+{
+ SYMTAB_NODE_PTR const_idp; /* constant id */
+ SYMTAB_NODE_PTR last_idp = NULL; /* last constant id */
+ TYPE_STRUCT_PTR tp = alloc_struct(TYPE_STRUCT);
+ int const_value = -1; /* constant value */
+
+ tp->form = ENUM_FORM;
+ tp->size = sizeof(int);
+ tp->type_idp = NULL;
+
+ get_token();
+
+ /* loop to process ids */
+ while (token == IDENTIFIER) {
+ search_and_enter_local_symtab(const_idp);
+ const_idp->defn.key = CONST_DEFN;
+ const_idp->defn.info.constant.value.integer = ++const_value;
+ const_idp->typep = tp;
+
+ /* link ids into list */
+ if (last_idp == NULL) tp->info.enumeration.const_idp = last_idp = const_idp;
+ else {
+ last_idp->next = const_idp;
+ last_idp = const_idp;
+ }
+ get_token();
+ if_token_get(COMMA);
+ } /* end while */
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+
+ tp->info.enumeration.max = const_value;
+ return(tp);
+} /* end enumeration_type */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* make_string_typep(length) Make a type structure for a string of the */
+/* given length. */
+/* return a pointer to it. */
+/* rewritten for new structure */
+
+TYPE_STRUCT_PTR make_string_typep(length)
+int length; /* string length */
+{
+ TYPE_STRUCT_PTR string_tp = alloc_struct(TYPE_STRUCT);
+ entry_debug("make_string_type");
+
+ if (length > MAX_EXPRESS_STRING) {
+ error(STRING_TOO_LONG);
+ }
+
+ string_tp->form = STRING_FORM;
+ string_tp->size = sizeof(STRING);
+ string_tp->type_idp = string_idp;
+/* string_tp->type_idp = NULL; */
+ string_tp->info.string.max_length = MAX_EXPRESS_STRING;
+ string_tp->info.string.length = length;
+
+ exit_debug("make_string_type");
+ return(string_tp);
+} /* end make_string_typep */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* calculate_array_size(tp) Return the size in bytes of an EXPRESS */
+/* array by recursively */
+/* calculating the size of each dimension. */
+
+int calculate_array_size(tp)
+TYPE_STRUCT_PTR tp; /* ptr to array type structure */
+{
+ if (tp->info.array.elmt_typep->size == 0) {
+ tp->info.array.elmt_typep->size =
+ calculate_array_size(tp->info.array.elmt_typep);
+ }
+
+ tp->size = tp->info.array.elmt_count * tp->info.array.elmt_typep->size;
+ return(tp->size);
+} /* end array_size */
+/***************************************************************************/
+
+
+/* VARIABLES */
+
+
+
+/***************************************************************************/
+/* attribute_declarations(rtn_idp, entity_tp, offset) */
+/* Process entity attribute definitions. All ids declared */
+/* with the same type are linked into a sublist, and all the */
+/* sublists are then liked together. */
+
+attribute_declarations(rtn_idp, entity_tp, offset)
+SYMTAB_NODE_PTR rtn_idp;
+TYPE_STRUCT_PTR entity_tp;
+int offset;
+{
+ SYMTAB_NODE_PTR idp, first_idp, last_idp; /* variable or field ids */
+ SYMTAB_NODE_PTR prev_last_idp = NULL; /* last id of a list */
+ TYPE_STRUCT_PTR tp; /* type */
+ int size;
+ int total_size = 0;
+
+ entry_debug("attribute_declarations (l2xidecl.c)");
+
+ /* loop to process sublist, each of a single type */
+ while (!token_in(follow_attributes_list)) {
+ first_idp = NULL;
+
+ /* loop to process each attribute in a list */
+ while (token == IDENTIFIER) {
+ search_and_enter_this_symtab(idp, entity_tp->info.entity.attribute_symtab);
+ idp->defn.key = ATTRIBUTE_DEFN;
+ idp->label_index = 0;
+
+ /* link ids into a sublist */
+ if (first_idp == NULL) {
+ first_idp = last_idp = idp;
+ }
+ else {
+ last_idp->next = idp;
+ last_idp = idp;
+ }
+ get_token();
+ if_token_get(COMMA);
+ } /* end while */
+
+ /* Process the sublist's type */
+ if_token_get_else_error(COLON, MISSING_COLON);
+ tp = get_type();
+ size = tp->size;
+
+ /* Assign the offset and the type to all ids in the list */
+ for (idp = first_idp; idp != NULL; idp = idp->next) {
+ idp->typep = tp;
+ idp->defn.info.data.offset = offset;
+ offset += size;
+ } /* end for */
+
+ /* link this sublist to previous sublist */
+ if (prev_last_idp != NULL) prev_last_idp->next = first_idp;
+ prev_last_idp = last_idp;
+
+ get_token(); /* move on from type processing */
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ } /* end while */
+
+ entity_tp->size = offset;
+
+ exit_debug("attribute_declarations");
+ return;
+} /* end ATTRIBUTE_DECLARATIONS */
+/***************************************************************************/
+
+
+
+
+
+
+/***************************************************************************/
+/* get_array_type() Process an array type */
+/* ARRAY <bound_spec> OF <elmt-type> */
+/* Make a structure and return pointer. */
+/* at entry: token is ARRAY */
+/* at exit: token is */
+
+TYPE_STRUCT_PTR get_array_type()
+{
+ TYPE_STRUCT_PTR tp = alloc_struct(TYPE_STRUCT);
+ TYPE_STRUCT_PTR index_tp; /* index type */
+ TYPE_STRUCT_PTR elmt_tp = tp; /* element type */
+ TYPE_STRUCT_PTR bound_tp; /* bound type */
+ int min, max, count;
+ int calculate_array_size();
+ entry_debug("get_array_type (l2xidecl.c)");
+
+ get_token();
+
+ elmt_tp->form = ARRAY_FORM;
+ elmt_tp->size = 0;
+ elmt_tp->type_idp = NULL;
+ elmt_tp->info.array.index_typep = integer_typep;
+
+ if (token != LBRACKET) error(MISSING_LBRACKET);
+
+ bound_tp = get_bound_spec_type();
+ min = bound_tp->info.bound.min;
+ max = bound_tp->info.bound.max;
+ if (min == QUERY_CHAR || max == QUERY_CHAR) {
+ error(INVALID_INDEX_TYPE);
+ count = 0;
+ }
+ else if (min > max) {
+ error(MIN_GT_MAX);
+ count = 0;
+ }
+ else {
+ elmt_tp->info.array.min_index = min;
+ elmt_tp->info.array.max_index = max;
+ count = (max - min) + 1;
+ }
+ elmt_tp->info.array.elmt_count = count;
+
+
+ /* sync. Should be OF */
+ synchronize(follow_indexes_list, declaration_start_list, statement_start_list);
+ if_token_get_else_error(OF, MISSING_OF);
+
+ /* element type */
+ elmt_tp->info.array.elmt_typep = get_type();
+ tp->size = calculate_array_size(tp); /* was array_size(tp); */
+
+ exit_debug("get_array_type");
+ return(tp);
+} /* end GET_ARRAY_TYPE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_bls_type() Process a BAG, etc type */
+/* BAG [ <bound_spec> ] OF <elmt-type> */
+/* Make a structure and return pointer. */
+/* at entry: token is BAG */
+/* at exit: token is */
+
+TYPE_STRUCT_PTR get_bls_type()
+{
+ TYPE_STRUCT_PTR tp = alloc_struct(TYPE_STRUCT);
+ TYPE_STRUCT_PTR index_tp; /* index type */
+ TYPE_STRUCT_PTR elmt_tp = tp; /* element type */
+ TYPE_STRUCT_PTR bound_tp; /* bound type */
+ int min, max, count, size;
+ entry_debug("get_bls_type (l2xidecl.c)");
+
+ count = 0;
+ if (token == XBAG) {
+ elmt_tp->form = BAG_FORM;
+ }
+ else if (token == XLIST) {
+ elmt_tp->form = LIST_FORM;
+ }
+ else if (token == SET) {
+ elmt_tp->form = SET_FORM;
+ }
+ elmt_tp->size = 0;
+ elmt_tp->type_idp = NULL;
+ elmt_tp->info.dynagg.index_typep = integer_typep;
+
+ get_token();
+ if (token == LBRACKET) { /* a bound spec */
+ bound_tp = get_bound_spec_type();
+ min = bound_tp->info.bound.min;
+ max = bound_tp->info.bound.max;
+ if (min == QUERY_CHAR) {
+ error(INVALID_INDEX_TYPE);
+ min = 0;
+ count = 0;
+ }
+ else if (min < 0) {
+ error(INVALID_INDEX_TYPE);
+ min = 0;
+ count = 0;
+ }
+ else if (max != QUERY_CHAR) {
+ if (min > max) {
+ error(MIN_GT_MAX);
+ max = min;
+ count = 0;
+ }
+ }
+ else {
+/* count = (max - min) + 1; */
+ count = 0;
+ }
+ }
+ else { /* default [0:?] bound spec */
+ min = 0;
+ max = QUERY_CHAR;
+ count = 0;
+ }
+
+ /* sync. Should be OF */
+ synchronize(follow_indexes_list, declaration_start_list, statement_start_list);
+ if_token_get_else_error(OF, MISSING_OF);
+
+ if (max == QUERY_CHAR) {
+ max = MAX_AGG_SIZE;
+ }
+
+ elmt_tp->info.dynagg.min_index = min;
+ elmt_tp->info.dynagg.max_index = max;
+ elmt_tp->info.dynagg.elmt_count = count;
+ elmt_tp->info.dynagg.elmt_typep = get_type();
+ tp->size = sizeof(LBS_PTR);
+
+ exit_debug("get_bls_type");
+ return(tp);
+} /* end GET_BLS_TYPE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_bound_spec_type() Process a bound spec */
+/* [ <int_expr> : <int_expr> ] */
+/* make a type structure and return a pointer to it */
+/* at entry: token is opening [ */
+/* at exit: token is after closing ] */
+
+TYPE_STRUCT_PTR get_bound_spec_type()
+{
+ TYPE_STRUCT_PTR tp;
+ entry_debug("get_bound_spec_type (l2xidecl.c)");
+
+ tp = alloc_struct(TYPE_STRUCT);
+
+ tp->form = BOUND_FORM;
+ tp->type_idp = NULL;
+ tp->size = sizeof(int);
+ tp->info.bound.bound_typep = integer_typep;
+
+ /* lower bound */
+ get_token();
+ tp->info.bound.min = get_bound_limit();
+
+ /* sync. should be a : */
+ synchronize(follow_min_bound_list, NULL, NULL);
+ if_token_get(COLON);
+ else if (token_in(follow_min_bound_list) ||
+ token_in(declaration_start_list) ||
+ token_in(statement_start_list)) error(MISSING_COLON);
+
+ /* upper bound */
+ tp->info.bound.max = get_bound_limit();
+
+ if_token_get_else_error(RBRACKET, MISSING_RBRACKET);
+
+ exit_debug("get_bound_spec_type");
+ return(tp);
+} /* end GET_BOUND_SPEC_TYPE */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* get_bound_limit(minmax_idp, minmaxp, typepp) Process the min or */
+/* max limits of a bound spec */
+/* [ + | - ] INTEGER_LITERAL */
+/* at entry: token is the limit (value) */
+/* at exit: token is after the limit */
+
+int get_bound_limit()
+{
+ TOKEN_CODE sign = PLUS; /* unary + or - sign */
+ int result = QUERY_CHAR; /* undef result */
+
+ /* unary + or - sign */
+ if ((token == PLUS) || (token == MINUS)) {
+ sign = token;
+ get_token();
+ }
+
+ /* numeric limit --- integer only */
+ if (token == NUMBER_LITERAL) {
+ if (literal.type == INTEGER_LIT) {
+ result = (sign == PLUS) ? literal.value.integer
+ : -literal.value.integer;
+ }
+ else error(INVALID_BOUND_TYPE);
+ }
+ else if (token == QUERY_CHAR) {
+ result = QUERY_CHAR;
+ }
+ else {
+ error(INVALID_BOUND_TYPE);
+ }
+
+ get_token();
+ return(result);
+} /* end GET_BOUND_LIMIT */
+/***************************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xidftc.h b/support/ltx2x/l2xidftc.h
new file mode 100644
index 0000000000..9889d5ae70
--- /dev/null
+++ b/support/ltx2x/l2xidftc.h
@@ -0,0 +1,13 @@
+/* l2xidftc.h definition strings */
+
+dfntc(UNDEFINED, "undefined")
+dfntc(CONST_DEFN, "constant")
+dfntc(TYPE_DEFN, "type")
+dfntc(VAR_DEFN, "variable")
+dfntc(ATTRIBUTE_DEFN, "attribute")
+dfntc(VALPARM_DEFN, "parameter")
+dfntc(VARPARM_DEFN, "VAR parameter")
+dfntc(PROG_DEFN, "program")
+dfntc(PROC_DEFN, "procedure")
+dfntc(FUNC_DEFN, "function")
+
diff --git a/support/ltx2x/l2xierr.c b/support/ltx2x/l2xierr.c
new file mode 100644
index 0000000000..3b84a2759f
--- /dev/null
+++ b/support/ltx2x/l2xierr.c
@@ -0,0 +1,410 @@
+/* l2xierr.c LTX2X interpreter error handler */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+
+/* externals */
+
+extern char *tokenp;
+extern BOOLEAN print_flag;
+extern char source_buffer[];
+extern char *bufferp;
+
+/* error messages: keyed to enum types in error.h from l2xiertc.h */
+
+char *error_messages[] = {
+#define petc(a, b) b,
+#define pwtc(a, b)
+#define rtetc(a, b)
+#define rtwtc(a, b)
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+ };
+
+
+char *warning_messages[] = {
+#define petc(a, b)
+#define pwtc(a, b) b,
+#define rtetc(a, b)
+#define rtwtc(a, b)
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+ };
+
+char *runtime_error_messages[] = {
+#define petc(a, b)
+#define pwtc(a, b)
+#define rtetc(a, b) b,
+#define rtwtc(a, b)
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+ };
+
+char *runtime_warning_messages[] = {
+#define petc(a, b)
+#define pwtc(a, b)
+#define rtetc(a, b)
+#define rtwtc(a, b) b,
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+ };
+
+/* stack types */
+typedef enum {
+#define fotc(a, b, c, d)
+#define sotc(a, b, c, d) a,
+#define sftc(a, b, c, d) a,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+} STACK_TYPE;
+
+
+/* LOCALS */
+#define EOS '\0'
+
+/* GLOBALS */
+
+int isynt_error_count = 0; /* number of syntax errors */
+int isynt_warn_count = 0; /* number of syntax warnings */
+int irun_error_count = 0; /* number of runtime errors */
+int irun_warn_count = 0; /* number of runtime warnings */
+char message_buffer[MAX_PRINT_LINE_LENGTH];
+
+/***************************************************************************/
+/* error(code) Print an arrow under the error, then the error message */
+
+error(code)
+ERROR_CODE code; /* error code */
+{
+ extern int buffer_offset;
+ char *message = error_messages[code];
+ int offset = buffer_offset - 2;
+
+ ++isynt_error_count;
+
+ /* print the arrow pointing to just scanned token */
+ if (print_flag) offset += 8;
+ sprintf(message_buffer, "%*s^\n", offset, " ");
+ if (print_flag) {
+ print_line(message_buffer);
+ }
+ else {
+ print_error(message_buffer);
+ }
+
+ /* print the error message */
+ sprintf(message_buffer, " ***ERROR: %s.\n", message);
+ if (print_flag) {
+ print_line(message_buffer);
+ }
+ else {
+ print_error(message_buffer);
+ }
+
+ *tokenp = EOS;
+
+ if (isynt_error_count > MAX_SYNTAX_ERRORS) {
+ sprintf(message_buffer, "Too many syntax errors.\n");
+ if (print_flag) {
+ print_line(message_buffer);
+ }
+ else {
+ print_error(message_buffer);
+ }
+ exit(-TOO_MANY_SYNTAX_ERRORS);
+ }
+
+} /* end error */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* compile_warning(code) Print an arrow under the error, then the */
+/* warning message */
+
+compile_warning(code)
+WARNING_CODE code; /* warning code */
+{
+ extern int buffer_offset;
+ char *message = warning_messages[code];
+ int offset = buffer_offset - 2;
+
+ ++isynt_warn_count;
+
+ /* print the arrow pointing to just scanned token */
+ if (print_flag) offset += 8;
+ sprintf(message_buffer, "%*s^\n", offset, " ");
+ if (print_flag) {
+ print_line(message_buffer);
+ }
+ else {
+ print_error(message_buffer);
+ }
+
+ /* print the warning message */
+ sprintf(message_buffer, " ***WARNING: %s.\n", message);
+ if (print_flag) {
+ print_line(message_buffer);
+ }
+ else {
+ print_error(message_buffer);
+ }
+
+ *tokenp = EOS;
+
+} /* end warning */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* runtime_error(code) Print a runtime error message and then debug */
+
+runtime_error(code)
+RUNTIME_ERROR_CODE code; /* error code */
+{
+ extern int exec_line_number;
+ extern long exec_stmt_count;
+ char *message = runtime_error_messages[code];
+ extern BOOLEAN debugger_command_flag;
+
+ ++irun_error_count;
+
+ if (SLD_OFF) { /* source level debugger disabled -- abort */
+ sprintf(message_buffer, "\n*** RUNTIME ERROR in line %d: %s\n",
+ exec_line_number, message);
+ print_error(message_buffer);
+ sprintf(message_buffer, "\nUnsuccessful completion. %ld statements executed.\n\n",
+ exec_stmt_count);
+ print_error(message_buffer);
+ exit(-code);
+ }
+
+ if (debugger_command_flag) {
+ print_error(message);
+ print_error("\n");
+ }
+ else {
+ sprintf(message_buffer, "\n*** RUNTIME ERROR in line %d: %s\n",
+ exec_line_number, message);
+ print_error(message_buffer);
+ read_debugger_command();
+ }
+
+} /* end runtime_error */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* runtime_warning(code) Print a runtime warning message and then debug */
+
+runtime_warning(code)
+RUNTIME_WARNING_CODE code; /* warning code */
+{
+ extern int exec_line_number;
+ extern long exec_stmt_count;
+ char *message = runtime_warning_messages[code];
+ extern BOOLEAN debugger_command_flag;
+
+ if (INVALID_STACK_ACCESS == code) return;
+
+ ++irun_warn_count;
+
+ if (SLD_OFF) { /* source level debugger disabled */
+ sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d: %s\n",
+ exec_line_number, message);
+ print_error(message_buffer);
+ return;
+ }
+
+ if (debugger_command_flag) {
+ print_error(message);
+ print_error("\n");
+ }
+ else {
+ sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d: %s\n",
+ exec_line_number, message);
+ print_error(message_buffer);
+ read_debugger_command();
+ }
+ return;
+} /* end runtime_warning */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* stack_warning(etype, ftype) Print a runtime warning message about */
+/* stack access and then debug */
+
+stack_warning(etype, ftype)
+STACK_TYPE etype; /* expected type */
+STACK_TYPE ftype; /* type actually found */
+{
+ extern int exec_line_number;
+ extern long exec_stmt_count;
+ RUNTIME_WARNING_CODE code1, code2;
+ extern BOOLEAN debugger_command_flag;
+
+ code1 = RUNTIME_WARN;
+ switch (etype) { /* report the expected type */
+ case STKINT:
+ case STKREA: {
+ code1 = EXPECTED_NUMBER;
+ break;
+ }
+ case STKLOG: {
+ code1 = EXPECTED_LOGICAL;
+ break;
+ }
+ case STKADD: {
+ code1 = EXPECTED_ADDRESS;
+ break;
+ }
+ case STKARY: {
+ code1 = EXPECTED_ARRAY;
+ break;
+ }
+ case STKBAG: {
+ code1 = EXPECTED_BAG;
+ break;
+ }
+ case STKLST: {
+ code1 = EXPECTED_LIST;
+ break;
+ }
+ case STKSET: {
+ code1 = EXPECTED_SET;
+ break;
+ }
+ case STKSTR: {
+ code1 = EXPECTED_STRING;
+ break;
+ }
+ case STKENT: {
+ code1 = EXPECTED_ENTITY;
+ break;
+ }
+ case STKUDF: {
+ code1 = EXPECTED_UDF;
+ break;
+ }
+ } /* finished expected type */
+
+ code2 = RUNTIME_WARN;
+ switch (ftype) { /* report the found type */
+ case STKINT:
+ case STKREA: {
+ code2 = FOUND_NUMBER;
+ break;
+ }
+ case STKLOG: {
+ code2 = FOUND_LOGICAL;
+ break;
+ }
+ case STKADD: {
+ code2 = FOUND_ADDRESS;
+ break;
+ }
+ case STKARY: {
+ code2 = FOUND_ARRAY;
+ break;
+ }
+ case STKBAG: {
+ code2 = FOUND_BAG;
+ break;
+ }
+ case STKLST: {
+ code2 = FOUND_LIST;
+ break;
+ }
+ case STKSET: {
+ code2 = FOUND_SET;
+ break;
+ }
+ case STKSTR: {
+ code2 = FOUND_STRING;
+ break;
+ }
+ case STKENT: {
+ code2 = FOUND_ENTITY;
+ break;
+ }
+ case STKUDF: {
+ code2 = FOUND_UDF;
+ break;
+ }
+ } /* finished found type */
+
+
+
+ if (SLD_OFF) { /* source level debugger disabled */
+ sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d:\n %s\n %s\n",
+ exec_line_number,
+ runtime_warning_messages[code1],
+ runtime_warning_messages[code2]);
+ print_error(message_buffer);
+ return;
+ }
+
+ if (debugger_command_flag) {
+ sprintf(message_buffer, "\n %s\n %s\n",
+ runtime_warning_messages[code1],
+ runtime_warning_messages[code2]);
+ print_error(message_buffer);
+ }
+ else {
+ sprintf(message_buffer, "\n*** RUNTIME WARNING in line %d:\n %s\n %s\n",
+ exec_line_number,
+ runtime_warning_messages[code1],
+ runtime_warning_messages[code2]);
+ print_error(message_buffer);
+ read_debugger_command();
+ }
+ return;
+} /* end STACK_WARNING */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* print_error(string) Prints to error file(s) */
+
+print_error(string)
+char string[];
+{
+
+ fprintf(ferr, "%s", string);
+ fflush(ferr);
+ fprintf(stderr, "%s", string);
+ fflush(stderr);
+ if (filout != stdout) {
+ fprintf(filout, "%s", string);
+ fflush(filout);
+ }
+ return;
+} /* end print_error */
+/***************************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xierr.h b/support/ltx2x/l2xierr.h
new file mode 100644
index 0000000000..a8f853bbfe
--- /dev/null
+++ b/support/ltx2x/l2xierr.h
@@ -0,0 +1,65 @@
+/* l2xierr.h for LTX2X interpreter */
+
+#ifndef error_h
+#define error_h
+
+#define MAX_SYNTAX_ERRORS 25
+
+/* error codes */
+
+
+ /* parser error codes */
+typedef enum {
+#define petc(a, b) a,
+#define pwtc(a, b)
+#define rtetc(a, b)
+#define rtwtc(a, b)
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+} ERROR_CODE;
+
+ /* parser warning codes */
+typedef enum {
+#define petc(a, b)
+#define pwtc(a, b) a,
+#define rtetc(a, b)
+#define rtwtc(a, b)
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+} WARNING_CODE;
+
+ /* runtime error codes */
+typedef enum {
+#define petc(a, b)
+#define pwtc(a, b)
+#define rtetc(a, b) a,
+#define rtwtc(a, b)
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+} RUNTIME_ERROR_CODE;
+
+ /* runtime warning codes */
+typedef enum {
+#define petc(a, b)
+#define pwtc(a, b)
+#define rtetc(a, b)
+#define rtwtc(a, b) a,
+#include "l2xiertc.h"
+#undef petc
+#undef pwtc
+#undef rtetc
+#undef rtwtc
+} RUNTIME_WARNING_CODE;
+
+
+#endif
+
diff --git a/support/ltx2x/l2xiertc.h b/support/ltx2x/l2xiertc.h
new file mode 100644
index 0000000000..3bcffc0f6c
--- /dev/null
+++ b/support/ltx2x/l2xiertc.h
@@ -0,0 +1,144 @@
+/* l2xiertc.h token codes, strings, etc for interpreter error reporting */
+
+ /* parser warnings */
+
+pwtc(WARN, "Something may be wrong")
+pwtc(ASSIGN_TO_UNDEF, "Assignment to indeterminate")
+
+
+ /* runtime warnings */
+
+rtwtc(INVALID_STACK_ACCESS, "Attempting out of range stack access")
+rtwtc(INVALID_STACK_TYPE, "Invalid value on the stack")
+rtwtc(RUNTIME_WARN, "Something may be wrong")
+rtwtc(RUN_ASSIGN_TO_UNDEF, "Assignment to indeterminate")
+rtwtc(EXPECTED_ADDRESS, "Expected an address on the stack")
+rtwtc(EXPECTED_ARRAY, "Expected an array on the stack")
+rtwtc(EXPECTED_BAG, "Expected a bag on the stack")
+rtwtc(EXPECTED_ENTITY, "Expected an entity on the stack")
+rtwtc(EXPECTED_ENUMERATION, "Expected an enumeration on the stack")
+rtwtc(EXPECTED_LIST, "Expected a list on the stack")
+rtwtc(EXPECTED_LOGICAL, "Expected a boolean or logical on the stack")
+rtwtc(EXPECTED_NUMBER, "Expected a number on the stack")
+rtwtc(EXPECTED_SET, "Expected a set on the stack")
+rtwtc(EXPECTED_STRING, "Expected a string on the stack")
+rtwtc(EXPECTED_UDF, "Expected indeterminate on the stack")
+rtwtc(FOUND_ADDRESS, "Found an address on the stack")
+rtwtc(FOUND_ARRAY, "Found an array on the stack")
+rtwtc(FOUND_BAG, "Found a bag on the stack")
+rtwtc(FOUND_ENTITY, "Found an entity on the stack")
+rtwtc(FOUND_ENUMERATION, "Found an enumeration on the stack")
+rtwtc(FOUND_LIST, "Found a list on the stack")
+rtwtc(FOUND_LOGICAL, "Found a boolean or logical on the stack")
+rtwtc(FOUND_NUMBER, "Found a number on the stack")
+rtwtc(FOUND_SET, "Found a set on the stack")
+rtwtc(FOUND_STRING, "Found a string on the stack")
+rtwtc(FOUND_UDF, "Found indeterminate on the stack")
+
+
+ /* parser errors */
+
+petc(NO_ERROR, "No error")
+petc(SYNTAX_ERROR, "Syntax error")
+petc(TOO_MANY_SYNTAX_ERRORS, "Too many syntax errors")
+petc(FAILED_SOURCE_FILE_OPEN, "Failed to open source file")
+petc(UNEXPECTED_END_OF_FILE, "Unexpected end of file")
+petc(INVALID_NUMBER, "Invalid number")
+petc(INVALID_FRACTION, "Invalid fraction")
+petc(INVALID_EXPONENT, "Invalid exponent")
+petc(TOO_MANY_DIGITS, "Too many digits")
+petc(REAL_OUT_OF_RANGE, "Real literal out of range")
+petc(INTEGER_OUT_OF_RANGE, "Integer literal out of range")
+petc(MISSING_RPAREN, "Missing ) (right parenthesis)")
+petc(INVALID_EXPRESSION, "Invalid expression")
+petc(INVALID_ASSIGNMENT, "Invalid assignment")
+petc(MISSING_IDENTIFIER, "Missing identifier")
+petc(MISSING_COLONEQUAL, "Missing :=")
+petc(UNDEFINED_IDENTIFIER, "Undefined identifier")
+petc(STACK_OVERFLOW, "Stack overflow")
+petc(INVALID_STATEMENT, "Invalid statement")
+petc(UNEXPECTED_TOKEN, "Unexpected token")
+petc(MISSING_SEMICOLON, "Missing ; (semicolon)")
+petc(MISSING_DO, "Missing DO")
+petc(MISSING_UNTIL, "Missing UNTIL")
+petc(MISSING_THEN, "Missing THEN")
+petc(INVALID_FOR_CONTROL, "Invalid FOR control")
+petc(MISSING_OF, "Missing OF")
+petc(INVALID_CONSTANT, "Invalid constant")
+petc(MISSING_CONSTANT, "Missing constant")
+petc(MISSING_COLON, "Missing : (colon)")
+petc(MISSING_END, "Missing END")
+petc(REDEFINED_IDENTIFIER, "Redefined identifier")
+petc(MISSING_EQUAL, "Missing = (equal)")
+petc(INVALID_TYPE, "Invalid type")
+petc(NOT_A_TYPE_IDENTIFIER, "Not a type identifier")
+petc(INVALID_SUBRANGE_TYPE, "Invalid subrange type")
+petc(NOT_A_CONSTANT_IDENTIFIER, "Not a constant identifier")
+petc(INCOMPATIBLE_TYPES, "Incompatible types")
+petc(INVALID_TARGET, "Invalid assignment target")
+petc(INVALID_IDENTIFIER_USAGE, "Invalid identifier usage")
+petc(INCOMPATIBLE_ASSIGNMENT, "Incompatible assignment")
+petc(MIN_GT_MAX, "Min limit greater than max limit")
+petc(MISSING_LBRACKET, "Missing [ (left bracket)")
+petc(MISSING_RBRACKET, "Missing ] (right bracket)")
+petc(INVALID_INDEX_TYPE, "Invalid index type")
+petc(MISSING_BEGIN, "Missing BEGIN")
+petc(MISSING_PERIOD, "Missing . (period)")
+petc(TOO_MANY_SUBSCRIPTS, "Too many subscripts")
+petc(INVALID_ATTRIBUTE, "Invalid attribute")
+petc(NESTING_TOO_DEEP, "Nesting too deep")
+petc(ALREADY_FORWARDED, "Already forwarded")
+petc(WRONG_NUMBER_OF_PARMS, "Wrong number of arguments")
+petc(INVALID_VAR_PARM, "Invalid VAR parameter")
+petc(NOT_A_RECORD_VARIABLE, "Not a record variable")
+petc(MISSING_VARIABLE, "Missing variable")
+petc(CODE_SEGMENT_OVERFLOW, "Code segment overflow")
+petc(UNIMPLEMENTED_FEATURE, "Unimplemented feature")
+petc(MISSING_ENDCODE, "Missing END_CODE")
+petc(UNEXPECTED_ENDCODE, "Unexpected END_CODE")
+petc(UNIMPLEMENTED_SIMPLE_TYPE, "Unimplemented simple type")
+petc(UNIMPLEMENTED_CONSTANT, "Unimplemented constant")
+petc(INVALID_BOUND_TYPE, "Invalid bound type")
+petc(MISSING_END_ALIAS, "Missing END_ALIAS")
+petc(MISSING_END_CALL, "Missing END_CALL")
+petc(MISSING_END_CASE, "Missing END_CASE")
+petc(MISSING_END_CONSTANT, "Missing END_CONSTANT")
+petc(MISSING_END_CONTEXT, "Missing END_CONTEXT")
+petc(MISSING_END_CRITERIA, "Missing END_CRITERIA")
+petc(MISSING_END_ENTITY, "Missing END_ENTITY")
+petc(MISSING_END_FUNCTION, "Missing END_FUNCTION")
+petc(MISSING_END_IF, "Missing END_IF")
+petc(MISSING_END_LOCAL, "Missing END_LOCAL")
+petc(MISSING_END_MODEL, "Missing END_MODEL")
+petc(MISSING_END_NOTES, "Missing END_NOTES")
+petc(MISSING_END_OBJECTIVE, "Missing END_OBJECTIVE")
+petc(MISSING_END_PARAMETER, "Missing END_PARAMETER")
+petc(MISSING_END_PROCEDURE, "Missing END_PROCEDURE")
+petc(MISSING_END_PURPOSE, "Missing END_PURPOSE")
+petc(MISSING_END_REALIZATION, "Missing END_REALIZATION")
+petc(MISSING_END_REFERENCES, "Missing END_REFERENCES")
+petc(MISSING_END_REPEAT, "Missing END_REPEAT")
+petc(MISSING_END_RULE, "Missing END_RULE")
+petc(MISSING_END_SCHEMA, "Missing END_SCHEMA")
+petc(MISSING_END_SCHEMA_DATA, "Missing END_SCHEMA_DATA")
+petc(MISSING_END_TEST_CASE, "Missing END_TEST_CASE")
+petc(MISSING_END_TYPE, "Missing END_TYPE")
+petc(MISSING_COMMA, "Missing , (comma)")
+petc(STRING_TOO_LONG, "String too long")
+petc(UNIMPLEMENTED_AGGREGATION_TYPE, "Unimplemented aggregation type")
+petc(INVALID_INCREMENT_CONTROL, "Invalid increment control")
+petc(MISSING_TO, "Missing TO")
+petc(MISSING_LPAREN, "Missing ( (left parenthesis)")
+petc(MISSING_RBRACE, "Missing } (right brace)")
+petc(EXPECTED_INTERVAL_OP, "Expected < or <=")
+
+ /* runtime errors */
+
+rtetc(RUNTIME_STACK_OVERFLOW, "Runtime stack overflow")
+rtetc(VALUE_OUT_OF_RANGE, "Value out of range")
+rtetc(INVALID_CASE_VALUE, "Invalid CASE expression value")
+rtetc(DIVISION_BY_ZERO, "Division by zero")
+rtetc(INVALID_FUNCTION_ARGUMENT, "Invalid function argument")
+rtetc(RUNTIME_STRING_TOO_LONG, "String too long")
+rtetc(INVALID_REGULAR_EXPRESSION, "Invalid regular expression")
+rtetc(UNIMPLEMENTED_RUNTIME_FEATURE, "Unimplemented runtime feature")
diff --git a/support/ltx2x/l2xiexec.h b/support/ltx2x/l2xiexec.h
new file mode 100644
index 0000000000..81cb53f32d
--- /dev/null
+++ b/support/ltx2x/l2xiexec.h
@@ -0,0 +1,97 @@
+/* l2xiexec.h for LTX2X interpreter */
+
+#ifndef exec_h
+#define exec_h
+
+#include "l2xicmon.h"
+#include "listsetc.h"
+
+/* following markers are now at the end of the TOKEN_CODE enumeration */
+/*
+* #define STATEMENT_MARKER 0x70
+* #define ADDRESS_MARKER 0x71
+*/
+
+/* runtime stack */
+
+
+ /* stack value types */
+typedef enum {
+#define sotc(a, b, c, d) a,
+#define sftc(a, b, c, d) a,
+#define fotc(a, b, c, d)
+#include "l2xisftc.h"
+#undef sotc
+#undef sftc
+#undef fotc
+} STACK_TYPE;
+
+
+typedef struct {
+ STACK_TYPE type;
+ union {
+ XPRSAINT integer; /* STKINT, STKLOG, STKUDF */
+ XPRSAREAL real; /* STKREA */
+ STRING string; /* STKSTR */
+ ADDRESS address; /* all others */
+ LBS_PTR head; /* STKBAG, STKLST, STKSET */
+ } value;
+} STACK_ITEM, *STACK_ITEM_PTR;
+
+typedef struct {
+ STACK_ITEM function_value;
+ STACK_ITEM static_link;
+ STACK_ITEM dynamic_link;
+ STACK_ITEM return_address;
+} *STACK_FRAME_HEADER_PTR;
+
+/* functions */
+
+SYMTAB_NODE_PTR get_symtab_cptr();
+int get_statement_cmarker();
+TYPE_STRUCT_PTR exec_routine_call();
+TYPE_STRUCT_PTR exec_expression();
+TYPE_STRUCT_PTR exec_variable();
+
+
+ICT *crunch_address_marker();
+ADDRESS fixup_address_marker();
+ADDRESS get_address_cmarker();
+XPRSAINT get_cinteger();
+ADDRESS get_caddress();
+ADDRESS get_address();
+XPRSAREAL get_real();
+ADDRESS get_static_link();
+ADDRESS get_dynamic_link();
+ADDRESS get_return_address();
+
+/* macros */
+
+/* get_ctoken -- extract next token code from the current code segment */
+/* #define get_ctoken() entry_debug("getting_ctoken (l2xiexec.h)"); \
+ code_segment_entry_debug(code_segmentp); \
+ ctoken = *code_segmentp++; \
+ exit_debug("got_ctoken")
+
+#define get_ctoken() code_segment_entry_debug(code_segmentp); \
+ ctoken = *code_segmentp++
+*/
+
+/* pop -- pop the runtime stack */
+#define pop() stack_access_debug("Popped", tos); \
+ --tos
+
+/* Tracing routine calls. To compile, #define trace beforehand */
+#ifndef trace
+#define trace_routine_entry(idp)
+#define trace_routine_exit(idp)
+#define trace_statement_execution()
+#define trace_data_store(idp, idp_tp, targetp, target_tp)
+#define trace_data_fetch(idp, tp, datap)
+#endif
+
+#endif
+
+
+
+
diff --git a/support/ltx2x/l2xiexpr.c b/support/ltx2x/l2xiexpr.c
new file mode 100644
index 0000000000..680069acbd
--- /dev/null
+++ b/support/ltx2x/l2xiexpr.c
@@ -0,0 +1,788 @@
+/* l2xiexpr.c LTX2X interpreter parsing routines for expressions */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+#ifndef l2xicpr_h
+#include "l2xicpr.h" /* extern token code lists */
+#endif
+
+/* EXTERNALS */
+
+extern TOKEN_CODE token;
+extern char token_string[];
+extern char word_string[];
+extern LITERAL literal;
+
+extern SYMTAB_NODE_PTR symtab_display[];
+extern int level;
+
+ /* built-in constants */
+extern SYMTAB_NODE_PTR false_idp, true_idp, unknown_idp;
+extern SYMTAB_NODE_PTR conste_idp, pi_idp, undef_idp;
+extern SYMTAB_NODE_PTR day_idp, month_idp, year_idp;
+
+/* FORWARDS */
+TYPE_STRUCT_PTR expression(), simple_expression(), term(), factor(),
+ function_call();
+TYPE_STRUCT_PTR simple_factor();
+TYPE_STRUCT_PTR index_list();
+
+
+/* MACROS */
+
+/* integer_operands(tp1, tp2) TRUE if both are integer, else FALSE */
+#define integer_operands(tp1, tp2) ((tp1 == integer_typep) && \
+ (tp2 == integer_typep))
+
+/* real_operands(tp1, tp2) TRUE if one or both operands are real, and */
+/* the other is integer, else FALSE */
+#define real_operands(tp1, tp2) (((tp1 == real_typep) && \
+ ((tp2 == real_typep) || \
+ (tp2 == integer_typep))) \
+ || \
+ ((tp2 == real_typep) && \
+ ((tp1 == real_typep) || \
+ (tp1 == integer_typep))))
+
+/* boolean_operands(tp1, tp2) TRUE if both are boolean, else FALSE */
+#define boolean_operands(tp1, tp2) ((tp1 == boolean_typep) && \
+ (tp2 == boolean_typep))
+
+/* logical_operands(tp1, tp2) TRUE if both are logical/boolean, else FALSE */
+#define logical_operands(tp1, tp2) ((tp1 == boolean_typep || tp1 == logical_typep) && \
+ (tp2 == boolean_typep || tp2 == logical_typep))
+
+/* string_operands(tp1, tp2) TRUE iff both are string */
+#define string_operands(tp1, tp2) ((tp1 == string_typep || \
+ tp1->form == STRING_FORM) && \
+ (tp2 == string_typep || \
+ tp2->form == STRING_FORM))
+
+/* NEW undef_types(tp1, tp2) TRUE if either is undefined, else FALSE */
+#define undef_types(tp1, tp2) ((tp1 == any_typep) || \
+ (tp2 == any_typep))
+
+/* NEW is_undef(tp1) TRUE if undefined, else FALSE */
+#define is_undef(tp1) (tp1 == any_typep)
+
+/* NEW set_undef(tp1) sets tp1 to be an undef */
+#define set_undef(tp1) tp1 = any_typep
+
+/***************************************************************************/
+/* expression() Process an expression consisting of a simple expression, */
+/* optionally followed by a relational operator and a */
+/* second simple expression. */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR expression()
+{
+ TYPE_STRUCT_PTR result_tp, tp2;
+ entry_debug("expression");
+
+ /* first simple expression */
+ result_tp = simple_expression();
+
+ /* if operator, process following expression */
+ if (token_in(rel_op_list)) {
+ result_tp = base_type(result_tp);
+ /* second expression */
+ get_token();
+ tp2 = base_type(simple_expression());
+ check_rel_op_types(result_tp, tp2);
+ result_tp = logical_typep;
+ }
+
+ exit_debug("expression");
+ return(result_tp);
+} /* end expression */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* simple_expression() Process a simple expression */
+/* consisting of terms seperated by +, -, OR, XXOR */
+/* operators. There may be an initial unary operator */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR simple_expression()
+{
+ TOKEN_CODE op; /* operator token */
+ TYPE_STRUCT_PTR result_tp, tp2;
+ BOOLEAN saw_unary_op = FALSE;
+ entry_debug("simple_expression");
+
+ /* remember intial unary op */
+ if ((token == PLUS) || (token == MINUS)) {
+ saw_unary_op = TRUE;
+ get_token();
+ }
+
+ /* first term */
+ result_tp = term();
+
+ /* if there was a unary operator, check its type for integer or real. */
+ if (saw_unary_op && (base_type(result_tp) != integer_typep) &&
+ (result_tp != real_typep)) error(INCOMPATIBLE_TYPES);
+
+ /* loop to process subsequent terms seperated by operators */
+ while (token_in(add_op_list)) {
+ op = token;
+ result_tp = base_type(result_tp);
+
+ get_token();
+ tp2 = base_type(term()); /* next term */
+ if (undef_types(result_tp, tp2)) {
+ set_undef(result_tp);
+ }
+ else {
+ switch (op) {
+ case PLUS: {
+ /* integer op integer -> integer */
+ if (integer_operands(result_tp, tp2)) result_tp = integer_typep;
+ /* numbers -> real, */
+ else if (real_operands(result_tp, tp2)) result_tp = real_typep;
+ /* string concatenation */
+ else if (string_operands(result_tp, tp2)) result_tp = string_typep;
+ else {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = &dummy_type;
+ }
+ break;
+ }
+ case MINUS: {
+ /* integer op integer -> integer */
+ if (integer_operands(result_tp, tp2)) result_tp = integer_typep;
+ /* otherwise numbers -> real, else error */
+ else if (real_operands(result_tp, tp2)) result_tp = real_typep;
+ else {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = &dummy_type;
+ }
+ break;
+ }
+ case OR:
+ case XXOR: {
+ /* boolean OR boolean -> boolean */
+ if (!logical_operands(result_tp, tp2)) {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = &dummy_type;
+ break;
+ }
+ result_tp = logical_typep;
+ break;
+ }
+ case XLIKE: {
+ /* string LIKE string -> boolean */
+ if (!string_operands(result_tp, tp2)) {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = &dummy_type;
+ break;
+ }
+ result_tp = logical_typep;
+ break;
+ }
+ } /* end switch */
+ }
+ } /* end while */
+
+ exit_debug("simple_expression");
+ return(result_tp);
+} /* end simple_expression */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* term() Process a term */
+/* consisting of factors seperated by */
+/* *, /, DIV, MOD, or AND */
+/* operators. */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR term()
+{
+ TOKEN_CODE op; /* operator token */
+ TYPE_STRUCT_PTR result_tp, tp2;
+ entry_debug("term");
+
+ /* first factor */
+ result_tp = factor();
+
+ /* loop to process subsequent factors seperated by operators */
+ while (token_in(mult_op_list)) {
+ op = token;
+ result_tp = base_type(result_tp);
+
+ get_token();
+ tp2 = base_type(factor()); /* next factor */
+ if (undef_types(result_tp, tp2)) {
+ set_undef(result_tp);
+ }
+ else {
+ switch (op) {
+ case STAR: {
+ /* integer op integer -> integer */
+ if (integer_operands(result_tp, tp2)) result_tp = integer_typep;
+ /* otherwise numbers -> real, else error */
+ else if (real_operands(result_tp, tp2)) result_tp = real_typep;
+ else {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = &dummy_type;
+ }
+ break;
+ }
+ case SLASH: {
+ /* number op number -> real */
+ if ((!real_operands(result_tp, tp2)) &&
+ (!integer_operands(result_tp, tp2))) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ result_tp = real_typep;
+ break;
+ }
+ case DIV:
+ case MOD: {
+ /* integer op integer -> integer */
+ if (!integer_operands(result_tp, tp2)) error(INCOMPATIBLE_TYPES);
+ result_tp = integer_typep;
+ break;
+ }
+ case AND: {
+ /* boolean op boolean -> boolean */
+ if (!logical_operands(result_tp, tp2)) {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = logical_typep;
+ break;
+ }
+ }
+ } /* end switch */
+ }
+ } /* end while */
+
+ exit_debug("term");
+ return(result_tp);
+} /* end term */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* factor() Process an EXPRESS factor */
+/* simple_factor [ ** simple_factor ] */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR factor()
+{
+ TOKEN_CODE op; /* operator token */
+ TYPE_STRUCT_PTR result_tp, tp2;
+ entry_debug("factor");
+
+ /* first factor */
+ result_tp = simple_factor();
+
+ op = token;
+ if (op == STARSTAR) {
+ result_tp = base_type(result_tp);
+ get_token();
+ tp2 = base_type(simple_factor());
+ if (undef_types(result_tp, tp2)) {
+ set_undef(result_tp);
+ }
+ else if (integer_operands(result_tp, tp2)) result_tp = integer_typep;
+ else if (real_operands(result_tp, tp2)) result_tp = real_typep;
+ else {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = &dummy_type;
+ }
+ }
+
+ exit_debug("factor");
+ return(result_tp);
+} /* end FACTOR */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* simple_factor() Process a simple factor */
+/* a variable, a number, NOT factor, a */
+/* parenthesized expression, or an interval expression */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR simple_factor()
+{
+ TYPE_STRUCT_PTR tp;
+ TYPE_STRUCT_PTR tp1, tp2;
+ TOKEN_CODE op;
+ entry_debug("simple_factor");
+
+ if (token_in(constant_list)) { /* language defined constant */
+ switch (token) {
+ case XFALSE : {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(false_idp);
+ tp = logical_typep;
+ break;
+ }
+ case XTRUE : {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(true_idp);
+ tp = logical_typep;
+ break;
+ }
+ case XUNKNOWN : {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(unknown_idp);
+ tp = logical_typep;
+ break;
+ }
+ case XCONST_E : {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(conste_idp);
+ tp = real_typep;
+ break;
+ }
+ case XPI : {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(pi_idp);
+ tp = real_typep;
+ break;
+ }
+ case QUERY_CHAR : {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(undef_idp);
+ set_undef(tp);
+ break;
+ }
+ case THE_DAY: {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(day_idp);
+ tp = integer_typep;
+ break;
+ }
+ case THE_MONTH: {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(month_idp);
+ tp = integer_typep;
+ break;
+ }
+ case THE_YEAR: {
+ change_crunched_token(IDENTIFIER);
+ crunch_symtab_node_ptr(year_idp);
+ tp = integer_typep;
+ break;
+ }
+ default : {
+ error(UNIMPLEMENTED_CONSTANT);
+ tp = &dummy_type;
+ break;
+ }
+ } /* end switch */
+ get_token();
+ exit_debug("factor at defined constants");
+ return(tp);
+ } /* end of language defined constants */
+
+ switch (token) {
+ case IDENTIFIER: {
+ SYMTAB_NODE_PTR idp;
+
+ search_and_find_all_symtab(idp);
+ switch (idp->defn.key) {
+ case FUNC_DEFN: {
+ crunch_symtab_node_ptr(idp);
+ get_token();
+ tp = routine_call(idp,TRUE);
+ break;
+ }
+ case PROC_DEFN: {
+ error(INVALID_IDENTIFIER_USAGE);
+ get_token();
+ actual_parm_list(idp,FALSE);
+ tp = &dummy_type;
+ break;
+ }
+ case CONST_DEFN: {
+ crunch_symtab_node_ptr(idp);
+ get_token();
+ tp = idp->typep;
+ break;
+ }
+ default: {
+ tp = variable(idp, EXPR_USE);
+ break;
+ }
+ } /* end switch */
+ break;
+ }
+ case NUMBER_LITERAL: {
+ SYMTAB_NODE_PTR np;
+
+ np = search_symtab(token_string, symtab_display[1]);
+ if (np == NULL) np = enter_symtab(token_string, symtab_display[1]);
+
+ if (literal.type == INTEGER_LIT ) {
+ tp = np->typep = integer_typep;
+ np->defn.info.constant.value.integer = literal.value.integer;
+ }
+ else { /* a real literal */
+ tp = np->typep = real_typep;
+ np->defn.info.constant.value.real = literal.value.real;
+ }
+ crunch_symtab_node_ptr(np);
+ get_token();
+ break;
+ }
+ case STRING_LITERAL: {
+ SYMTAB_NODE_PTR np;
+ int length = strlen(literal.value.string);
+
+ np = search_symtab(token_string, symtab_display[1]);
+ if (np == NULL) np = enter_symtab(token_string, symtab_display[1]);
+ np->typep = tp = make_string_typep(length);
+ np->info = alloc_bytes(length + 1);
+ strcpy(np->info, literal.value.string);
+ crunch_symtab_node_ptr(np);
+ get_token();
+ break;
+ }
+ case NOT: {
+ get_token();
+ tp = simple_factor();
+ break;
+ }
+ case LPAREN: {
+ get_token();
+ tp = expression();
+
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ break;
+ }
+ case LBRACE: { /* interval expression {expr op var op expr} */
+ get_token();
+ tp1 = simple_expression();
+ op = token;
+ if (op != LT && op != LE) {
+ error(EXPECTED_INTERVAL_OP);
+ }
+ get_token();
+ tp = simple_expression();
+ check_rel_op_types(tp1, tp);
+ op = token;
+ if (op != LT && op != LE) {
+ error(EXPECTED_INTERVAL_OP);
+ }
+ get_token();
+ tp2 = simple_expression();
+ check_rel_op_types(tp, tp2);
+ if_token_get_else_error(RBRACE, MISSING_RBRACE);
+ tp = logical_typep;
+ break;
+ }
+ default: {
+ error(INVALID_EXPRESSION);
+ tp = &dummy_type;
+ break;
+ }
+ } /* end switch */
+
+ exit_debug("simple_factor");
+ return(tp);
+
+} /* end SIMPLE_FACTOR */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* variable(var_idp, use) Process a variable */
+/* consisting of */
+/* a simple id, an array id with subscripts, */
+/* or an entity id with attributes */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR variable(var_idp, use)
+SYMTAB_NODE_PTR var_idp; /* var id */
+USE use; /* how variable is used */
+{
+ TYPE_STRUCT_PTR tp = var_idp->typep;
+ DEFN_KEY defn_key = var_idp->defn.key;
+ TYPE_STRUCT_PTR array_subscript_list();
+ TYPE_STRUCT_PTR entity_attr();
+ entry_debug("variable");
+
+ crunch_symtab_node_ptr(var_idp);
+
+ /* check the definition of the variable */
+ switch (defn_key) {
+ case VAR_DEFN:
+ case VALPARM_DEFN:
+ case VARPARM_DEFN:
+ case FUNC_DEFN:
+ case UNDEFINED: {
+ break;
+ }
+ default: {
+ tp = &dummy_type;
+ error(INVALID_IDENTIFIER_USAGE);
+ break;
+ }
+ } /* end switch */
+
+ get_token();
+
+ /* there must not be a parameter list, but parse for one anyway */
+ if (token == LPAREN) {
+ error(UNEXPECTED_TOKEN);
+ actual_parm_list(var_idp, FALSE);
+ exit_debug("variable (unexpected parm list)");
+ return(tp);
+ }
+
+ /* subscripts or fields? */
+ while ((token == LBRACKET) || (token == PERIOD)) {
+ if (token == PERIOD) {
+ tp = entity_attr(tp);
+ }
+ else {
+ if (var_idp->typep == string_typep ||
+ var_idp->typep->form == STRING_FORM) { /* substring op */
+ tp = index_list(tp);
+ }
+ else { /* aggregate index */
+ tp = array_subscript_list(tp);
+ }
+ }
+ }
+
+ exit_debug("variable");
+ return(tp);
+
+} /* end variable */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* index_list(tp) Process a (pair of) subscript v */
+/* '[' <int_expr> [ ':' <int_expr> ] ']' */
+/* return a pointer to the type structure */
+/* at entry: token is opening [ */
+/* at exit: token is after closing ] */
+
+TYPE_STRUCT_PTR index_list(tp)
+TYPE_STRUCT_PTR tp; /* type of var just before opening [ */
+{
+ TYPE_STRUCT_PTR ss1_tp, ss2_tp;
+ entry_debug("index_list (l2xiexpr.c)");
+
+ /* check on var type */
+ if (tp == string_typep || tp->form == STRING_FORM) { /* OK */
+ ;
+ }
+ else {
+ error(UNEXPECTED_TOKEN);
+ }
+
+ /* do first expression */
+ get_token();
+ ss1_tp = expression();
+ if (ss1_tp != integer_typep) error(INCOMPATIBLE_TYPES);
+
+ if (token == COLON) { /* do second expression */
+ get_token();
+ ss2_tp = expression();
+ if (ss2_tp != integer_typep) error(INCOMPATIBLE_TYPES);
+ }
+
+ if_token_get_else_error(RBRACKET, MISSING_RBRACKET);
+ exit_debug("index_list");
+ return(tp);
+
+} /* end INDEX_LIST */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* array_subscript_list(tp) Process a list of subscripts */
+/* [ <expr>, <expr>, ... ] */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR array_subscript_list(tp)
+TYPE_STRUCT_PTR tp;
+{
+ TYPE_STRUCT_PTR index_tp, elmt_tp, ss_tp;
+
+ /* loop to process the list */
+ do {
+ if (tp->form == ARRAY_FORM) {
+ index_tp = tp->info.array.index_typep;
+ elmt_tp = tp->info.array.elmt_typep;
+ get_token();
+ ss_tp = expression();
+
+ /* check assignment compatibility */
+ if (!is_assign_type_compatible(index_tp, ss_tp)) error(INCOMPATIBLE_TYPES);
+ tp = elmt_tp;
+ }
+ else if (tp->form == BAG_FORM ||
+ tp->form == LIST_FORM ||
+ tp->form == SET_FORM) {
+ index_tp = tp->info.dynagg.index_typep;
+ elmt_tp = tp->info.dynagg.elmt_typep;
+ get_token();
+ ss_tp = expression();
+
+ /* check assignment compatibility */
+ if (!is_assign_type_compatible(index_tp, ss_tp)) error(INCOMPATIBLE_TYPES);
+ tp = elmt_tp;
+ }
+ else {
+ error(TOO_MANY_SUBSCRIPTS);
+ while ((token != RBRACKET) && (!token_in(statement_end_list))) {
+ get_token();
+ }
+ }
+ } while (token == COMMA); /* end do */
+
+ if_token_get_else_error(RBRACKET, MISSING_RBRACKET);
+ return(tp);
+
+} /* end array_subscript_list */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* entity_attr(tp) Process an entity attribute */
+/* . <attr-variable> */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR entity_attr(tp)
+TYPE_STRUCT_PTR tp;
+{
+ SYMTAB_NODE_PTR attr_idp;
+
+ get_token();
+
+ if ((token == IDENTIFIER) && (tp->form == ENTITY_FORM)) {
+ search_this_symtab(attr_idp, tp->info.entity.attribute_symtab);
+
+ crunch_symtab_node_ptr(attr_idp);
+ get_token();
+ if (attr_idp != NULL) return(attr_idp->typep);
+ else {
+ error(INVALID_ATTRIBUTE);
+ return(&dummy_type);
+ }
+ }
+ else {
+ get_token();
+ error(INVALID_ATTRIBUTE);
+ return(&dummy_type);
+ }
+
+} /* end entity_attr */
+/***************************************************************************/
+
+
+
+
+/* TYPE COMPATIBILITY */
+
+
+/***************************************************************************/
+/* check_rel_op_types(tp1, tp2) Check operand types of a relational */
+/* operator */
+
+check_rel_op_types(tp1, tp2)
+TYPE_STRUCT_PTR tp1;
+TYPE_STRUCT_PTR tp2;
+{
+
+ /* identical scalar or enumeration types */
+ if ((tp1 == tp2) &&
+ ((tp1->form == SCALAR_FORM) || (tp1->form == ENUM_FORM))) {
+ return;
+ }
+
+ /* one integer and one real */
+ if (((tp1 == integer_typep) && (tp2 == real_typep)) ||
+ ((tp2 == integer_typep) && (tp1 == real_typep))) {
+ return;
+ }
+
+ /* two arbitrary strings */
+ if (string_operands(tp1, tp2)) {
+ return;
+ }
+
+ /* for the IN operator */
+ /* tp2 is a dynamic aggregate, tp1 is the elmt type */
+ if (is_dynagg(tp2)) {
+ if (tp1 == tp2->info.dynagg.elmt_typep) {
+ return;
+ }
+ }
+
+ error(INCOMPATIBLE_TYPES);
+} /* end check_rel_op_types */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* is_assign_type_compatible(tp1, tp2) Check if a value of type tp2 */
+/* can be assigned to a variable of type tp1 */
+/* (i.e. tp1 := tp2) */
+/* return TRUE if types assignment compatible, else FALSE */
+
+BOOLEAN is_assign_type_compatible(tp1, tp2)
+TYPE_STRUCT_PTR tp1;
+TYPE_STRUCT_PTR tp2;
+{
+
+ tp1 = base_type(tp1);
+ tp2 = base_type(tp2);
+
+ if (tp1 == tp2) return(TRUE);
+ if (is_undef(tp2)) {
+ compile_warning(ASSIGN_TO_UNDEF);
+ return(TRUE);
+ }
+
+ /* real := integer */
+ if ((tp1 == real_typep) && (tp2 == integer_typep)) return(TRUE);
+
+ if (string_operands(tp1, tp2)) return(TRUE);
+
+ /* incompatible */
+ return(FALSE);
+
+} /* end is_assign_type_compatible */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* base_type(tp) Return the range type of a subrange type */
+
+TYPE_STRUCT_PTR base_type(tp)
+TYPE_STRUCT_PTR tp;
+{
+ return((tp->form == SUBRANGE_FORM)
+ ? tp->info.subrange.range_typep
+ : tp);
+} /* end base_type */
+/***************************************************************************/
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xiidbg.c b/support/ltx2x/l2xiidbg.c
new file mode 100644
index 0000000000..f6c077b48b
--- /dev/null
+++ b/support/ltx2x/l2xiidbg.c
@@ -0,0 +1,271 @@
+/* l2xiidbg.c LTX2X interpreter debugging routines for interpreter code */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiexec.h"
+#include "l2xiidbg.h"
+
+/* EXTERNALS */
+
+/* extern FILE *fcodeseg; */ /* code segment o/p file */
+
+/* GLOBALS */
+
+char dbuff[256]; /* a character buffer for internal use */
+int dlindent = 2; /* line indentation */
+int PLEVEL = 0; /* routine nesting level */
+char dbuffer[256]; /* character buffer for external use */
+
+/********************************************************************/
+/* debug_print(s) prints a debugging string */
+
+debug_print(s)
+char s[];
+{
+ if (DEBUG <= 0) return;
+
+ fprintf(stderr, "%s", s);
+ fflush(stderr);
+ fprintf(ferr, "%s", s);
+ fflush(ferr);
+} /* end debug_print */
+/********************************************************************/
+
+
+
+/********************************************************************/
+/* log_print(s) prints a string to the log(s) */
+
+log_print(s)
+char s[];
+{
+
+ fprintf(stderr, "%s", s);
+ fflush(stderr);
+ fprintf(ferr, "%s", s);
+ fflush(ferr);
+} /* end log_print */
+/********************************************************************/
+
+
+
+/********************************************************************/
+/* entry_debug(s) prints the name of a routine at entry */
+
+entry_debug(s)
+char s[]; /* name of the routine */
+{
+ if (DEBUG < Dtrace) return;
+
+ PLEVEL++; /* increase the nesting level */
+ sprintf(dbuff, "%*s Entering: %s\n", PLEVEL*dlindent, " ", s);
+ debug_print(dbuff);
+
+} /* end entry_debug */
+/********************************************************************/
+
+
+/********************************************************************/
+/* exit_debug(s) prints the name of a routine at exit */
+
+exit_debug(s)
+char s[]; /* name of the routine */
+{
+ if (DEBUG < Dtrace) return;
+
+ sprintf(dbuff, "%*s Exiting: %s\n", PLEVEL*dlindent, " ", s);
+ debug_print(dbuff);
+ PLEVEL--; /* decrement the nesting level */
+
+} /* end entry_debug */
+/********************************************************************/
+
+
+
+/********************************************************************/
+/* code_segment_debug() Prints a code segment */
+
+code_segment_debug(code_segment, limit)
+int *code_segment;
+int *limit;
+
+{
+ int i = 0;
+ SYMTAB_NODE_PTR sp;
+ int cp;
+
+/* if (DEBUG < Dbasic) return; */
+
+ sprintf(dbuff, "\n CREATED CODE_SEGMENT\n");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ while (code_segment != limit) {
+ cp = (int) *code_segment;
+ if (cp == STATEMENT_MARKER) { /* a statement marker */
+ sprintf(dbuff, "%d %d %d %s\n",
+ code_segment, i, cp, "<statement_marker>");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ *code_segment++;
+ i++;
+ cp = (int) *code_segment;
+ sprintf(dbuff, "%d %d %d %s\n",
+ code_segment, i, cp, "<the line number>");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ }
+ else if (cp == ADDRESS_MARKER) { /* an address marker */
+ sprintf(dbuff, "%d %d %d %s\n",
+ code_segment, i, cp, "<address_marker>");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ *code_segment++;
+ i++;
+ cp = (int) *code_segment;
+ sprintf(dbuff, "%d %d %d %s\n",
+ code_segment, i, cp, "<the address>");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ }
+ else if (tok_code_to_str(cp) != NULL) { /* a token code */
+ sprintf(dbuff, "%d %d %d %s\n",
+ code_segment, i, cp, tok_code_to_str(cp));
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ }
+ else { /* should be a symtab node ptr */
+ sprintf(dbuff, "%d %d %d",
+ code_segment, i, cp);
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ fflush(fcodeseg);
+ if (cp <= 0) { /* REAL PROBLEM */
+ sprintf(dbuff, " <Possible problem: value out of range!>\n");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ }
+ else {
+ sp = (SYMTAB_NODE_PTR) cp;
+ sprintf(dbuff, " %s\n",
+ sp->name);
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ }
+ }
+
+ *code_segment++;
+ i++;
+ } /* end while */
+
+ sprintf(dbuff, "\nFinished printing the code segment\n");
+ if (DEBUG >= Dbasic) debug_print(dbuff);
+ fprintf(fcodeseg, "%s", dbuff);
+ fflush(fcodeseg);
+
+
+} /* end code_segment_debug */
+/********************************************************************/
+
+
+/********************************************************************/
+/* code_segment_entry_debug() Prints an entry in a code segment */
+
+code_segment_entry_debug(code_entry)
+int *code_entry;
+{
+ int cp;
+
+ if (DEBUG < Dbasic) return;
+
+ cp = (int) *code_entry;
+ if (STATEMENT_MARKER == cp) { /* a statement marker */
+ sprintf(dbuff, "%d %d %s\n",
+ code_entry, cp, "<statement_marker>");
+ debug_print(dbuff);
+ return;
+ }
+ else if (ADDRESS_MARKER == cp) { /* an address marker */
+ sprintf(dbuff, "%d %d %s\n",
+ code_entry, cp, "<address_marker>");
+ debug_print(dbuff);
+ return;
+ }
+ else if (tok_code_to_str(cp) != NULL) { /* a token code */
+ sprintf(dbuff, "%d %d %s\n",
+ code_entry, cp, tok_code_to_str(cp));
+ debug_print(dbuff);
+ return;
+ }
+ else { /* should be an address of some sort */
+ sprintf(dbuff, "%d %d %s\n",
+ code_entry, cp, "<an address>");
+ debug_print(dbuff);
+ return;
+ }
+} /* end code_segment_entry_debug */
+/********************************************************************/
+
+
+/********************************************************************/
+/* scan_source_debug() Print current state of source buffer */
+
+extern int ch; /* current input character */
+extern char source_buffer[]; /* the source buffer */
+extern int buffer_offset; /* char offset into source buffer */
+extern char *bufferp; /* source buffer ptr */
+
+scan_source_debug()
+{
+
+ if (DEBUG < Dscan) return;
+
+ sprintf(dbuff, "Source line : %s", source_buffer);
+ debug_print(dbuff);
+ debug_print("\n");
+/* sprintf(dbuff, "Source line state: %c ^ %s", ch, bufferp); */
+ sprintf(dbuff, "Source line state: ");
+ debug_print(dbuff);
+ sprintf(dbuff, "%c", ch);
+ debug_print(dbuff);
+ debug_print("^");
+ sprintf(dbuff, "%s", bufferp);
+ debug_print(dbuff);
+ debug_print("\n");
+
+} /* end scan_source_debug */
+/********************************************************************/
+
+
+
+/********************************************************************/
+/* scan_token_debug() Print info about current token */
+
+extern TOKEN_CODE token; /* current token code */
+extern char *tokenp; /* token string ptr */
+extern char token_string[]; /* token string */
+
+scan_token_debug()
+{
+
+ if (DEBUG < Dscan) return;
+
+ sprintf(dbuff, "Token code: %d ; token string: %s\n",
+ token, token_string);
+ debug_print(dbuff);
+
+} /* end scan_token_debug */
+/********************************************************************/
+
+
+
+/********************************************************************/
+
+
+
+/********************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xiidbg.h b/support/ltx2x/l2xiidbg.h
new file mode 100644
index 0000000000..f7915cc9b4
--- /dev/null
+++ b/support/ltx2x/l2xiidbg.h
@@ -0,0 +1,22 @@
+/* l2xiidbg.h for debugging LTX2X interpreter code */
+/* BASED ON: idebug.h (unaltered) */
+
+#ifndef idebug_h
+#define idebug_h
+
+extern int DEBUG; /* debugging severity, 0 = no debug */
+extern int Dbasic; /* DEBUG >= Dbasic basic debugging */
+extern int Dtrace; /* DEBUG >= Dtrace debug routine call tree */
+extern int Dscan; /* DEBUG >= Dscan debug scan source buffer */
+extern int Dstack; /* DEBUG >= Dstack debug runtime stack */
+extern int Danalyze; /* DEBUG >= Danalyze debug declarations */
+extern int Dtraceall; /* DEBUG >= Dtraceall debug all code */
+extern char dbuffer[]; /* a buffer for debugging use */
+
+/* debug_print(STRING string); print a debugging string */
+
+ /* entry_debug and exit_debug must be used as a pair */
+/* entry_debug(STRING name); print routine "name-string" at routine entry */
+/* exit_debug(STRING name); print routine "name-string" at routine exit */
+
+#endif
diff --git a/support/ltx2x/l2xiprse.h b/support/ltx2x/l2xiprse.h
new file mode 100644
index 0000000000..b010f318d8
--- /dev/null
+++ b/support/ltx2x/l2xiprse.h
@@ -0,0 +1,49 @@
+/* l2xiprse.h for LTX2X interpreter parser module */
+/* BASED ON: parser.h (unaltered except for common names) */
+
+#ifndef parser_h
+#define parser_h
+
+#include "l2xicmon.h"
+#include "l2xisymt.h"
+
+/* users of a variable */
+
+typedef enum {
+ EXPR_USE, TARGET_USE, VARPARM_USE,
+} USE;
+
+/* FUNCTIONS */
+
+TYPE_STRUCT_PTR expression();
+TYPE_STRUCT_PTR variable();
+TYPE_STRUCT_PTR routine_call();
+TYPE_STRUCT_PTR base_type();
+BOOLEAN is_assign_type_compatible();
+
+/* MACROS for parsing */
+
+/* if_token_get if token = token_code, get the next token */
+
+#define if_token_get(token_code) \
+ if (token == token_code) get_token()
+
+/* if_token_get_else_error if token = token code, get next token, else error */
+
+#define if_token_get_else_error(token_code, error_code) \
+ if (token == token_code) get_token(); \
+ else error(error_code)
+
+/* ANALYSIS routine calls */
+/* Unless the following statements are preceeded by #define analyze */
+/* calls to the analysis routines are not compiled. */
+
+#ifndef analyze
+#define analyze_const_defn(idp)
+#define analyze_var_decl(idp)
+#define analyze_type_defn(idp)
+#define analyze_routine_header(idp)
+#define analyze_block(idp)
+#endif
+
+#endif
diff --git a/support/ltx2x/l2xirexp.c b/support/ltx2x/l2xirexp.c
new file mode 100644
index 0000000000..1da732b35d
--- /dev/null
+++ b/support/ltx2x/l2xirexp.c
@@ -0,0 +1,814 @@
+/* l2xirexp.c builds recognizers for two kinds of regular expressions */
+/* Based on rexpr.c, part of the PCCTS compiler/generator distribution */
+/*
+ * This file contains code for
+ *
+ * int rexpr(char *expr, char *s);
+ *
+ * which answers
+ *
+ * 1 if 's' is in the language described by the regular expression 'expr'
+ * 0 if it is not
+ * -1 if the regular expression is invalid
+ *
+ * Language membership is determined by constructing a non-deterministic
+ * finite automata (NFA) from the regular expression. A depth-
+ * first-search is performed on the NFA (graph) to check for a match of 's'.
+ * Each non-epsilon arc consumes one character from 's'. Backtracking is
+ * performed to check all possible paths through the NFA.
+ *
+ * Regular expressions follow the meta-language:
+ *
+ * <regExpr> ::= <andExpr> ( '|' <andExpr> )*
+ *
+ * <andExpr> ::= <expr> ( <expr> )*
+ *
+ * <expr> ::= {'~'} '[' <atomList> ']' <repeatSymbol>
+ * | '(' <regExpr> ')' <repeatSymbol>
+ * | '{' <regExpr> '}' <repeatSymbol>
+ * | <atom> <repeatSymbol>
+ *
+ * <repeatSymbol> ::= { '*' | '+' }
+ *
+ * <atomList> ::= <atom> ( <atom> )*
+ * | { <atomList> } <atom> '-' <atom> { <atomList> }
+ *
+ * <atom> ::= Token[Atom]
+ *
+ * Notes:
+ * ~ means complement the set in [..]. i.e. all characters
+ * not listed
+ * * means match 0 or more times (can be on expression
+ * or atom)
+ * + means match 1 or more times (can be on expression
+ * or atom)
+ * {} optional
+ * () grouping
+ * [] set of atoms
+ * x-y all characters from x to y (found only in [..])
+ * \xx the character with value xx
+ *
+ * Examples:
+ * [a-z]+
+ * match 1 or more lower-case letters (e.g. variable)
+ *
+ * 0x[0-9A-Fa-f]+
+ * match a hex number with 0x on front (e.g. 0xA1FF)
+ *
+ * [0-9]+.[0-9]+{e[0-9]+}
+ * match a floating point number (e.g. 3.14e21)
+ *
+ * Code example:
+ * if ( rexpr("[a-zA-Z][a-zA-Z0-9]+", str) ) then str is keyword
+ *
+ * Terence Parr
+ * Purdue University
+ * April 1991
+ */
+/**********************************************************************/
+/* some modifications by Peter Wilson, Catholic University of America */
+/*
+* Complement changed from ~[...] to [^...] to match AWK/lex
+* Optional changed from {...} to (r)? to match AWK/lex
+* Swapped parameters in rexpr()
+*
+* Major additions/changes to support the EXPRESS LIKE operator:
+* string LIKE pattern -> TRUE or FALSE
+*
+* @ matches any letter
+* ^ matches any uppercase letter
+* ? matches any character
+* & matches remainder of string
+* # matches any digit
+* $ matches any substring terminated by space or end of string
+* * matches any number of characters
+* \ escape character
+*
+*/
+/**********************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "l2xirexp.h"
+#include "l2xiidbg.h"
+
+
+static int regExpr();
+static int andExpr();
+static int expr();
+static int repeatSymbol();
+static int atomList();
+static int next();
+static ArcPtr newGraphArc();
+static NodePtr newNode();
+static int ArcBetweenGraphNode();
+static Graph BuildNFA_atom();
+static Graph BuildNFA_AB();
+static Graph BuildNFA_AorB();
+static Graph BuildNFA_set();
+static Graph BuildNFA_Astar();
+static Graph BuildNFA_Aplus();
+static Graph BuildNFA_Aoptional();
+
+static char *_c;
+static int rx_token, tokchar;
+static NodePtr accept;
+static NodePtr freelist = NULL;
+
+int like_op = 0; /* PRW = 1 iff processing EXPRESS LIKE pattern */
+
+/*
+ * return 1 if s in language described by expr
+ * 0 if s is not
+ * -1 if expr is an invalid regular expression
+ */
+rexpr(s, expr)
+char *expr, *s;
+{
+ NodePtr p,q;
+ Graph nfa;
+ int result;
+
+ entry_debug("rexpr (l2xirexp.c)");
+ sprintf(dbuffer, "rexpr(%s, %s);\n", s, expr);
+ debug_print(dbuffer);
+ like_op = 0;
+ freelist = NULL;
+ _c = expr;
+ next();
+ if ( regExpr(&nfa) == -1 ) return -1;
+ accept = nfa.right;
+ result = match(nfa.left, s);
+ /* free all your memory */
+ p = q = freelist;
+ while ( p!=NULL ) { q = p->track; free(p); p = q; }
+ exit_debug("rexpr");
+ return result;
+}
+
+/*
+ * do a depth-first-search on the NFA looking for a path from start to
+ * accept state labelled with the characters of 's'.
+ */
+match(automaton, s)
+NodePtr automaton;
+char *s;
+{
+ ArcPtr p;
+
+ if ( automaton == accept && *s == '\0' ) return 1; /* match */
+
+ for (p=automaton->arcs; p!=NULL; p=p->next) /* try all arcs */
+ {
+ if ( p->label == Epsilon )
+ {
+ if ( match(p->target, s) ) return 1;
+ }
+ else if ( p->label == *s )
+ if ( match(p->target, s+1) ) return 1;
+ }
+ return 0;
+}
+
+/*
+ * <regExpr> ::= <andExpr> ( '|' {<andExpr>} )*
+ *
+ * Return -1 if syntax error
+ * Return 0 if none found
+ * Return 1 if a regExrp was found
+ */
+static
+regExpr(g)
+GraphPtr g;
+{
+ Graph g1, g2;
+
+ if ( andExpr(&g1) == -1 )
+ {
+ return -1;
+ }
+
+ while ( rx_token == '|' )
+ {
+ int a;
+ next();
+ a = andExpr(&g2);
+ if ( a == -1 ) return -1; /* syntax error below */
+ else if ( !a ) return 1; /* empty alternative */
+ g1 = BuildNFA_AorB(g1, g2);
+ }
+
+ if ( rx_token!='\0' ) return -1;
+
+ *g = g1;
+ return 1;
+}
+
+/*
+ * <andExpr> ::= <expr> ( <expr> )*
+ */
+static
+andExpr(g)
+GraphPtr g;
+{
+ Graph g1, g2;
+
+ if ( expr(&g1) == -1 )
+ {
+ return -1;
+ }
+
+/* PRW while ( rx_token==Atom || rx_token=='{' || rx_token=='(' || rx_token=='~' || rx_token=='[' ) */
+ while ( rx_token==Atom || rx_token=='(' || rx_token=='[' )
+ {
+ if (expr(&g2) == -1) return -1;
+ g1 = BuildNFA_AB(g1, g2);
+ }
+
+ *g = g1;
+ return 1;
+}
+
+/*
+ * <expr> ::= {'~'} '[' <atomList> ']' <repeatSymbol>
+ * | '(' <regExpr> ')' <repeatSymbol>
+ * | '{' <regExpr> '}' <repeatSymbol>
+ * | <atom> <repeatSymbol>
+ * PRW changed above to:
+ * <expr> ::= '[' {'^'} <atomList> ']' <repeatSymbol>
+ * | '(' <regExpr> ')' <repeatSymbol>
+ * | <atom> <repeatSymbol>
+ */
+static
+expr(g)
+GraphPtr g;
+{
+ int complement = 0;
+ char s[257]; /* alloc space for string of char in [] */
+
+/* PRW if ( rx_token == '~' || rx_token == '[' ) */
+ if ( rx_token == '[' )
+ {
+ next();
+ if (rx_token == '^') { complement = 1; next();}
+/* PRW if ( rx_token == '~' ) {complement = 1; next();}
+* if ( rx_token != '[' ) return -1;
+* next();
+*/
+ if ( atomList( s, complement ) == -1 ) return -1;
+ *g = BuildNFA_set( s );
+ if ( rx_token != ']' ) return -1;
+ next();
+ repeatSymbol( g );
+ return 1;
+ }
+ if ( rx_token == '(' )
+ {
+ next();
+ if ( regExpr( g ) == -1 ) return -1;
+ if ( rx_token != ')' ) return -1;
+ next();
+ repeatSymbol( g );
+ return 1;
+ }
+/* PRW if ( rx_token == '{' )
+* {
+* next();
+* if ( regExpr( g ) == -1 ) return -1;
+* if ( rx_token != '}' ) return -1;
+* next();
+* -- S p e c i a l C a s e O p t i o n a l { } --
+* if ( rx_token != '*' && rx_token != '+' )
+* {
+* *g = BuildNFA_Aoptional( *g );
+* }
+* repeatSymbol( g );
+* return 1;
+* }
+*/
+ if ( rx_token == Atom )
+ {
+ *g = BuildNFA_atom( tokchar );
+ next();
+ repeatSymbol( g );
+ return 1;
+ }
+
+ return -1;
+}
+
+/*
+ * <repeatSymbol> ::= { '*' | '+' }
+ * PRW changed to ::= { '*' | '+' | '?' }
+ */
+static
+repeatSymbol(g)
+GraphPtr g;
+{
+ switch ( rx_token )
+ {
+ case '*' : *g = BuildNFA_Astar( *g ); next(); break;
+ case '+' : *g = BuildNFA_Aplus( *g ); next(); break;
+ case '?' : *g = BuildNFA_Aoptional( *g ); next(); break;
+ }
+ return 1;
+}
+
+/*
+ * <atomList> ::= <atom> { <atom> }*
+ * { <atomList> } <atom> '-' <atom> { <atomList> }
+ *
+ * a-b is same as ab
+ * q-a is same as q
+ */
+static
+atomList(p, complement)
+char *p;
+int complement;
+{
+ static unsigned char set[256]; /* no duplicates */
+ int first, last, i;
+ char *s = p;
+
+ if ( rx_token != Atom ) return -1;
+
+ for (i=0; i<256; i++) set[i] = 0;
+ while ( rx_token == Atom )
+ {
+ if ( !set[tokchar] ) *s++ = tokchar;
+ set[tokchar] = 1; /* Add atom to set */
+ next();
+ if ( rx_token == '-' ) /* have we found '-' */
+ {
+ first = *(s-1); /* Get last char */
+ next();
+ if ( rx_token != Atom ) return -1;
+ else
+ {
+ last = tokchar;
+ }
+ for (i = first+1; i <= last; i++)
+ {
+ if ( !set[tokchar] ) *s++ = i;
+ set[i] = 1; /* Add atom to set */
+ }
+ next();
+ }
+ }
+ *s = '\0';
+ if ( complement )
+ {
+ for (i=0; i<256; i++) set[i] = !set[i];
+ for (i=1,s=p; i<256; i++) if ( set[i] ) *s++ = i;
+ *s = '\0';
+ }
+ return 1;
+}
+
+/* a somewhat stupid lexical analyzer */
+static
+next()
+{
+ /* PRW seperate scanners for regular expression and LIKE operator */
+ if (like_op == 0) { /* regex scanning */
+ while ( *_c==' ' || *_c=='\t' || *_c=='\n' ) _c++;
+ if ( *_c=='\\' )
+ {
+ _c++;
+ if ( isdigit(*_c) )
+ {
+ int n=0;
+ while ( isdigit(*_c) )
+ {
+ n = n*10 + (*_c++ - '0');
+ }
+ if ( n>255 ) n=255;
+ tokchar = n;
+ }
+ else
+ {
+ switch (*_c)
+ {
+ case 'n' : tokchar = '\n'; break;
+ case 't' : tokchar = '\t'; break;
+ case 'r' : tokchar = '\r'; break;
+ default : tokchar = *_c;
+ }
+ _c++;
+ }
+ rx_token = Atom;
+ }
+ else if ( isgraph(*_c) && *_c!='['
+ && *_c!='('
+ && *_c!='-'
+ && *_c!=')'
+ && *_c!=']'
+ && *_c!='?'
+ && *_c!='+'
+ && *_c!='*'
+ && *_c!='^'
+ && *_c!='|' )
+ { /* PRW deleted {, } and ~ while adding ^ and ? */
+ rx_token = Atom;
+ tokchar = *_c++;
+ }
+ else
+ {
+ rx_token = tokchar = *_c++;
+ }
+ return;
+ } /* end of regex scanner */
+ else if (like_op == 1) { /* LIKE scanning */
+ while ( *_c==' ' || *_c=='\t' || *_c=='\n' ) _c++;
+ if ( *_c=='\\' )
+ {
+ _c++;
+ switch (*_c)
+ {
+ case 'n' : tokchar = '\n'; break;
+ case 't' : tokchar = '\t'; break;
+ case 'r' : tokchar = '\r'; break;
+ default : tokchar = *_c;
+ }
+ _c++;
+ rx_token = Atom;
+ }
+ else if ( isgraph(*_c) && *_c!='@'
+ && *_c!='^'
+ && *_c!='?'
+ && *_c!='&'
+ && *_c!='#'
+ && *_c!='$'
+ && *_c!='*'
+ && *_c!='!' )
+ {
+ rx_token = Atom;
+ tokchar = *_c++;
+ }
+ else
+ {
+ rx_token = tokchar = *_c++;
+ }
+ return;
+ } /* end of LIKE scanner */
+}
+
+/* N F A B u i l d i n g R o u t i n e s */
+
+static
+ArcPtr
+newGraphArc()
+{
+ ArcPtr p;
+ p = (ArcPtr) calloc(1, sizeof(Arc));
+ if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);}
+ if ( freelist != NULL ) p->track = (ArcPtr) freelist;
+ freelist = (NodePtr) p;
+ return p;
+}
+
+static
+NodePtr
+newNode()
+{
+ NodePtr p;
+ p = (NodePtr) calloc(1, sizeof(Node));
+ if ( p==NULL ) {fprintf(stderr,"rexpr: out of memory\n"); exit(-1);}
+ if ( freelist != NULL ) p->track = freelist;
+ freelist = p;
+ return p;
+}
+
+static
+ArcBetweenGraphNodes(i, j, label)
+NodePtr i, j;
+int label;
+{
+ ArcPtr a;
+
+ a = newGraphArc();
+ if ( i->arcs == NULL ) i->arctail = i->arcs = a;
+ else {(i->arctail)->next = a; i->arctail = a;}
+ a->label = label;
+ a->target = j;
+}
+
+static Graph
+BuildNFA_atom(label)
+int label;
+{
+ Graph g;
+
+ g.left = newNode();
+ g.right = newNode();
+ ArcBetweenGraphNodes(g.left, g.right, label);
+ return( g );
+}
+
+static Graph
+BuildNFA_AB(A, B)
+Graph A, B;
+{
+ Graph g;
+
+ ArcBetweenGraphNodes(A.right, B.left, Epsilon);
+ g.left = A.left;
+ g.right = B.right;
+ return( g );
+}
+
+static Graph
+BuildNFA_AorB(A, B)
+Graph A, B;
+{
+ Graph g;
+
+ g.left = newNode();
+ ArcBetweenGraphNodes(g.left, A.left, Epsilon);
+ ArcBetweenGraphNodes(g.left, B.left, Epsilon);
+ g.right = newNode();
+ ArcBetweenGraphNodes(A.right, g.right, Epsilon);
+ ArcBetweenGraphNodes(B.right, g.right, Epsilon);
+ return( g );
+}
+
+static Graph
+BuildNFA_set( s )
+char *s;
+{
+ Graph g;
+
+ if ( s == NULL ) return g;
+
+ g.left = newNode();
+ g.right = newNode();
+ while ( *s != '\0' )
+ {
+ ArcBetweenGraphNodes(g.left, g.right, *s++);
+ }
+ return g;
+}
+
+static Graph
+BuildNFA_Astar( A )
+Graph A;
+{
+ Graph g;
+
+ g.left = newNode();
+ g.right = newNode();
+
+ ArcBetweenGraphNodes(g.left, A.left, Epsilon);
+ ArcBetweenGraphNodes(g.left, g.right, Epsilon);
+ ArcBetweenGraphNodes(A.right, g.right, Epsilon);
+ ArcBetweenGraphNodes(A.right, A.left, Epsilon);
+
+ return( g );
+}
+
+static Graph
+BuildNFA_Aplus( A )
+Graph A;
+{
+ ArcBetweenGraphNodes(A.right, A.left, Epsilon);
+
+ return( A );
+}
+
+static Graph
+BuildNFA_Aoptional( A )
+Graph A;
+{
+ Graph g;
+
+ g.left = newNode();
+ g.right = newNode();
+
+ ArcBetweenGraphNodes(g.left, A.left, Epsilon);
+ ArcBetweenGraphNodes(g.left, g.right, Epsilon);
+ ArcBetweenGraphNodes(A.right, g.right, Epsilon);
+
+ return( g );
+}
+
+
+/* LIKE operator code */
+
+
+
+/************************************************************************/
+/* likeExpr() Process likeExpr */
+
+static likeExpr(g)
+GraphPtr g;
+{
+ int complement = 0;
+ char s[257];
+ int i;
+ Graph g2;
+
+ if (rx_token == '\\') { /* escape char */
+ next();
+ }
+ if (rx_token == '!') { /* NOT char */
+ complement = 1;
+ next();
+ }
+
+ if (rx_token == Atom) {
+ if (complement == 1) {
+ do_not_atom(s, tokchar);
+ *g = BuildNFA_set(s);
+ }
+ else {
+ *g = BuildNFA_atom(tokchar);
+ }
+ next();
+ return(1);
+ }
+ else if ( rx_token == '@'
+ || rx_token == '^'
+ || rx_token == '?'
+ || rx_token == '&'
+ || rx_token == '#'
+ || rx_token == '$'
+ || rx_token == '*' ) {
+ do_like_meta(rx_token, s, complement);
+ *g = BuildNFA_set(s);
+ if ( rx_token == '&'
+ || rx_token == '*'
+ || rx_token == '$' ) { /* multiple chars */
+ *g = BuildNFA_Astar(*g);
+ if (rx_token == '$') { /* add 0 or more following space chars */
+ g2 = BuildNFA_atom(' ');
+ g2 = BuildNFA_Astar(g2);
+ *g = BuildNFA_AB(*g, g2);
+ }
+ }
+ next();
+ return(1);
+ }
+
+ return(-1); /* should not be here */
+} /* end LIKEEXPR */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* likePat() Process likePat ::= <likeExpr> ( <likeExpr> )* */
+
+static likePat(g)
+GraphPtr g;
+{
+ Graph g1, g2;
+
+ if (likeExpr(&g1) == -1) {
+ return(-1);
+ }
+
+ while (rx_token != '\0') {
+ if (likeExpr(&g2) == -1) {
+ return(-1);
+ }
+ g1 = BuildNFA_AB(g1, g2);
+ }
+ *g = g1;
+ return(1);
+} /* end LIKEPAT */
+/************************************************************************/
+
+/************************************************************************/
+/* like_expr(expr,s) */
+/* returns -1 if expr not an EXPRESS LIKE pattern */
+/* 0 if s does not match pattern expr */
+/* 1 if s matches pattern expr */
+
+int like_expr(s, expr)
+char *s; /* string to be matched */
+char *expr; /* the pattern */
+{
+ NodePtr p, q;
+ Graph nfa;
+ int result;
+
+ entry_debug("like_expr (l2xirexp.c)");
+ sprintf(dbuffer, "like_expr(%s, %s);\n", s, expr);
+ debug_print(dbuffer);
+
+ like_op = 1; /* set correct scanner */
+ freelist = NULL;
+ _c = expr;
+ next();
+ if (likePat(&nfa) == -1) {
+ return(-1);
+ }
+ accept = nfa.right;
+ result = match(nfa.left, s);
+ /* free memory */
+ p = q = freelist;
+ while (p != NULL) {
+ q = p->track;
+ free(p);
+ p = q;
+ }
+ exit_debug("like_expr");
+ return(result);
+} /* end LIKE_EXPR */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* do_not_atom() Process !a */
+
+int do_not_atom(p, c)
+char *p;
+int c; /* the negated atom char */
+{
+ static unsigned char set [256];
+ int i;
+ char *s = p;
+
+ for (i = 0; i < 256; i++) { /* all characters */
+ set[i] = 1;
+ }
+ set[c] = !set[c]; /* except for this one */
+
+ for (i = 1, s = p; i < 256; i++) {
+ if (set[i]) *s++ = i;
+ }
+ *s = '\0';
+ return(1);
+} /* end DO_NOT_ATOM */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* do_like_meta() Process EXPRESS LIKE meta character */
+
+int do_like_meta(meta, p, complement)
+int meta; /* the meta character */
+char *p;
+int complement; /* = 1 if complement the set */
+{
+ static unsigned char set[256];
+ int i;
+ char *s = p;
+
+ /* ensure all character are noted in the set */
+ for (i = 0; i < 256; i++) set[i] = 1;
+
+ switch (meta) {
+ case '@' : { /* a single alphabetic character */
+ for (i = 0; i < 256; i++) set[i] = 0;
+ for (i = 'a'; i <= 'z'; i++) set[i] = 1;
+ for (i = 'A'; i <= 'Z'; i++) set[i] = 1;
+ break;
+ }
+ case '^' : { /* a single upper case alphabetic character */
+ for (i = 0; i < 256; i++) set[i] = 0;
+ for (i = 'A'; i <= 'Z'; i++) set[i] = 1;
+ break;
+ }
+ case '?' : { /* a single character */
+ break;
+ }
+ case '&' : { /* remainder of string */
+ break;
+ }
+ case '#' : { /* a single digit */
+ for (i = 0; i < 256; i++) set[i] = 0;
+ for (i = '0'; i <= '9'; i++) set[i] = 1;
+ break;
+ }
+ case '$' : { /* substring ended by space or EOS */
+ i = ' ';
+ set[i] = !set[i];
+ break;
+ }
+ case '*' : { /* any character */
+ break;
+ }
+ default : { /* an ERROR */
+ return(-1);
+ }
+ } /* end switch */
+
+ if (complement == 1) { /* invert the set */
+ for (i = 0; i < 256; i++) set[i] = !set[i];
+ }
+
+ /* add all the search characters to the string */
+ for (i = 1, s = p; i < 256; i++) {
+ if (set[i]) *s++ = i;
+ }
+ *s = '\0';
+ return(1);
+} /* end DO_LIKE_META */
+/************************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xirexp.h b/support/ltx2x/l2xirexp.h
new file mode 100644
index 0000000000..ee8814c70e
--- /dev/null
+++ b/support/ltx2x/l2xirexp.h
@@ -0,0 +1,28 @@
+/* l2xirexp.h Include file for regular expression code */
+
+#define Atom 256 /* token Atom (an impossible char value) */
+#define Epsilon 257 /* epsilon arc (an impossible char value) */
+
+/* track field must be same for all node types */
+typedef struct _a {
+ struct _a *track; /* track mem allocation */
+ int label;
+ struct _a *next;
+ struct _n *target;
+ } Arc, *ArcPtr;
+
+typedef struct _n {
+ struct _n *track;
+ ArcPtr arcs, arctail;
+ } Node, *NodePtr;
+
+typedef struct {
+ NodePtr left,
+ right;
+ } Graph, *GraphPtr;
+
+int rexpr();
+int match();
+int like_expr();
+
+
diff --git a/support/ltx2x/l2xirtne.c b/support/ltx2x/l2xirtne.c
new file mode 100644
index 0000000000..c7dc7b8675
--- /dev/null
+++ b/support/ltx2x/l2xirtne.c
@@ -0,0 +1,651 @@
+/* l2xirtne.c LTX2X interpreter Routine parser */
+/* parse programs and declared procedures and functions */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+#include "l2xiexec.h"
+#ifndef l2xicpr_h
+#include "l2xicpr.h" /* extern token code lists */
+#endif
+
+/* EXTERNALS */
+
+extern int line_number;;
+extern long exec_stmt_count;
+
+extern TOKEN_CODE token;
+extern char word_string[];
+extern SYMTAB_NODE_PTR symtab_display[];
+extern int level;
+
+extern ICT *code_buffer;
+extern ICT *code_bufferp;
+
+extern STACK_ITEM *stack;
+extern STACK_ITEM_PTR tos;
+extern STACK_ITEM_PTR stack_frame_basep;
+extern STACK_ITEM_PTR maxtos;
+extern TYPE_STRUCT_PTR get_type();
+
+/* GLOBALS */
+
+char buffer[MAX_PRINT_LINE_LENGTH];
+
+/* FORWARDS */
+
+SYMTAB_NODE_PTR formal_parm_list();
+SYMTAB_NODE_PTR procedure_header();
+SYMTAB_NODE_PTR function_header();
+ICT *create_code_segment();
+
+
+
+/***************************************************************************/
+/* init_stack initialise the runtime stack */
+
+init_stack()
+{
+
+ entry_debug("init_stack");
+
+ /* allocate runtime stack */
+ stack = alloc_array(STACK_ITEM, MAX_STACK_SIZE);
+ stack_frame_basep = tos = stack;
+ stack_frame_debug();
+
+ maxtos = tos; /* current max top of stack */
+ /* initialise the program's stack frame */
+ level = 1;
+ stack_frame_basep = tos + 1;
+ stack_frame_debug();
+ push_integer(0); /* function return value */
+ push_address(NULL); /* static link */
+ push_address(NULL); /* dynamic link */
+ push_address(NULL); /* return address */
+
+
+ exit_debug("init_stack");
+ return;
+} /* end init_stack */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* create_dummy_prog() create a dummy program symbol table node */
+/* Based on program and program_header */
+/* Must be called BEFORE any scanning or parsing */
+/* returns pointer to program id node */
+
+SYMTAB_NODE_PTR create_dummy_prog()
+{
+ SYMTAB_NODE_PTR program_idp; /* program id */
+ entry_debug("creat_dummy_prog");
+
+ /* make up fake program name */
+ strcpy(word_string, "_PrOgRaM");
+ search_and_enter_local_symtab(program_idp);
+ program_idp->defn.key = PROG_DEFN;
+ program_idp->defn.info.routine.key = DECLARED;
+ program_idp->defn.info.routine.parm_count = 0;
+ program_idp->defn.info.routine.total_parm_size = 0;
+ program_idp->defn.info.routine.total_local_size = 0;
+ program_idp->typep = &dummy_type;
+ program_idp->label_index = 0;
+
+ enter_scope(NULL);
+
+ /* no program parameters */
+
+ program_idp->defn.info.routine.locals = NULL;
+ program_idp->defn.info.routine.parms = NULL;
+
+ exit_debug("create_dummy_prog");
+ return(program_idp);
+} /* end create_dummy_prog */
+/***************************************************************************/
+
+
+
+
+
+/***************************************************************************/
+/* a_function Process an EXPRESS function */
+/* FUNCTION <header> <body> END_FUNCTION ; */
+/* at entry, token is FUNCTION */
+/* at exit, token is after END_FUNCTION ; */
+
+a_function()
+{
+ SYMTAB_NODE_PTR rtn_idp; /* routine id */
+ entry_debug("a_function");
+
+ rtn_idp = function_header();
+
+ /* sync. Should be ; */
+ synchronize(follow_header_list, declaration_start_list, statement_start_list);
+ if_token_get(SEMICOLON);
+ else if (token_in(declaration_start_list) || token_in(statement_start_list))
+ error(MISSING_SEMICOLON);
+
+ /* block or forward */
+ if (strcmp(word_string, "forward") != 0) {
+ rtn_idp->defn.info.routine.key = DECLARED;
+ analyze_routine_header(rtn_idp);
+ rtn_idp->defn.info.routine.locals = NULL;
+ function_body(rtn_idp);
+
+ rtn_idp->defn.info.routine.code_segment = create_code_segment();
+ analyze_block(rtn_idp->defn.info.routine.code_segment);
+ if_token_get_else_error(XEND_FUNCTION, MISSING_END_FUNCTION);
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+ }
+ else {
+ get_token();
+ rtn_idp->defn.info.routine.key = FORWARD;
+ analyze_routine_header(rtn_idp);
+ }
+
+ rtn_idp->defn.info.routine.local_symtab = exit_scope();
+
+ exit_debug("a_function");
+ return;
+
+} /* end A_FUNCTION */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* function_body(rtn_idp) Process body of a function */
+/* at entry, token is after ; ending the header */
+/* at exit, token is after a ; and should be END_FUNCTION */
+
+function_body(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ extern BOOLEAN block_flag;
+ entry_debug("function_body");
+
+ if (token_in(declaration_start_list)) {
+ declarations(rtn_idp);
+/* synchronize(follow_decls_list, NULL, NULL); */
+ }
+ /* possibly need an else skip_declarations(rtn_idp); here */
+
+ block_flag = TRUE;
+ /* possibly empty list of statements */
+ if (token_in(statement_start_list)) {
+ crunch_token();
+ statements();
+ crunch_statement_marker();
+ change_crunched_token(END_OF_STATEMENTS);
+ }
+ block_flag = FALSE;
+
+/* if_token_get_else_error(XEND_FUNCTION, MISSING_END_FUNCTION);
+* if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+*/
+
+ exit_debug("function_body");
+ return;
+} /* end FUNCTION_BODY */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* a_procedure() Process EXPRESS procedure */
+/* FUN/PROC <routine_header> ; <block> */
+/* at entry, token is PROCEDURE */
+/* at exit, token is past final ; */
+
+a_procedure()
+{
+ SYMTAB_NODE_PTR rtn_idp; /* routine id */
+ entry_debug("a_procedure");
+
+ rtn_idp = procedure_header();
+
+ /* sync. Should be ; */
+ synchronize(follow_header_list, declaration_start_list, statement_start_list);
+ if_token_get(SEMICOLON);
+ else if (token_in(declaration_start_list) || token_in(statement_start_list))
+ error(MISSING_SEMICOLON);
+
+ /* block or forward */
+ if (strcmp(word_string, "forward") != 0) {
+ rtn_idp->defn.info.routine.key = DECLARED;
+ analyze_routine_header(rtn_idp);
+ rtn_idp->defn.info.routine.locals = NULL;
+ function_body(rtn_idp);
+
+ rtn_idp->defn.info.routine.code_segment = create_code_segment();
+ analyze_block(rtn_idp->defn.info.routine.code_segment);
+ if_token_get_else_error(XEND_PROCEDURE, MISSING_END_PROCEDURE);
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+ }
+ else {
+ get_token();
+ rtn_idp->defn.info.routine.key = FORWARD;
+ analyze_routine_header(rtn_idp);
+ }
+
+ rtn_idp->defn.info.routine.local_symtab = exit_scope();
+
+ exit_debug("a_procedure");
+ return;
+} /* end A_PROCEDURE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* procedure_header() Process a procedure header */
+/* PROCEDURE <id> */
+/* or PROCEDURE <id> ( <parm-list> ) */
+/* returns pointer to the procedure id node. */
+
+SYMTAB_NODE_PTR procedure_header()
+{
+ SYMTAB_NODE_PTR proc_idp; /* procedure id */
+ SYMTAB_NODE_PTR parm_listp; /* formal param list */
+ int parm_count;
+ int total_parm_size;
+ BOOLEAN forward_flag = FALSE; /* TRUE iff forward */
+ entry_debug("procedure_header");
+
+ get_token();
+
+ /* if proc id has already been declared in this scope, */
+ /* it must be a forward */
+ if (token == IDENTIFIER) {
+ search_local_symtab(proc_idp);
+ if (proc_idp == NULL) {
+ enter_local_symtab(proc_idp);
+ proc_idp->defn.key = PROC_DEFN;
+ proc_idp->defn.info.routine.total_local_size = 0;
+ proc_idp->typep = &dummy_type;
+ proc_idp->label_index = 0;
+ }
+ else if ((proc_idp->defn.key == PROC_DEFN) &&
+ (proc_idp->defn.info.routine.key == FORWARD))
+ forward_flag = TRUE;
+ else error(REDEFINED_IDENTIFIER);
+
+ get_token();
+ }
+ else error(MISSING_IDENTIFIER);
+
+ /* sync. Should be ( or ; */
+ synchronize(follow_proc_id_list, declaration_start_list, statement_start_list);
+ enter_scope(NULL);
+
+ /* optional formal parameters, if FORWARD shouldn't be any, but parse */
+ /* for error recovery */
+ if (token == LPAREN) {
+ parm_listp = formal_parm_list(&parm_count, &total_parm_size);
+ if (forward_flag) error(ALREADY_FORWARDED);
+ else {
+ proc_idp->defn.info.routine.parm_count = parm_count;
+ proc_idp->defn.info.routine.total_parm_size = total_parm_size;
+ proc_idp->defn.info.routine.parms = parm_listp;
+ }
+ }
+ else if (!forward_flag) {
+ proc_idp->defn.info.routine.parm_count = 0;
+ proc_idp->defn.info.routine.total_parm_size = 0;
+ proc_idp->defn.info.routine.parms = NULL;
+ }
+
+ proc_idp->typep = NULL;
+ exit_debug("procedure_header");
+ return(proc_idp);
+} /* end procedure_header */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* function_header() Process a function header */
+/* FUNCTION <id> : <type-id> */
+/* or FUNCTION <id> ( <parm-list> ) : <type-id> */
+/* returns pointer to the function id node. */
+
+SYMTAB_NODE_PTR function_header()
+{
+ SYMTAB_NODE_PTR func_idp, type_idp; /* function and type id */
+ SYMTAB_NODE_PTR parm_listp; /* formal param list */
+ int parm_count;
+ int total_parm_size;
+ BOOLEAN forward_flag = FALSE; /* TRUE iff forward */
+ entry_debug("function_header");
+
+ get_token();
+
+ /* if func id has already been declared in this scope, */
+ /* it must be a forward */
+ if (token == IDENTIFIER) {
+ search_local_symtab(func_idp);
+ if (func_idp == NULL) {
+ enter_local_symtab(func_idp);
+ func_idp->defn.key = FUNC_DEFN;
+ func_idp->defn.info.routine.total_local_size = 0;
+ func_idp->typep = &dummy_type;
+ func_idp->label_index = 0;
+ }
+ else if ((func_idp->defn.key == FUNC_DEFN) &&
+ (func_idp->defn.info.routine.key == FORWARD))
+ forward_flag = TRUE;
+ else error(REDEFINED_IDENTIFIER);
+
+ get_token();
+ }
+ else error(MISSING_IDENTIFIER);
+
+ /* sync. Should be ( or : or ; */
+ synchronize(follow_func_id_list, declaration_start_list, statement_start_list);
+ enter_scope(NULL);
+
+ /* optional formal parameters, if FORWARD shouldn't be any, but parse */
+ /* for error recovery */
+ if (token == LPAREN) {
+ parm_listp = formal_parm_list(&parm_count, &total_parm_size);
+ if (forward_flag) error(ALREADY_FORWARDED);
+ else {
+ func_idp->defn.info.routine.parm_count = parm_count;
+ func_idp->defn.info.routine.total_parm_size = total_parm_size;
+ func_idp->defn.info.routine.parms = parm_listp;
+ }
+ }
+ else if (!forward_flag) {
+ func_idp->defn.info.routine.parm_count = 0;
+ func_idp->defn.info.routine.total_parm_size = 0;
+ func_idp->defn.info.routine.parms = NULL;
+ }
+
+ /* for a forward, should not be a type, but parse anyway */
+ if (!forward_flag || (token == COLON)) {
+ if_token_get_else_error(COLON, MISSING_COLON);
+
+/* changed for EXPRESS
+ if (token == IDENTIFIER) {
+ search_and_find_all_symtab(type_idp);
+ if (type_idp->defn.key != TYPE_DEFN) error(INVALID_TYPE);
+ if (!forward_flag) func_idp->typep = type_idp->typep;
+ get_token();
+ }
+ else {
+ error(MISSING_IDENTIFIER);
+ func_idp->typep = &dummy_type;
+ }
+*/
+ if (!forward_flag) func_idp->typep = get_type();
+ get_token();
+ if (forward_flag) error(ALREADY_FORWARDED);
+ }
+
+ exit_debug("function_header");
+ return(func_idp);
+} /* end function_header */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* formal_parm_list(countp, total_size) Process formal parameter list */
+/* ( VAR <id-list> : <type> ; */
+/* <id-list> : <type> ; ... ) */
+/* return a pointer to the head of the parameter id list */
+
+SYMTAB_NODE_PTR formal_parm_list(countp, total_sizep)
+int *countp; /* ptr to count of parameters */
+int *total_sizep; /* ptr to total byte size of parameters */
+{
+ SYMTAB_NODE_PTR parm_idp, first_idp, last_idp; /* parm ids */
+ SYMTAB_NODE_PTR prev_last_idp = NULL; /* last id of list */
+ SYMTAB_NODE_PTR parm_listp = NULL; /* parm list */
+ SYMTAB_NODE_PTR type_idp; /* type id */
+ TYPE_STRUCT_PTR parm_tp; /* parm type */
+ DEFN_KEY parm_defn; /* parm definition */
+ int parm_count = 0; /* count of parms */
+ int parm_offset = STACK_FRAME_HEADER_SIZE;
+ entry_debug("formal_parm_list");
+
+ get_token();
+
+ /* loop to process declarations seperated by ; */
+ while ((token == IDENTIFIER) || (token == VAR)) {
+ first_idp = NULL;
+ /* VAR parm? */
+ if (token == VAR) {
+ parm_defn = VARPARM_DEFN;
+ get_token();
+ }
+ else parm_defn = VALPARM_DEFN;
+
+ /* <id list> */
+ while (token == IDENTIFIER) {
+ search_and_enter_local_symtab(parm_idp);
+ parm_idp->defn.key = parm_defn;
+ parm_idp->label_index = 0;
+ ++parm_count;
+
+ if (parm_listp == NULL) parm_listp = parm_idp;
+
+ /* link parms together */
+ if (first_idp == NULL) first_idp = last_idp = parm_idp;
+ else {
+ last_idp->next = parm_idp;
+ last_idp = parm_idp;
+ }
+ get_token();
+ if_token_get(COMMA);
+ }
+
+ if_token_get_else_error(COLON, MISSING_COLON);
+
+/* changed following for EXPRESS
+ if (token == IDENTIFIER) {
+ search_and_find_all_symtab(type_idp);
+ if (type_idp->defn.key != TYPE_DEFN) error(INVALID_TYPE);
+ parm_tp = type_idp->typep;
+ get_token();
+ }
+ else {
+ error(MISSING_IDENTIFIER);
+ parm_tp = &dummy_type;
+ }
+*/
+ parm_tp = get_type();
+ get_token();
+
+ /* assign the offset and the type to all parm ids in the sublist */
+ for (parm_idp = first_idp; parm_idp != NULL; parm_idp = parm_idp->next) {
+ parm_idp->typep = parm_tp;
+ parm_idp->defn.info.data.offset = parm_offset++;
+ }
+
+ /* link this sublist to the list of all parm ids */
+ if (prev_last_idp != NULL) prev_last_idp->next = first_idp;
+ prev_last_idp = last_idp;
+
+ /* sync: Should be ; or ) */
+ synchronize(follow_parms_list, NULL, NULL);
+ if_token_get(SEMICOLON);
+ } /* end while */
+
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ *countp = parm_count;
+ *total_sizep = parm_offset - STACK_FRAME_HEADER_SIZE;
+
+ exit_debug("formal_parm_list");
+ return(parm_listp);
+} /* end formal_parm_list */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* routine_call(rtn_idp, parm_check_flag) Process a call to a procedure */
+/* or function */
+/* return pointer to the type structure of the call */
+
+TYPE_STRUCT_PTR routine_call(rtn_idp, parm_check_flag)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+BOOLEAN parm_check_flag; /* if TRUE then check parms */
+{
+ TYPE_STRUCT_PTR declared_routine_call(), standard_routine_call();
+ entry_debug("routine_call");
+
+ if ((rtn_idp->defn.info.routine.key == DECLARED) ||
+ (rtn_idp->defn.info.routine.key == FORWARD) ||
+ (!parm_check_flag)) {
+ exit_debug("routine_call");
+ return(declared_routine_call(rtn_idp, parm_check_flag));
+ }
+ else {
+ exit_debug("routine_call");
+ return(standard_routine_call(rtn_idp));
+ }
+} /* end routine_call */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* declared_routine_call(rtn_idp, parm_check_flag) Process a call to a */
+/* declared function or procedure */
+/* <id> or */
+/* <id> ( <parm-list> ) */
+/* The actual params are checked against the */
+/* formal params for type and number. */
+/* return pointer to type structure of the call */
+
+TYPE_STRUCT_PTR declared_routine_call(rtn_idp, parm_check_flag)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+BOOLEAN parm_check_flag; /* if TRUE then check parms */
+{
+ entry_debug("declared_routine_call");
+
+ actual_parm_list(rtn_idp, parm_check_flag);
+
+ exit_debug("declared_routine_call");
+ return(rtn_idp->defn.key == PROC_DEFN ? NULL : rtn_idp->typep);
+} /* end declared_routine_call */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* actual_parm_list(rtn_idp, parm_check_flag) Process actual param list */
+/* ( <expr-list> ) */
+
+actual_parm_list(rtn_idp, parm_check_flag)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+BOOLEAN parm_check_flag; /* if TRUE then check parms */
+{
+ SYMTAB_NODE_PTR formal_parm_idp;
+ DEFN_KEY formal_parm_defn;
+ TYPE_STRUCT_PTR formal_parm_tp, actual_parm_tp;
+ entry_debug("actual_parm_list");
+
+ if (parm_check_flag) formal_parm_idp = rtn_idp->defn.info.routine.parms;
+
+ if (token == LPAREN) {
+ /* loop to process actual param expressions */
+ do {
+ /* get info on corresponding formal params */
+ if (parm_check_flag && (formal_parm_idp != NULL)) {
+ formal_parm_defn = formal_parm_idp->defn.key;
+ formal_parm_tp = formal_parm_idp->typep;
+ }
+
+ get_token();
+
+ /* Actual and formal parms must be consistent. */
+ /* Actual parm may be an expression */
+ if ((formal_parm_idp == NULL) ||
+ (formal_parm_defn == VALPARM_DEFN) ||
+ (!parm_check_flag)) {
+ actual_parm_tp = expression();
+ if (parm_check_flag &&
+ (formal_parm_idp != NULL) &&
+ (!is_assign_type_compatible(formal_parm_tp, actual_parm_tp)))
+ error(INCOMPATIBLE_TYPES);
+ }
+
+ /* Now the same for VAR params */
+ else {
+ if (token == IDENTIFIER) {
+ SYMTAB_NODE_PTR idp;
+
+ search_and_find_all_symtab(idp);
+ actual_parm_tp = variable(idp, VARPARM_USE);
+
+ if (formal_parm_tp != actual_parm_tp) error(INCOMPATIBLE_TYPES);
+ }
+ else { /* not a variable, but parse anyway */
+ actual_parm_tp = expression();
+ error(INVALID_VAR_PARM);
+ }
+ }
+
+ /* check if there are more actuals than formals */
+ if (parm_check_flag) {
+ if (formal_parm_idp == NULL) error(WRONG_NUMBER_OF_PARMS);
+ else formal_parm_idp = formal_parm_idp->next;
+ }
+
+ /* sync. Should be , or ) */
+ synchronize(follow_parm_list, statement_end_list, NULL);
+
+ } while (token == COMMA); /* end do */
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+
+ /* check for fewer actuals than formals */
+ if (parm_check_flag && (formal_parm_idp != NULL)) error(WRONG_NUMBER_OF_PARMS);
+
+ exit_debug("actual_parm_list");
+ return;
+} /* end actual_parm_list */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* block(rtn_idp) Process a block, which consists of declarations */
+/* followed by a compound statement */
+
+old_block(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ extern BOOLEAN block_flag;
+ entry_debug("block");
+
+ declarations(rtn_idp);
+
+ /* sync. Should be ; */
+ synchronize(follow_decls_list, NULL, NULL);
+ if (token != BEGIN) error(MISSING_BEGIN);
+
+ crunch_token();
+
+ block_flag = TRUE;
+ compound_statement();
+ block_flag = FALSE;
+
+ exit_debug("block");
+ return;
+} /* end block */
+/***************************************************************************/
+
diff --git a/support/ltx2x/l2xiscan.c b/support/ltx2x/l2xiscan.c
new file mode 100644
index 0000000000..7140145811
--- /dev/null
+++ b/support/ltx2x/l2xiscan.c
@@ -0,0 +1,1215 @@
+/* l2xiscan.c LTX2X Interpreter lexing routines */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+
+#include <stdio.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/timeb.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xiidbg.h"
+#ifndef l2xicpr_h
+#include "l2xicpr.h" /* before/after token code lists */
+#endif
+
+#define EOF_CHAR 257
+#define TAB_SIZE 8
+#define QUOTE_CHAR '\''
+
+#define MIN_RESERVED_WORD_LENGTH 2
+#define MAX_RESERVED_WORD_LENGTH 15
+
+/* US_CHAR is for ltx2x, adding undescore character */
+#define US_CHAR '_'
+
+/* CHARACTER CODES */
+
+typedef enum{
+ LETTER,
+ DIGIT,
+ QUOTE,
+ SPECIAL,
+ EOF_CODE,
+ USCORE, /* for ltx2x underscore */
+} CHAR_CODE;
+
+#define EOS '\0'
+
+/* RESERVED WORD TABLES */
+
+typedef struct {
+ char *string;
+ TOKEN_CODE token_code;
+} RW_STRUCT;
+
+RW_STRUCT rw_2[] = {
+ {"if", IF}, /* P&E */
+ {"in", IN}, /* P&E */
+ {"of", OF}, /* P&E */
+ {"or", OR}, /* P&E */
+ {"to", TO}, /* P&E */
+ {"as", XAS},
+ {"by", XBY},
+ {"pi", XPI},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_3[] = {
+ {"and", AND}, /* P&E */
+ {"div", DIV}, /* P&E */
+ {"end", END}, /* P&E */
+ {"for", FOR}, /* P&E */
+ {"mod", MOD}, /* P&E */
+ {"not", NOT}, /* P&E */
+ {"set", SET}, /* P&E */
+ {"var", VAR}, /* P&E */
+ {"bag", XBAG},
+ {"use", XUSE},
+ {"xor", XXOR},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_4[] = {
+ {"case", CASE}, /* P&E */
+ {"else", ELSE}, /* P&E */
+ {"file", FFILE},
+ {"then", THEN}, /* P&E */
+ {"type", TYPE}, /* P&E */
+ {"with", WITH}, /* P&E */
+ {"from", XFROM},
+ {"list", XLIST},
+ {"real", XREAL},
+ {"rule", XRULE},
+ {"skip", XSKIP},
+ {"like", XLIKE},
+ {"self", XSELF},
+ {"true", XTRUE},
+ {"call", XCALL},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_5[] = {
+ {"array", ARRAY}, /* P&E */
+ {"begin", BEGIN}, /* P&E */
+ {"until", UNTIL}, /* P&E */
+ {"while", WHILE}, /* P&E */
+ {"alias", XALIAS},
+ {"fixed", XFIXED},
+ {"local", XLOCAL},
+ {"model", XMODEL},
+ {"oneof", XONEOF},
+ {"query", XQUERY},
+ {"where", XWHERE},
+ {"andor", XANDOR},
+ {"false", XFALSE},
+ {"notes", XNOTES},
+ {"subof", XSUBOF},
+ {"supof", XSUPOF},
+ {"using", XUSING},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_6[] = {
+ {"repeat", REPEAT}, /* P&E */
+ {"binary", XBINARY},
+ {"derive", XDERIVE},
+ {"end_if", XEND_IF},
+ {"entity", XENTITY},
+ {"escape", XESCAPE},
+ {"number", XNUMBER},
+ {"return", XRETURN},
+ {"schema", XSCHEMA},
+ {"select", XSELECT},
+ {"string", XSTRING},
+ {"unique", XUNIQUE},
+ {"import", XIMPORT},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_7[] = {
+ {"boolean", XBOOLEAN},
+ {"context", XCONTEXT},
+ {"generic", XGENERIC},
+ {"integer", XINTEGER},
+ {"inverse", XINVERSE},
+ {"logical", XLOGICAL},
+ {"subtype", XSUBTYPE},
+ {"const_e", XCONST_E},
+ {"unknown", XUNKNOWN},
+ {"purpose", XPURPOSE},
+ {"the_day", THE_DAY},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_8[] = {
+ {"end_code", ENDCODE}, /* for ltx2x */
+ {"function", FUNCTION}, /* P&E */
+ {"abstract", XABSTRACT},
+ {"constant", XCONSTANT},
+ {"end_case", XEND_CASE},
+ {"end_rule", XEND_RULE},
+ {"end_type", XEND_TYPE},
+ {"optional", XOPTIONAL},
+ {"criteria", XCRITERIA},
+ {"the_year", THE_YEAR},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_9[] = {
+ {"procedure", PROCEDURE}, /* P&E */
+ {"aggregate", XAGGREGATE},
+ {"end_alias", XEND_ALIAS},
+ {"end_local", XEND_LOCAL},
+ {"end_model", XEND_MODEL},
+ {"otherwise", XOTHERWISE},
+ {"reference", XREFERENCE},
+ {"supertype", XSUPERTYPE},
+ {"end_notes", XEND_NOTES},
+ {"objective", XOBJECTIVE},
+ {"parameter", XPARAMETER},
+ {"test_case", XTEST_CASE},
+ {"the_month", THE_MONTH},
+ {NULL, 0 },
+};
+
+RW_STRUCT rw_10[] = {
+ {"end_entity", XEND_ENTITY},
+ {"end_repeat", XEND_REPEAT},
+ {"end_schema", XEND_SCHEMA},
+ {"references", XREFERENCES},
+ {NULL, 0},
+};
+
+RW_STRUCT rw_11[] = {
+ {"end_context", XEND_CONTEXT},
+ {"enumeration", XENUMERATION},
+ {"end_purpose", XEND_PURPOSE},
+ {"realization", XREALIZATION},
+ {"schema_data", XSCHEMA_DATA},
+ {NULL, 0},
+};
+
+RW_STRUCT rw_12[] = {
+ {"end_constant", XEND_CONSTANT},
+ {"end_function", XEND_FUNCTION},
+ {"end_criteria", XEND_CRITERIA},
+ {NULL, 0},
+};
+
+RW_STRUCT rw_13[] = {
+ {"end_procedure", XEND_PROCEDURE},
+ {"end_objective", XEND_OBJECTIVE},
+ {"end_parameter", XEND_PARAMETER},
+ {"end_test_case", XEND_TEST_CASE},
+ {NULL, 0},
+};
+
+RW_STRUCT rw_14[] = {
+ {"end_references", XEND_REFERENCES},
+ {NULL, 0},
+};
+
+RW_STRUCT rw_15[] = {
+ {"end_realization", XEND_REALIZATION},
+ {"end_schema_data", XEND_SCHEMA_DATA},
+ {NULL, 0},
+};
+
+
+
+RW_STRUCT *rw_table[] = {
+ NULL, NULL, rw_2, rw_3, rw_4, rw_5, rw_6, rw_7, rw_8, rw_9,
+ rw_10, rw_11, rw_12, rw_13, rw_14, rw_15,
+};
+
+/* token lists */
+/* Tokens that start or follow a statement */
+TOKEN_CODE statement_start_list[] = {BEGIN, CASE, IF, REPEAT,
+ IDENTIFIER, XRETURN, XSKIP, XESCAPE, 0};
+TOKEN_CODE statement_end_list[] = {SEMICOLON, TO, ENDCODE, END_OF_FILE, 0};
+
+/* Tokens that start a declaration */
+TOKEN_CODE declaration_start_list[] = {XENTITY, TYPE, XRULE, XCONSTANT,
+ XLOCAL, PROCEDURE, FUNCTION,
+ 0};
+
+TOKEN_CODE follow_indexes_list[] = {OF, IDENTIFIER, ARRAY, XBAG, XLIST, SET,
+ XBINARY, XBOOLEAN, XINTEGER, XLOGICAL,
+ XNUMBER, XREAL, XSTRING, XGENERIC,
+ SEMICOLON, ENDCODE, END_OF_FILE, 0};
+
+/* Operator tokens */
+TOKEN_CODE rel_op_list[] = {LT, LE, EQUAL, NE, GE, GT, COLONEQUALCOLON,
+ COLONNEQCOLON, IN, XLIKE, 0};
+TOKEN_CODE add_op_list[] = {PLUS, MINUS, OR, XXOR, 0};
+TOKEN_CODE mult_op_list[] = {STAR, SLASH, DIV, MOD, AND, 0};
+
+TOKEN_CODE follow_header_list[] = {SEMICOLON, ENDCODE, END_OF_FILE, 0};
+
+TOKEN_CODE follow_proc_id_list[] = {LPAREN, SEMICOLON, ENDCODE, END_OF_FILE, 0};
+
+TOKEN_CODE follow_func_id_list[] = {LPAREN, COLON, SEMICOLON, END_OF_FILE, 0};
+
+/* Tokens that follow a formal parameter list */
+TOKEN_CODE follow_parms_list[] = {RPAREN, SEMICOLON, ENDCODE, END_OF_FILE, 0};
+/* Tokens that follow an actual parameter list */
+TOKEN_CODE follow_parm_list[] = {COMMA, RPAREN, 0};
+
+/* Tokens that can follow an expression */
+TOKEN_CODE follow_expr_list[] = {OF, SEMICOLON, ENDCODE, END_OF_FILE, 0};
+
+/* Tokens that can start or follow a case label */
+TOKEN_CODE case_label_start_list[] = {IDENTIFIER, NUMBER_LITERAL, PLUS, MINUS,
+ STRING_LITERAL, XOTHERWISE, 0};
+TOKEN_CODE follow_case_label_list[] = {COLON, SEMICOLON, 0};
+
+/* Tokens that follow declarations in SETUP code */
+TOKEN_CODE ltx2x_follow_decls_list[] = {SEMICOLON, BEGIN, CASE, IF, REPEAT,
+ IDENTIFIER, ENDCODE, 0};
+/* Tokens that follow declarations in procedures/functions */
+TOKEN_CODE follow_decls_list[] = {SEMICOLON, BEGIN, CASE, IF, REPEAT,
+ IDENTIFIER, XRETURN, XEND_FUNCTION,
+ XEND_PROCEDURE, ENDCODE, END_OF_FILE, 0};
+
+/* The tokens for simple types */
+TOKEN_CODE simple_type_list[] = {XBINARY, XBOOLEAN, XINTEGER, XLOGICAL,
+ XNUMBER, XREAL, XSTRING, XGENERIC, 0};
+
+/* the tokens of constants */
+TOKEN_CODE constant_list[] = {QUERY_CHAR, XCONST_E, XFALSE, XPI, XSELF, XTRUE,
+ XUNKNOWN, THE_DAY, THE_MONTH, THE_YEAR, 0};
+
+/* The tokens of aggregates */
+TOKEN_CODE aggregation_type_list[] = {ARRAY, SET, XAGGREGATE, XBAG, XLIST, 0};
+
+TOKEN_CODE follow_min_bound_list[] = {COLON, NUMBER_LITERAL, LPAREN, MINUS,
+ PLUS, 0};
+
+/* The tokens that can follow an entity's explicit attributes */
+TOKEN_CODE follow_attributes_list[] = {XDERIVE, XUNIQUE, XINVERSE, XWHERE,
+ XEND_ENTITY, 0};
+
+/* GLOBALS */
+
+/* char ch; */
+int ch;
+TOKEN_CODE token; /* code of current token */
+LITERAL literal; /* value of a literal */
+int buffer_offset; /* char offset into source buffer */
+int level = 0; /* current nesting level */
+int line_number = 0; /* current source line number */
+BOOLEAN print_flag = TRUE; /* TRUE to print source lines */
+BOOLEAN block_flag = FALSE; /* TRUE iff parsing a block */
+
+BOOLEAN in_comment = FALSE; /* TRUE iff in an EXPRESS comment */
+BOOLEAN in_eol_comment = FALSE; /* TRUE iff in an EXPRESS eol comment */
+int num_opencom = 0; /* # of open EXPRESS comment markers */
+
+char source_buffer[MAX_SOURCE_LINE_LENGTH]; /* source file buffer */
+char token_string[MAX_TOKEN_STRING_LENGTH]; /* token string */
+char word_string[MAX_TOKEN_STRING_LENGTH]; /* single-cased token string */
+char *bufferp = source_buffer; /* ptr to source buffer */
+char *tokenp = token_string; /* ptr to token string */
+
+int digit_count; /* total # of digits in number */
+BOOLEAN count_error; /* TRUE iff too many digits in number */
+
+/* int page_number = 0; current o/p page number */
+/* int line_count = MAX_LINES_PER_PAGE; # of lines on current o/p page */
+
+char source_name[MAX_FILE_NAME_LENGTH]; /* name of source file */
+char date[DATE_STRING_LENGTH]; /* current date and time */
+
+FILE *source_file;
+
+/* CHAR_CODE char_table[256]; ----------- add two to this */
+CHAR_CODE char_table[258]; /* ----------- added two to this */
+
+/* array of string representation of token codes */
+char *tok_code_strs[] = {
+#define sctc(a, b, c) b,
+#include "l2xisctc.h"
+#undef sctc
+};
+
+/* MACROS */
+
+/* char_code(ch) return the character code of ch */
+#define char_code(ch) char_table[ch]
+
+/* FORWARDS */
+
+/* init_tok_code_strs(); */
+
+/***************************************************************************/
+/* init_scanner(name) Initialise the scanner globals and open source */
+/* file. */
+
+/***************************************************************************/
+/* init_scanner(afil) Initialise the scanner globals and set the source */
+/* file. */
+
+init_scanner(afil)
+FILE *afil; /* source file */
+{
+ int ich;
+
+/*
+ * sprintf(dbuffer,"\n init_scanner called with name = %s\n", name);
+* debug_print(dbuffer);
+*/
+
+ /* initialise character table */
+ for (ich = 0; ich < 256; ++ich) char_table[ich] = SPECIAL;
+ for (ich = '0'; ich <= '9'; ++ich) char_table[ich] = DIGIT;
+ for (ich = 'A'; ich <= 'Z'; ++ich) char_table[ich] = LETTER;
+ for (ich = 'a'; ich <= 'z'; ++ich) char_table[ich] = LETTER;
+
+ char_table[QUOTE_CHAR] = QUOTE;
+ char_table[US_CHAR] = USCORE;
+ char_table[EOF_CHAR] = EOF_CODE;
+
+ source_file = afil;
+
+ /* get the first character */
+ bufferp = "";
+ get_char();
+
+ debug_print(" init_scanner: All done\n");
+ return;
+} /* end init_scanner */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* quit_scanner() no more scanning */
+
+quit_scanner()
+{
+/* close_source_file(); */
+} /* end quit_scanner */
+/***************************************************************************/
+
+
+/* CHARACTER ROUTINES */
+
+
+/***************************************************************************/
+/* get_char() set ch to next char from the source buffer */
+
+get_char()
+{
+ BOOLEAN get_source_line();
+
+
+ /* if current source line exhausted, get next line */
+ /* if file exhausted, set ch to EOF character and return */
+ if (*bufferp == EOS) {
+ if (!get_source_line()) {
+ ch = EOF_CHAR;
+ return;
+ }
+ bufferp = source_buffer;
+ buffer_offset = 0;
+ }
+
+ ch = *bufferp++;
+
+ /* special character processing */
+ /* tab --- up buffer offset to next multiple of TAB_SIZE, and replace */
+ /* ch with a blank */
+ /* newline -- replace ch with a blank */
+ /* { (start of comment) -- skip over comment and replace with a blank */
+ switch (ch) {
+ case '\t': {
+ buffer_offset += TAB_SIZE - buffer_offset%TAB_SIZE;
+ ch = ' ';
+ break;
+ }
+ case '\n': {
+ ++buffer_offset;
+ ch = ' ';
+ break;
+ }
+ case '-': { /* start of eol comment? */
+ if (*bufferp == '-') { /* yest, an eol comment */
+ skip_eol_comment();
+ ch = ' ';
+ }
+ else {
+ ++buffer_offset;
+ }
+ break;
+ }
+ case '(': { /* start of long comment? */
+ if (*bufferp == '*') { /* yes, a long comment */
+ skip_long_comment();
+ ch = ' ';
+ }
+ else {
+ ++buffer_offset;
+ }
+ break;
+ }
+ default: {
+ ++buffer_offset;
+ break;
+ }
+ } /* end switch */
+} /* end get_char */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* skip_comment() skip over a comment and set ch to 'end of comment' char */
+
+skip_comment()
+{
+ do {
+ get_char();
+ } while ((ch != '}') && (ch != EOF_CHAR));
+} /* end skip_coment */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* skip_eol_comment() skip over an EXPRESS eol comment */
+
+skip_eol_comment()
+{
+
+ /* skip to the next line */
+ if (!get_source_line()) {
+ ch = EOF_CHAR;
+ return;
+ }
+ bufferp = source_buffer;
+ buffer_offset = 0;
+ return;
+
+} /* end SKIP_EOL_COMMENT */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* skip_long_comment() skip over an EXPRESS long comment */
+
+skip_long_comment()
+{
+ BOOLEAN get_source_line();
+ num_opencom = 1;
+
+ /* update buffer pointers to the * after the ( */
+ *bufferp++;
+ ++buffer_offset;
+
+ while (num_opencom > 0) {
+ /* if current source line exhausted, get next line */
+ /* if file exhausted, set ch to EOF character and return */
+ if (*bufferp == EOS) {
+ if (!get_source_line()) {
+ ch = EOF_CHAR;
+ return;
+ }
+ bufferp = source_buffer;
+ buffer_offset = 0;
+ }
+
+ ch = *bufferp++;
+ switch (ch) {
+ case '(': { /* start of long comment? */
+ if (*bufferp == '*') { /* yes */
+ num_opencom++;
+ *bufferp++;
+ ++buffer_offset;
+ }
+ break;
+ }
+ case '*': { /* end of long comment? */
+ if (*bufferp == ')') { /* yes */
+ num_opencom--;
+ *bufferp++;
+ ++buffer_offset;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ } /* end switch */
+
+ ++buffer_offset;
+ } /* end while */
+
+ return;
+} /* end SKIP_LONG_COMMENT */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* skip_blanks skip past any blanks at current location in source */
+/* buffer and set ch to next non-blank char */
+
+skip_blanks()
+{
+ while (ch == ' ') get_char();
+} /* end skip_blanks */
+/***************************************************************************/
+
+
+/* TOKEN ROUTINES */
+ /* after a token has been extracted, ch is the first char after the token */
+
+/***************************************************************************/
+/* get_token extract next token from source buffer */
+
+get_token()
+{
+ entry_debug("get_token");
+ scan_source_debug();
+
+ skip_blanks();
+ tokenp = token_string;
+
+ switch (char_code(ch)) {
+ case LETTER: {
+ get_word();
+ break;
+ }
+ case DIGIT: {
+ get_number();
+ break;
+ }
+ case QUOTE: {
+ get_string();
+ break;
+ }
+ case EOF_CODE: {
+ token = END_OF_FILE;
+ break;
+ }
+ default: {
+ get_special();
+ break;
+ }
+ } /* end switch */
+
+ scan_token_debug();
+
+ /* for the interpeter: If parsing a block, crunch the token code */
+ /* and append it to the code buffer */
+ if (block_flag) crunch_token();
+
+ exit_debug("get_token");
+} /* end get_token */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_word extract a word, shift into single case. If not a reserved */
+/* set token to IDENTIFIER */
+/* for ltx2x, added underscore as an allowed word character */
+
+get_word()
+{
+ BOOLEAN is_reserved_word();
+ entry_debug("get_word");
+ scan_source_debug();
+
+ /* extract the word */
+ while ((char_code(ch) == LETTER) ||
+ (char_code(ch) == DIGIT) ||
+ (char_code(ch) == USCORE)) {
+ *tokenp++ = ch;
+ get_char();
+ }
+ *tokenp = EOS;
+ shift_word();
+
+ if (!is_reserved_word()) token = IDENTIFIER;
+
+ exit_debug("get_word");
+} /* end get_word */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* shift_word() copy a word token into word_string with all letters */
+/* in the same (lower? higher?) case */
+
+shift_word()
+{
+ int offset = 'a' - 'A'; /* offset to downshift a letter */
+ char *wp = word_string;
+ char *tp = token_string;
+
+ /* copy word into word_string, shifting as we go */
+ do {
+ *wp++ = (*tp >= 'A') && (*tp <= 'Z') /* check for wrong case letter */
+ ? *tp + offset /* shift and copy */
+ : *tp; /* or just copy */
+ ++tp;
+ } while (*tp != EOS);
+ *wp = EOS;
+
+} /* end shift_word */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_number extract a number token and set literal to its value. */
+/* set token to NUMBER_LITERAL */
+
+get_number()
+{
+ int whole_count = 0; /* # of digits in whole part */
+ int decimal_offset = 0; /* # of digits to move decimal */
+ char exponent_sign = '+';
+ int exponent = 0; /* value of exponent */
+ XPRSAREAL nvalue = 0.0; /* value of number */
+ XPRSAREAL evalue = 0.0; /* value of exponent */
+ BOOLEAN saw_dotdot = FALSE; /* TRUE if found .. */
+ entry_debug("get_number");
+
+ digit_count = 0;
+ count_error = FALSE;
+ token = NO_TOKEN;
+
+ literal.type = INTEGER_LIT;
+
+ /* extract the whole part of the number */
+ accumulate_value(&nvalue, INVALID_NUMBER);
+ if (token == ERROR) {
+ exit_debug("get_number");
+ return;
+ }
+ whole_count = digit_count;
+
+ /* if current char is a . then either start of fraction or .. */
+ if (ch == '.') {
+ get_char();
+ if (ch == '.') {
+ /* have a .. token, backup bufferp so that the token can be */
+ /* extracted next */
+ saw_dotdot = TRUE;
+ --bufferp;
+ }
+ else { /* start of a fraction */
+ literal.type = REAL_LIT;
+ *tokenp++ = '.';
+ /* accumulate fraction part */
+ accumulate_value(&nvalue, INVALID_FRACTION);
+ if (token == ERROR) return;
+ decimal_offset = whole_count - digit_count;
+ }
+ }
+
+ /* extract the exponent part, if any. None if seen a .. */
+ if (!saw_dotdot && ((ch == 'E') || (ch == 'e'))) {
+ literal.type = REAL_LIT;
+ *tokenp++ = ch;
+ get_char();
+
+ /* get sign, if any */
+ if ((ch == '+') || (ch == '-')) {
+ *tokenp++ = exponent_sign = ch;
+ get_char();
+ }
+ /* extract the exponent and accumulate into evalue */
+ accumulate_value(&evalue, INVALID_EXPONENT);
+ if (token == ERROR) return;
+ if (exponent_sign == '-') evalue = -evalue;
+ }
+
+ /* Too many digits? */
+ if (count_error) {
+ error(TOO_MANY_DIGITS);
+ token = ERROR;
+ exit_debug("get_number");
+ return;
+ }
+
+ /* adjust the number's value using decimal_offset and exponent */
+ exponent = evalue + decimal_offset;
+ if ((exponent + whole_count < -MAX_EXPONENT) ||
+ (exponent + whole_count > MAX_EXPONENT)) {
+ error(REAL_OUT_OF_RANGE);
+ token = ERROR;
+ exit_debug("get_number");
+ return;
+ }
+ if (exponent != 0) {
+ nvalue = nvalue*pow(10.0, (double) exponent);
+ }
+
+ /* set the literal's value */
+ if (literal.type == INTEGER_LIT) {
+ if ((nvalue < -MAX_INTEGER) ||
+ (nvalue > MAX_INTEGER)) {
+ error(INTEGER_OUT_OF_RANGE);
+ token = ERROR;
+ exit_debug("get_number");
+ return;
+ }
+ literal.value.integer = (XPRSAINT) nvalue;
+ }
+ else {
+ literal.value.real = nvalue;
+ }
+
+ *tokenp = EOS;
+ token = NUMBER_LITERAL;
+
+ exit_debug("get_number");
+
+} /* end get_number */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_string() Extract a string token. Set token to STRING_LITERAL. */
+/* Quotes are stored as part of token_string, but not */
+/* as part of literal.value.string */
+
+get_string()
+{
+ char *sp = literal.value.string;
+
+ *tokenp++ = QUOTE_CHAR;
+ get_char();
+
+ /* extract the string (two consecutive quotes represent a single quote) */
+ while (ch != EOF_CHAR) {
+ if (ch == QUOTE_CHAR) {
+ *tokenp++ = ch;
+ get_char();
+ if (ch != QUOTE_CHAR) break;
+ }
+ *tokenp++ = ch;
+ *sp++ = ch;
+ get_char();
+ }
+ *tokenp = EOS;
+ *sp = EOS;
+ token = STRING_LITERAL;
+ literal.type = STRING_LIT;
+
+ sprintf(dbuffer, "Scanned string: sp = %s, tokenp = %s\n",
+ literal.value.string, token_string);
+ debug_print(dbuffer);
+
+} /* end get_string */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_special() Extract a special token. Most are single chars, but some */
+/* are multiple. Set appropriate token value */
+
+get_special()
+{
+ *tokenp++ = ch;
+ switch (ch) {
+ case ')': token = RPAREN; get_char(); break;
+ case '+': token = PLUS; get_char(); break;
+ case '[': token = LBRACKET; get_char(); break;
+ case ']': token = RBRACKET; get_char(); break;
+ case ';': token = SEMICOLON; get_char(); break;
+ case ',': token = COMMA; get_char(); break;
+ case '.': token = PERIOD; get_char(); break;
+ case '/': token = SLASH; get_char(); break;
+ /* extra for EXPRESS */
+ case '{': token = LBRACE; get_char(); break;
+ case '}': token = RBRACE; get_char(); break;
+ case '?': token = QUERY_CHAR; get_char(); break;
+ case '%': token = PERCENT; get_char(); break;
+ case '\\': token = BACKSLASH; get_char(); break;
+ case '@': token = COMMERCIAL_AT; get_char(); break;
+ case '!': token = EXCLAMATION; get_char(); break;
+ case '"': token = DOUBLEQUOTE; get_char(); break;
+
+ case '*': { /* * (EXPRESS or ** or *) */
+ get_char();
+ if (ch == '*') {
+ *tokenp++ = '*';
+ token = STARSTAR;
+ get_char();
+ }
+ else if (ch == ')') {
+ *tokenp++ = ')';
+ token = STARPAREN;
+ get_char();
+ }
+ else {
+ token = STAR;
+ }
+ break;
+ }
+
+ case '-': { /* - (EXPRESS or -- or -> ) */
+ get_char();
+ if (ch == '-') {
+ *tokenp++ = '-';
+ token = MINUSMINUS;
+ get_char();
+ }
+ else if (ch == '>') {
+ *tokenp++ = '>';
+ token = MINUSGT;
+ get_char();
+ }
+ else {
+ token = MINUS;
+ }
+ break;
+ }
+
+ case '=': { /* = (EXPRESS == ) */
+ get_char();
+ if (ch == '=') {
+ *tokenp++ = '=';
+ token = EQUALEQUAL;
+ get_char();
+ }
+ else {
+ token = EQUAL;
+ }
+ break;
+ }
+
+
+ case ':': { /* : or := (EXPRESS or :=: or :<>: ) */
+ get_char();
+ if (ch == '=') {
+ *tokenp++ = '=';
+ token = COLONEQUAL;
+ get_char();
+ if (ch == ':') {
+ *tokenp++ = ':';
+ token = COLONEQUALCOLON;
+ get_char();
+ }
+ }
+ else if (ch == '<') {
+ get_char();
+ if (ch == '>') {
+ get_char();
+ if (ch == ':') {
+ *tokenp++ = '<';
+ *tokenp++ = '>';
+ *tokenp++ = ':';
+ token = COLONNEQCOLON;
+ get_token();
+ }
+ }
+ }
+ else {
+ token = COLON;
+ }
+ break;
+ }
+
+ case '<': { /* < or <= or <> (EXPRESS-I <- ) */
+ get_char();
+ if (ch == '=') {
+ *tokenp++ = '=';
+ token = LE;
+ get_char();
+ }
+ else if (ch == '>') {
+ *tokenp++ = '>';
+ token = NE;
+ get_char();
+ }
+ else if (ch == '-') {
+ *tokenp++ = '-';
+ token = LTMINUS;
+ get_char();
+ }
+ else {
+ token = LT;
+ }
+ break;
+ }
+
+ case '>': { /* > or >= */
+ get_char();
+ if (ch == '=') {
+ *tokenp++ = '=';
+ token = GE;
+ get_char();
+ }
+ else token = GT;
+ break;
+ }
+
+
+ case '(': { /* ( (EXPRESS (* ) */
+ get_char();
+ if (ch == '*') {
+ *tokenp++ = '*';
+ token = PARENSTAR;
+ get_char();
+ }
+ else {
+ token = LPAREN;
+ }
+ break;
+ }
+
+ case '|': { /* (EXPRESS | or || ) */
+ get_char();
+ if (ch == '|') {
+ *tokenp++ = '|';
+ token = BARBAR;
+ get_char();
+ }
+ else {
+ token = BAR;
+ }
+ break;
+ }
+
+
+ default: {
+ token = ERROR;
+ get_char();
+ break;
+ }
+
+ } /* end switch */
+ *tokenp = EOS;
+} /* end get_special */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* accumulate_value(valuep, error_code) Extract a number part (digits) */
+/* and accumulate its value. */
+/* Error if first char not a digit */
+
+accumulate_value(valuep, error_code)
+XPRSAREAL *valuep;
+ERROR_CODE error_code;
+{
+ XPRSAREAL value = *valuep;
+
+ /* error if first char not a digit */
+ if (char_code(ch) != DIGIT) {
+ error(error_code);
+ token = ERROR;
+ return;
+ }
+
+ /* accumulate the value, provided not too many digits */
+ do {
+ *tokenp++ = ch;
+ if (++digit_count <= MAX_DIGIT_COUNT) value = 10*value + (ch - '0');
+ else count_error = TRUE;
+ get_char();
+ } while (char_code(ch) == DIGIT); /* end do */
+ *valuep = value;
+
+
+} /* end accumulate_value */
+/***************************************************************************/
+
+
+/* TOKEN TESTERS */
+
+
+/***************************************************************************/
+/* token_in(token_list) If the current token is in token_list */
+/* return TRUE, else FALSE. */
+
+BOOLEAN token_in(token_list)
+TOKEN_CODE token_list[];
+{
+ TOKEN_CODE *atokenp;
+
+ if (token_list == NULL) return(FALSE);
+ for (atokenp = &token_list[0]; *atokenp; ++atokenp) {
+ if (token == *atokenp) return(TRUE);
+ }
+ return(FALSE);
+} /* end */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* synchronize(token_list1, token_list2, token_list3) If the current token */
+/* is not in any of the lists, flag it as an error. Then skip tokens */
+/* until one of those in the lists is found */
+
+synchronize(token_list1, token_list2, token_list3)
+TOKEN_CODE token_list1[], token_list2[], token_list3[];
+{
+ BOOLEAN error_flag = (!token_in(token_list1)) &&
+ (!token_in(token_list2)) &&
+ (!token_in(token_list3));
+
+ if (error_flag) {
+/* error(token == END_OF_FILE ? UNEXPECTED_END_OF_FILE
+* : UNEXPECTED_TOKEN);
+*/
+ if (token == END_OF_FILE) error(UNEXPECTED_END_OF_FILE);
+ else if (token == ENDCODE) error(UNEXPECTED_ENDCODE);
+ else error(UNEXPECTED_TOKEN);
+ /* skip tokens to synchronize */
+ while ((!token_in(token_list1)) &&
+ (!token_in(token_list2)) &&
+ (!token_in(token_list3)) &&
+ ((token != END_OF_FILE) || (token != ENDCODE))) {
+ get_token();
+ }
+ }
+} /* end synchronize */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* is_reserved_word() If token is a reserved word, set token and */
+/* return TRUE, else return FALSE */
+
+BOOLEAN is_reserved_word()
+{
+ int word_length = strlen(word_string);
+ RW_STRUCT *rwp;
+
+ /* is length in range? */
+ if ((word_length >= MIN_RESERVED_WORD_LENGTH) &&
+ (word_length <= MAX_RESERVED_WORD_LENGTH)) { /* check in approp. word list */
+ for (rwp = rw_table[word_length]; rwp->string != NULL; ++rwp) {
+ if (strcmp(word_string, rwp->string) == 0) {
+ token = rwp->token_code;
+ return(TRUE);
+ }
+ }
+ }
+ return(FALSE);
+} /* end is_reserved_word */
+/***************************************************************************/
+
+
+/* SOURCE FILE ROUTINES */
+
+
+/***************************************************************************/
+/* open_source_file(name) Open the named file and fetch the first char */
+
+open_source_file(name)
+char *name;
+{
+ if ((name == NULL) || ((source_file = fopen(name, "r")) == NULL)) {
+ error(FAILED_SOURCE_FILE_OPEN);
+ exit(-FAILED_SOURCE_FILE_OPEN);
+ }
+
+ /* get the first character */
+ bufferp = "";
+ get_char();
+} /* end open_source_file */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* close_source_file() */
+
+close_source_file()
+{
+ fclose(source_file);
+} /* end close_source_file */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_source_line() Read the next line from the source file. If there is */
+/* one, print it out and return TRUE. */
+/* return FALSE for end of file */
+
+BOOLEAN get_source_line()
+{
+ char print_buffer[MAX_SOURCE_LINE_LENGTH + 9];
+ entry_debug("get_source_line");
+
+ if ((fgets(source_buffer, MAX_SOURCE_LINE_LENGTH, source_file)) != NULL) {
+ ++line_number;
+
+ if (print_flag) {
+ sprintf(print_buffer, "%4d %d: %s", line_number, level, source_buffer);
+ print_line(print_buffer);
+ }
+ exit_debug("get_source_line");
+ return(TRUE);
+ }
+ exit_debug("get_source_line");
+ return(FALSE);
+} /* end get_source_line */
+/***************************************************************************/
+
+
+/* PRINTOUT ROUTINES */
+
+
+/***************************************************************************/
+/* print_line(line) Print out a line. */
+
+print_line(line)
+char line[];
+{
+ char save_ch;
+ char *save_chp = NULL;
+ entry_debug("print_line");
+
+ if (strlen(line) > MAX_PRINT_LINE_LENGTH) {
+ save_chp = &line[MAX_PRINT_LINE_LENGTH];
+ save_ch = *save_chp;
+ *save_chp = EOS;
+ }
+/* fprintf(filout, "%s", line); */
+ /* ltx2x change, print to stdout, not o/p file */
+/* printf("%s", line); just print to error file */
+ fprintf(ferr, "%s", line); /* PW addition -> error file */
+
+ if (save_chp) *save_chp = save_ch;
+
+ exit_debug("print_line");
+ return;
+} /* end print_line */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* tok_code_to_str(tok) Returns a string wrt a TOKEN_CODE */
+
+char *tok_code_to_str(tok)
+TOKEN_CODE tok;
+{
+
+ if ((tok >= NO_TOKEN) && (tok <= EOTC)) return(tok_code_strs[tok]);
+
+ return(NULL);
+
+} /* end tok_code_to_str */
+/***************************************************************************/
diff --git a/support/ltx2x/l2xiscan.h b/support/ltx2x/l2xiscan.h
new file mode 100644
index 0000000000..3b862b6e78
--- /dev/null
+++ b/support/ltx2x/l2xiscan.h
@@ -0,0 +1,36 @@
+/* l2xiscan.h for LTX2X interpreter scanner */
+
+#ifndef scanner_h
+#define scanner_h
+
+#include "l2xicmon.h"
+
+/* token codes */
+
+typedef enum {
+#define sctc(a, b, c) a,
+#include "l2xisctc.h"
+#undef sctc
+} TOKEN_CODE;
+
+
+/* literal structure */
+typedef enum {
+ INTEGER_LIT,
+ REAL_LIT,
+ STRING_LIT,
+} LITERAL_TYPE;
+
+typedef struct {
+ LITERAL_TYPE type;
+ union {
+ XPRSAINT integer;
+ XPRSAREAL real;
+ char string[MAX_SOURCE_LINE_LENGTH];
+ } value;
+} LITERAL;
+
+/* functions */
+BOOLEAN token_in();
+
+#endif
diff --git a/support/ltx2x/l2xisctc.h b/support/ltx2x/l2xisctc.h
new file mode 100644
index 0000000000..e2b66382ed
--- /dev/null
+++ b/support/ltx2x/l2xisctc.h
@@ -0,0 +1,174 @@
+/* l2xisctc.h token codes and strings, etc for interpreter scanner etc */
+
+/*
+ * a = code enumeration
+ * b = string version of code enumeration
+ * c = string forming the token itself
+ */
+
+sctc(NO_TOKEN, "NO_TOKEN", "<no token>")
+sctc(IDENTIFIER, "IDENTIFIER", "<IDENTIFIER>")
+sctc(NUMBER_LITERAL, "NUMBER_LITERAL", "<NUMBER_LITERAL>")
+sctc(STRING_LITERAL, "STRING_LITERAL", "<STRING_LITERAL>")
+sctc(STAR, "STAR", "*")
+sctc(LPAREN, "LPAREN", "(")
+sctc(RPAREN, "RPAREN", ")")
+sctc(MINUS, "MINUS", "-")
+sctc(PLUS, "PLUS", "+")
+sctc(EQUAL, "EQUAL", "=")
+sctc(LBRACKET, "LBRACKET", "[")
+sctc(RBRACKET, "RBRACKET", "]")
+sctc(COLON, "COLON", ":")
+sctc(SEMICOLON, "SEMICOLON", ";")
+sctc(LT, "LT", "<")
+sctc(GT, "GT", ">")
+sctc(COMMA, "COMMA", ",")
+sctc(PERIOD, "PERIOD", ".")
+sctc(SLASH, "SLASH", "/")
+sctc(COLONEQUAL, "COLONEQUAL", ":=")
+sctc(LE, "LE", "<=")
+sctc(GE, "GE", ">=")
+sctc(NE, "NE", "<>")
+sctc(END_OF_FILE, "END_OF_FILE", "<END_OF_FILE>")
+sctc(ERROR, "ERROR", "<ERROR>")
+sctc(AND, "AND", "AND")
+sctc(ARRAY, "ARRAY", "ARRAY")
+sctc(BEGIN, "BEGIN", "BEGIN")
+sctc(CASE, "CASE", "CASE")
+sctc(DIV, "DIV", "DIV")
+sctc(ELSE, "ELSE", "ELSE")
+sctc(END, "END", "END")
+sctc(FFILE, "FFILE", "FILE")
+sctc(FOR, "FOR", "FOR")
+sctc(FUNCTION, "FUNCTION", "FUNCTION")
+sctc(IF, "IF", "IF")
+sctc(IN, "IN", "IN")
+sctc(MOD, "MOD", "MOD")
+sctc(NOT, "NOT", "NOT")
+sctc(OF, "OF", "OF")
+sctc(OR, "OR", "OR")
+sctc(PROCEDURE, "PROCEDURE", "PROCEDURE")
+sctc(REPEAT, "REPEAT", "REPEAT")
+sctc(SET, "SET", "SET")
+sctc(THEN, "THEN", "THEN")
+sctc(TO, "TO", "TO")
+sctc(TYPE, "TYPE", "TYPE")
+sctc(UNTIL, "UNTIL", "UNTIL")
+sctc(VAR, "VAR", "VAR")
+sctc(WHILE, "WHILE", "WHILE")
+sctc(WITH, "WITH", "WITH")
+sctc(ENDCODE, "END_CODE", "END_CODE")
+sctc(END_OF_STATEMENTS, "END_OF_STATEMENTS", "<END_OF_STATEMENTS>")
+sctc(THE_DAY, "THE_DAY", "THE_DAY")
+sctc(THE_MONTH, "THE_MONTH", "THE_MONTH")
+sctc(THE_YEAR, "THE_YEAR", "THE_YEAR")
+sctc(BACKSLASH, "BACKSLASH", "\\")
+sctc(BAR, "BAR", "|")
+sctc(BARBAR, "BARBAR", "||")
+sctc(COLONEQUALCOLON, "COLONEQUALCOLON", ":=:")
+sctc(COLONNEQCOLON, "COLONNEQCOLON", ":<>:")
+sctc(COMMERCIAL_AT, "COMMERCIAL_AT", "@")
+sctc(DOUBLEQUOTE, "DOUBLEQUOTE", "\"")
+sctc(EQUALEQUAL, "EQUALEQUAL", "==")
+sctc(EXCLAMATION, "EXCLAMATION", "!")
+sctc(LBRACE, "LBRACE", "{")
+sctc(LTMINUS, "LTMINUS", "<-")
+sctc(MINUSGT, "MINUSGT", "->")
+sctc(MINUSMINUS, "MINUSMINUS", "--")
+sctc(PARENSTAR, "PARENSTAR", "(*")
+sctc(PERCENT, "PERCENT", "%")
+sctc(QUERY_CHAR, "QUERY_CHAR", "?")
+sctc(RBRACE, "RBRACE", "}")
+sctc(STARPAREN, "STARPAREN", "*)")
+sctc(STARSTAR, "STARSTAR", "**")
+sctc(XABSTRACT, "XABSTRACT", "ABSTRACT")
+sctc(XAGGREGATE, "XAGGREGATE", "AGGREGATE")
+sctc(XALIAS, "XALIAS", "ALIAS")
+sctc(XAS, "XAS", "AS")
+sctc(XBAG, "XBAG", "BAG")
+sctc(XBINARY, "XBINARY", "BINARY")
+sctc(XBOOLEAN, "XBOOLEAN", "BOOLEAN")
+sctc(XBY, "XBY", "BY")
+sctc(XCONSTANT, "XCONSTANT", "CONSTANT")
+sctc(XCONTEXT, "XCONTEXT", "CONTEXT")
+sctc(XDERIVE, "XDERIVE", "DERIVE")
+sctc(XEND_ALIAS, "XEND_ALIAS", "END_ALIAS")
+sctc(XEND_CASE, "XEND_CASE", "END_CASE")
+sctc(XEND_CONSTANT, "XEND_CONSTANT", "END_CONSTANT")
+sctc(XEND_CONTEXT, "XEND_CONTEXT", "END_CONTEXT")
+sctc(XEND_ENTITY, "XEND_ENTITY", "END_ENTITY")
+sctc(XEND_FUNCTION, "XEND_FUNCTION", "END_FUNCTION")
+sctc(XEND_IF, "XEND_IF", "END_IF")
+sctc(XEND_LOCAL, "XEND_LOCAL", "END_LOCAL")
+sctc(XEND_MODEL, "XEND_MODEL", "END_MODEL")
+sctc(XEND_PROCEDURE, "XEND_PROCEDURE", "END_PROCEDURE")
+sctc(XEND_REPEAT, "XEND_REPEAT", "END_REPEAT")
+sctc(XEND_RULE, "XEND_RULE", "END_RULE")
+sctc(XEND_SCHEMA, "XEND_SCHEMA", "END_SCHEMA")
+sctc(XEND_TYPE, "XEND_TYPE", "END_TYPE")
+sctc(XENTITY, "XENTITY", "ENTITY")
+sctc(XENUMERATION, "XENUMERATION", "ENUMERATION")
+sctc(XESCAPE, "XESCAPE", "ESCAPE")
+sctc(XFIXED, "XFIXED", "FIXED")
+sctc(XFROM, "XFROM", "FROM")
+sctc(XGENERIC, "XGENERIC", "GENERIC")
+sctc(XINTEGER, "XINTEGER", "INTEGER")
+sctc(XINVERSE, "XINVERSE", "INVERSE")
+sctc(XLIST, "XLIST", "LIST")
+sctc(XLOCAL, "XLOCAL", "LOCAL")
+sctc(XLOGICAL, "XLOGICAL", "LOGICAL")
+sctc(XMODEL, "XMODEL", "MODEL")
+sctc(XNUMBER, "XNUMBER", "NUMBER")
+sctc(XONEOF, "XONEOF", "ONEOF")
+sctc(XOPTIONAL, "XOPTIONAL", "OPTIONAL")
+sctc(XOTHERWISE, "XOTHERWISE", "OTHERWISE")
+sctc(XQUERY, "XQUERY", "QUERY")
+sctc(XREAL, "XREAL", "REAL")
+sctc(XREFERENCE, "XREFERENCE", "REFERENCE")
+sctc(XRETURN, "XRETURN", "RETURN")
+sctc(XRULE, "XRULE", "RULE")
+sctc(XSCHEMA, "XSCHEMA", "SCHEMA")
+sctc(XSELECT, "XSELECT", "SELECT")
+sctc(XSKIP, "XSKIP", "SKIP")
+sctc(XSTRING, "XSTRING", "STRING")
+sctc(XSUBTYPE, "XSUBTYPE", "SUBTYPE")
+sctc(XSUPERTYPE, "XSUPERTYPE", "SUPERTYPE")
+sctc(XUNIQUE, "XUNIQUE", "UNIQUE")
+sctc(XUSE, "XUSE", "USE")
+sctc(XWHERE, "XWHERE", "WHERE")
+sctc(XANDOR, "XANDOR", "ANDOR")
+sctc(XLIKE, "XLIKE", "LIKE")
+sctc(XXOR, "XXOR", "XOR")
+sctc(XSELF, "XSELF", "SELF")
+sctc(XCONST_E, "XCONST_E", "CONST_E")
+sctc(XPI, "XPI", "PI")
+sctc(XFALSE, "XFALSE", "FALSE")
+sctc(XTRUE, "XTRUE", "TRUE")
+sctc(XUNKNOWN, "XUNKNOWN", "UNKNOWN")
+sctc(XCALL, "XCALL", "CALL")
+sctc(XCRITERIA, "XCRITERIA", "CRITERIA")
+sctc(XEND_CALL, "XEND_CALL", "END_CALL")
+sctc(XEND_CRITERIA, "XEND_CRITERIA", "END_CRITERIA")
+sctc(XEND_NOTES, "XEND_NOTES", "END_NOTES")
+sctc(XEND_OBJECTIVE, "XEND_OBJECTIVE", "END_OBJECTIVE")
+sctc(XEND_PARAMETER, "XEND_PARAMETER", "END_PARAMETER")
+sctc(XEND_PURPOSE, "XEND_PURPOSE", "END_PURPOSE")
+sctc(XEND_REALIZATION, "XEND_REALIZATION", "END_REALIZATION")
+sctc(XEND_REFERENCES, "XEND_REFERENCES", "END_REFERENCES")
+sctc(XEND_SCHEMA_DATA, "XEND_SCHEMA_DATA", "END_SCHEMA_DATA")
+sctc(XEND_TEST_CASE, "XEND_TEST_CASE", "END_TEST_CASE")
+sctc(XIMPORT, "XIMPORT", "IMPORT")
+sctc(XNOTES, "XNOTES", "NOTES")
+sctc(XOBJECTIVE, "XOBJECTIVE", "OBJECTIVE")
+sctc(XPARAMETER, "XPARAMETER", "PARAMETER")
+sctc(XPURPOSE, "XPURPOSE", "PURPOSE")
+sctc(XREALIZATION, "XREALIZATION", "REALIZATION")
+sctc(XREFERENCES, "XREFERENCES", "REFERENCES")
+sctc(XSCHEMA_DATA, "XSCHEMA_DATA", "SCHEMA_DATA")
+sctc(XSUBOF, "XSUBOF", "SUBOF")
+sctc(XSUPOF, "XSUPOF", "SUPOF")
+sctc(XTEST_CASE, "XTEST_CASE", "TEST_CASE")
+sctc(XUSING, "XUSING", "USING")
+sctc(EOTC, "EOTC", "<EOTC>") /* this and the following must always be the last */
+sctc(STATEMENT_MARKER, "STATEMENT_MARKER", "<STATEMENT_MARKER>")
+sctc(ADDRESS_MARKER, "ADDRESS_MARKER", "<ADDRESS_MARKER>")
diff --git a/support/ltx2x/l2xisdcl.c b/support/ltx2x/l2xisdcl.c
new file mode 100644
index 0000000000..f4fff6ad1a
--- /dev/null
+++ b/support/ltx2x/l2xisdcl.c
@@ -0,0 +1,420 @@
+/* l2xisdcl.c LTX2X declaration analysis */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiidbg.h"
+
+/* EXTERNALS */
+
+extern int line_number;
+extern TOKEN_CODE token;
+
+/* GLOBALS */
+
+char buffer[MAX_PRINT_LINE_LENGTH];
+
+char *defn_names[] = {
+#define dfntc(a, b) b,
+#include "l2xidftc.h"
+#undef dfntc
+};
+
+
+char *form_names[] = {
+#define fotc(a, b, c, d) d,
+#define sotc(a, b, c, d)
+#define sftc(a, b, c, d) d,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+};
+
+
+
+/* ANALYSIS */
+
+
+/***************************************************************************/
+/* analyze_const_defn(idp) Analyze a constant definition */
+
+analyze_const_defn(idp)
+SYMTAB_NODE_PTR idp; /* constant id */
+{
+ char *bp;
+
+ if (DEBUG < Danalyze) return;
+
+ /* the name */
+ sprintf(buffer, ">> id = %s\n", idp->name);
+ debug_print(buffer);
+ sprintf(buffer, ">> address = %d\n", idp);
+
+ /* definition and value */
+ sprintf(buffer, ">> defn = %s, value = ", defn_names[idp->defn.key]);
+ bp = buffer + strlen(buffer);
+
+ if ((idp->typep == integer_typep) || (idp->typep->form == ENUM_FORM))
+ sprintf(bp, "%d\n", idp->defn.info.constant.value.integer);
+ else if (idp->typep == real_typep)
+ sprintf(bp, "%g\n", idp->defn.info.constant.value.real);
+ else if (idp->typep->form == ARRAY_FORM) /* ????????????????????????? */
+ sprintf(bp, "'%s'\n", idp->defn.info.constant.value.stringp);
+ else if (idp->typep->form == STRING_FORM)
+ sprintf(bp, "'%s'\n", idp->defn.info.constant.value.stringp);
+ debug_print(buffer);
+
+ /* and type. careful as an enum type will get into an infinite loop */
+ if (idp->typep->form != ENUM_FORM) analyze_type(idp->typep, FALSE);
+
+} /* end analyze_const_defn */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_type_defn(idp) Analyze a type definition */
+
+analyze_type_defn(idp)
+SYMTAB_NODE_PTR idp; /* id */
+{
+ char *bp;
+
+ if (DEBUG < Danalyze) return;
+
+ /* the type's name, definition ... */
+ sprintf(buffer, ">>id = %s\n", idp->name);
+ debug_print(buffer);
+ sprintf(buffer, ">> address = %d\n", idp);
+ debug_print(buffer);
+
+ sprintf(buffer, ">> defn = %s\n", defn_names[idp->defn.key]);
+/* print_line(buffer); */
+ debug_print(buffer);
+
+ /* and type */
+ analyze_type(idp->typep, TRUE);
+
+} /* end analyze_type_defn */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_type(tp, verbose_flag) Analyze a type definition */
+
+analyze_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ char *bp;
+
+ if (DEBUG < Danalyze) return;
+
+ if (tp == NULL) return;
+
+ /* the form, byte size (and name) */
+ sprintf(buffer, ">> form = %s, size = %d bytes, type id = ",
+ form_names[tp->form], tp->size);
+ bp = buffer + strlen(buffer);
+ if (tp->type_idp != NULL)
+ sprintf(bp, "%s\n", tp->type_idp->name);
+ else {
+ sprintf(bp, "<unnamed type>\n");
+ verbose_flag = TRUE;
+ }
+ debug_print(buffer);
+
+ /* do the appropriate analysus */
+ switch (tp->form) {
+ case ENUM_FORM: {
+ analyze_enum_type(tp, verbose_flag);
+ break;
+ }
+ case SUBRANGE_FORM: {
+ analyze_subrange_type(tp, verbose_flag);
+ break;
+ }
+ case ARRAY_FORM: {
+ analyze_array_type(tp, verbose_flag);
+ break;
+ }
+ case STRING_FORM: {
+ verbose_flag = TRUE;
+ analyze_string_type(tp, verbose_flag);
+ break;
+ }
+ case BOUND_FORM: {
+ analyze_bound_type(tp, verbose_flag);
+ break;
+ }
+ case ENTITY_FORM: {
+ analyze_entity_type(tp, verbose_flag);
+ break;
+ }
+ case BAG_FORM:
+ case LIST_FORM:
+ case SET_FORM: {
+ analyze_bls_type(tp, verbose_flag);
+ break;
+ }
+ default: {
+ break;
+ }
+ } /* end switch */
+
+} /* end analyze_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_enum_type(tp, verbose_flag) Analyze an enumeration type */
+
+analyze_enum_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ /* loop to analyze each enum constant as a constant defn */
+ debug_print(">> -- Enum Constants --\n");
+ for (idp = tp->info.enumeration.const_idp; idp != NULL; idp = idp->next) {
+ analyze_const_defn(idp);
+ }
+
+} /* end analyze_enum_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_subrange_type(tp, verbose_flag) Analyze a subrange type */
+
+analyze_subrange_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ sprintf(buffer, ">> min value = %d, max value = %d\n",
+ tp->info.subrange.min, tp->info.subrange.max);
+ debug_print(buffer);
+
+ debug_print(">> -- Range Type -- \n");
+ analyze_type(tp->info.subrange.range_typep, FALSE);
+
+} /* end analyze_subrange_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_bound_type(tp, verbose_flag) Analyze a bound type */
+
+analyze_bound_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ sprintf(buffer, ">> min value = %d, max value = %d\n",
+ tp->info.bound.min, tp->info.bound.max);
+ debug_print(buffer);
+
+ debug_print(">> -- Bound Type -- \n");
+ analyze_type(tp->info.bound.bound_typep, FALSE);
+
+} /* end analyze_bound_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_array_type(tp, verbose_flag) Analyze an array type */
+
+analyze_array_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ sprintf(buffer, ">> element count = %d\n",
+ tp->info.array.elmt_count);
+ debug_print(buffer);
+ sprintf(buffer, ">> index limits = %d to %d\n",
+ tp->info.array.min_index, tp->info.array.max_index);
+ debug_print(buffer);
+
+ debug_print(">> -- INDEX TYPE -- \n");
+ analyze_type(tp->info.array.index_typep, FALSE);
+
+ debug_print(">> -- ELEMENT TYPE -- \n");
+ analyze_type(tp->info.array.elmt_typep, FALSE);
+
+} /* end analyze_array_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_bls_type(tp, verbose_flag) Analyze a bag, etc type */
+
+analyze_bls_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ sprintf(buffer, ">> element count = %d\n",
+ tp->info.dynagg.elmt_count);
+ debug_print(buffer);
+ sprintf(buffer, ">> index limits = %d to %d\n",
+ tp->info.dynagg.min_index, tp->info.dynagg.max_index);
+ debug_print(buffer);
+
+ debug_print(">> -- INDEX TYPE -- \n");
+ analyze_type(tp->info.dynagg.index_typep, FALSE);
+
+ debug_print(">> -- ELEMENT TYPE -- \n");
+ analyze_type(tp->info.dynagg.elmt_typep, FALSE);
+
+} /* end analyze_bls_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_string_type(tp, verbose_flag) Analyze a string type */
+
+analyze_string_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ sprintf(buffer, ">> maximum length = %d\n",
+ tp->info.string.max_length);
+ debug_print(buffer);
+
+ sprintf(buffer, ">> length = %d\n",
+ tp->info.string.length);
+ debug_print(buffer);
+ return;
+
+} /* end analyze_string_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_entity_type(tp, verbose_flag) Analyze an entity type */
+
+analyze_entity_type(tp, verbose_flag)
+TYPE_STRUCT_PTR tp; /* pointer to type structure */
+BOOLEAN verbose_flag; /* TRUE for verbose analysis */
+{
+ SYMTAB_NODE_PTR idp; /* id */
+
+ if (DEBUG < Danalyze) return;
+
+ if (!verbose_flag) return;
+
+ /* loop to analyze each attribute as a variable decl */
+ debug_print(">> -- Attributes -- \n");
+ for (idp = tp->info.entity.attribute_symtab; idp != NULL; idp = idp->next) {
+ analyze_var_decl(idp);
+ }
+
+} /* end analyze_entity_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_var_decl(idp) Analyze a variable declaration */
+
+analyze_var_decl(idp)
+SYMTAB_NODE_PTR idp; /* id */
+{
+
+ if (DEBUG < Danalyze) return;
+
+ /* the name, definition and offset */
+ sprintf(buffer, ">> id = %s\n", idp->name);
+ debug_print(buffer);
+ sprintf(buffer, ">> address = %d\n", idp);
+ debug_print(buffer);
+
+ sprintf(buffer, ">> defn = %s, offset = %d\n",
+ defn_names[idp->defn.key], idp->defn.info.data.offset);
+/* print_line(buffer); */
+ debug_print(buffer);
+
+ /* and type */
+ analyze_type(idp->typep, FALSE);
+
+} /* end analyze_var_decl */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_block(code_segment) a dummy procedure */
+
+analyze_block(code_segment)
+char *code_segment;
+{
+ return;
+} /* end analyze_block */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* analyze_routine_header(rtn_idp) a dummy procedure */
+
+analyze_routine_header(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+
+{
+ return;
+} /* end analyze_routine_header */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xisftc.h b/support/ltx2x/l2xisftc.h
new file mode 100644
index 0000000000..95e7471cc5
--- /dev/null
+++ b/support/ltx2x/l2xisftc.h
@@ -0,0 +1,24 @@
+/* l2xisftc.h Interpreter stack and form codes */
+
+/* fotc = FORM only *
+/* sotc = STACK only */
+/* sftc = STACK and FORM correspond */
+
+/* STACK string FORM string */
+
+sftc(STKNOF, "", NO_FORM, "no form")
+sotc(STKADD, "address", NO_FORM, "")
+sftc(STKARY, "array", ARRAY_FORM, "array")
+sftc(STKBAG, "bag", BAG_FORM, "bag")
+fotc(STKNOF, "", BOUND_FORM, "bound")
+sftc(STKENT, "entity", ENTITY_FORM, "entity")
+fotc(STKINT, "integer", ENUM_FORM, "enumeration")
+sotc(STKINT, "integer", SCALAR_FORM, "scalar")
+sftc(STKLST, "list", LIST_FORM, "list")
+sotc(STKLOG, "logical", ENUM_FORM, "enumeration")
+sotc(STKREA, "real", SCALAR_FORM, "scalar")
+fotc(STKNOF, "", SCALAR_FORM, "scalar")
+sftc(STKSET, "set", SET_FORM, "set")
+sftc(STKSTR, "string", STRING_FORM, "string")
+fotc(STKNOF, "", SUBRANGE_FORM, "subrange")
+sotc(STKUDF, "indeterminate", NO_FORM, "")
diff --git a/support/ltx2x/l2xistd.c b/support/ltx2x/l2xistd.c
new file mode 100644
index 0000000000..49c3dbc9cb
--- /dev/null
+++ b/support/ltx2x/l2xistd.c
@@ -0,0 +1,667 @@
+/* l2xistd.c LTX2X interpreter Parsing for calls to standard functions */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+
+
+#define DEFAULT_NUMERIC_FIELD_WIDTH 10
+#define DEFAULT_PRECISION 2
+
+/* EXTERNALS */
+
+extern TOKEN_CODE token;
+extern char word_string[];
+extern SYMTAB_NODE_PTR symtab_display[];
+extern int level;
+extern TOKEN_CODE follow_parm_list[];
+extern TOKEN_CODE statement_end_list[];
+
+/* FORWARDS */
+
+TYPE_STRUCT_PTR eof_eoln(), abs_sqr(), arctan_cos_exp_ln_sin_sqrt(),
+ pred_succ(), odd(), ord(), round_trunc();
+TYPE_STRUCT_PTR atan(), exists_etc(), nvl_etc();
+TYPE_STRUCT_PTR rexpr_etc(), hibound_etc(), length_etc();
+
+/***************************************************************************/
+/* standard_routine_call (rtn_idp) Process call to standard function */
+/* return pointer to type structure of the call */
+
+TYPE_STRUCT_PTR standard_routine_call(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+
+ switch (rtn_idp->defn.info.routine.key) {
+ case READ:
+ case READLN: {
+ read_readln(rtn_idp);
+ return(NULL);
+ }
+ case WRITE:
+ case WRITELN: {
+ write_writeln(rtn_idp);
+ return(NULL);
+ }
+ case EOFF:
+ case EOLN: {
+ return(eof_eoln(rtn_idp));
+ }
+ case ABS: /* real or int arg -> real or int */
+ {
+ return(abs_sqr());
+ }
+ case COS: /* real or int arg -> real */
+ case EXP:
+ case SIN:
+ case SQRT:
+ case XACOS:
+ case XASIN:
+ case XLOG:
+ case XLOG2:
+ case XLOG10:
+ case XTAN: {
+ return(arctan_cos_exp_ln_sin_sqrt());
+ }
+ case XATAN: {
+ return(atan());
+ }
+ case ODD: { /* int arg -> boolean */
+ return(odd());
+ }
+ case ROUND: /* real arg -> int */
+ case TRUNC: {
+ return(round_trunc());
+ }
+ case L2XPRINT:
+ case L2XPRINTLN: { /* extra for ltx2x */
+ print_println(rtn_idp);
+ return(NULL);
+ }
+ case L2XSYSTEM: { /* extra for ltx2x */
+ system_etc(rtn_idp);
+ return(NULL);
+ }
+ case L2XREXPR: { /* extra for ltx2x two strings -> boolean */
+ return(rexpr_etc());
+ }
+ case XEXISTS: { /* any arg -> boolean */
+ return(exists_etc());
+ }
+ case XNVL: { /* two args -> one of these */
+ return(nvl_etc());
+ }
+ case XHIBOUND: /* agg arg -> int */
+ case XHIINDEX:
+ case XLOBOUND:
+ case XLOINDEX:
+ case XSIZEOF: {
+ return(hibound_etc());
+ }
+ case XLENGTH: { /* string arg -> int */
+ return(length_etc());
+ }
+ case XINSERT:
+ case XREMOVE: {
+ insert_etc(rtn_idp);
+ return(NULL);
+ }
+ case XBLENGTH: /* unimplemented EXPRESS functions */
+ case XFORMAT:
+ case XROLESOF:
+ case XTYPEOF:
+ case XUSEDIN:
+ case XVALUE:
+ case XVALUE_IN:
+ case XVALUE_UNIQUE: {
+ error(UNIMPLEMENTED_FEATURE);
+ return(NULL);
+ }
+ default : { /* should not be here */
+ error(UNEXPECTED_TOKEN);
+ return(NULL);
+ }
+ } /* end switch */
+} /* end standard_routine_call */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* read_readln(rtn_idp) Process call to read or readln */
+
+read_readln(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual param type */
+
+ /* parameters are optional for readln */
+ if (token == LPAREN) {
+ do {
+ get_token();
+ /* actuals should be variables, but parse anyway */
+ if (token == IDENTIFIER) {
+ SYMTAB_NODE_PTR idp;
+ search_and_find_all_symtab(idp);
+ actual_parm_tp = base_type(variable(idp, VARPARM_USE));
+/* if (actual_parm_tp->form != SCALAR_FORM) error(INCOMPATIBLE_TYPES); */
+ if (actual_parm_tp != integer_typep &&
+ actual_parm_tp != real_typep &&
+ actual_parm_tp != logical_typep &&
+ actual_parm_tp != string_typep) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ }
+ else {
+ actual_parm_tp = expression();
+ error(INVALID_VAR_PARM);
+ }
+ /* sync. Should be , or ) */
+ synchronize(follow_parm_list, statement_end_list, NULL);
+ } while (token == COMMA); /* end do */
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ } /* end if */
+ else {
+ if (rtn_idp->defn.info.routine.key == READ) error(WRONG_NUMBER_OF_PARMS);
+ }
+
+} /* end read_readln */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* write_writeln(rtn_idp) Process call to write or writeln */
+/* Each actual parameter can be: */
+/* <expr> or */
+/* <expr> : <expr> or */
+/* <expr> : <expr> : <expr> */
+
+write_writeln(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */
+ TYPE_STRUCT_PTR field_width_tp, precision_tp;
+
+ /* params are optional for writeln */
+ if (token == LPAREN) {
+ do {
+ get_token();
+ actual_parm_tp = base_type(expression());
+
+ if ((actual_parm_tp->form != SCALAR_FORM) &&
+ (actual_parm_tp != logical_typep) &&
+ (actual_parm_tp->form != STRING_FORM) &&
+ (actual_parm_tp->form != ENUM_FORM))
+ error(INVALID_EXPRESSION);
+
+ /* optional field width expression */
+ if (token == COLON) {
+ get_token();
+ field_width_tp = base_type(expression());
+ if (field_width_tp != integer_typep) error(INCOMPATIBLE_TYPES);
+
+ /* optional precision spec */
+ if (token == COLON) {
+ get_token();
+ precision_tp = base_type(expression());
+ if (precision_tp != integer_typep) error(INCOMPATIBLE_TYPES);
+
+ } /* end colon if */
+ } /* end colon if */
+ /* sync. Should be , or ) */
+ synchronize(follow_parm_list, statement_end_list, NULL);
+ } while (token == COMMA); /* end do */
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ } /* end if */
+ else {
+ if (rtn_idp->defn.info.routine.key == WRITE) error(WRONG_NUMBER_OF_PARMS);
+ }
+
+} /* end write_writeln */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* print_println(rtn_idp) Process call to print or println */
+/* Each actual parameter can be: */
+/* <expr> or */
+/* <expr> : <expr> or */
+/* <expr> : <expr> : <expr> */
+/* At this point, identical to write_writeln */
+
+print_println(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */
+ TYPE_STRUCT_PTR field_width_tp, precision_tp;
+
+ /* params are optional for println */
+ if (token == LPAREN) {
+ do {
+ get_token();
+ actual_parm_tp = base_type(expression());
+
+ if ((actual_parm_tp->form != SCALAR_FORM) &&
+ (actual_parm_tp != logical_typep) &&
+ (actual_parm_tp->form != STRING_FORM) &&
+ (actual_parm_tp->form != ENUM_FORM))
+ error(INVALID_EXPRESSION);
+
+ /* optional field width expression */
+ if (token == COLON) {
+ get_token();
+ field_width_tp = base_type(expression());
+ if (field_width_tp != integer_typep) error(INCOMPATIBLE_TYPES);
+
+ /* optional precision spec */
+ if (token == COLON) {
+ get_token();
+ precision_tp = base_type(expression());
+ if (precision_tp != integer_typep) error(INCOMPATIBLE_TYPES);
+
+ } /* end colon if */
+ } /* end colon if */
+ /* sync. Should be , or ) */
+ synchronize(follow_parm_list, statement_end_list, NULL);
+ } while (token == COMMA); /* end do */
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ } /* end if */
+ else {
+ if (rtn_idp->defn.info.routine.key == WRITE) error(WRONG_NUMBER_OF_PARMS);
+ }
+
+} /* end print_println */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* eof_eoln(rtn_idp) Process call to eof or eoln. No parameters. */
+/* return boolean result. */
+
+TYPE_STRUCT_PTR eof_eoln(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ TYPE_STRUCT_PTR result_tp = logical_typep;
+
+ if (token == LPAREN) {
+ error(WRONG_NUMBER_OF_PARMS);
+ actual_parm_list(rtn_idp, FALSE);
+ }
+ return(result_tp);
+} /* end eof_eoln */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* system_etc() Process call to system, etc */
+/* fun('string') */
+/* One string parameter, no return value */
+/* at entry, token is `fun' */
+/* at exit, token is after closing ) */
+
+system_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */
+
+ if (token == LPAREN) {
+ get_token();
+ actual_parm_tp = base_type(expression());
+ if (actual_parm_tp != string_typep &&
+ (actual_parm_tp->form != STRING_FORM)) {
+ error(INVALID_EXPRESSION);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else {
+ error(WRONG_NUMBER_OF_PARMS);
+ }
+
+ return;
+} /* end SYSTEM_ETC */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* length_etc() Process call to length, etc */
+/* fun('string') */
+/* One string parameter, integer return value */
+/* at entry, token is `fun' */
+/* at exit, token is after closing ) */
+
+TYPE_STRUCT_PTR length_etc()
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */
+ TYPE_STRUCT_PTR result_tp = integer_typep; /* result type */
+ if (token == LPAREN) {
+ get_token();
+ actual_parm_tp = base_type(expression());
+ if (actual_parm_tp != string_typep &&
+ (actual_parm_tp->form != STRING_FORM)) {
+ error(INVALID_EXPRESSION);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else {
+ error(WRONG_NUMBER_OF_PARMS);
+ }
+
+ return(result_tp);
+} /* end LENGTH_ETC */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* hibound_etc() Process call to hibound, etc */
+/* fun(agg) */
+/* One aggregate parameter, integer return value */
+/* at entry, token is `fun' */
+/* at exit, token is after closing ) */
+
+TYPE_STRUCT_PTR hibound_etc()
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */
+ TYPE_STRUCT_PTR result_tp = integer_typep; /* result type */
+ if (token == LPAREN) {
+ get_token();
+ actual_parm_tp = base_type(expression());
+ if ((actual_parm_tp->form != ARRAY_FORM) &&
+ (actual_parm_tp->form != BAG_FORM) &&
+ (actual_parm_tp->form != LIST_FORM) &&
+ (actual_parm_tp->form != SET_FORM) ) {
+ error(INVALID_EXPRESSION);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else {
+ error(WRONG_NUMBER_OF_PARMS);
+ }
+
+ return(result_tp);
+} /* end HIBOUND_ETC */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* rexpr_etc() Process call to rexpr, etc */
+/* fun('string', 'string') */
+/* Two string parameters, boolean return value */
+/* at entry, token is `fun' */
+/* at exit, token is after closing ) */
+
+TYPE_STRUCT_PTR rexpr_etc()
+{
+ TYPE_STRUCT_PTR actual_parm_tp; /* actual parm type */
+ TYPE_STRUCT_PTR result_tp = logical_typep; /* result type */
+
+ if (token == LPAREN) {
+ get_token();
+ actual_parm_tp = base_type(expression());
+ if (actual_parm_tp != string_typep &&
+ actual_parm_tp->form != STRING_FORM) {
+ error(INVALID_EXPRESSION);
+ }
+ if_token_get_else_error(COMMA, MISSING_COMMA);
+ actual_parm_tp = base_type(expression());
+ if (actual_parm_tp != string_typep &&
+ actual_parm_tp->form != STRING_FORM) {
+ error(INVALID_EXPRESSION);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else {
+ error(WRONG_NUMBER_OF_PARMS);
+ }
+
+ return(result_tp);
+} /* end REXPR_ETC */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exists_etc Process call to exists, etc */
+/* fun(any) -> boolean */
+/* any type parm -> boolean result */
+
+TYPE_STRUCT_PTR exists_etc()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp = logical_typep; /* result type */
+
+ if (token == LPAREN) {
+ get_token();
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(result_tp);
+} /* end EXISTS_ETC */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* nvl_etc Process NVL, etc */
+/* fun(p1, p2) -> p1 or p2 */
+/* Two args, any type, returns one of them */
+
+TYPE_STRUCT_PTR nvl_etc()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+
+ if_token_get_else_error(COMMA, MISSING_COMMA);
+ /* PERHAPS SHOULD CHECK FOR ASSIGNMENT COMPATIBILITY */
+/*
+* if (parm_tp != base_type(expression()) ) {
+* error(INCOMPATIBLE_TYPES);
+* }
+*/
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(parm_tp);
+} /* end NVL_ETC */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* abs_sqr Process call to abs or sqr. */
+/* integer parm -> integer result */
+/* real parm -> real result */
+
+TYPE_STRUCT_PTR abs_sqr()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp; /* result type */
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+
+ if ((parm_tp != integer_typep) && (parm_tp != real_typep)) {
+ error(INCOMPATIBLE_TYPES);
+ result_tp = real_typep;
+ }
+ else result_tp = parm_tp;
+
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(result_tp);
+} /* end abs_sqr */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* arctan_cos_exp_ln_sin_sqrt Process call to these */
+/* integer parm -> real result */
+/* real parm -> real result */
+
+TYPE_STRUCT_PTR arctan_cos_exp_ln_sin_sqrt()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+
+ if ((parm_tp != integer_typep) && (parm_tp != real_typep)) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(real_typep);
+} /* end arctan_cos_exp_ln_sin_sqrt */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* atan Process call to these */
+/* fun(p1, p2) */
+/* integer parm -> real result */
+/* real parm -> real result */
+
+TYPE_STRUCT_PTR atan()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+
+ if ((parm_tp != integer_typep) && (parm_tp != real_typep)) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ if_token_get_else_error(COMMA, MISSING_COMMA);
+ parm_tp = base_type(expression());
+ if ((parm_tp != integer_typep) && (parm_tp != real_typep)) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(real_typep);
+} /* end ATAN */
+/***************************************************************************/
+
+
+
+
+
+/***************************************************************************/
+/* odd Process call to odd. */
+/* integer parm -> boolean result */
+
+TYPE_STRUCT_PTR odd()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp = logical_typep;
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+
+ if (parm_tp != integer_typep) {
+ error(INCOMPATIBLE_TYPES);
+ }
+
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(logical_typep);
+} /* end odd */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* round_trunc Process call to round or trunc. */
+/* real parm -> integer result */
+
+TYPE_STRUCT_PTR round_trunc()
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+
+ if (parm_tp != real_typep) {
+ error(INCOMPATIBLE_TYPES);
+ }
+
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+ return(integer_typep);
+} /* end round_trunc */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* insert_etc Process a call to INSERT, etc */
+/* list procedures */
+/* INSERT(LIST, GENERIC, INTEGER) */
+/* REMOVE(LIST, INTEGER) */
+
+insert_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual parm type */
+
+ if (token == LPAREN) {
+ get_token();
+ parm_tp = base_type(expression());
+ if (parm_tp->form != LIST_FORM) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ if_token_get_else_error(COMMA, MISSING_COMMA);
+ if (rtn_idp->defn.info.routine.key == XINSERT) {
+ expression();
+ if_token_get_else_error(COMMA, MISSING_COMMA);
+ }
+ parm_tp = base_type(expression());
+ if (parm_tp != integer_typep) {
+ error(INCOMPATIBLE_TYPES);
+ }
+ if_token_get_else_error(RPAREN, MISSING_RPAREN);
+ }
+ else error(WRONG_NUMBER_OF_PARMS);
+
+} /* end INSERT_ETC */
+/***************************************************************************/
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xistmt.c b/support/ltx2x/l2xistmt.c
new file mode 100644
index 0000000000..b71d39de9e
--- /dev/null
+++ b/support/ltx2x/l2xistmt.c
@@ -0,0 +1,719 @@
+/* l2xistmt.c LTX2X interpreter parsing routines for statements */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiexec.h"
+#include "l2xiidbg.h"
+
+#ifndef l2xicpr_h
+#include "l2xicpr.h" /* extern token code lists */
+#endif
+
+
+/* EXTERNALS */
+
+extern TOKEN_CODE token;
+extern char token_string[];
+extern char word_string[];
+extern LITERAL literal;
+extern SYMTAB_NODE_PTR symtab_display[];
+extern int level;
+extern ICT *code_bufferp;
+extern SYMTAB_NODE_PTR true_idp, false_idp, unknown_idp;
+
+/* FORWARDS */
+
+TOKEN_CODE case_branch();
+
+/***************************************************************************/
+/* statement() Call routines to process a statement, depending on the */
+/* the first token of the statement. */
+/* at entry, token is one of statement_start_list */
+/* at exit, token is the closing (e.g., ; or END_ ) */
+
+statement()
+{
+ entry_debug("statement");
+
+ if (token != BEGIN) crunch_statement_marker();
+
+ /* call the proper routine from the first token */
+ switch (token) {
+ case IDENTIFIER: {
+ SYMTAB_NODE_PTR idp;
+ /* assignment or procedure call ? */
+ search_and_find_all_symtab(idp);
+ if (idp->defn.key == PROC_DEFN ||
+ idp->defn.key == FUNC_DEFN) {
+ crunch_symtab_node_ptr(idp);
+ get_token();
+ routine_call(idp, TRUE);
+ }
+ else assignment_statement(idp);
+ break;
+ }
+ case REPEAT: {
+ grepeat_statement();
+ break;
+ }
+ case IF: {
+ if_statement();
+ break;
+ }
+ case CASE: {
+ case_statement();
+ break;
+ }
+ case BEGIN: {
+ compound_statement();
+ break;
+ }
+ case XRETURN: {
+ return_statement();
+ break;
+ }
+ case XSKIP: {
+ skip_statement();
+ break;
+ }
+ case XESCAPE: {
+ escape_statement();
+ break;
+ }
+ } /* end switch */
+
+ /* sync. Only a semicolon, END, ELSE or UNTIL can follow a statement */
+ /* check for mssing semicolon */
+ synchronize(statement_end_list, statement_start_list, NULL);
+ if (token_in(statement_start_list)) error(MISSING_SEMICOLON);
+
+ exit_debug("statement");
+ return;
+} /* end statement */
+/***************************************************************************/
+
+
+TOKEN_CODE end_funproc_list[] = {XEND_FUNCTION, XEND_PROCEDURE, 0};
+
+/***************************************************************************/
+/* return_statement() Process EXPRESS return statement */
+/* RETURN [ '(' <expression> ')' ] ';' */
+/* at entry, token is RETURN */
+/* at exit, token is ; or END_FUNPROC */
+
+return_statement()
+{
+ entry_debug("return_statement");
+
+ get_token();
+ switch (token) {
+ case SEMICOLON : {
+ exit_debug("return_statement");
+ return;
+ }
+ case LPAREN : {
+ expression();
+ exit_debug("return_statement");
+ return;
+ }
+ default : {
+ synchronize(end_funproc_list, NULL, NULL);
+ exit_debug("return_statement");
+ return;
+ }
+
+ } /* end switch */
+
+} /* end RETURN_STATEMENT */
+/***************************************************************************/
+
+
+
+
+
+/***************************************************************************/
+/* assignment_statement(var_idp) Process an assignment statement */
+/* <id> := <expr> */
+
+assignment_statement(var_idp)
+SYMTAB_NODE_PTR var_idp; /* target variable id */
+{
+ TYPE_STRUCT_PTR var_tp, expr_tp; /* types of var and expression */
+ entry_debug("assignment_statement");
+
+ var_tp = variable(var_idp, TARGET_USE);
+ if_token_get_else_error(COLONEQUAL, MISSING_COLONEQUAL);
+
+ expr_tp = expression();
+
+ if (!is_assign_type_compatible(var_tp, expr_tp)) {
+ error(INCOMPATIBLE_ASSIGNMENT);
+ }
+
+ exit_debug("assignment_statement");
+ return;
+} /* end assignment_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* grepeat_statement() Process a REPEAT statement */
+/* REPEAT [ <inc_control> ] [ <while_control> ] [ <until_control> ] ; */
+/* <stmt-list> END_REPEAT */
+/* at entry: token is REPEAT */
+/* at exit: token is after END_REPEAT; */
+
+grepeat_statement()
+{
+ TYPE_STRUCT_PTR expr_tp;
+ ADDRESS loop_end_location;
+ entry_debug("grepeat_statement");
+
+ get_token();
+ loop_end_location = crunch_address_marker(NULL); /* place holder */
+
+ /* controls */
+ if (token == IDENTIFIER) { /* increment control */
+ inc_control();
+ }
+ while_control();
+ until_control();
+ if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON);
+
+ /* the list of statements */
+ do {
+ statement();
+ while (token == SEMICOLON) get_token();
+ } while (token_in(statement_start_list));
+
+/* if_token_get_else_error(SEMICOLON, MISSING_SEMICOLON); */
+ if_token_get_else_error(XEND_REPEAT, MISSING_END_REPEAT);
+
+ /* finally set the address marker for after the END_REPEAT */
+ fixup_address_marker(loop_end_location);
+
+ exit_debug("grepeat_statement");
+ return;
+} /* end GREPEAT_STATEMENT */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* inc_control() Process an increment control */
+/* var := <expr> TO <expr> [ BY <expr> ] */
+/* at entry: token is var */
+/* at exit: token is after <expr> */
+
+inc_control()
+{
+ SYMTAB_NODE_PTR by_np;
+ SYMTAB_NODE_PTR for_idp;
+ TYPE_STRUCT_PTR for_tp, expr_tp, by_tp;
+ TOKEN_CODE save_tok;
+ entry_debug("inc_control (l2xistmt.c)");
+
+ /* fake a FOR */
+ save_tok = token;
+ change_crunched_token(FOR);
+ crunch_extra_token(save_tok);
+
+ search_and_find_all_symtab(for_idp);
+ crunch_symtab_node_ptr(for_idp);
+ if ((for_idp->level != level) || (for_idp->defn.key != VAR_DEFN)) {
+ error(INVALID_INCREMENT_CONTROL);
+ }
+
+ for_tp = base_type(for_idp->typep);
+ get_token();
+
+ if ((for_tp != integer_typep) ) {
+ error(INCOMPATIBLE_TYPES);
+ }
+
+ if_token_get_else_error(COLONEQUAL, MISSING_COLONEQUAL);
+
+ expr_tp = expression();
+ if (!is_assign_type_compatible(for_tp, expr_tp)) {
+ error(INCOMPATIBLE_TYPES);
+ }
+
+ if (token == TO) {
+ get_token();
+ }
+ else {
+ error(MISSING_TO);
+ }
+
+ expr_tp = expression();
+ if (!is_assign_type_compatible(for_tp, expr_tp)) {
+ error(INCOMPATIBLE_TYPES);
+ }
+
+ if (token == XBY) { /* BY <expr> */
+ get_token();
+ expr_tp = expression();
+ if (!is_assign_type_compatible(for_tp, expr_tp)) {
+ error(INCOMPATIBLE_TYPES);
+ get_token();
+ }
+ }
+ else { /* fake a BY */
+ save_tok = token;
+ change_crunched_token(XBY);
+ crunch_extra_token(NUMBER_LITERAL);
+ by_np = search_symtab("1", symtab_display[1]);
+ if (by_np == NULL) {
+ by_np = enter_symtab("1", symtab_display[1]);
+ }
+ by_tp = integer_typep;
+ by_np->defn.info.constant.value.integer = 1;
+ crunch_symtab_node_ptr(by_np);
+ crunch_extra_token(save_tok);
+ }
+
+ exit_debug("inc_control");
+} /* end INC_CONTROL */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* while_control() Process a WHILE control */
+/* WHILE <expr> */
+/* at entry: token may be WHILE */
+/* at exit: token is after <expr> */
+
+while_control()
+{
+ TYPE_STRUCT_PTR expr_tp;
+ TOKEN_CODE save_tok;
+ entry_debug("while_control (l2xistmt.c)");
+
+ if (token != WHILE) { /* fake a WHILE */
+ save_tok = token;
+ change_crunched_token(WHILE);
+ crunch_extra_token(IDENTIFIER);
+ crunch_symtab_node_ptr(true_idp);
+ crunch_extra_token(save_tok);
+ exit_debug("while_control");
+ return;
+ }
+
+ get_token();
+
+ expr_tp = expression();
+ if (expr_tp != logical_typep) error(INCOMPATIBLE_TYPES);
+
+ exit_debug("while_control");
+ return;
+} /* end WHILE_CONTROL */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* until_control() Process an UNTIL control */
+/* UNTIL <expr> */
+/* at entry: token may be UNTIL */
+/* at exit: token is after <expr> */
+
+until_control()
+{
+ TYPE_STRUCT_PTR expr_tp;
+ TOKEN_CODE save_tok;
+ entry_debug("until_control (l2xistmt.c)");
+
+ if (token != UNTIL) { /* fake an UNTIL */
+ save_tok = token;
+ change_crunched_token(UNTIL);
+ crunch_extra_token(IDENTIFIER);
+ crunch_symtab_node_ptr(false_idp);
+ crunch_extra_token(save_tok);
+ exit_debug("until_control");
+ return;
+ }
+
+ get_token();
+
+ expr_tp = expression();
+ if (expr_tp != logical_typep) error(INCOMPATIBLE_TYPES);
+
+
+ exit_debug("until_control");
+ return;
+} /* end UNTIL_CONTROL */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* if_statement() Process an IF statement */
+/* IF <expr> THEN <stmt> END_IF or */
+/* IF <expr> THEN <stmt> ELSE <stmt> END_IF */
+
+if_statement()
+{
+ TYPE_STRUCT_PTR expr_tp;
+ ADDRESS if_end_location;
+ ADDRESS false_location;
+ entry_debug("if_statement");
+
+ get_token();
+ false_location = crunch_address_marker(NULL);
+
+ expr_tp = expression();
+ if (expr_tp != logical_typep) error(INCOMPATIBLE_TYPES);
+
+ if_token_get_else_error(THEN, MISSING_THEN);
+ statements();
+ fixup_address_marker(false_location);
+
+ /* the ELSE branch */
+ if (token == ELSE) {
+ get_token();
+ if_end_location = crunch_address_marker(NULL);
+
+ statements();
+
+ fixup_address_marker(if_end_location);
+ }
+ if_token_get_else_error(XEND_IF, MISSING_END_IF);
+
+ exit_debug("if_statement");
+ return;
+} /* end if_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* case_statement() Process a CASE statement */
+/* CASE <expr> OF */
+/* <case-branch> */
+/* END_CASE */
+/* CASE globals */
+
+typedef struct case_item {
+ int label_value;
+ ADDRESS branch_location;
+ struct case_item *next;
+} CASE_ITEM, *CASE_ITEM_PTR;
+
+CASE_ITEM_PTR case_item_head, case_item_tail;
+int case_label_count;
+
+case_statement()
+{
+ BOOLEAN another_branch;
+ TYPE_STRUCT_PTR expr_tp;
+ TYPE_STRUCT_PTR case_label();
+ CASE_ITEM_PTR case_itemp, next_case_itemp;
+ ICT *branch_table_location;
+ ICT *case_end_chain = NULL;
+ TOKEN_CODE save_tok;
+ entry_debug("case_statement");
+
+ /* initialisations for the branch table */
+ get_token();
+ branch_table_location = crunch_address_marker(NULL);
+ case_item_head = case_item_tail = NULL;
+ case_label_count = 0;
+
+
+ expr_tp = expression();
+ if (((expr_tp->form != SCALAR_FORM) &&
+ (expr_tp->form != ENUM_FORM) &&
+ (expr_tp->form != SUBRANGE_FORM)) ||
+ (expr_tp == real_typep)) error(INCOMPATIBLE_TYPES);
+
+ /* sync. Should be OF */
+ synchronize(follow_expr_list, case_label_start_list, NULL);
+ if_token_get_else_error(OF, MISSING_OF);
+
+ /* loop to process CASE branches */
+ another_branch = token_in(case_label_start_list);
+ while (another_branch) {
+ if (token_in(case_label_start_list)) case_branch(expr_tp);
+ /* link another address marker at the end of the branch to point to */
+ /* the end of the CASE statement */
+ case_end_chain = crunch_address_marker(case_end_chain);
+
+ if (token == SEMICOLON) {
+ get_token();
+ another_branch = TRUE;
+ }
+ else if (token_in(case_label_start_list)) {
+/* error(MISSING_SEMICOLON); */
+ another_branch = TRUE;
+ }
+ else another_branch = FALSE;
+ } /* end while */
+
+ debug_print("case_statement: finished case branches\n");
+
+ /* emit the branch table */
+ fixup_address_marker(branch_table_location);
+ crunch_integer(case_label_count);
+ case_itemp = case_item_head;
+ debug_print("case_statement: starting loop over case_itemp\n");
+ while (case_itemp != NULL) {
+ crunch_integer(case_itemp->label_value);
+ crunch_offset(case_itemp->branch_location);
+ next_case_itemp = case_itemp->next;
+ free(case_itemp);
+ case_itemp = next_case_itemp;
+ }
+
+ debug_print("case_statement: finished loop over case_itemp\n");
+
+ if_token_get_else_error(XEND_CASE, MISSING_END_CASE);
+
+ /* fix up the branch address markers */
+ while (case_end_chain != NULL) {
+ sprintf(dbuffer, "case statement: case_end_chain = %d\n", case_end_chain);
+ debug_print(dbuffer);
+ case_end_chain = fixup_address_marker(case_end_chain);
+ }
+
+
+ exit_debug("case_statement");
+ return;
+} /* end case_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* case_branch(expr_tp) Process a CASE branch */
+/* <case-label-list> : <stmt> */
+
+TOKEN_CODE case_branch(expr_tp)
+TYPE_STRUCT_PTR expr_tp; /* type of CASE expression */
+{
+ BOOLEAN another_label;
+ TYPE_STRUCT_PTR label_tp;
+ CASE_ITEM_PTR case_itemp;
+ CASE_ITEM_PTR old_case_item_tail = case_item_tail;
+ TYPE_STRUCT_PTR case_label();
+ TOKEN_CODE save_tok;
+ entry_debug("case_branch");
+
+ /* process <case-label-list> */
+ do {
+ label_tp = case_label();
+ if (expr_tp != label_tp && label_tp != any_typep) error(INCOMPATIBLE_TYPES);
+
+ get_token();
+ if (token == COMMA) {
+ get_token();
+ if (token_in(case_label_start_list)) another_label = TRUE;
+ else {
+ error(MISSING_CONSTANT);
+ another_label = FALSE;
+ }
+ }
+ else another_label = FALSE;
+ } while (another_label); /* end do over case label list */
+
+ /* sync Sholud be : */
+ synchronize(follow_case_label_list, statement_start_list, NULL);
+ if_token_get_else_error(COLON, MISSING_COLON);
+
+ /* loop to fill in the branch location field of each item for this branch */
+ case_itemp = old_case_item_tail == NULL
+ ? case_item_head
+ : old_case_item_tail->next;
+ while (case_itemp != NULL) {
+ case_itemp->branch_location = code_bufferp;
+ case_itemp = case_itemp->next;
+ }
+
+
+ statement();
+ /* make a `fake' compound statement to enable multiple */
+ /* statements for a particular case */
+/*
+* save_tok = token;
+* change_crunched_token(BEGIN);
+* crunch_extra_token(save_tok);
+* statements();
+* save_tok = token;
+* change_crunched_token(END);
+* crunch_extra_token(SEMICOLON);
+* crunch_extra_token(save_tok);
+*/
+
+ exit_debug("case_branch");
+ return(save_tok);
+} /* end case_branch */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* case_label() Process a case label */
+/* return a pointer to its type structure */
+
+TYPE_STRUCT_PTR case_label()
+{
+ TOKEN_CODE sign = PLUS; /* unary + or - */
+ BOOLEAN saw_sign = FALSE; /* TRUE iff unary sign */
+ TYPE_STRUCT_PTR label_tp;
+ CASE_ITEM_PTR case_itemp = alloc_struct(CASE_ITEM);
+ entry_debug("case_label");
+
+ /* link in case item for this label */
+ if (case_item_head != NULL) {
+ case_item_tail->next = case_itemp;
+ case_item_tail = case_itemp;
+ }
+ else {
+ case_item_head = case_item_tail = case_itemp;
+ }
+ case_itemp->next = NULL;
+ ++case_label_count;
+
+
+ /* unary + or - */
+ if ((token == PLUS) || (token == MINUS)) {
+ sign = token;
+ saw_sign = TRUE;
+ get_token();
+ }
+
+ /* numeric constant --- integer only */
+ if (token == NUMBER_LITERAL) {
+ SYMTAB_NODE_PTR np = search_symtab(token_string, symtab_display[1]);
+ if (np == NULL) np = enter_symtab(token_string, symtab_display[1]);
+ crunch_symtab_node_ptr(np);
+
+ if (literal.type == INTEGER_LIT)
+ case_itemp->label_value = sign == PLUS
+ ? literal.value.integer
+ : -literal.value.integer;
+ else error(INVALID_CONSTANT);
+ exit_debug("case_label");
+ return(integer_typep);
+ }
+
+ else if (token == XOTHERWISE) { /* default --- any type */
+ case_itemp->label_value = XOTHERWISE;
+ exit_debug("case_label");
+ return(any_typep);
+ }
+
+ /* id constant: int, char, or enum only */
+ else if (token == IDENTIFIER) {
+ SYMTAB_NODE_PTR idp;
+
+ search_all_symtab(idp);
+ crunch_symtab_node_ptr(idp);
+
+ if (idp == NULL) {
+ error(UNDEFINED_IDENTIFIER);
+ exit_debug("case_label");
+ return(&dummy_type);
+ }
+ else if (idp->defn.key != CONST_DEFN) {
+ error(NOT_A_CONSTANT_IDENTIFIER);
+ exit_debug("case_label");
+ return(&dummy_type);
+ }
+ else if (idp->typep == integer_typep) {
+ case_itemp->label_value = sign = PLUS
+ ? idp->defn.info.constant.value.integer
+ : -idp->defn.info.constant.value.integer;
+
+ exit_debug("case_label");
+ return(integer_typep);
+ }
+ else if (idp->typep->form == ENUM_FORM) {
+ if (saw_sign) error(INVALID_CONSTANT);
+ case_itemp->label_value = idp->defn.info.constant.value.integer;
+ exit_debug("case_label");
+ return(idp->typep);
+ }
+ else {
+ exit_debug("case_label");
+ return(&dummy_type);
+ }
+ }
+
+ else {
+ error(INVALID_CONSTANT);
+ exit_debug("case_label");
+ return(&dummy_type);
+ }
+
+} /* end case_label */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* compound_statement() Process a compound statement */
+/* BEGIN <stmt-list> END */
+
+compound_statement()
+{
+ entry_debug("compound_statement");
+
+ get_token();
+ do {
+ statement();
+ while (token == SEMICOLON) get_token();
+ if (token == END) break;
+ /* sync. Should be at the start of next statement */
+ synchronize(statement_start_list, NULL, NULL);
+ } while (token_in(statement_start_list));
+ if_token_get_else_error(END, MISSING_END);
+
+ exit_debug("compound_statement");
+ return;
+} /* end compound_statement */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* skip_statement() Process a SKIP statement */
+/* SKIP; */
+/* at entry: token is SKIP */
+/* at exit: token is after SKIP */
+
+skip_statement()
+{
+ entry_debug("skip_statement (l2xistmt.c)");
+
+ get_token();
+
+ exit_debug("skip_statement");
+} /* end SKIP_STATEMENT */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* escape_statement() Process a ESCAPE statement */
+/* ESCAPE; */
+/* at entry: token is ESCAPE */
+/* at exit: token is after ESCAPE */
+
+escape_statement()
+{
+ entry_debug("escape_statement (l2xistmt.c)");
+
+ get_token();
+
+ exit_debug("escape_statement");
+} /* end ESCAPE_STATEMENT */
+/***************************************************************************/
+
+
diff --git a/support/ltx2x/l2xistup.c b/support/ltx2x/l2xistup.c
new file mode 100644
index 0000000000..53c7f94fa0
--- /dev/null
+++ b/support/ltx2x/l2xistup.c
@@ -0,0 +1,477 @@
+/* l2xistup LTX2X interpreter initialisation and start up code */
+
+#include <stdio.h>
+#include "getopt.h"
+#include "l2xicmon.h"
+#include "l2xisymt.h"
+#include "l2xiexec.h"
+#include "l2xierr.h" /* need this for MISSING_ENDCODE */
+#include "l2xiscan.h" /* need this for SEMICOLON, etc */
+#include "l2xiprse.h" /* need this for if_token_get_else_error */
+
+#include "l2xiidbg.h"
+
+#ifndef l2xicpr_h
+#include "l2xicpr.h" /* the before/after token lists */
+#endif
+
+
+/* EXTERNALS */
+
+/* extern int exec_line_number; */
+/* extern char word_string[]; */
+/* extern SYMTAB_NODE_PTR symtab_display[]; */
+/* extern int level; */
+
+extern TYPE_STRUCT_PTR integer_typep, real_typep,
+ boolean_typep;
+extern int exec_stmt_count;
+extern STACK_ITEM *stack;
+/* extern SYMTAB_NODE_PTR program(); */
+extern SYMTAB_NODE_PTR create_dummy_prog();
+
+extern int DEBUG; /* defined in l2xlib.c */
+extern int cl_debug; /* defined in l2xlib.c */
+extern int cdebug; /* defined in l2xlib.c */
+extern int edebug; /* defined in l2xlib.c */
+
+extern BOOLEAN executed_return; /* TRUE iff return statement executed */
+
+/* GLOBALS */
+
+char THE_TITLE[] = "THE INTERPRETER";
+char INT_FILE_VERSION[] = "Version 0.1";
+char INT_FILE_DATE[] = "January 1997";
+
+/* int DEBUG = 0; debugging level */
+int Dbasic = 1; /* DEBUG >= Dbasic -> basic debugging */
+int Danalyze = 2; /* DEBUG >= Danalyze -> declaration analysis debugging */
+int Dtrace = 3; /* DEBUG >= Dtrace -> trace routine call tree */
+int Dscan = 4; /* DEBUG >= Dscan -> source buffer debugging */
+int Dtraceall = 5; /* DEBUG >= Dtraceall -> */
+int Dott = 100; /* Hopefully, too high for all debugging */
+extern int SLD_OFF; /* FALSE to enable source level debugger */
+
+ICT *code_buffer; /* code buffer */
+ICT *code_bufferp; /* code buffer ptr */
+
+FILE *ferr; /* error o/p */
+FILE *fcodeseg; /* code segment o/p */
+FILE *filout; /* output file */
+
+ /* EXTERNALS */
+extern ICT *create_code_segment();
+extern TYPE_STRUCT dummy_type;
+extern TOKEN_CODE statement_start_list[];
+extern TOKEN_CODE token;
+extern TOKEN_CODE ctoken;
+extern ICT *code_segmentp;
+extern FILE *source_file; /* file the scanner reads */
+extern FILE *yyout; /* output file for LTX2X */
+extern int get_ct_linenum(); /* gets current ct line number */
+extern void set_ct_linenum(); /* sets current ct line number */
+extern int line_number; /* interp scanners line number */
+extern FILE *filerr; /* LTX2X's error file */
+
+
+ /* FORWARDS */
+/* SYMTAB_NODE_PTR create_dummy_prog(); */
+void start_code();
+
+
+/***************************************************************************/
+/* code_setup(filtabin) Initialise the scanner, etc then */
+/* call the start_code routine to do the work. */
+
+SYMTAB_NODE_PTR code_setup(filtabin)
+FILE *filtabin; /* input file */
+{
+ char optchar;
+ int n, k;
+ SYMTAB_NODE_PTR program_idp;
+/* BOOLEAN cdebug = TRUE; if TRUE enable source Code debug */
+/* BOOLEAN edebug = TRUE; if TRUE enable Execution debug */
+
+ /* print the banner */
+/*
+* fprintf(stdout, "\n %s", THE_TITLE);
+* fprintf(stdout, "\n (%s, %s)\n", INT_FILE_VERSION, INT_FILE_DATE);
+*/
+
+ /* open output log files */
+/* ferr = fopen("interp.err", "w"); */
+ ferr = filerr; /* set error file to be ltx2x's */
+ fcodeseg = fopen("interp.csg", "w");
+
+/* fprintf(stdout, "\nLog file is interp.err\n"); */
+ fprintf(stdout, "Code segment log file is interp.csg\n");
+
+ fprintf(ferr, "Error log file for %s (%s, %s)\n",
+ THE_TITLE, INT_FILE_VERSION, INT_FILE_DATE);
+ fprintf(ferr, "Author: Peter Wilson (Catholic University and NIST)\n");
+ fprintf(ferr, "Email any comments or suggestions to: pwilson@cme.nist.gov\n\n");
+ fprintf(ferr, "Code segment log file is interp.csg\n\n");
+
+ /* set the output file */
+ filout = yyout;
+
+
+ /* set debug level for source Code */
+ if (cdebug) {
+ DEBUG = cl_debug;
+ }
+ else {
+ DEBUG = 0;
+ }
+
+
+
+ /* initialise the scanner */
+/* init_scanner(argv[k]); */
+ line_number = get_ct_linenum(); /* set scanner's line number counter */
+ init_scanner(filtabin);
+
+ /* initialise code buffer */
+ code_buffer = alloc_array(ICT, MAX_CODE_BUFFER_SIZE);
+ code_bufferp = code_buffer;
+ if (DEBUG >= Dbasic) {
+ sprintf(dbuffer, "Initialised: code_buffer = %d, code_bufferp = %d\n",
+ code_buffer, code_bufferp);
+ debug_print(dbuffer);
+ }
+
+ /* initialise the symbol table */
+ init_symtab();
+ if (DEBUG >= Dbasic) {
+ sprintf(dbuffer, "Initialised the symbol table\n");
+ debug_print(dbuffer);
+ }
+
+ /* create an artificial program node */
+ program_idp = create_dummy_prog();
+
+ /* parse the remainder of the code */
+ /* zero or more declarations, followed by zero or more statements */
+ start_code(program_idp);
+
+ /* Don't think we want this as everyting from now on is in prog scope */
+/* program_idp->defn.info.routine.local_symtab = exit_scope(); */
+ program_idp->defn.info.routine.code_segment = create_code_segment();
+ analyze_block(program_idp->defn.info.routine.code_segment);
+
+ /* reset CT line number to the scanner's value */
+ set_ct_linenum(line_number);
+ return(program_idp);
+
+
+
+ /* free the stack */
+/*
+ free(stack);
+ fprintf(filout, "\n\nCompleted. %ld statements executed. \n\n",
+ exec_stmt_count);
+
+ if (DEBUG >= Dbasic) {
+ sprintf(dbuffer, "\n\n***That's all for run4\n\n");
+ debug_print(dbuffer);
+ }
+ return(program_idp);
+*/
+} /* end CODE_SETUP */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* SYMTAB_NODE_PTR create_dummy_prog() create an artifical program node */
+/* much of this code comes from `program_header' */
+
+SYMTAB_NODE_PTR old_create_dummy_prog()
+{
+
+ SYMTAB_NODE_PTR prog_idp;
+
+ prog_idp = alloc_struct(SYMTAB_NODE);
+ /* use dummy program name */
+/* strcpy(word_string, "_PrOgRaM"); */
+/* search_and_enter_local_symtab(prog_idp); */
+ prog_idp->defn.key = PROG_DEFN;
+ prog_idp->defn.info.routine.key = DECLARED;
+ prog_idp->defn.info.routine.parm_count = 0;
+ prog_idp->defn.info.routine.total_parm_size = 0;
+ prog_idp->defn.info.routine.total_local_size = 0;
+ prog_idp->typep = &dummy_type;
+ prog_idp->label_index = 0;
+
+ enter_scope(NULL);
+
+ prog_idp->defn.info.routine.locals = NULL;
+ prog_idp->defn.info.routine.parms = NULL;
+
+ return(prog_idp);
+} /* end CREATE_DUMMY_PROG */
+/***************************************************************************/
+
+
+TOKEN_CODE ltx2x_start_declarations_list[] = {XCONSTANT, XLOCAL, PROCEDURE,
+ FUNCTION, 0};
+
+/***************************************************************************/
+/* start_code(rtn_idp) Parse the starting code, which consists of */
+/* declarations, followed by zero or more statements */
+/* ends at token ENDCODE */
+/* ( similar to block in interp ) */
+
+void start_code(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* id of `program' or routine */
+{
+
+ extern BOOLEAN block_flag;
+
+ get_token();
+ if (token == ENDCODE) {
+ crunch_token();
+ crunch_statement_marker();
+ return;
+ }
+
+ if (token_in(declaration_start_list)) {
+ declarations(rtn_idp);
+ /* error synchronization: Should be ; */
+ synchronize(ltx2x_follow_decls_list, NULL, NULL);
+ }
+ else {
+ skip_declarations(rtn_idp);
+ }
+
+ if (token == ENDCODE) {
+ crunch_token();
+ crunch_statement_marker();
+ return;
+ }
+
+/* if (token == BEGIN) {
+* crunch_token();
+* }
+*/
+
+ block_flag = TRUE;
+
+ /* now for possibly empty list of statements */
+ statement_block();
+/* if (token_in(statement_start_list)) {
+* crunch_token();
+* statements();
+* }
+*/
+ block_flag = FALSE;
+
+ return;
+
+} /* end START_CODE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* statements() process a set of statements */
+/* originally based on `compound_statement' */
+/* at entry, token is (crunched) start of a statement */
+/* at exit, token is after closing ; of a statement */
+
+statements()
+{
+
+ entry_debug("statements");
+/* get_token(); */
+
+ while (token_in(statement_start_list)) {
+ statement();
+ get_token();
+ }
+
+ exit_debug("statements");
+ return;
+
+} /* end STATEMENTS */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* statement_block() Process a list of statements ended by END_CODE */
+/* at entry, token is start of a statement or ENDCODE */
+/* at exit, parsing is complete */
+
+statement_block()
+{
+ entry_debug("statement_block");
+
+ if (token_in(statement_start_list)) {
+ crunch_token();
+ statements();
+ }
+
+ if (token != ENDCODE) {
+ error(MISSING_ENDCODE);
+ }
+ else {
+ crunch_statement_marker();
+/* crunch_token(); */
+ }
+
+ exit_debug("statement_block");
+ return;
+} /* end STATEMENT_BLOCK */
+/***************************************************************************/
+
+
+
+
+
+/***************************************************************************/
+/* code_action(filtabin) Parsing for CODE: */
+/* */
+
+ICT *code_action(filtabin)
+FILE *filtabin; /* the input file */
+{
+ extern BOOLEAN block_flag;
+ entry_debug("code_action");
+
+ /* set the file and the line number for the scanner */
+ source_file = filtabin;
+ line_number = get_ct_linenum();
+
+ get_token();
+
+ if (token == ENDCODE) {
+ crunch_token();
+ crunch_statement_marker();
+ exit_debug("code_action at ENDCODE");
+ return(create_code_segment());
+ }
+
+/* if (token == BEGIN) {
+* crunch_token();
+* }
+*/
+
+ block_flag = TRUE;
+
+ /* now for possibly empty list of statements */
+
+ statement_block();
+/* if (token_in(statement_start_list)) {
+* crunch_token();
+* statements();
+* }
+*/
+ block_flag = FALSE;
+
+ /* reset the CT line number to the scanner's value */
+ set_ct_linenum(line_number);
+
+ /* store results in a new code segment, and return it */
+
+ exit_debug("code_action");
+ return(create_code_segment());
+
+} /* end CODE_ACTION */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_startup(prog_idp) Execute the start up code */
+/* based on `program' */
+
+exec_startup(prog_idp)
+SYMTAB_NODE_PTR prog_idp; /* program id */
+{
+ entry_debug("exec_startup");
+
+
+ /* set debug level for Execution */
+ if (edebug) {
+ DEBUG = cl_debug;
+ }
+ else {
+ DEBUG = 0;
+ }
+
+ /* Execute the program */
+ /* allocate runtime stack and initialise program's stack frame */
+ init_stack();
+ /* initialise the debugger */
+ init_debugger();
+
+ /* allocate locals and point to the code */
+ routine_entry(prog_idp);
+
+ /* DO IT */
+ get_ctoken();
+ while (ctoken != ENDCODE) exec_statement();
+
+ exit_debug("exec_startup");
+ return;
+} /* end EXEC_STARTUP */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_statements(code_seg) Execute set of statements */
+/* based on `execute' and `routine_entry' */
+
+exec_statements(code_seg)
+ICT *code_seg; /* the code */
+{
+ entry_debug("exec_statements");
+ if (code_seg == NULL) return;
+
+ /* switch to new code segment */
+ code_segmentp = code_seg;
+
+ get_ctoken();
+ while (ctoken != ENDCODE) exec_statement();
+
+ exit_debug("exec_statements");
+ return;
+} /* end EXEC_STATEMENTS */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_algorithm() Execute the body of an algorithm */
+/* This is a rewrite of Pascal execute() in l2xixutl.c */
+/* call this from exec_declared_routine_call() in l2xixstm.c */
+/* (FUNCTION, PROCEDURE ) */
+/* last token is END_OF_STATEMENTS */
+
+exec_algorithm(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* ponter to the routine */
+{
+ entry_debug("exec_algorithm");
+ executed_return = FALSE;
+
+ routine_entry(rtn_idp);
+
+ get_ctoken();
+ while (ctoken != END_OF_STATEMENTS && !executed_return) exec_statement();
+
+ routine_exit(rtn_idp);
+
+ exit_debug("exec_algorithm");
+ return;
+} /* end EXEC_ALGORITHM */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+
+
+
+
diff --git a/support/ltx2x/l2xisymt.c b/support/ltx2x/l2xisymt.c
new file mode 100644
index 0000000000..2c69f735fe
--- /dev/null
+++ b/support/ltx2x/l2xisymt.c
@@ -0,0 +1,416 @@
+/* l2xisymt.c LTX2X interpreter symbol table code */
+/* BASED ON: symtab.c (common names altered) */
+/* added PRINT and PRINTLN to init_symtab */
+
+#include <stdio.h>
+#include <time.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xisymt.h"
+#include "l2xiidbg.h"
+#include "l2xiexec.h"
+
+
+/* EXTERNALS */
+
+extern int level;
+
+extern int DEBUG;
+
+/* GLOBALS */
+
+SYMTAB_NODE_PTR symtab_display[MAX_NESTING_LEVEL];
+
+TYPE_STRUCT_PTR integer_typep, real_typep, /* predefined types */
+ boolean_typep;
+TYPE_STRUCT_PTR logical_typep, string_typep,
+ binary_typep, generic_typep,
+ any_typep;
+
+SYMTAB_NODE_PTR false_idp, true_idp, unknown_idp; /* logical constants */
+SYMTAB_NODE_PTR conste_idp, pi_idp; /* real constants */
+SYMTAB_NODE_PTR undef_idp; /* `?' constant */
+SYMTAB_NODE_PTR day_idp, month_idp, year_idp;
+
+SYMTAB_NODE_PTR string_idp;
+
+TYPE_STRUCT dummy_type = { /* for bad type defs */
+ NO_FORM, /* form */
+ 0, /* size */
+ NULL /* type id */
+ };
+
+
+/***************************************************************************/
+/* search_symtab(name, np) Search for a name in the symbol table. */
+/* return pointer to entry if found, else NULL. */
+
+SYMTAB_NODE_PTR search_symtab(name, np)
+char *name; /* name to look for */
+SYMTAB_NODE_PTR np; /* pointer to symtab root */
+{
+ int cmp;
+ entry_debug("search_symtab");
+
+ /* loop to check each node. If not found, continue down the left */
+ /* or right subtree. Return when a match */
+
+ while (np != NULL) {
+ cmp = strcmp(name, np->name);
+ if (cmp == 0) { /* got it */
+ exit_debug("search_symtab at found");
+ return(np);
+ }
+ np = cmp < 0 ? np->left : np->right; /* continue */
+ }
+
+ exit_debug("search_symtab at not found");
+ return(NULL); /* not found */
+} /* end search_symtab */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* search_symtab_display(name) Search all the symbol tables in the */
+/* symbol table display for a name. */
+/* return the pointer to the entry if found, else NULL */
+
+SYMTAB_NODE_PTR search_symtab_display(name)
+char *name;
+{
+ short i;
+ SYMTAB_NODE_PTR np; /* pointer to symbol table node */
+ entry_debug("search_symtab_display");
+
+ for (i = level; i >= 0; --i) {
+ np =search_symtab(name, symtab_display[i]);
+ if (np != NULL) {
+ exit_debug("search_symtab_display at found");
+ return(np);
+ }
+ }
+
+ exit_debug("search_symtab_display at not found");
+ return(NULL);
+} /* end search_symtab_display */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* enter_symtab(name, npp) Enter a name into the symtab */
+/* return pointer to the entry */
+
+SYMTAB_NODE_PTR enter_symtab(name, npp)
+char *name; /* name to enter */
+SYMTAB_NODE_PTR *npp; /* ptr to ptr to symtab root */
+{
+ int cmp; /* result of strcmp */
+ SYMTAB_NODE_PTR new_nodep; /* ptr to new entry */
+ SYMTAB_NODE_PTR np; /* ptr to node to test */
+ entry_debug("enter_symtab");
+
+ /* create the new node for name */
+ new_nodep = alloc_struct(SYMTAB_NODE);
+ new_nodep->name = alloc_bytes(strlen(name) + 1);
+ strcpy(new_nodep->name, name);
+ new_nodep->left = new_nodep->right = new_nodep->next = NULL;
+ new_nodep->info = NULL;
+ new_nodep->defn.key = UNDEFINED;
+ new_nodep->typep = NULL;
+ new_nodep->level = level;
+ new_nodep->label_index = 0;
+
+ /* loop to find the insertion point (binary tree) */
+ while ((np = *npp) != NULL) {
+ cmp = strcmp(name, np->name);
+ npp = cmp < 0 ? &(np->left) : &(np->right);
+ }
+ *npp = new_nodep; /* replace */
+
+ exit_debug("enter_symtab");
+ return(new_nodep);
+} /* end enter_symtab */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* init_symtab() Initialise the symtab with predefined identifiers, */
+/* types, and routines */
+
+init_symtab() /* ---------------------- in final */
+{
+ SYMTAB_NODE_PTR integer_idp, real_idp, boolean_idp;
+ SYMTAB_NODE_PTR logical_idp, binary_idp,
+ generic_idp, anytype_idp;
+
+ int temp;
+ time_t tp1, tp2;
+ struct tm *ts;
+
+ /* temporarily switch off any debugging output */
+ temp = DEBUG;
+ DEBUG = 0;
+
+ /* initialise the level 0 (the global?) symbol table */
+ symtab_display[0] = NULL;
+
+ /* predefined Pascal types */
+ enter_name_local_symtab(integer_idp, "integer");
+ enter_name_local_symtab(real_idp, "real");
+ enter_name_local_symtab(boolean_idp, "boolean");
+ /* and extra EXPRESS types */
+ enter_name_local_symtab(logical_idp, "logical");
+ enter_name_local_symtab(string_idp, "string");
+ enter_name_local_symtab(binary_idp, "binary");
+ enter_name_local_symtab(generic_idp, "generic");
+ enter_name_local_symtab(anytype_idp, "???????");
+
+ integer_typep = alloc_struct(TYPE_STRUCT);
+ real_typep = alloc_struct(TYPE_STRUCT);
+ boolean_typep = alloc_struct(TYPE_STRUCT);
+ logical_typep = alloc_struct(TYPE_STRUCT);
+ string_typep = alloc_struct(TYPE_STRUCT);
+ binary_typep = alloc_struct(TYPE_STRUCT);
+ generic_typep = alloc_struct(TYPE_STRUCT);
+ any_typep = alloc_struct(TYPE_STRUCT);
+
+ integer_idp->defn.key = TYPE_DEFN;
+ integer_idp->typep = integer_typep;
+ integer_typep->form = SCALAR_FORM;
+ integer_typep->size = sizeof(STACK_ITEM);
+ integer_typep->type_idp = integer_idp;
+
+ real_idp->defn.key = TYPE_DEFN;
+ real_idp->typep = real_typep;
+ real_typep->form = SCALAR_FORM;
+ real_typep->size = sizeof(STACK_ITEM);
+ real_typep->type_idp = real_idp;
+
+ boolean_idp->defn.key = TYPE_DEFN;
+ boolean_idp->typep = boolean_typep;
+ boolean_typep->form = ENUM_FORM;
+ boolean_typep->size = sizeof(STACK_ITEM);
+ boolean_typep->type_idp = boolean_idp;
+ boolean_typep->info.enumeration.max = 1;
+ boolean_idp->typep->info.enumeration.const_idp = false_idp;
+
+ logical_idp->defn.key = TYPE_DEFN;
+ logical_idp->typep = boolean_typep;
+ logical_typep->form = ENUM_FORM;
+ logical_typep->size = sizeof(STACK_ITEM);
+ logical_typep->type_idp = logical_idp;
+ logical_typep->info.enumeration.max = 2;
+ logical_idp->typep->info.enumeration.const_idp = unknown_idp;
+
+ string_idp->defn.key = TYPE_DEFN;
+ string_idp->typep = string_typep;
+ string_typep->form = STRING_FORM;
+ string_typep->size = sizeof(STACK_ITEM);
+ string_typep->type_idp = string_idp;
+ string_typep->info.string.max_length = MAX_EXPRESS_STRING;
+ string_typep->info.string.length = 0;
+
+ binary_idp->defn.key = TYPE_DEFN;
+ binary_idp->typep = binary_typep;
+ binary_typep->form = SCALAR_FORM;
+ binary_typep->size = sizeof(STACK_ITEM);
+ binary_typep->type_idp = binary_idp;
+
+ generic_idp->defn.key = TYPE_DEFN;
+ generic_idp->typep = generic_typep;
+ generic_typep->form = SCALAR_FORM;
+ generic_typep->size = sizeof(STACK_ITEM);
+ generic_typep->type_idp = generic_idp;
+
+ anytype_idp->defn.key = TYPE_DEFN;
+ anytype_idp->typep = any_typep;
+ any_typep->form = SCALAR_FORM;
+ any_typep->size = sizeof(STACK_ITEM);
+ any_typep->type_idp = anytype_idp;
+
+
+ /* predefined constants */
+
+ enter_name_local_symtab(false_idp, "false");
+ enter_name_local_symtab(true_idp, "true");
+ enter_name_local_symtab(unknown_idp, "unknown");
+ enter_name_local_symtab(pi_idp, "pi");
+ enter_name_local_symtab(conste_idp, "const_e");
+ enter_name_local_symtab(undef_idp, "?");
+ enter_name_local_symtab(day_idp, "the_day");
+ enter_name_local_symtab(month_idp, "the_month");
+ enter_name_local_symtab(year_idp, "the_year");
+
+
+ false_idp->defn.key = CONST_DEFN;
+ false_idp->defn.info.constant.value.integer = FALSE_REP;
+ false_idp->typep = logical_typep;
+ false_idp->next = unknown_idp;
+
+ unknown_idp->defn.key = CONST_DEFN;
+ unknown_idp->defn.info.constant.value.integer = UNKNOWN_REP;
+ unknown_idp->typep = logical_typep;
+ unknown_idp->next = true_idp;
+
+ true_idp->defn.key = CONST_DEFN;
+ true_idp->defn.info.constant.value.integer = TRUE_REP;
+ true_idp->typep = logical_typep;
+
+ pi_idp->defn.key = CONST_DEFN;
+ pi_idp->typep = real_typep;
+ pi_idp->defn.info.constant.value.real = 3.141592654;
+
+ conste_idp->defn.key = CONST_DEFN;
+ conste_idp->typep = real_typep;
+ conste_idp->defn.info.constant.value.real = 2.718281828;
+
+ undef_idp->defn.key = CONST_DEFN;
+ undef_idp->typep = any_typep;
+ undef_idp->defn.info.constant.value.character = '\?';
+
+ /* do the current date */
+ tp1 = time(&tp2);
+ ts = localtime(&tp1);
+ sprintf(dbuffer, "year = %d, month = %d, day = %d\n",
+ (ts->tm_year+1900), (ts->tm_mon+1), (ts->tm_mday));
+ debug_print(dbuffer);
+
+ day_idp->defn.key = CONST_DEFN;
+ day_idp->typep = integer_typep;
+ day_idp->defn.info.constant.value.integer = ts->tm_mday;
+
+ month_idp->defn.key = CONST_DEFN;
+ month_idp->typep = integer_typep;
+ month_idp->defn.info.constant.value.integer = ts->tm_mon + 1;
+
+ year_idp->defn.key = CONST_DEFN;
+ year_idp->typep = integer_typep;
+ year_idp->defn.info.constant.value.integer = ts->tm_year + 1900;
+
+
+ /* standard routines */
+
+ enter_standard_routine("read", READ, PROC_DEFN);
+ enter_standard_routine("readln", READLN, PROC_DEFN);
+ enter_standard_routine("write", WRITE, PROC_DEFN);
+ enter_standard_routine("writeln", WRITELN, PROC_DEFN);
+
+ enter_standard_routine("abs", ABS, FUNC_DEFN);
+ enter_standard_routine("cos", COS, FUNC_DEFN);
+ enter_standard_routine("eof", EOFF, FUNC_DEFN);
+ enter_standard_routine("eoln", EOLN, FUNC_DEFN);
+ enter_standard_routine("exp", EXP, FUNC_DEFN);
+ enter_standard_routine("odd", ODD, FUNC_DEFN);
+ enter_standard_routine("round", ROUND, FUNC_DEFN);
+ enter_standard_routine("sin", SIN, FUNC_DEFN);
+ enter_standard_routine("sqrt", SQRT, FUNC_DEFN);
+ enter_standard_routine("trunc", TRUNC, FUNC_DEFN);
+
+ /* extra for ltx2x */
+ enter_standard_routine("print", L2XPRINT, PROC_DEFN);
+ enter_standard_routine("println", L2XPRINTLN, PROC_DEFN);
+ enter_standard_routine("system", L2XSYSTEM, PROC_DEFN);
+ enter_standard_routine("rexpr", L2XREXPR, FUNC_DEFN);
+
+ /* extra for EXPRESS */
+ enter_standard_routine("acos", XACOS, FUNC_DEFN);
+ enter_standard_routine("asin", XASIN, FUNC_DEFN);
+ enter_standard_routine("atan", XATAN, FUNC_DEFN);
+ enter_standard_routine("log", XLOG, FUNC_DEFN);
+ enter_standard_routine("log2", XLOG2, FUNC_DEFN);
+ enter_standard_routine("log10", XLOG10, FUNC_DEFN);
+ enter_standard_routine("tan", XTAN, FUNC_DEFN);
+ enter_standard_routine("blength", XBLENGTH, FUNC_DEFN);
+ enter_standard_routine("exists", XEXISTS, FUNC_DEFN);
+ enter_standard_routine("format", XFORMAT, FUNC_DEFN);
+ enter_standard_routine("hibound", XHIBOUND, FUNC_DEFN);
+ enter_standard_routine("hiindex", XHIINDEX, FUNC_DEFN);
+ enter_standard_routine("length", XLENGTH, FUNC_DEFN);
+ enter_standard_routine("lobound", XLOBOUND, FUNC_DEFN);
+ enter_standard_routine("loindex", XLOINDEX, FUNC_DEFN);
+ enter_standard_routine("nvl", XNVL, FUNC_DEFN);
+ enter_standard_routine("rolesof", XROLESOF, FUNC_DEFN);
+ enter_standard_routine("sizeof", XSIZEOF, FUNC_DEFN);
+ enter_standard_routine("typeof", XTYPEOF, FUNC_DEFN);
+ enter_standard_routine("usedin", XUSEDIN, FUNC_DEFN);
+ enter_standard_routine("value", XVALUE, FUNC_DEFN);
+ enter_standard_routine("value_in", XVALUE_IN, FUNC_DEFN);
+ enter_standard_routine("value_unique", XVALUE_UNIQUE, FUNC_DEFN);
+ enter_standard_routine("insert", XINSERT, PROC_DEFN);
+ enter_standard_routine("remove", XREMOVE, PROC_DEFN);
+
+ /* restore debugging */
+ DEBUG = temp;
+ return;
+} /* end init_symtab */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* enter_standard_routine(name, routine_key, defn_key) Enter a standard */
+/* procedure or function name into the symtab */
+
+enter_standard_routine(name, routine_key, defn_key)
+char *name; /* name string */
+ROUTINE_KEY routine_key;
+DEFN_KEY defn_key;
+{
+ SYMTAB_NODE_PTR rtn_idp = enter_name_local_symtab(rtn_idp, name);
+
+ rtn_idp->defn.key = defn_key;
+ rtn_idp->defn.info.routine.key = routine_key;
+ rtn_idp->defn.info.routine.parms = NULL;
+ rtn_idp->defn.info.routine.local_symtab = NULL;
+ rtn_idp->typep = NULL;
+
+} /* end enter_standard_routine */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* enter_scope(symtab_root) Enter a new nesting level by creating a new */
+/* scope. Push the given symbol table onto the display stack */
+
+enter_scope(symtab_root)
+SYMTAB_NODE_PTR symtab_root;
+{
+ entry_debug("enter_scope");
+ if (++level >= MAX_NESTING_LEVEL) {
+ error(NESTING_TOO_DEEP);
+ exit(-NESTING_TOO_DEEP);
+ }
+ symtab_display[level] = symtab_root;
+
+ exit_debug("enter_scope");
+ return;
+} /* end enter_scope */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exit_scope(symtab_root) Exit the current new nesting level by closing */
+/* the current scope. Pop the current symbol table off the */
+/* display stack, and return a pointer to it */
+
+SYMTAB_NODE_PTR exit_scope()
+{
+ SYMTAB_NODE_PTR symtab_root = symtab_display[level--];
+ entry_debug("exit_scope");
+ exit_debug("exit_scope");
+ return(symtab_root);
+} /* end enter_scope */
+/***************************************************************************/
+
+
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xisymt.h b/support/ltx2x/l2xisymt.h
new file mode 100644
index 0000000000..edfa186bc5
--- /dev/null
+++ b/support/ltx2x/l2xisymt.h
@@ -0,0 +1,139 @@
+/* l2xisymt.h Symbol table common for LTX2X interpreter */
+/* the principal typedefs are in file licomsym.h */
+
+#ifndef symtab_h
+#define symtab_h
+
+#include "l2xicmon.h"
+
+#ifndef licomsym_h
+#include "licomsym.h" /* contains the typedefs */
+#endif
+
+typedef char *STRING; /* a pointer to a char */
+typedef STRING *PTRADR; /* pointer to a pointer to a char */
+
+ /* use names rather than integers for TRUE (1) /FALSE (0) values */
+#define FALSE_REP -999
+#define UNKNOWN_REP -99
+#define TRUE_REP -9
+
+/* the simple pre-defined types */
+extern TYPE_STRUCT dummy_type;
+extern TYPE_STRUCT_PTR integer_typep, real_typep;
+extern TYPE_STRUCT_PTR string_typep, binary_typep;
+extern TYPE_STRUCT_PTR boolean_typep, logical_typep;
+extern TYPE_STRUCT_PTR generic_typep, any_typep;
+
+
+/* FUNCTIONS */
+
+SYMTAB_NODE_PTR search_symtab();
+SYMTAB_NODE_PTR search_symtab_display();
+SYMTAB_NODE_PTR enter_symtab();
+SYMTAB_NODE_PTR exit_scope();
+TYPE_STRUCT_PTR make_string_typep();
+
+
+/* MACROS */
+
+#define is_array(tp) (tp->form == ARRAY_FORM)
+
+#define is_dynagg(tp) (tp->form == BAG_FORM || \
+ tp->form == LIST_FORM || \
+ tp->form == SET_FORM)
+
+
+
+/* table searching macros */
+
+/**************************************************************************/
+/* search_local_symtab() search the local symtab for the current id name. */
+/* set a pointer to the entry, else NULL */
+#define search_local_symtab(idp) \
+ idp = search_symtab(word_string, symtab_display[level])
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* search_this_symtab() search the given symtab for the current id name. */
+/* set a pointer to the entry, else NULL */
+#define search_this_symtab(idp, this_symtab) \
+ idp = search_symtab(word_string, this_symtab)
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* search_all_symtab() search the symtab display for the current id name. */
+/* set a pointer to the entry, else NULL */
+#define search_all_symtab(idp) \
+ idp = search_symtab_display(word_string)
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* search_and_find_all_symtab() search the symtab display for the current */
+/* id name. If not found, ID UNDEFINED error, and */
+/* enter into the local symtab. */
+/* set a pointer to the entry. */
+#define search_and_find_all_symtab(idp) \
+ if ((idp = search_symtab_display(word_string)) == NULL) { \
+ error(UNDEFINED_IDENTIFIER); \
+ idp = enter_symtab(word_string, &symtab_display[level]); \
+ idp->defn.key = UNDEFINED; \
+ idp->typep = &dummy_type; \
+ }
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* enter_local_symtab() enter the current id name into the local symtab */
+/* and set pointer to the entry */
+#define enter_local_symtab(idp) \
+ idp = enter_symtab(word_string, &symtab_display[level])
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* enter_name_local_symtab() enter the given name into the local symtab */
+/* and set pointer to the entry */
+#define enter_name_local_symtab(idp, name) \
+ idp = enter_symtab(name, &symtab_display[level])
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* search_and_enter_local_symtab() search the symtab display for the */
+/* current id name. If not found enter it, else */
+/* ID REDEFINED error. */
+/* set a pointer to the entry. */
+#define search_and_enter_local_symtab(idp) \
+ if ((idp = search_symtab(word_string, symtab_display[level])) == NULL) { \
+ idp = enter_symtab(word_string, &symtab_display[level]); \
+ } \
+ else error(REDEFINED_IDENTIFIER)
+/**************************************************************************/
+
+
+
+/**************************************************************************/
+/* search_and_enter_this_symtab() search the given symtab for the */
+/* current id name. If not found enter it, else */
+/* ID REDEFINED error. */
+/* set a pointer to the entry. */
+#define search_and_enter_this_symtab(idp, this_symtab) \
+ if ((idp = search_symtab(word_string, this_symtab)) == NULL) { \
+ idp = enter_symtab(word_string, &this_symtab); \
+ } \
+ else error(REDEFINED_IDENTIFIER)
+/**************************************************************************/
+
+#endif
+
+
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xixref.c b/support/ltx2x/l2xixref.c
new file mode 100644
index 0000000000..e787a630b7
--- /dev/null
+++ b/support/ltx2x/l2xixref.c
@@ -0,0 +1,204 @@
+/* l2xixref.c Interpeter X-referencing */
+/* BASED ON: xref.c (unaltered except for common names) */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+
+#define DEBUG 0
+
+#define MAX_LINENUMS_PER_LINE 10
+
+/* line number item and list header */
+typedef struct linenum_item {
+ struct linenum_item *next;
+ int line_number;
+} LINENUM_ITEM, *LINENUM_ITEM_PTR;
+
+typedef struct {
+ LINENUM_ITEM_PTR first_linenum;
+ LINENUM_ITEM_PTR last_linenum;
+} LINENUM_HEADER, *LINENUM_HEADER_PTR;
+
+/* EXTERNALS */
+
+extern int line_number;
+extern TOKEN_CODE token;
+extern char word_string[];
+extern SYMTAB_NODE_PTR symtab_root;
+
+
+/***************************************************************************/
+/* main(argc, argv() loop to process identifiers, then print xref */
+/* call as: xref infile */
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ SYMTAB_NODE_PTR np; /* ptr to symtab entry */
+ LINENUM_HEADER_PTR hp; /* ptr to line item list header */
+
+ if (DEBUG) {
+ fprintf(stderr, "\n ****Starting program xref\nCalling init_scanner\n");
+ fflush(stderr);
+ }
+
+ init_scanner(argv[1]);
+
+ if (DEBUG) {
+ fprintf(stderr, "Returned from init_scanner\nProcessing tokens\n");
+ fflush(stderr);
+ }
+
+ /* process tokens until end of file */
+ do {
+ get_token();
+ if (token == END_OF_FILE) break;
+ if (token == IDENTIFIER) {
+ /* put identifier into symtab if not there, and record the */
+ /* line number in the symtab entry */
+ np = search_symtab(word_string, symtab_root);
+ if (np == NULL) {
+ np = enter_symtab(word_string, &symtab_root);
+ hp = alloc_struct(LINENUM_HEADER);
+ hp->first_linenum = hp->last_linenum = NULL;
+ np->info = (char *) hp;
+ }
+ record_line_number(np, line_number);
+ }
+ } while (token != PERIOD); /* end do */
+
+ if (DEBUG) {
+ fprintf(stderr, "Finished token processing\nCalling print_xref\n\n");
+ fflush(stderr);
+ }
+
+ /* print the xref listing */
+ printf("\n\nCross-Reference");
+ printf( "\n---------------\n");
+ print_xref(symtab_root);
+
+ if (DEBUG) {
+ fprintf(stderr, "\n\nReturned from print_xref\nCalling quit_scanner\n");
+ fflush(stderr);
+ }
+
+ quit_scanner();
+
+ if (DEBUG) {
+ fprintf(stderr, "Returned from quit_scanner\n***That's all\n\n");
+ fflush(stderr);
+ }
+
+} /* end main */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* record_line_number(np, number) Record a line number into the */
+/* symtab entry */
+
+record_line_number(np, number)
+SYMTAB_NODE_PTR np; /* ptr to symtab entry */
+int number; /* line number */
+{
+ LINENUM_ITEM_PTR ip; /* ptr to line item */
+ LINENUM_HEADER_PTR hp; /* ptr to line item list header */
+
+ /* create a new line number item */
+ ip = alloc_struct(LINENUM_ITEM);
+ ip->line_number = number;
+ ip->next = NULL;
+
+ /* link it to the list */
+ hp = (LINENUM_HEADER_PTR) np->info;
+ if (hp->first_linenum == NULL) hp->first_linenum = hp->last_linenum = ip;
+ else {
+ (hp->last_linenum)->next = ip;
+ hp->last_linenum = ip;
+ }
+
+} /* end record_line_number */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* print_xref(np) Print x-refed names and line numbers in alpha order */
+
+print_xref(np)
+SYMTAB_NODE_PTR np; /* pointer to subtree */
+{
+ int n;
+ LINENUM_ITEM_PTR ip; /* ptr to line item */
+ LINENUM_HEADER_PTR hp; /* ptr to line item list header */
+
+ if (np == NULL) return;
+
+ /* print the left subtree */
+ print_xref(np->left);
+
+ /* then print the root of the subtree with at most MAX_LINENUMS_PER_LINE */
+ printf("\n%-16s ", np->name);
+ n = strlen(np->name) > 16 ? 0 : MAX_LINENUMS_PER_LINE;
+ hp = (LINENUM_HEADER_PTR) np->info;
+ for (ip = hp->first_linenum; ip != NULL; ip = ip->next) {
+ if (n == 0) {
+ printf("\n%-16s ", " ");
+ n = MAX_LINENUMS_PER_LINE;
+ }
+ printf(" %4d", ip->line_number);
+ --n;
+ }
+ printf("\n");
+
+ /* now print the right subtree */
+ print_xref(np->right);
+
+} /* end print_xref */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* () */
+/*
+
+()
+{
+
+
+} /* end */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* () */
+/*
+
+()
+{
+
+
+} /* end */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* () */
+/*
+
+()
+{
+
+
+} /* end */
+/***************************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xixstd.c b/support/ltx2x/l2xixstd.c
new file mode 100644
index 0000000000..43f513e889
--- /dev/null
+++ b/support/ltx2x/l2xixstd.c
@@ -0,0 +1,1233 @@
+/* l2xixstd.c LTX2X interpreter standard procedure/function Executor routines */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+#include "l2xiexec.h"
+
+#include "listsetc.h"
+
+
+#define DEFAULT_NUMERIC_FIELD_WIDTH 10
+#define DEFAULT_PRECISION 4
+ /* added for ltx2x */
+#define MAX_LTX2X_BUFFER 2000
+
+/* EXTERNALS */
+
+
+extern int level;
+extern int exec_line_number; /* no. of line executed */
+
+extern ICT *code_segmentp; /* code segment ptr */ /* used? */
+extern TOKEN_CODE ctoken; /* token from code segment */
+
+extern STACK_ITEM *stack; /* runtime stack */
+extern STACK_ITEM_PTR tos; /* ptr to top of runtime stack */
+extern STACK_ITEM_PTR stack_frame_basep; /* ptr to stack fame base */
+extern STACK_ITEM_PTR stack_display[]; /* ????????? */
+
+
+extern BOOLEAN is_value_undef();
+
+extern STRING get_stacked_string();
+
+extern STACK_TYPE form2stack[]; /* map form type to stack type */
+extern TYPE_FORM stack2form[]; /* map stack type to form type */
+
+extern STACK_ITEM_PTR create_copy_value();
+
+/* FORWARDS */
+
+TYPE_STRUCT_PTR exec_eof_eoln(), exec_abs_sqr(),
+ exec_arctan_cos_exp_ln_sin_sqrt(),
+ exec_odd(), exec_round_trunc();
+TYPE_STRUCT_PTR exec_atan(), exec_exists_etc(), exec_nvl_etc();
+TYPE_STRUCT_PTR exec_rexpr_etc(), exec_hibound_etc(), exec_length_etc();
+
+/* GLOBALS */
+
+BOOLEAN eof_flag = FALSE;
+char acbuffer[MAX_LTX2X_BUFFER]; /* added for ltx2x */
+
+
+
+/************************************************************************/
+/* exec_standard_routine_call(rtn_idp) Execute a call to a standard */
+/* procedure or function */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_standard_routine_call(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ entry_debug("exec_standard_routine_call");
+
+ switch (rtn_idp->defn.info.routine.key) {
+ case READ:
+ case READLN: {
+ exec_read_readln(rtn_idp);
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+ }
+ case WRITE:
+ case WRITELN: {
+ exec_write_writeln(rtn_idp);
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+ }
+ case EOFF:
+ case EOLN: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_eof_eoln(rtn_idp));
+ }
+ case ABS: /* real or int -> real or int */
+ {
+ exit_debug("exec_standard_routine_call");
+ return(exec_abs_sqr(rtn_idp));
+ }
+ case COS: /* real or int -> real */
+ case EXP:
+ case SIN:
+ case SQRT:
+ case XACOS:
+ case XASIN:
+ case XLOG:
+ case XLOG2:
+ case XLOG10:
+ case XTAN: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_arctan_cos_exp_ln_sin_sqrt(rtn_idp));
+ }
+ case XATAN: { /* extra for EXPRESS */
+ exit_debug("exec_standard_routine_call");
+ return(exec_atan(rtn_idp));
+ }
+ case ODD: { /* int -> boolean */
+ exit_debug("exec_standard_routine_call");
+ return(exec_odd());
+ }
+ case ROUND: /* real -> int */
+ case TRUNC: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_round_trunc(rtn_idp));
+ }
+ case L2XPRINT:
+ case L2XPRINTLN: { /* added for ltx2x */
+ exec_print_println(rtn_idp);
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+ }
+ case L2XSYSTEM: { /* added for ltx2x */
+ exec_system_etc(rtn_idp);
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+ }
+ case L2XREXPR: { /* added for ltx2x */
+ exit_debug("exec_standard_routine_call");
+ return(exec_rexpr_etc(rtn_idp));
+ }
+ case XHIBOUND:
+ case XHIINDEX:
+ case XLOBOUND:
+ case XLOINDEX:
+ case XSIZEOF: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_hibound_etc(rtn_idp));
+ }
+ case XLENGTH: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_length_etc(rtn_idp));
+ }
+ case XEXISTS: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_exists_etc(rtn_idp));
+ }
+ case XNVL: {
+ exit_debug("exec_standard_routine_call");
+ return(exec_nvl_etc(rtn_idp));
+ }
+ case XINSERT:
+ case XREMOVE: {
+ exec_insert_etc(rtn_idp);
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+ }
+ case XBLENGTH:
+ case XFORMAT:
+ case XROLESOF:
+ case XTYPEOF:
+ case XUSEDIN:
+ case XVALUE:
+ case XVALUE_IN:
+ case XVALUE_UNIQUE: { /* unimplemented EXPRESS stuff */
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+ }
+ default: {
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ break;
+ }
+
+ } /* end switch */
+
+ exit_debug("exec_standard_routine_call");
+ return(NULL);
+} /* end exec_standard_routine_call */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_read_readln(rtn_idp) Execute a call to READ or READLN */
+
+exec_read_readln(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ SYMTAB_NODE_PTR parm_idp; /* param id */
+ TYPE_STRUCT_PTR parm_tp; /* param type */
+ STACK_ITEM_PTR targetp; /* ptr to read target */
+ XPRSAINT i1;
+ XPRSAREAL r1;
+ int len;
+ char ch;
+ char tbuff[MAX_LTX2X_BUFFER];
+ STRING lhs;
+
+ entry_debug("exec_read_readln");
+
+ /* params are optional for readln */
+ get_ctoken();
+ if (ctoken == LPAREN) { /* id list */
+ do {
+ get_ctoken();
+ parm_idp = get_symtab_cptr();
+ parm_tp = base_type(exec_variable(parm_idp, VARPARM_USE));
+ targetp = (STACK_ITEM_PTR) get_address(tos);
+ pop(); /* pop off address */
+
+ if (parm_tp == integer_typep) {
+ scanf("%d", &i1);
+ put_integer(targetp, i1);
+ }
+ else if (parm_tp == real_typep) {
+ scanf("%g", &r1);
+ put_real(targetp, r1);
+ }
+ else { /* a string or a logical */
+ scanf("%sMAX_LTX2X_BUFFER", tbuff);
+ len = strlen(tbuff);
+ sprintf(dbuffer, "strlen(str) = %d, str = %s\n", len, tbuff);
+ debug_print(dbuffer);
+ if (parm_tp == logical_typep) { /* check which one */
+ if (len == 4 && (tbuff[0] == 't' || tbuff[0] == 'T')) { /* TRUE */
+ put_true(targetp);
+ }
+ else if (len == 5 && (tbuff[0] == 'f' || tbuff[0] == 'F')) { /* FALSE */
+ put_false(targetp);
+ }
+ else if (len == 7 && (tbuff[0] == 'u' || tbuff[0] == 'U')) { /* UNKNOWN */
+ put_unknown(targetp);
+ }
+ else { /* an error */
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ put_unknown(targetp);
+ }
+ }
+ else { /* a string */
+ free(targetp->value.string);
+ lhs = alloc_bytes(len+1);
+ sprintf(dbuffer, "lhs = %d", lhs);
+ debug_print(dbuffer);
+ strcpy(lhs, tbuff);
+ sprintf(dbuffer, ", str = %s\n", lhs);
+ debug_print(dbuffer);
+ put_string(targetp, lhs);
+ }
+ }
+
+ trace_data_store(parm_idp, parm_idp->typep, targetp, parm_tp);
+ } while (ctoken == COMMA); /* end do */
+ get_ctoken(); /* token after RPAREN */
+ }
+
+ if (rtn_idp->defn.info.routine.key == READLN) {
+ do {
+ ch = getchar();
+ } while(!eof_flag && (ch != '\n'));
+ }
+
+ exit_debug("exec_read_readln");
+ return;
+} /* end exec_read_readln */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_write_writeln(rtn_idp) Execute a call to WRITE or WRITELN */
+/* Each actual parameter can be: <expr> */
+/* or <expr> : <expr> */
+/* or <expr> : <expr> : <expr> */
+
+exec_write_writeln(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* parameter type */
+ STACK_TYPE stype;
+ XPRSAINT field_width;
+ XPRSAINT precision;
+ entry_debug("exec_write_writeln");
+
+ /* parameters are optional for writeln */
+ get_ctoken();
+ if (ctoken == LPAREN) {
+ do {
+ /* push value */
+ get_ctoken();
+ parm_tp = base_type(exec_expression());
+
+ /* check if dynamic agg */
+ if (is_dynagg(parm_tp)) parm_tp = parm_tp->info.dynagg.elmt_typep;
+
+ field_width = DEFAULT_NUMERIC_FIELD_WIDTH;
+ precision = DEFAULT_PRECISION;
+
+ /* optional field width expresion */
+ if (ctoken == COLON) {
+ get_ctoken();
+ exec_expression();
+ if (!is_value_undef(tos)) {
+ field_width = get_integer(tos);
+ }
+ pop(); /* field width */
+
+ /* optional decimal places expresion */
+ if (ctoken == COLON) {
+ get_ctoken();
+ exec_expression();
+ if (!is_value_undef(tos)) {
+ precision = get_integer(tos);
+ }
+ pop(); /* precision */
+ }
+ }
+
+ if (parm_tp->form == ARRAY_FORM) { /* array, address on top of stack */
+ if (get_stackval_type(tos) == STKADD) {
+ copy_value(tos, get_address(tos));
+ }
+ }
+
+ stype = get_stackval_type(tos);
+
+ /* write value */
+ if (is_value_undef(tos)) {
+ printf("%*c", field_width, get_undef(tos));
+ }
+ else if (stype == STKINT) {
+ printf("%*d", field_width, get_integer(tos));
+ }
+ else if (stype == STKREA) {
+ printf("%*.*g", field_width, precision, get_real(tos));
+ }
+ else if (stype == STKLOG) {
+ field_width = 0;
+ switch (get_logical(tos)) {
+ case TRUE_REP: {
+ printf("%*s", -field_width, "TRUE");
+ break;
+ }
+ case FALSE_REP: {
+ printf("%*s", -field_width, "FALSE");
+ break;
+ }
+ case UNKNOWN_REP: {
+ printf("%*s", -field_width, "UNKNOWN");
+ break;
+ }
+ default: {
+ printf("%*s", -field_width, "??UNKNOWN??");
+ break;
+ }
+ } /* end switch */
+ }
+ else if (parm_tp == string_typep || parm_tp->form == STRING_FORM) {
+ field_width = 0;
+ printf("%*s", -field_width, get_stacked_string(tos) );
+ }
+
+ pop(); /* value */
+ } while (ctoken == COMMA); /* end do */
+
+ get_ctoken(); /* token after RPAREN */
+ } /* end of if over parameters */
+
+ if (rtn_idp->defn.info.routine.key == WRITELN) putchar('\n');
+
+ exit_debug("exec_write_writeln");
+ return;
+} /* end exec_write_writeln */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_print_println(rtn_idp) Execute a call to PRINT or PRINTLN */
+/* Each actual parameter can be: <expr> */
+/* or <expr> : <expr> */
+/* or <expr> : <expr> : <expr> */
+/* Identical to exec_write_writeln, except output is to ltx2x myprint */
+
+exec_print_println(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* parameter type */
+ STACK_TYPE stype;
+ XPRSAINT field_width;
+ XPRSAINT precision;
+ entry_debug("exec_print_println");
+
+ /* parameters are optional for println */
+ get_ctoken();
+ if (ctoken == LPAREN) {
+ do {
+ /* push value */
+ get_ctoken();
+ parm_tp = base_type(exec_expression());
+
+ /* check if dynamic agg */
+ if (is_dynagg(parm_tp)) {
+ parm_tp = parm_tp->info.dynagg.elmt_typep;
+ }
+
+ field_width = DEFAULT_NUMERIC_FIELD_WIDTH;
+ precision = DEFAULT_PRECISION;
+
+
+ /* optional field width expresion */
+ if (ctoken == COLON) {
+ get_ctoken();
+ exec_expression();
+ if (!is_value_undef(tos)) {
+ field_width = get_integer(tos);
+ }
+ pop(); /* field width */
+
+ /* optional decimal places expresion */
+ if (ctoken == COLON) {
+ get_ctoken();
+ exec_expression();
+ if (!is_value_undef(tos)) {
+ precision = get_integer(tos);
+ }
+ pop(); /* precision */
+ }
+ }
+
+ if (parm_tp->form == ARRAY_FORM) { /* array, address on top of stack */
+ if (get_stackval_type(tos) == STKADD) {
+ copy_value(tos, get_address(tos));
+ }
+ }
+
+ stype = get_stackval_type(tos);
+ /* write value */
+ if (is_value_undef(tos)) {
+ sprintf(acbuffer, "%*c", field_width, get_undef(tos));
+ }
+ else if (stype == STKINT) {
+ sprintf(acbuffer, "%*d", field_width, get_integer(tos));
+ }
+ else if (stype == STKREA) {
+ sprintf(acbuffer, "%*.*g", field_width, precision, get_real(tos));
+ }
+ else if (stype == STKLOG) {
+ field_width = 0;
+ switch (get_logical(tos)) {
+ case TRUE_REP: {
+ sprintf(acbuffer, "%*s", -field_width, "TRUE");
+ break;
+ }
+ case FALSE_REP: {
+ sprintf(acbuffer, "%*s", -field_width, "FALSE");
+ break;
+ }
+ case UNKNOWN_REP: {
+ sprintf(acbuffer, "%*s", -field_width, "UNKNOWN");
+ break;
+ }
+ default: {
+ sprintf(acbuffer, "%*s", -field_width, "??UNKNOWN??");
+ break;
+ }
+ } /* end switch */
+ }
+ else if (parm_tp == string_typep || parm_tp->form == STRING_FORM) {
+ field_width = 0;
+ sprintf(acbuffer, "%*s", -field_width, get_stacked_string(tos) );
+ }
+ myprint(acbuffer);
+ pop(); /* value */
+ } while (ctoken == COMMA); /* end do */
+
+ get_ctoken(); /* token after RPAREN */
+ } /* end of if over parameters */
+
+ if (rtn_idp->defn.info.routine.key == L2XPRINTLN) myprint("\n");
+
+ exit_debug("exec_print_println");
+ return;
+} /* end exec_print_println */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_insert_etc(rtn_idp) Execute a call to procedure INSERT, etc */
+/* INSERT(<list>, <item>, <posn>) */
+/* REMOVE(<list>, <posn>) */
+/* at entry: ctoken is `proc' */
+/* at exit: ctoken is the token after the closing ) */
+
+exec_insert_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* parameter type */
+ LBS_PTR list;
+ LBS_NODE_PTR nod;
+ STACK_ITEM_PTR pitem;
+ XPRSAINT pos;
+ int code = rtn_idp->defn.info.routine.key;
+
+ entry_debug("exec_insert_etc (l2xixstd.c)");
+
+ /* first parameter */
+ get_ctoken(); /* should be ( */
+ get_ctoken(); /* should be param 1 */
+ parm_tp = base_type(exec_expression());
+ if (parm_tp->form != LIST_FORM) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ list = (LBS_PTR) get_address_type(tos, STKLST);
+ sprintf(dbuffer, "list = %d\n", list);
+ debug_print(dbuffer);
+ pop(); /* first parm */
+ get_ctoken(); /* start of next parameter */
+
+ if (code == XINSERT) { /* do INSERT second param */
+ exec_expression();
+ pitem = create_copy_value(tos);
+ sprintf(dbuffer, "pitem = %d\n", pitem);
+ debug_print(dbuffer);
+ get_ctoken(); /* start of next parameter */
+ }
+
+ /* final parameter */
+ parm_tp = base_type(exec_expression());
+ pos = get_integer(tos);
+ pop(); /* last parm */
+ get_ctoken(); /* token after closing ) */
+
+ switch (code) {
+ case XINSERT: {
+ nod = lbs_insert(list, (genptr) pitem, pos);
+ sprintf(dbuffer, "inserted node = %d, with data = %d, at pos = %d, into list = %d\n",
+ nod, pitem, pos, list);
+ debug_print(dbuffer);
+ pop(); /* middle parm */
+ break;
+ }
+ case XREMOVE: {
+ nod = lbs_remove(list, pos);
+ sprintf(dbuffer, "removed node = %d\n", nod);
+ debug_print(dbuffer);
+ break;
+ }
+ } /* end switch */
+
+ exit_debug("exec_insert_etc");
+ return;
+} /* end EXEC_INSERT_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_eof_eoln(rtn_idp) Execute a call to EOF or EOLN */
+/* No parameters => boolean result */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_eof_eoln(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ char ch = getchar();
+ entry_debug("exec_eof_eoln");
+
+ switch (rtn_idp->defn.info.routine.key) {
+ case EOFF: {
+ if (eof_flag || feof(stdin)) {
+ eof_flag = TRUE;
+ push_true();
+ }
+ else {
+ push_false();
+ ungetc(ch, stdin);
+ }
+ break;
+ }
+ case EOLN: {
+ if (eof_flag || feof(stdin)) {
+ eof_flag = TRUE;
+ push_true();
+ }
+ else {
+ push_logical(ch == '\n' ? TRUE_REP : FALSE_REP);
+ ungetc(ch, stdin);
+ }
+ break;
+ }
+ } /* end switch */
+
+ get_ctoken(); /* token after function name */
+
+ exit_debug("exec_eof_eoln");
+ return(logical_typep);
+} /* end exec_eof_eoln */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_system_etc(rtn_idp) Execute a call to system, etc */
+/* fun('string') */
+/* String parameter, no result */
+/* at entry, ctoken is `fun' */
+/* at exit, ctoken is token after closing ) */
+
+exec_system_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ entry_debug("exec_system_etc");
+
+ get_ctoken(); /* should be ( */
+ get_ctoken(); /* start of param */
+ parm_tp = base_type(exec_expression());
+ if (parm_tp->form != STRING_FORM) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ switch (rtn_idp->defn.info.routine.key) {
+ case L2XSYSTEM : {
+ system(get_stacked_string(tos));
+ break;
+ }
+ default : {
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ break;
+ }
+ } /* end switch */
+ }
+
+ get_ctoken(); /* token after closing ) */
+ exit_debug("exec_system_etc");
+ return;
+} /* end EXEC_SYSTEM_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_rexpr_etc(rtn_idp) Execute a call to REXPR, etc */
+/* In general, any function fun(p1, p2) that: */
+/* p1 and p2 are strings --> boolean result */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_rexpr_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm1_tp, parm2_tp; /* actual param types */
+ TYPE_STRUCT_PTR result_tp = logical_typep;
+ STRING parm1, parm2; /* parameters */
+ BOOLEAN undef_parm = FALSE;
+ int code = rtn_idp->defn.info.routine.key;
+ int result;
+ entry_debug("exec_rexpr_etc (l2xixstd.c)");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken(); /* start of first parameter */
+ parm1_tp = base_type(exec_expression());
+ if (is_value_undef(tos)) {
+ undef_parm = TRUE;
+ }
+ else {
+ parm1 = get_stacked_string(tos);
+ }
+/* get_ctoken(); COMMA */
+ get_ctoken(); /* start of second parameter */
+ parm2_tp = base_type(exec_expression());
+ if (is_value_undef(tos)) {
+ undef_parm = TRUE;
+ }
+ else {
+ parm2 = get_stacked_string(tos);
+ }
+ pop();
+
+ if (code == L2XREXPR) { /* parm1 = string, parm2 = pattern */
+ if (undef_parm) {
+ put_undef(tos);
+ }
+ else {
+ result = rexpr(parm1, parm2);
+ if (result < 0) {
+ runtime_error(INVALID_REGULAR_EXPRESSION);
+ put_undef(tos);
+ }
+ else if (result == 0) {
+ put_false(tos);
+ }
+ else {
+ put_true(tos);
+ }
+ }
+ }
+
+ get_ctoken(); /* token after RPAREN */
+
+ exit_debug("exec_rexpr_etc");
+ return(result_tp);
+} /* end EXEC_REXPR_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_hibound_etc(rtn_idp) Execute a call to HIBOUND, etc */
+/* agg type -> integer */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_hibound_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp = integer_typep; /* result type */
+ XPRSAINT result = 0;
+ STACK_TYPE stype;
+ TYPE_FORM ftype;
+ int code = rtn_idp->defn.info.routine.key;
+ entry_debug("exec_hibound_etc");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken();
+ parm_tp = base_type(exec_expression());
+ if (is_value_undef(tos)) {
+ put_undef(tos);
+ get_ctoken(); /* token after RPAREN */
+ exit_debug("exec_hibound_etc");
+ return(result_tp);
+ }
+ ftype = parm_tp->form;
+ if ((ftype != ARRAY_FORM) &&
+ (ftype != BAG_FORM) &&
+ (ftype != LIST_FORM) &&
+ (ftype != SET_FORM) ) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ put_undef(tos);
+ get_ctoken(); /* token after RPAREN */
+ exit_debug("exec_hibound_etc");
+ return(result_tp);
+ }
+
+ stype = get_stackval_type(tos);
+ if (stype != form2stack[ftype] &&
+ stype != STKADD) {
+ stack_warning(form2stack[ftype], stype);
+ }
+
+ switch (code) {
+ case XHIBOUND: { /* declared upper bound */
+ if (parm_tp->form == ARRAY_FORM) {
+ result = parm_tp->info.array.max_index;
+ }
+ else {
+ result = parm_tp->info.dynagg.max_index;
+ }
+ break;
+ }
+ case XHIINDEX: { /* declared array upper bound, or # of elements */
+ if (parm_tp->form == ARRAY_FORM) {
+ result = parm_tp->info.array.max_index;
+ }
+ else {
+ result = NELS((LBS_PTR) get_address_type(tos, stype));
+ }
+ break;
+ }
+ case XLOBOUND: { /* declared lower bound */
+ if (parm_tp->form == ARRAY_FORM) {
+ result = parm_tp->info.array.min_index;
+ }
+ else {
+ result = parm_tp->info.dynagg.min_index;
+ }
+ break;
+ }
+ case XLOINDEX: { /* declared array lower bound, or 1 */
+ if (parm_tp->form == ARRAY_FORM) {
+ result = parm_tp->info.array.min_index;
+ }
+ else {
+ result = 1;
+ }
+ break;
+ }
+ case XSIZEOF: { /* # of actual elements */
+ if (parm_tp->form == ARRAY_FORM) {
+ result = parm_tp->info.array.max_index - parm_tp->info.array.min_index + 1;
+ }
+ else {
+ result = NELS((LBS_PTR) get_address_type(tos, stype));
+ }
+ break;
+ }
+
+ default: { /* should not be here */
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ get_ctoken();
+ put_undef(tos);
+ exit_debug("exec_hibound_etc");
+ return(result_tp);
+ }
+ } /* end switch */
+
+ get_ctoken(); /* token after RPAREN */
+
+ put_integer(tos, result);
+ exit_debug("exec_hibound_etc");
+ return(result_tp);
+} /* end EXEC_HIBOUND_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_length_etc(rtn_idp) Execute a call to LENGTH, etc */
+/* fun('string') */
+/* String parameter, integer result */
+/* at entry, ctoken is `fun' */
+/* at exit, ctoken is token after closing ) */
+
+TYPE_STRUCT_PTR exec_length_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp; /* returned type */
+ XPRSAINT result = 0;
+ entry_debug("exec_length_etc (l2xixstd.c)");
+
+ get_ctoken(); /* should be ( */
+ get_ctoken(); /* start of param */
+ parm_tp = base_type(exec_expression());
+ if (parm_tp->form != STRING_FORM) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ switch (rtn_idp->defn.info.routine.key) {
+ case XLENGTH : { /* # of chars in a string */
+ result = (XPRSAINT) strlen(get_stacked_string(tos));
+ break;
+ }
+ default : {
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ break;
+ }
+ } /* end switch */
+ }
+
+ get_ctoken(); /* token after closing ) */
+ put_integer(tos, result);
+ exit_debug("exec_length_etc");
+ return(result_tp);
+} /* end EXEC_LENGTH_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_exists_etc(rtn_idp) Execute a call to EXISTS, etc */
+/* any type -> boolean */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_exists_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp; /* result type */
+ int code = rtn_idp->defn.info.routine.key;
+ entry_debug("exec_exists_etc");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken();
+ parm_tp = base_type(exec_expression());
+
+ if (code == XEXISTS) {
+ if (is_value_undef(tos)) {
+ put_true(tos);
+ }
+ else {
+ put_false(tos);
+ }
+ }
+
+ get_ctoken(); /* token after RPAREN */
+
+ exit_debug("exec_exists_etc");
+ return(logical_typep);
+} /* end EXEC_EXISTS_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_nvl_etc(rtn_idp) Execute a call to NVL, etc */
+/* In general, any function fun(p1, p2) that: */
+/* any compatible params --> compatible result */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_nvl_etc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm1_tp, parm2_tp; /* actual param types */
+ TYPE_STRUCT_PTR result_tp;
+ STACK_ITEM_PTR parm1, parm2; /* parameters */
+ int code = rtn_idp->defn.info.routine.key;
+ entry_debug("exec_nvl_etc");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken(); /* start of first parameter */
+ parm1_tp = base_type(exec_expression());
+ parm1 = tos;
+ get_ctoken(); /* COMMA */
+ get_ctoken(); /* start of second parameter */
+ parm2_tp = base_type(exec_expression());
+ parm2 = tos;
+
+
+ if (code == XNVL) {
+ if (is_value_undef(parm1)) {
+ copy_value(parm1, parm2);
+ result_tp = parm2_tp;
+ }
+ else {
+ result_tp = parm1_tp;
+ }
+ }
+
+ get_ctoken(); /* token after RPAREN */
+
+ exit_debug("exec_nvl_etc");
+ return(result_tp);
+} /* end EXEC_NVL_ETC */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_abs_sqr(rtn_idp) Execute a call to ABS or SQR */
+/* Integer --> integer result */
+/* real --> real result */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_abs_sqr(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp; /* result type */
+ XPRSAINT i1;
+ XPRSAREAL r1;
+ int code = rtn_idp->defn.info.routine.key;
+ entry_debug("exec_abs_sqr");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken();
+ parm_tp = base_type(exec_expression());
+
+ if (is_value_undef(tos)) {
+ ;
+ }
+ if (code == ABS) {
+ if (parm_tp == integer_typep) {
+ i1 = get_integer(tos);
+ if (i1 >= 0) {
+ put_integer(tos, i1);
+ }
+ else {
+ put_integer(tos, -i1);
+ }
+ }
+ else {
+ r1 = (XPRSAREAL) fabs((double) get_real(tos));
+ put_real(tos, r1);
+ }
+ }
+
+ get_ctoken(); /* token after RPAREN */
+
+ exit_debug("exec_abs_sqr");
+ return(parm_tp);
+} /* end exec_abs_sqr */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_arctan_cos_exp_ln_sin_sqrt(rtn_idp) Execute a call to ARCTAN, */
+/* COS, EXP, LN, SIN or SQRT */
+/* In general, any function fun(p1) that: */
+/* integer or real param --> real result */
+/* return a pointer to the type stucture of the call */
+/* NOTE calling C library routines acos() and asin() give wierd interp error */
+
+TYPE_STRUCT_PTR exec_arctan_cos_exp_ln_sin_sqrt(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm_tp; /* actual param type */
+ int code = rtn_idp->defn.info.routine.key;
+ XPRSAREAL r1, r2;
+ entry_debug("exec_arctan_cos_exp_ln_sin_sqrt");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken();
+ parm_tp = base_type(exec_expression());
+
+ if (is_value_undef(tos)) {
+ get_ctoken(); /* token after RPAREN */
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt");
+ return(real_typep);
+ }
+
+ if (parm_tp == integer_typep) {
+ put_real(tos, (XPRSAREAL) get_integer(tos));
+ }
+
+ r1 = (double) get_real(tos);
+
+ /* check input value */
+ if (((code == SQRT) && (r1 < 0.0)) ||
+ ((code == XACOS) && (r1 < -1.0 || r1 > 1.0)) ||
+ ((code == XASIN) && (r1 < -1.0 || r1 > 1.0)) ||
+ ((code == XLOG) && (r1 <= 0.0)) ||
+ ((code == XLOG2) && (r1 <= 0.0)) ||
+ ((code == XLOG10) && (r1 <= 0.0)) ) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt");
+ }
+ else {
+ switch (rtn_idp->defn.info.routine.key) {
+ case COS: {
+ put_real(tos, (XPRSAREAL) cos(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (COS)");
+ break;
+ }
+ case EXP: {
+ put_real(tos, (XPRSAREAL) exp(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (EXP)");
+ break;
+ }
+ case SIN: {
+ put_real(tos, (XPRSAREAL) sin(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (SIN)");
+ break;
+ }
+ case SQRT: {
+ put_real(tos, (XPRSAREAL) sqrt(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (SQRT)");
+ break;
+ }
+ case XACOS: {
+ put_real(tos, (XPRSAREAL) acos(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (ACOS)");
+ break;
+ }
+ case XASIN: {
+ put_real(tos, (XPRSAREAL) asin(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (ASIN)");
+ break;
+ }
+ case XLOG: {
+ put_real(tos, (XPRSAREAL) log(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (LOG)");
+ break;
+ }
+ case XLOG2: { /* log_a(x) = ln(x)/ln(a) : ln(2) = 0.6931 47180 55994 */
+ put_real(tos, (1.442695 * ((XPRSAREAL) log(r1))));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (LOG2)");
+ break;
+ }
+ case XLOG10: {
+ put_real(tos, (XPRSAREAL) log10(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (LOG10)");
+ break;
+ }
+ case XTAN: {
+ put_real(tos, (XPRSAREAL) tan(r1));
+ exit_debug("exec_arctan_cos_exp_ln_sin_sqrt (TAN)");
+ break;
+ }
+ } /* end switch */
+ }
+
+ get_ctoken(); /* token after RPAREN */
+
+ return(real_typep);
+} /* end exec_arctan_cos_exp_ln_sin_sqrt */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_atan(rtn_idp) Execute a call to ATAN, */
+/* In general, any function fun(p1, p2) that: */
+/* integer or real param --> real result */
+/* return a pointer to the type stucture of the call */
+/* NOTE: Calling C library function atan2() gives wierd interp. error */
+
+TYPE_STRUCT_PTR exec_atan(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR parm1_tp, parm2_tp; /* actual param type */
+ TYPE_STRUCT_PTR result_tp;
+ STACK_ITEM_PTR parm1, parm2;
+ int code = rtn_idp->defn.info.routine.key;
+ XPRSAREAL r1;
+ XPRSAREAL r2;
+ entry_debug("exec_atan");
+
+ get_ctoken(); /* LPAREN */
+ get_ctoken(); /* start of first parameter */
+ parm1_tp = base_type(exec_expression());
+ parm1 = tos;
+
+ get_ctoken(); /* COMMA */
+ get_ctoken(); /* start of second parameter */
+ parm2_tp = base_type(exec_expression());
+ parm2 = tos;
+
+ if (code == XATAN) {
+ if (is_value_undef(parm1) || is_value_undef(parm2)) {
+ put_undef(parm1);
+ }
+ else {
+ if (parm1_tp == integer_typep) {
+ put_real(parm1, (XPRSAREAL) get_integer(parm1));
+ }
+ r1 = get_real(parm1);
+ if (parm2_tp == integer_typep) {
+ put_real(parm2, (XPRSAREAL) get_integer(parm2));
+ }
+ r2 = get_real(parm2);
+ if (r1 == 0.0 && r2 == 0.0) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ r1 = (double) r1;
+ r2 = (double) r2;
+ put_real(parm1, (XPRSAREAL) atan2(r1, r2));
+ }
+ }
+ }
+
+ pop();
+ get_ctoken(); /* token after RPAREN */
+
+ exit_debug("exec_atan");
+ return(real_typep);
+} /* end EXEC_ATAN */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_odd() Execute a call to ODD */
+/* integer param --> boolean result */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_odd()
+{
+ XPRSAINT i1;
+ entry_debug("exec_odd");
+ get_ctoken(); /* LPAREN */
+ get_ctoken();
+ exec_expression();
+
+ if (!is_value_undef(tos)) {
+ i1 = get_integer(tos);
+ i1 &= 1;
+ if (i1 == 0) {
+ put_false(tos);
+ }
+ else {
+ put_true(tos);
+ }
+ }
+
+ get_ctoken(); /* after RPAREN */
+
+ exit_debug("exec_odd");
+ return(logical_typep);
+} /* end exec_odd */
+/************************************************************************/
+
+
+
+/************************************************************************/
+/* exec_round_trunc(rtn_idp) Execute a call to ROUND or TRUNC */
+/* real param --> integer result */
+/* return a pointer to the type stucture of the call */
+
+TYPE_STRUCT_PTR exec_round_trunc(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ XPRSAREAL r1;
+ XPRSAINT i1;
+
+ entry_debug("exec_round_trunc");
+ get_ctoken(); /* LPAREN */
+ get_ctoken();
+ exec_expression();
+
+ if (!is_value_undef(tos)) {
+ r1 = get_real(tos);
+ if (rtn_idp->defn.info.routine.key == ROUND) {
+ i1 = r1 > 0.0
+ ? (XPRSAINT) (r1 + 0.5)
+ : (XPRSAINT) (r1 - 0.5);
+ }
+ else {
+ i1 = (XPRSAINT) r1;
+ }
+ put_integer(tos, i1);
+ }
+
+ get_ctoken(); /* after RPAREN */
+
+ exit_debug("exec_round_trunc");
+ return(integer_typep);
+} /* end exec_round_trunc */
+/************************************************************************/
+
+
+
+
+
diff --git a/support/ltx2x/l2xixstm.c b/support/ltx2x/l2xixstm.c
new file mode 100644
index 0000000000..e74f7e2814
--- /dev/null
+++ b/support/ltx2x/l2xixstm.c
@@ -0,0 +1,881 @@
+/* l2xixstm.c LTX2X interpreter statement executor routines */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+#include "l2xiexec.h"
+
+/* GLOBALS */
+
+BOOLEAN executed_return; /* TRUE iff return statement executed */
+
+/* EXTERNALS */
+
+extern int level;
+extern int exec_line_number;;
+extern long exec_stmt_count;
+
+extern ICT *code_segmentp; /* code segment ptr */
+extern ICT *statement_startp; /* ptr to start of statement */
+extern TOKEN_CODE ctoken; /* token from code segment */
+
+extern STACK_ITEM *stack; /* runtime stack */
+extern STACK_ITEM_PTR tos; /* ptr to top of runtime stack */
+extern STACK_ITEM_PTR stack_frame_basep; /* ptr to stack fame base */
+
+extern BOOLEAN stack_flag;
+
+extern BOOLEAN is_value_undef();
+extern STRING get_stacked_string();
+
+/* MACROS */
+
+/* is_undef(tp1) TRUE iff type tp1 is undef */
+#define is_undef(tp1) (tp1 == any_typep)
+
+
+/***************************************************************************/
+/* exec_statement() Execute a statement by calling appropriate routine */
+/* returns the token code of the statement */
+
+TOKEN_CODE exec_statement()
+{
+ TOKEN_CODE stmt_tok;
+ entry_debug("exec_statement (l2xixstm.c)");
+
+ if (ctoken == STATEMENT_MARKER) {
+ exec_line_number = get_statement_cmarker();
+ ++exec_stmt_count;
+
+ statement_startp = code_segmentp;
+ trace_statement_execution();
+ get_ctoken();
+ }
+ stmt_tok = ctoken;
+
+ switch (ctoken) {
+ case IDENTIFIER: {
+ SYMTAB_NODE_PTR idp = get_symtab_cptr();
+
+ if (idp->defn.key == PROC_DEFN ||
+ idp->defn.key == FUNC_DEFN) exec_routine_call(idp);
+ else exec_assignment_statement(idp);
+ break;
+ }
+ case BEGIN: {
+ exec_compound_statement();
+ break;
+ }
+ case CASE: {
+ exec_case_statement();
+ break;
+ }
+ case IF: {
+ exec_if_statement();
+ break;
+ }
+ case REPEAT: {
+ exec_grepeat_statement();
+ break;
+ }
+ case SEMICOLON:
+ case END:
+ case ELSE:
+ case UNTIL: {
+ break;
+ }
+ /* extensions for EXPRESS and ltx2x */
+ case XSKIP : {
+ break;
+ }
+ case XESCAPE : {
+ break;
+ }
+ case XRETURN : {
+ exec_return_statement();
+ exit_debug("exec_statement at XRETURN");
+ return(stmt_tok);
+ }
+ case END_OF_STATEMENTS: {
+ exit_debug("exec_statement at END_OF_STATEMENTS");
+ return(stmt_tok);
+ }
+ case ENDCODE: {
+ exit_debug("exec_statement at ENDCODE");
+ return(stmt_tok);
+ }
+/* case ENDCODE: { added for ltx2x to stop execution */
+/* exit_debug("exec_statement");
+* return;
+* break;
+* }
+*/
+ default: {
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ break;
+ }
+ } /* end switch */
+
+ while (ctoken == SEMICOLON) get_ctoken();
+
+ exit_debug("exec_statement");
+ return(stmt_tok);
+} /* end exec_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_return_statement() Execute a return statement */
+/* at entry, ctoken = RETURN */
+/* at exit, ctoken is token after RETURN */
+
+exec_return_statement()
+{
+ entry_debug("exec_return_statement");
+
+ get_ctoken();
+/* if (ctoken == LPAREN) exec_expression(); */
+ executed_return = TRUE;
+
+ exit_debug("exec_return_statement");
+ return;
+} /* end EXEC_RETURN_STATEMENT */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_assignment_statement(idp) Execute an assignment statement */
+/* */
+
+exec_assignment_statement(idp)
+SYMTAB_NODE_PTR idp; /* target variable id */
+{
+ STACK_ITEM_PTR targetp; /* ptr to assignment target */
+ TYPE_STRUCT_PTR target_tp, base_target_tp, expr_tp;
+ BOOLEAN data_area;
+
+ entry_debug("exec_assignment_statement");
+ data_area = FALSE;
+
+ /* Assignment to function id: target is first item of appropriate stack frame */
+ if (idp->defn.key == FUNC_DEFN) {
+ STACK_ITEM_PTR hp;
+ int delta; /* difference in levels */
+
+ hp = (STACK_ITEM_PTR) stack_frame_basep;
+ delta = level - idp->level - 1;
+ while (delta-- > 0) {
+ hp = (STACK_ITEM_PTR) get_static_link((ADDRESS) hp);
+ }
+ targetp = (STACK_ITEM_PTR) hp;
+ target_tp = idp->typep;
+ get_ctoken();
+ }
+
+ /* Assignment to variable: Routine exec_variable leaves target address */
+ /* on top of stack */
+ else {
+ if ((idp->typep->form == ARRAY_FORM) || (idp->typep->form == ENTITY_FORM)) {
+ data_area = TRUE;
+ debug_print("data_area is TRUE\n");
+ }
+ target_tp = exec_variable(idp, TARGET_USE);
+ targetp = (STACK_ITEM_PTR) get_address(tos);
+
+ pop(); /* pop off the target address */
+ }
+
+ base_target_tp = base_type(target_tp);
+
+ /* Routine exec-expression leaves expression value on top of stack */
+ get_ctoken();
+ expr_tp = exec_expression();
+
+ if (stack_flag) {
+ log_print("Assignment LHS: ");
+ expression_type_debug(target_tp);
+ log_print("Assignment RHS: ");
+ expression_type_debug(expr_tp);
+ }
+
+
+ /* do the assignment */
+
+ exec_the_assign(targetp, target_tp, expr_tp);
+
+ trace_data_store(idp, idp->typep, targetp, target_tp);
+
+ exit_debug("exec_assignment_statement");
+ return;
+} /* end exec_assignment_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_the_assign(targetp, target_tp, expr_tp) Do the actual assignment */
+/* targetp, target_tp are the target and its type; */
+/* expr_tp is the RHS type with its value on top of the stack. */
+/* The current token is unchanged */
+
+exec_the_assign(targetp, target_tp, expr_tp)
+STACK_ITEM_PTR targetp; /* ptr to LHS */
+TYPE_STRUCT_PTR target_tp; /* ptr to type of LHS */
+TYPE_STRUCT_PTR expr_tp; /* ptr to type of RHS */
+{
+ TYPE_STRUCT_PTR base_target_tp; /* ptr to LHS base type */
+ STACK_TYPE rhstype; /* type on top of the stack */
+ int size;
+ entry_debug("exec_the_assign");
+
+ if (is_undef(expr_tp) || is_value_undef(tos)) {
+ put_undef(targetp);
+ pop();
+ exit_debug("exec_the_assign at undef");
+ return;
+ }
+
+ rhstype = get_stackval_type(tos);
+ if (expr_tp->form == ARRAY_FORM) { /* then RHS is an array (element?) */
+ if (rhstype == STKADD) {
+ copy_value(tos, get_address(tos));
+ }
+ }
+
+ base_target_tp = base_type(target_tp);
+
+ if ((target_tp == real_typep) && (base_type(expr_tp) == integer_typep)) {
+ /* real := integer */
+ put_real(targetp, (XPRSAREAL) get_integer(tos));
+ }
+
+ else if (target_tp == logical_typep) {
+ /* logical := logical */
+ put_logical(targetp, get_logical(tos));
+ }
+
+ else if (target_tp->form == STRING_FORM && expr_tp->form == STRING_FORM) {
+ /* string := string */
+ exec_string_assign((STACK_ITEM_PTR) targetp);
+ }
+
+ else if (target_tp->form == ARRAY_FORM) {
+ if (base_type(expr_tp) == target_tp->info.array.elmt_typep) { /* array := el */
+ copy_value(targetp, tos);
+ }
+ else { /* assume array := array */
+ ICT *ptr1 = (ICT *) targetp;
+ ICT *ptr2 = get_address(tos);
+ size = target_tp->size;
+ while (size--) *ptr1++ = *ptr2++;
+ }
+ }
+
+ else if (target_tp->form == ENTITY_FORM ) {
+ /* entity := entity */
+ ICT *ptr1 = (ICT *) targetp;
+ ICT *ptr2 = get_address(tos);
+ size = target_tp->size;
+ while (size--) *ptr1++ = *ptr2++;
+ }
+ else if ((base_target_tp == integer_typep) ||
+ (target_tp->form == ENUM_FORM)) {
+ /* Range check assignment to integer or enumeration subrange */
+ if ((target_tp->form == SUBRANGE_FORM) &&
+ ((get_integer(tos) < target_tp->info.subrange.min) ||
+ (get_integer(tos) > target_tp->info.subrange.max))) {
+ runtime_error(VALUE_OUT_OF_RANGE);
+ }
+
+ /* integer := integer */
+ /* enumeration := enumeration */
+ put_integer(targetp, get_integer(tos));
+ }
+
+ else {
+ /* real := real */
+ put_real(targetp, get_real(tos));
+ }
+
+ pop(); /* pop expression value */
+
+ exit_debug("exec_the_assign");
+ return;
+} /* end EXEC_THE_ASSIGN */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_string_assign Execute string := string */
+/* */
+
+exec_string_assign(targetp)
+STACK_ITEM_PTR targetp; /* the LHS */
+{
+ STRING rhs; /* the RHS */
+ STRING lhs;
+ int num;
+ int maxchrs;
+ entry_debug("exec_string_assign");
+
+ rhs = get_stacked_string(tos); /* top of stack points to the string */
+ free(targetp->value.string);
+ num = strlen(rhs);
+ sprintf(dbuffer, "strlen(str) = %d, str = %s\n", num, rhs);
+ debug_print(dbuffer);
+ lhs = alloc_bytes(num+1);
+ sprintf(dbuffer, "lhs = %d", lhs);
+ debug_print(dbuffer);
+ strcpy(lhs, rhs);
+ sprintf(dbuffer, ", str = %s\n", lhs);
+ debug_print(dbuffer);
+
+ put_string(targetp, lhs);
+/* set_string(targetp, rhs); */
+
+ exit_debug("exec_string_assign");
+ return;
+} /* end EXEC_STRING_ASSIGN */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* set_string(var_idp, str) Attaches string str to variable */
+
+set_string(var_idp, str)
+SYMTAB_NODE_PTR var_idp; /* variable in the symbol table */
+STRING str; /* the string */
+{
+ int num;
+ int maxchrs = 527;
+ TYPE_STRUCT_PTR strtyp;
+ entry_debug("set_string (l2xixstm.c)");
+
+ sprintf(dbuffer, "var_idp = %d\n", var_idp);
+ debug_print(dbuffer);
+ num = strlen(str);
+ sprintf(dbuffer, "num = strlen(str) = %d\n", num);
+ debug_print(dbuffer);
+ debug_print(str);
+ strtyp = var_idp->typep;
+/* maxchrs = var_idp->typep->info.string.max_length; */
+/* maxchrs = strtyp->info.string.max_length; */
+ sprintf(dbuffer, "\nmaxchrs = %d\n", maxchrs);
+ debug_print(dbuffer);
+ if (num > maxchrs) {
+ runtime_error(RUNTIME_STRING_TOO_LONG);
+ free(var_idp->info);
+ var_idp->info = alloc_bytes(maxchrs + 1);
+ strncpy(var_idp->info, str, maxchrs);
+ var_idp->info[maxchrs] = '\0';
+ strtyp->info.string.length = maxchrs;
+ }
+ else {
+/* free(var_idp->info); */
+ var_idp->info = alloc_bytes(num+1);
+ strcpy(var_idp->info, str);
+/* strtyp->info.string.length = num; */
+ }
+
+ exit_debug("set_string");
+} /* end SET_STRING */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_routine_call(rtn_idp) Execute procedure or function call. */
+/* return pointer to the type structure */
+
+TYPE_STRUCT_PTR exec_routine_call(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ TYPE_STRUCT_PTR exec_declared_routine_call();
+ TYPE_STRUCT_PTR exec_standard_routine_call();
+ entry_debug("exec_routine_call");
+
+ if (rtn_idp->defn.info.routine.key == DECLARED) {
+ exit_debug("exec_routine_call");
+ return(exec_declared_routine_call(rtn_idp));
+ }
+ else {
+ exit_debug("exec_routine_call");
+ return(exec_standard_routine_call(rtn_idp));
+ }
+
+} /* end exec_routine_call */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_declared_routine_call(rtn_idp) Execute a call to a declared */
+/* function or procedure */
+/* return pointer to the type structure */
+
+TYPE_STRUCT_PTR exec_declared_routine_call(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* routine id */
+{
+ int old_level = level; /* level of caller */
+ int new_level = rtn_idp->level + 1; /* level of callee */
+ STACK_ITEM_PTR new_stack_frame_basep;
+ STACK_ITEM_PTR hp; /* ptr to frame header */
+ entry_debug("exec_declared_routine_call");
+
+ /* set up stack frame of callee */
+ new_stack_frame_basep = tos + 1;
+ push_stack_frame_header(old_level, new_level);
+
+ /* push parameter values onto the stack */
+ get_ctoken();
+ if (ctoken == LPAREN) {
+ exec_actual_parms(rtn_idp);
+ get_ctoken(); /* the token after the RPAREN */
+ }
+
+ /* set the return address in the new stack frame, and execute callee */
+ level = new_level;
+ stack_frame_basep = new_stack_frame_basep;
+ hp = stack_frame_basep;
+/* put_address(hp->return_address, (code_segmentp - 1)); */
+ put_return_address(hp, (code_segmentp - 1));
+/* execute(rtn_idp); changed this call for EXPRESS */
+ exec_algorithm(rtn_idp);
+
+ /* return from callee */
+ level = old_level;
+ get_ctoken(); /* first token after return */
+
+ exit_debug("exec_declared_routine_call");
+ return(rtn_idp->defn.key == PROC_DEFN ? NULL : rtn_idp->typep);
+
+} /* end exec_declared_routine_call */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_actual_parms(rtn_idp) Push the values of the actual parameters */
+/* onto the stack */
+
+exec_actual_parms(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* id of callee routine */
+{
+ SYMTAB_NODE_PTR formal_idp; /* formal param id */
+ TYPE_STRUCT_PTR formal_tp, actual_tp;
+ entry_debug("exec_actual_parms");
+
+ /* loop to execute actual params */
+ for (formal_idp = rtn_idp->defn.info.routine.parms;
+ formal_idp != NULL;
+ formal_idp = formal_idp->next) {
+ formal_tp = formal_idp->typep;
+ get_ctoken();
+
+ /* value parameter */
+ if (formal_idp->defn.key == VALPARM_DEFN) {
+ actual_tp = exec_expression();
+
+ /* Range check for a subrange formal param */
+ if (formal_tp->form == SUBRANGE_FORM) {
+ TYPE_STRUCT_PTR base_formal_tp = base_type(formal_tp);
+ XPRSAINT value;
+
+ value = get_integer(tos);
+ if ((value < formal_tp->info.subrange.min) ||
+ (value > formal_tp->info.subrange.max)) {
+ runtime_error(VALUE_OUT_OF_RANGE);
+ }
+ }
+
+ else if ((formal_tp == real_typep) &&
+ (base_type(actual_tp) == integer_typep)) {
+ /* real formal := integer actual */
+ put_real(tos, (XPRSAREAL) get_integer(tos));
+ }
+
+ if ((formal_tp->form == ARRAY_FORM) ||
+ (formal_tp->form == ENTITY_FORM)) {
+ /* formal param is array or entity. Make a copy */
+ int size = formal_tp->size;
+ ICT *ptr1 = alloc_array(ICT, size);
+ ICT *ptr2 = get_address(tos); /* ??????????????????? */
+ ICT *save_ptr = ptr1;
+
+ while (size--) *ptr1++ = *ptr2++;
+ put_address(tos, save_ptr);
+ }
+ } /* end value param */
+
+ /* a VAR parameter */
+ else {
+ SYMTAB_NODE_PTR idp = get_symtab_cptr();
+ exec_variable(idp, VARPARM_USE);
+ }
+
+ } /* end for loop */
+
+ exit_debug("exec_actual_parms");
+} /* end exec_actual_parms */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_compound_statement() Execute a compound statement */
+/* */
+
+exec_compound_statement()
+{
+ entry_debug("exec_compound_statement");
+
+ get_ctoken();
+ while (ctoken != END) exec_statement();
+ get_ctoken();
+
+ exit_debug("exec_compound_statement");
+ return;
+} /* end exec_compound_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_case_statement() Execute a CASE statement */
+/* CASE <expr> OF */
+/* <case-branch> */
+/* END */
+
+exec_case_statement()
+{
+ XPRSAINT case_expr_value; /* CASE expr value */
+ XPRSAINT case_label_count; /* CASE label count */
+ XPRSAINT case_label_value; /* CASE label value */
+ ADDRESS branch_table_location; /* branch table address */
+ ADDRESS case_branch_location; /* CASE branch address */
+ TYPE_STRUCT_PTR case_expr_tp; /* CASE expr type */
+ BOOLEAN done = FALSE;
+ BOOLEAN found_otherwise = FALSE;
+ ADDRESS otherwise_location;
+ entry_debug("exec_case_statement");
+
+ get_ctoken(); /* token after CASE */
+ branch_table_location = get_address_cmarker();
+
+ /* evaluate the CASE expr */
+ get_ctoken();
+ case_expr_tp = exec_expression();
+ case_expr_value = get_integer(tos);
+ pop(); /* expression value */
+
+ /* search the branch table for the expr value */
+ code_segmentp = branch_table_location;
+ get_ctoken();
+ case_label_count = get_cinteger();
+ while (!done && case_label_count--) {
+ case_label_value = get_cinteger();
+ case_branch_location = get_caddress();
+ done = case_label_value == case_expr_value;
+ if (case_label_value == XOTHERWISE) {
+ found_otherwise = TRUE;
+ otherwise_location = case_branch_location;
+ }
+ }
+
+ /* if found, goto the appropriate CASE branch */
+ if (case_label_count >= 0) {
+ code_segmentp = case_branch_location;
+ get_ctoken();
+ exec_statement();
+
+
+ code_segmentp = get_address_cmarker();
+ get_ctoken();
+ }
+ else if (found_otherwise) {
+ code_segmentp = otherwise_location;
+ get_ctoken();
+ exec_statement();
+
+ code_segmentp = get_address_cmarker();
+ get_ctoken();
+ }
+ else {
+ runtime_error(INVALID_CASE_VALUE);
+ }
+
+ exit_debug("exec_case_statement");
+ return;
+} /* end exec_case_statement */
+/***************************************************************************/
+
+
+
+
+
+/***************************************************************************/
+/* exec_if_statement() Execute an IF statement */
+/* IF <expr> THEN <stmt> END_IF */
+/* or */
+/* IF <expr> THEN <stmt> ELSE <stmt> END_IF */
+
+exec_if_statement()
+{
+ ADDRESS false_location; /* address of false branch */
+ BOOLEAN test;
+ entry_debug("exec_if_statement");
+
+ get_ctoken(); /* token after if */
+ false_location = get_address_cmarker();
+
+ /* evaluate the boolean expression */
+ get_ctoken();
+ exec_expression();
+ test = get_logical(tos) == TRUE_REP;
+ pop(); /* boolean value */
+
+ if (test) { /* do the TRUE branch */
+ get_ctoken(); /* token after THEN */
+ while (ctoken != ELSE && ctoken != XEND_IF) exec_statement();
+ if (ctoken == ELSE) {
+ get_ctoken();
+ code_segmentp = get_address_cmarker();
+ get_ctoken(); /* token after false stmt */
+ }
+ }
+ else { /* do the ELSE branch if there is one */
+ code_segmentp = false_location;
+ get_ctoken();
+
+ if (ctoken == ELSE ) {
+ get_ctoken();
+ get_address_cmarker(); /* skip the address marker */
+
+ get_ctoken();
+ while(ctoken != XEND_IF) exec_statement();
+ }
+ }
+ get_ctoken(); /* after the END_IF */
+
+
+ exit_debug("exec_if_statement");
+ return;
+} /* end exec_if_statement */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_grepeat_statement() Execute an EXPRESS REPEAT statement */
+/* REPEAT [ <inc_control> ] <while_control> <until_control> */
+/* <stmt-list> END_REPEAT; */
+/* at entry: ctoken is REPEAT */
+/* at exit: ctoken is after END_REPEAT; */
+
+exec_grepeat_statement()
+{
+ SYMTAB_NODE_PTR control_idp; /* control var id */
+ TYPE_STRUCT_PTR control_tp; /* control var type */
+ STACK_ITEM_PTR targetp; /* ptr to control target */
+ ADDRESS loop_start_location; /* address of start of loop */
+ ADDRESS loop_end_location; /* address of end of loop */
+ ADDRESS until_start_location;
+ ADDRESS to_start_location;
+ ADDRESS while_start_location;
+ ADDRESS statements_start_location;
+ BOOLEAN loop_done = FALSE;
+ BOOLEAN is_increment_control = FALSE; /* TRUE iff there is an inc. control */
+ int control_value; /* value of control var */
+ int initial_value, final_value, delta_value;
+ TOKEN_CODE stmt_tok;
+ entry_debug("exec_grepeat_statement (l2xixstm.c)");
+
+ /* the first time through */
+ get_ctoken(); /* code (address marker) token after REPEAT */
+ loop_end_location = get_address_cmarker();
+ sprintf(dbuffer, "loop_end_location = %d\n", loop_end_location);
+ debug_print(dbuffer);
+ get_ctoken(); /* source token after REPEAT */
+
+ if (ctoken == FOR) { /* increment control */
+ is_increment_control = TRUE;
+ get_ctoken(); /* IDENTIFIER for the variable */
+ /* get address of control var's stack item */
+ control_idp = get_symtab_cptr();
+ control_tp = exec_variable(control_idp, TARGET_USE);
+ targetp = (STACK_ITEM_PTR) get_address(tos);
+ pop(); /* pop control var's address */
+
+ /* evaluate the initial expression */
+ get_ctoken();
+ exec_expression();
+ initial_value = get_integer(tos);
+ pop(); /* initial value */
+ put_integer(targetp, initial_value);
+ control_value = initial_value;
+
+ /* evaluate the final expression */
+ get_ctoken();
+ to_start_location = code_segmentp -1;
+ sprintf(dbuffer, "to_start_location = %d\n", to_start_location);
+ debug_print(dbuffer);
+ exec_expression();
+ final_value = get_integer(tos);
+ pop(); /* final value */
+
+ /* get the increment */
+ get_ctoken();
+ exec_expression();
+ delta_value = get_integer(tos);
+ pop(); /* delta value */
+ /* check the bound */
+ if ((delta_value >= 0 && control_value > final_value) ||
+ (delta_value < 0 && control_value < final_value)) {
+ code_segmentp = loop_end_location;
+ get_ctoken();
+ loop_done = TRUE;
+ }
+ if (loop_done) {
+ exit_debug("exec_grepeat_statement");
+ return;
+ }
+ }
+
+ /* check the WHILE condition */
+ get_ctoken();
+ while_start_location = code_segmentp -1;
+ sprintf(dbuffer, "while_start_location = %d\n", while_start_location);
+ debug_print(dbuffer);
+ exec_expression();
+ if (get_logical(tos) == FALSE_REP) { /* finished */
+ code_segmentp = loop_end_location;
+ get_ctoken();
+ loop_done = TRUE;
+ }
+ pop(); /* the WHILE value */
+ if (loop_done) {
+ exit_debug("exec_grepeat_statement");
+ return;
+ }
+
+ /* skip the UNTIL condition */
+ get_ctoken();
+ until_start_location = code_segmentp -1;
+ sprintf(dbuffer, "until_start_location = %d\n", until_start_location);
+ debug_print(dbuffer);
+ while (ctoken != STATEMENT_MARKER) get_ctoken();
+ statements_start_location = code_segmentp -1;
+ sprintf(dbuffer, "statements_start_location = %d\n", statements_start_location);
+ debug_print(dbuffer);
+
+ /* do the statements */
+ do {
+ stmt_tok = exec_statement();
+ if (stmt_tok == XSKIP) {
+ code_segmentp = until_start_location;
+ break;
+ }
+ else if (stmt_tok == XESCAPE) {
+ code_segmentp = loop_end_location;
+ get_ctoken();
+ loop_done = TRUE;
+ pop();
+ exit_debug("exec_grepeat_statement");
+ return;
+ }
+ } while (ctoken != XEND_REPEAT);
+
+ /* This finishes the first pass, do subsequent passes */
+ do {
+ /* check the UNTIL expression */
+ code_segmentp = until_start_location;
+ get_ctoken();
+ exec_expression();
+ if (get_logical(tos) == TRUE_REP) { /* finished */
+ code_segmentp = loop_end_location;
+ get_ctoken();
+ loop_done = TRUE;
+ }
+ pop(); /* the UNTIL value */
+ if (loop_done) {
+ exit_debug("exec_grepeat_statement");
+ return;
+ }
+
+ /* increment control now */
+ if (is_increment_control) {
+ /* perform the increment */
+ control_value = get_integer(targetp) + delta_value;
+ put_integer(targetp, control_value);
+ /* do the check */
+ code_segmentp = to_start_location;
+ get_ctoken();
+ exec_expression();
+ get_integer(tos);
+ if ((delta_value >= 0 && control_value > final_value) ||
+ (delta_value < 0 && control_value < final_value)) {
+ code_segmentp = loop_end_location;
+ get_ctoken();
+ loop_done = TRUE;
+ }
+ pop(); /* the to value */
+ if (loop_done) {
+ exit_debug("exec_grepeat_statement");
+ return;
+ }
+ }
+
+ /* check the WHILE */
+ code_segmentp = while_start_location;
+ get_ctoken();
+ exec_expression();
+ if (get_logical(tos) == FALSE_REP) {
+ code_segmentp = loop_end_location;
+ get_ctoken();
+ loop_done = TRUE;
+ }
+ pop(); /* the WHILE value */
+ if (loop_done) {
+ exit_debug("exec_grepeat_statement");
+ return;
+ }
+
+ /* and now back to executing the statements */
+ code_segmentp = statements_start_location;
+ get_ctoken();
+ do {
+ exec_statement();
+ } while (ctoken != XEND_REPEAT);
+ /* start again checking the UNTIL condition */
+ code_segmentp = until_start_location;
+ } while(TRUE);
+
+
+ exit_debug("exec_grepeat_statement");
+ return;
+
+} /* end EXEC_GREPEAT_STATEMENT */
+/***************************************************************************/
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xixutl.c b/support/ltx2x/l2xixutl.c
new file mode 100644
index 0000000000..47b0d5f2a7
--- /dev/null
+++ b/support/ltx2x/l2xixutl.c
@@ -0,0 +1,1866 @@
+/* l2xixutl.c LTX2X Executor utility routines */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiidbg.h"
+#include "l2xiexec.h"
+
+#include "listsetc.h"
+
+/* EXTERNALS */
+
+extern TOKEN_CODE token;
+extern int line_number;;
+extern int level;
+
+extern BOOLEAN executed_return; /* TRUE iff return statement executed */
+
+/* GLOBALS */
+
+ICT *code_buffer; /* code buffer */
+ICT *code_bufferp; /* code buffer ptr */
+ICT *code_segmentp; /* code segment ptr */
+ICT *code_segment_limit; /* end of code segment */
+
+ICT *statement_startp; /* ptr to start of statement */
+TOKEN_CODE ctoken; /* token from code segment */
+int exec_line_number; /* no. of line executed */
+long exec_stmt_count = 0; /* count of executed statements */
+
+STACK_ITEM *stack; /* runtime stack */
+STACK_ITEM_PTR tos; /* ptr to top of runtime stack */
+STACK_ITEM_PTR stack_frame_basep; /* ptr to stack fame base */
+STACK_ITEM_PTR maxtos; /* current max top of runtime stack */
+
+/* map from form type to stack type */
+STACK_TYPE form2stack[] = {
+#define fotc(a, b, c, d) a,
+#define sotc(a, b, c, d)
+#define sftc(a, b, c, d) a,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+};
+
+/* map from stack type to form type */
+TYPE_FORM stack2form[] = {
+#define fotc(a, b, c, d)
+#define sotc(a, b, c, d) c,
+#define sftc(a, b, c, d) c,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+};
+
+/* FORWARDS */
+
+ADDRESS get_static_link();
+ADDRESS get_dynamic_link();
+ADDRESS get_return_address();
+STACK_TYPE get_stackval_type();
+
+/* CODE SEGMENT ROUTINES */
+
+
+/***************************************************************************/
+/* create_code_segment() Create a code segment and copy in the contents */
+/* of the code buffer. Reset the code buffer pointer */
+/* return a pointer to the segment */
+
+ICT *create_code_segment()
+{
+ ICT *code_segment = alloc_array(ICT, (code_bufferp - code_buffer));
+ entry_debug("create_code_segment");
+
+ code_segment_limit = code_segment + (code_bufferp - code_buffer);
+ code_bufferp = code_buffer;
+ code_segmentp = code_segment;
+
+ /* copy in the contents of the code buffer */
+ while (code_segmentp != code_segment_limit) {
+ *code_segmentp++ = *code_bufferp++;
+ }
+ /* reset the code buffer pointer */
+ code_bufferp = code_buffer;
+
+ code_segment_debug(code_segment, code_segment_limit);
+
+ exit_debug("create_code_segment");
+ return(code_segment);
+
+} /* end create_code_segment */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* crunch_token() Append the token code to the code buffer. */
+/* Called by the scanner routine only while parsing a block */
+
+
+crunch_token()
+{
+ int token_code = token; /* integer sized token code */
+ entry_debug("crunch_token");
+
+ if ((code_bufferp - code_buffer) >= MAX_CODE_BUFFER_SIZE - sizeof(token_code)) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+
+ *code_bufferp++ = (ICT) token_code;
+
+ exit_debug("crunch_token");
+ return;
+} /* end crunch_token */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* crunch_extra_token() Append the token code to the code buffer. */
+
+crunch_extra_token(tok)
+TOKEN_CODE tok;
+{
+ entry_debug("crunch_extra_token (l2xixutl.c)");
+
+ if ((code_bufferp - code_buffer) >= MAX_CODE_BUFFER_SIZE - sizeof(tok)) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+
+ *code_bufferp++ = (ICT) tok;
+
+ exit_debug("crunch_extra_token");
+ return;
+} /* end CRUNCH_EXTRA_TOKEN */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* get_ctoken() Gets next crunched token */
+
+TOKEN_CODE get_ctoken()
+{
+ entry_debug("get_ctoken (l2xixutl.c)");
+
+ code_segment_entry_debug(code_segmentp);
+ ctoken = *code_segmentp++;
+
+ exit_debug("get_ctoken");
+ return(ctoken);
+} /* end GET_CTOKEN */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* change_crunched_token(newtok) Replace the last token in the code */
+/* segment by newtok */
+
+change_crunched_token(newtok)
+int newtok; /* integer sized new token code */
+{
+ ICT *bp;
+ entry_debug("change_crunched_token");
+
+ bp = code_bufferp;
+ bp--;
+
+ *bp = (ICT) newtok;
+
+ exit_debug("change_crunched_token");
+ return;
+} /* end CHANGE_CRUNCHED_TOKEN */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* backup_crunched() prepare to write over last code entry */
+/* */
+
+backup_crunched()
+{
+ entry_debug("backup_crunched");
+
+ code_bufferp--;
+
+ exit_debug("backup_crunched");
+ return;
+} /* end BACKUP_CRUNCHED */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* crunch_symtab_node_ptr(np) Append a symbol table node pointer to the */
+/* code buffer */
+
+crunch_symtab_node_ptr(np)
+SYMTAB_NODE_PTR np; /* pointer to append */
+{
+/* SYMTAB_NODE_PTR *npp = (SYMTAB_NODE_PTR *) code_bufferp; */
+ ICT *npp = code_bufferp;
+
+ entry_debug("crunch_symtab_node_ptr");
+
+ if ((code_bufferp - code_buffer) >=
+ (MAX_CODE_BUFFER_SIZE - sizeof(SYMTAB_NODE_PTR))) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+ else {
+ *npp = (ICT) np;
+ code_bufferp++;
+ }
+
+ exit_debug("crunch_symtab_node_ptr");
+ return;
+} /* end crunch_symtab_node_ptr */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* get_symtab_cptr() Extract a symbol table node pointer from the current */
+/* code segment */
+/* return the symbol table node pointer */
+
+SYMTAB_NODE_PTR get_symtab_cptr()
+{
+ SYMTAB_NODE_PTR np;
+ ICT *npp = code_segmentp;
+
+ np = (SYMTAB_NODE_PTR) *npp;
+/* code_segmentp += sizeof(SYMTAB_NODE_PTR); */
+ code_segmentp++;
+
+ return(np);
+} /* end get_symtab_cptr */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* crunch_statement_marker() Append a statement marker to the code buffer */
+/* */
+
+crunch_statement_marker()
+{
+ entry_debug("crunch_statement_marker");
+
+ if ((code_bufferp - code_buffer) >= MAX_CODE_BUFFER_SIZE) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+ else {
+ ICT save_code = *(--code_bufferp);
+
+ *code_bufferp++ = STATEMENT_MARKER;
+ *((int *) code_bufferp) = line_number;
+ code_bufferp++;
+ *code_bufferp++ = save_code;
+ }
+
+ exit_debug("crunch_statement_marker");
+ return;
+} /* end crunch_statement_marker */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_statement_cmarker() Extract a statement marker from the current */
+/* code segment. */
+/* return its line number. */
+
+
+int get_statement_cmarker()
+{
+ int line_num;
+ entry_debug("get_statement_cmarker");
+
+
+ if (ctoken == STATEMENT_MARKER) {
+ line_num = *((int *) code_segmentp);
+ code_segmentp++;
+ }
+
+ exit_debug("get_statement_cmarker");
+ return(line_num);
+} /* end get_statement_cmarker */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* crunch_address_marker(address) Append a code address to the code */
+/* buffer */
+/* return the address of the address */
+
+ICT *crunch_address_marker(address)
+ADDRESS address;
+{
+
+ ICT *save_code_bufferp;
+
+ if ((code_bufferp - code_buffer) >= MAX_CODE_BUFFER_SIZE - sizeof(ADDRESS)) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+ else {
+ ICT save_code = *(--code_bufferp);
+
+ *code_bufferp++ = (ICT) ADDRESS_MARKER;
+ save_code_bufferp = code_bufferp;
+ *((ADDRESS *) code_bufferp) = address;
+ code_bufferp++;
+ *code_bufferp++ = save_code;
+ }
+
+ return(save_code_bufferp);
+} /* end crunch_address_marker */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* get_address_cmarker Extract an address marker from current code */
+/* segment. Add its offset value to the code segment */
+/* address. */
+/* return new address */
+
+ADDRESS get_address_cmarker()
+{
+ ADDRESS address; /* address to be returned */
+
+ if (ctoken == ADDRESS_MARKER) {
+ address = *((int *) code_segmentp) + code_segmentp - 1;
+ code_segmentp++;
+ }
+
+ return(address);
+
+} /* end get_address_cmarker */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* fixup_address_marker(address) Fix up an address marker with the offset */
+/* from the address marker to the current */
+/* code buffer address. */
+/* return the old value of the address marker */
+
+ADDRESS fixup_address_marker(address)
+ADDRESS address; /* address of marker to be fixed up */
+{
+
+/* ADDRESS old_address = address; */
+/* int *old_address = *((ADDRESS *) address); */
+ ADDRESS old_address = *((ADDRESS *) address);
+
+ *((int *) address) = code_bufferp - address;
+ return(old_address);
+
+} /* end fixup_address_marker */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* crunch_integer(value) Append an integer value to the code buffer */
+
+crunch_integer(value)
+XPRSAINT value;
+{
+
+ if ((code_bufferp - code_buffer) >= MAX_CODE_BUFFER_SIZE - sizeof(XPRSAINT)) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+ else {
+ *code_bufferp++ = (ICT) value;
+ }
+
+} /* end crunch_integer */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* get_cinteger Extract an integer from the current code segment */
+/* return the value */
+
+XPRSAINT get_cinteger()
+{
+ XPRSAINT value;
+
+ value = (XPRSAINT) *code_segmentp++;
+
+ return(value);
+
+} /* end get_cinteger */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* crunch_offset(address) Append an integer value to the code that */
+/* represents the offset from the given address */
+/* to the current code buffer address */
+
+crunch_offset(address)
+ADDRESS address;
+{
+ ICT *temp;
+
+ if ((code_bufferp - code_buffer) >= MAX_CODE_BUFFER_SIZE - sizeof(int)) {
+ error(CODE_SEGMENT_OVERFLOW);
+ exit(-CODE_SEGMENT_OVERFLOW);
+ }
+ else {
+ temp = code_bufferp;
+ *code_bufferp++ = address - temp;
+ }
+
+} /* end crunch_offset */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* get_caddress() Extract an offset from the current code segment and */
+/* add it to the code segment address. */
+/* return the new address */
+
+ADDRESS get_caddress()
+{
+ ADDRESS address;
+
+ address = *((int *) code_segmentp) + code_segmentp - 1;
+ code_segmentp++;
+
+ return(address);
+
+} /* end get_caddress */
+/***************************************************************************/
+
+
+/* EXECUTOR UTILITIES */
+
+
+/***************************************************************************/
+/* get_element_type(tp) Given an aggregate type, return the element type */
+
+TYPE_STRUCT_PTR get_element_type(agg_tp)
+TYPE_STRUCT_PTR agg_tp; /* the aggregate type */
+{
+ TYPE_STRUCT_PTR et;
+
+ if (is_array(agg_tp)) return(agg_tp->info.array.elmt_typep);
+ else if (is_dynagg(agg_tp)) return(agg_tp->info.dynagg.elmt_typep);
+ else return(agg_tp);
+
+} /* end GET_ELEMENT_TYPE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_integer(item_value) Push an integer onto the runtime stack */
+
+push_integer(item_value)
+XPRSAINT item_value;
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_integer");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKINT;
+ itemp->value.integer = item_value;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_integer");
+ return;
+} /* end push_integer */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_integer(sptr, item_value) Put an integer into the runtime stack */
+
+put_integer(sptr, item_value)
+STACK_ITEM_PTR sptr;
+XPRSAINT item_value;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_integer");
+
+ itemp->type = STKINT;
+ itemp->value.integer = item_value;
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_integer");
+ return;
+} /* end put_integer */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* int get_integer(sptr) Get an integer from the runtime stack */
+
+XPRSAINT get_integer(sptr)
+STACK_ITEM_PTR sptr;
+{
+ int item_value = 0;
+ XPRSAREAL r1;
+ STACK_ITEM_PTR itemp = sptr;
+ STACK_TYPE stype;
+ entry_debug("get_integer");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ return(item_value);
+ }
+
+ stype = itemp->type;
+ if (stype == STKINT) {
+ item_value = itemp->value.integer;
+ }
+ else if (stype == STKREA) { /* real value, return nearest integer */
+ r1 = itemp->value.real;
+ item_value = r1 > 0.0 ? (XPRSAINT) (r1 + 0.5)
+ : (XPRSAINT) (r1 - 0.5);
+ }
+ else {
+ stack_warning(STKINT, stype);
+ }
+
+ exit_debug("get_integer");
+ return(item_value);
+} /* end get_integer */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_real(item_value) Push a real onto the runtime stack */
+
+push_real(item_value)
+XPRSAREAL item_value;
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_real");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKREA;
+ itemp->value.real = item_value;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_real");
+ return;
+} /* end push_real */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_real(sptr, item_value) Put a real into the runtime stack */
+
+put_real(sptr, item_value)
+STACK_ITEM_PTR sptr;
+XPRSAREAL item_value;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_real");
+
+
+ itemp->type = STKREA;
+ itemp->value.real = item_value;
+
+ stack_access_debug("Put",itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_real");
+ return;
+} /* end put_real */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* float get_real(sptr) Get a real from the runtime stack */
+
+XPRSAREAL get_real(sptr)
+STACK_ITEM_PTR sptr;
+{
+ XPRSAREAL item_value = 0.0;
+ STACK_ITEM_PTR itemp = sptr;
+ STACK_TYPE stype;
+ entry_debug("get_real");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ return(item_value);
+ }
+
+ stype = itemp->type;
+ if (stype == STKREA) {
+ item_value = itemp->value.real;
+ }
+ else if (stype == STKINT) { /* convert integer to float */
+ item_value = (XPRSAREAL) itemp->value.integer;
+ }
+ else {
+ stack_warning(STKREA, stype);
+ }
+
+ exit_debug("get_real");
+ return(item_value);
+} /* end get_real */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_address(item_value) Push an address onto the runtime stack */
+
+push_address(address)
+ADDRESS address;
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_address");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKADD;
+ itemp->value.address = address;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_address");
+ return;
+} /* end push_address */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_address(sptr, item_value) Put an address into the runtime stack */
+
+put_address(sptr, address)
+STACK_ITEM_PTR sptr;
+ADDRESS address;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_address");
+
+
+ itemp->type = STKADD;
+ itemp->value.address = address;
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_address");
+ return;
+} /* end put_address */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* ADDRESS get_address(sptr) Get an address from the runtime stack */
+
+ADDRESS get_address(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ ADDRESS address = NULL;
+ STACK_TYPE stype;
+ entry_debug("get_address");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ return(address);
+ }
+
+ stype = get_stackval_type(itemp);
+ if (stype == STKINT ||
+ stype == STKREA ||
+ stype == STKLOG ||
+ stype == STKSTR ||
+ stype == STKBAG ||
+ stype == STKLST ||
+ stype == STKSET ||
+ stype == STKUDF) {
+ stack_warning(STKADD, stype);
+ }
+ else {
+ address = itemp->value.address;
+ }
+
+ exit_debug("get_address");
+ return(address);
+} /* end get_address */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_address_type(item_value, type) Push an address onto the runtime */
+/* stack */
+
+push_address_type(address, type)
+ADDRESS address;
+STACK_TYPE type;
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_address_type (l2xixutl.c)");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ switch (type) {
+ case STKBAG:
+ case STKLST:
+ case STKSET: {
+ itemp->type = type;
+ itemp->value.head = (LBS_PTR) address;
+ break;
+ }
+ case STKSTR: {
+ itemp->type = type;
+ itemp->value.string = (STRING) address;
+ break;
+ }
+ default : {
+ itemp->type = type;
+ itemp->value.address = address;
+ break;
+ }
+ }
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_address_type");
+ return;
+} /* end push_address_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_address_type(sptr, item_value, type) Put an address into the runtime stack */
+
+put_address_type(sptr, address, type)
+STACK_ITEM_PTR sptr;
+ADDRESS address;
+STACK_TYPE type;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_address_type (l2xixutl.c)");
+
+ switch (type) {
+ case STKBAG:
+ case STKLST:
+ case STKSET: {
+ itemp->type = type;
+ itemp->value.head = (LBS_PTR) address;
+ break;
+ }
+ case STKSTR: {
+ itemp->type = type;
+ itemp->value.string = (STRING) address;
+ break;
+ }
+ default : {
+ itemp->type = type;
+ itemp->value.address = address;
+ break;
+ }
+ }
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_address_type");
+ return;
+} /* end put_address_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* ADDRESS get_address_type(sptr, type) Get an address from the runtime stack */
+
+ADDRESS get_address_type(sptr, type)
+STACK_ITEM_PTR sptr;
+STACK_TYPE type;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ ADDRESS address = NULL;
+ STACK_TYPE ftype;
+ entry_debug("get_address_type (l2xixutl.c)");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ return(NULL);
+ }
+
+ ftype = get_stackval_type(itemp);
+ if (type != ftype) stack_warning(type, ftype);
+
+ switch (ftype) {
+ case STKBAG:
+ case STKLST:
+ case STKSET: {
+ address = (ADDRESS) itemp->value.head;
+ break;
+ }
+ case STKSTR: {
+ address = (ADDRESS) itemp->value.string;
+ break;
+ }
+ case STKADD:
+ case STKARY:
+ case STKENT: {
+ address = itemp->value.address;
+ break;
+ }
+ }
+
+ exit_debug("get_address_type");
+ return(address);
+} /* end get_address_type */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_stackval_type(sptr) Returns the type of value in the stack */
+
+STACK_TYPE get_stackval_type(sptr)
+STACK_ITEM_PTR sptr;
+{
+ entry_debug("get_stackval_type (l2xixutl.c)");
+
+ if (sptr == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+
+ exit_debug("get_stackval_type");
+ return(sptr->type);
+} /* end GET_STACKVAL_TYPE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_false() Push false onto runtime stack */
+
+push_false()
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_false");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKLOG;
+ itemp->value.integer = FALSE_REP;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_false");
+ return;
+} /* end PUSH_FALSE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_unknown() Push unknown onto runtime stack */
+
+push_unknown()
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_unknown");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKLOG;
+ itemp->value.integer = UNKNOWN_REP;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_unknown");
+ return;
+} /* end PUSH_UNKNOWN */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_true() Push true onto runtime stack */
+
+push_true()
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_true");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKLOG;
+ itemp->value.integer = TRUE_REP;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_true");
+ return;
+} /* end PUSH_TRUE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_false() Put false onto runtime stack */
+
+put_false(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_false");
+
+ itemp->type = STKLOG;
+ itemp->value.integer = FALSE_REP;
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_false");
+ return;
+} /* end PUT_FALSE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_unknown() Put unknown onto runtime stack */
+
+put_unknown(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_unknown");
+
+ itemp->type = STKLOG;
+ itemp->value.integer = UNKNOWN_REP;
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_unknown");
+ return;
+} /* end PUT_UNKNOWN */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_true() Put true onto runtime stack */
+
+put_true(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_true");
+
+ itemp->type = STKLOG;
+ itemp->value.integer = TRUE_REP;
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_true");
+ return;
+} /* end PUT_TRUE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_logical() Push logical value onto runtime stack */
+
+push_logical(item_value)
+LOGICAL_REP item_value;
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_logical");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKLOG;
+ itemp->value.integer = item_value;
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_logical");
+ return;
+} /* end PUSH_LOGICAL */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_logical() Put logical value onto runtime stack */
+
+put_logical(sptr, item_value)
+STACK_ITEM_PTR sptr;
+LOGICAL_REP item_value;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_logical");
+
+ itemp->type = STKLOG;
+ itemp->value.integer = item_value;
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_logical");
+ return;
+} /* end PUT_LOGICAL */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_logical(sptr) Get a boolean/logical from the runtime stack */
+
+LOGICAL_REP get_logical(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ LOGICAL_REP item_value = UNKNOWN_REP;
+ entry_debug("get_logical");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+
+ if (itemp->type != STKLOG) {
+ stack_warning(STKLOG, itemp->type);
+ }
+ else {
+ item_value = itemp->value.integer;
+ }
+
+ exit_debug("get_logical");
+ return(item_value);
+} /* end GET_LOGICAL */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_string(item_value) Push a string onto the stack */
+
+STRING push_string(item_value)
+STRING item_value;
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_string");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKSTR;
+ itemp->value.string = item_value;
+
+ stack_access_debug("Pushed", tos);
+
+ exit_debug("push_string");
+ return;
+} /* end PUSH_STRING */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_string(sptr, item_value) Put a string into the stack */
+
+STRING put_string(sptr, item_value)
+STACK_ITEM_PTR sptr;
+STRING item_value;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_string");
+
+ itemp->type = STKSTR;
+ itemp->value.string = item_value;
+
+ stack_access_debug("Put", itemp);
+
+ if (itemp > tos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+
+ exit_debug("put_string");
+ return;
+} /* end PUT_STRING */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_stacked_string(sptr) Get a string from the stack */
+
+STRING get_stacked_string(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ STRING item_value = "";
+ entry_debug("get_stacked_string");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+
+ if (itemp->type != STKSTR) {
+ stack_warning(STKSTR, itemp->type);
+ }
+ else {
+ item_value = itemp->value.string;
+ }
+
+ exit_debug("get_stacked_string");
+ return(item_value);
+} /* end GET_STACKED_STRING */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* push_undef() Push undefined `?' onto runtime stack */
+
+push_undef()
+{
+ STACK_ITEM_PTR itemp = ++tos;
+ entry_debug("push_undef");
+
+ maxtos = tos > maxtos ? tos : maxtos;
+
+ if (itemp >= &stack[MAX_STACK_SIZE]) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ }
+
+ itemp->type = STKUDF;
+ itemp->value.integer = '\?';
+
+ stack_access_debug("Pushed", tos);
+ exit_debug("push_undef");
+ return;
+} /* end PUSH_UNDEF */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* put_undef(sptr) Put undefined `?' into runtime stack */
+
+put_undef(sptr)
+STACK_ITEM_PTR sptr;
+{
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("put_undef");
+
+
+ itemp->type = STKUDF;
+ itemp->value.integer = '\?';
+
+ stack_access_debug("Put", itemp);
+ if (itemp > maxtos) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ exit_debug("put_undef");
+ return;
+} /* end PUT_UNDEF */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* get_undef() Get undefined `?' from runtime stack */
+
+char get_undef(sptr)
+STACK_ITEM_PTR sptr;
+{
+ char item_value = ' ';
+ STACK_ITEM_PTR itemp = sptr;
+ entry_debug("get_undef");
+ stack_access_debug("Got", itemp);
+
+ if (itemp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+
+ if (itemp->type != STKUDF) {
+ item_value = ' ';
+ runtime_warning(STKUDF, itemp->type);
+ }
+ else {
+ item_value = itemp->value.integer;
+ }
+
+ exit_debug("get_undef");
+ return(item_value);
+} /* end GET_UNDEF */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* is_value_undef(sptr) TRUE iff value on stack at sptr is undef */
+
+BOOLEAN is_value_undef(sptr)
+STACK_ITEM_PTR sptr;
+{
+ BOOLEAN result = FALSE;
+
+ if (sptr == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ }
+ else {
+ result = (sptr->type == STKUDF);
+ }
+ return(result);
+} /* end IS_VALUE_UNDEF */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* copy_value(to, from) Copies stack value */
+
+copy_value(top, fromp)
+STACK_ITEM_PTR top;
+STACK_ITEM_PTR fromp;
+{
+ STACK_TYPE type;
+ entry_debug("copy_value (l2xixutl.c)");
+
+ if (top == NULL || fromp == NULL) {
+ runtime_warning(INVALID_STACK_ACCESS);
+ exit_debug("copy_value");
+ return;
+ }
+
+ stack_access_debug("Copy -- replacing: ", top);
+ stack_access_debug(" with: ", fromp);
+ type = fromp->type;
+ switch (type) {
+ case STKINT: {
+ top->type = type;
+ top->value.integer = fromp->value.integer;
+ break;
+ }
+ case STKREA: {
+ top->type = type;
+ top->value.real = fromp->value.real;
+ break;
+ }
+ case STKADD:
+ case STKARY:
+ case STKBAG:
+ case STKLST:
+ case STKSET:
+ case STKENT: {
+ top->type = type;
+ top->value.address = fromp->value.address;
+ break;
+ }
+ case STKUDF: {
+ put_undef(top);
+ break;
+ }
+ default: {
+ break;
+ }
+ } /* end switch */
+
+ exit_debug("copy_value");
+ return;
+} /* end COPY_VALUE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* create_copy_value(fromp) Copies a stack value to a new value */
+/* returns pointer to the new copied value */
+
+STACK_ITEM_PTR create_copy_value(fromp)
+STACK_ITEM_PTR fromp;
+{
+ STACK_TYPE type;
+ STACK_ITEM_PTR top;
+ entry_debug("create_copy_value (l2xixutl.c)");
+
+ /* get the memory required */
+ top = alloc_struct(STACK_ITEM);
+ if (top == NULL) {
+ runtime_error(RUNTIME_STACK_OVERFLOW);
+ exit_debug("create_copy_value");
+ return(NULL);
+ }
+
+ type = fromp->type;
+ switch (type) {
+ case STKINT: {
+ top->type = type;
+ top->value.integer = fromp->value.integer;
+ break;
+ }
+ case STKREA: {
+ top->type = type;
+ top->value.real = fromp->value.real;
+ break;
+ }
+ case STKADD:
+ case STKARY:
+ case STKBAG:
+ case STKLST:
+ case STKSET:
+ case STKENT: {
+ top->type = type;
+ top->value.address = fromp->value.address;
+ break;
+ }
+ case STKUDF: {
+ put_undef(top);
+ break;
+ }
+ default: {
+ break;
+ }
+ } /* end switch */
+ stack_access_debug("Created copy of: ", fromp);
+ stack_access_debug(" as: ", top);
+
+ exit_debug("create_copy_value");
+ return(top);
+} /* end CREATE_COPY_VALUE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* execute(rtn_idp) Execute a routine's code segment */
+/* */
+
+execute(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp;
+{
+ entry_debug("execute");
+
+ routine_entry(rtn_idp);
+
+ get_ctoken();
+ exec_statement();
+
+ routine_exit(rtn_idp);
+
+ exit_debug("execute");
+ return;
+} /* end execute */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* routine_entry(rtn_idp) Point to the new routine's code segment */
+/* and allocate its locals */
+
+routine_entry(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* new routine's id */
+{
+ SYMTAB_NODE_PTR var_idp; /* local variable id */
+ entry_debug("routine_entry");
+ stack_debug();
+
+ trace_routine_entry(rtn_idp);
+
+ /* switch to new code segment */
+ code_segmentp = rtn_idp->defn.info.routine.code_segment;
+
+ /* allocate local variables */
+ for (var_idp = rtn_idp->defn.info.routine.locals;
+ var_idp != NULL;
+ var_idp = var_idp->next) {
+ alloc_local(var_idp->typep);
+ }
+
+ stack_debug();
+ exit_debug("routine_entry");
+ return;
+} /* end routine_entry */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* routine_exit(rtn_idp) Deallocate the routine's parameters and locals. */
+/* Cut off its stack frame and return to the */
+/* caller's code segment. */
+
+routine_exit(rtn_idp)
+SYMTAB_NODE_PTR rtn_idp; /* exiting routine's id */
+{
+ SYMTAB_NODE_PTR idp; /* local variable or param id */
+ STACK_FRAME_HEADER_PTR hp; /* ptr to stack frame header */
+ TYPE_STRUCT_PTR target_tp; /* ptr to return type of routine */
+ TYPE_STRUCT_PTR expr_tp; /* ptr to type of RETURN expression */
+
+ entry_debug("routine_exit");
+ stack_debug();
+
+ trace_routine_exit(rtn_idp);
+
+ /* Treat a RETURN expression as an assignment to the routine's id */
+ if (ctoken == LPAREN) {
+ target_tp = rtn_idp->typep;
+ expr_tp = exec_expression();
+ exec_the_assign(stack_frame_basep, target_tp, expr_tp);
+ }
+
+ /* Deallocate parameters and local variables */
+ for (idp = rtn_idp->defn.info.routine.parms;
+ idp != NULL;
+ idp = idp->next) {
+ free_data(idp);
+ }
+ for (idp = rtn_idp->defn.info.routine.locals;
+ idp != NULL;
+ idp = idp->next) {
+ free_data(idp);
+ }
+
+ /* pop off the stack frame and return to caller's code segmnent */
+ entry_debug("routine_exit: pop the frame stack");
+ stack_debug();
+ hp = (STACK_FRAME_HEADER_PTR) stack_frame_basep;
+ code_segmentp = get_return_address(hp);
+ tos = (rtn_idp->defn.key == PROC_DEFN)
+ ? stack_frame_basep - 1
+ : stack_frame_basep;
+ stack_frame_basep = (STACK_ITEM_PTR) get_dynamic_link(hp);
+
+ exit_debug("routine_exit: pop the frame stack");
+ stack_debug();
+ exit_debug("routine_exit");
+ return;
+} /* end routine_exit */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* push_stack_frame_header(old_level, new_level) Allocate the callee */
+/* routine's stack frame */
+
+push_stack_frame_header(old_level, new_level)
+int old_level; /* level of caller */
+int new_level; /* level of callee */
+{
+ STACK_FRAME_HEADER_PTR hp;
+ STACK_ITEM_PTR newbasep; /* pointer to base of new frame */
+ entry_debug("push_stack_frame_header");
+
+ stack_debug();
+/* push_integer(0); return value */
+ hp = (STACK_FRAME_HEADER_PTR) stack_frame_basep;
+ newbasep = tos + 1;
+ push_frame_data(0, NULL, NULL, NULL);
+
+ /* static link */
+ if (new_level == (old_level + 1)) {
+ /* calling a routine nested in the caller */
+ /* push pointer to caller's stack frame */
+ put_static_link(newbasep, (ADDRESS) hp);
+ }
+ else if (new_level == old_level) {
+ /* calling routine at the same level */
+ /* push pointer to stack of common parent */
+ put_static_link(newbasep, get_static_link(hp));
+ }
+ else {
+ /* calling a routine at a lesser level (nested less deeply ) */
+ /* push pointer to stack of nearest common ancestor */
+ int delta = (old_level - new_level);
+
+ while (delta-- >= 0) {
+ hp = (STACK_FRAME_HEADER_PTR) get_static_link(hp);
+ }
+ put_static_link(newbasep, hp);
+ }
+
+ put_dynamic_link(newbasep, stack_frame_basep);
+
+ stack_debug();
+ exit_debug("push_stack_frame_header");
+ return;
+} /* end push_stack_frame_header */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* alloc_local(tp) Allocate a local variable on the stack */
+/* */
+
+alloc_local(tp)
+TYPE_STRUCT_PTR tp; /* ptr to type of variable */
+{
+ LBS_PTR lbs; /* pointer to dynamic agg */
+ STACK_TYPE stktyp;
+ entry_debug("alloc_local");
+
+ if (tp == integer_typep) {
+ push_integer(0);
+ }
+ else if (tp == real_typep) {
+ push_real(0.0);
+ }
+ else if (tp == boolean_typep) {
+ push_false(); /* FALSE */
+ }
+ else if (tp == string_typep || tp->form == STRING_FORM) {
+ push_string(NULL);
+ }
+ else if (tp == logical_typep) {
+ push_unknown();
+ }
+ else {
+ switch (tp->form) {
+ case ENUM_FORM: {
+ push_integer(0);
+ break;
+ }
+ case SUBRANGE_FORM: {
+ alloc_local(tp->info.subrange.range_typep);
+ break;
+ }
+ case ARRAY_FORM: {
+ ADDRESS ptr = (ADDRESS) alloc_array(STACK_ITEM_PTR, tp->size);
+ sprintf(dbuffer, "Allocated %d bytes for array at %d\n",
+ tp->size, ptr);
+ debug_print(dbuffer);
+ push_address((ADDRESS) ptr);
+ break;
+ }
+ case ENTITY_FORM: {
+ ADDRESS ptr = (ADDRESS) alloc_array(STACK_ITEM_PTR, tp->size);
+ sprintf(dbuffer, "Allocated %d bytes for entity at %d\n",
+ tp->size, ptr);
+ debug_print(dbuffer);
+ push_address_type((ADDRESS) ptr, STKENT);
+ break;
+ }
+ case BAG_FORM:
+ case LIST_FORM:
+ case SET_FORM: {
+ lbs = lbs_init();
+ push_address_type(lbs, form2stack[tp->form]);
+ break;
+ }
+ } /* end switch */
+ }
+
+ exit_debug("alloc_local");
+ return;
+} /* end alloc_local */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* free_data(idp) Deallocate the data area of an array or record local */
+/* variable or value parameter */
+
+free_data(idp)
+SYMTAB_NODE_PTR idp; /* parm or variable id */
+{
+ STACK_ITEM_PTR itemp; /* ptr to stack item */
+ TYPE_STRUCT_PTR tp = idp->typep; /* ptr to id's type */
+ entry_debug("free_data");
+
+ if (((tp->form == ARRAY_FORM) || (tp->form == ENTITY_FORM)) &&
+ (idp->defn.key != VARPARM_DEFN)) {
+ stack_frame_debug();
+ itemp = stack_frame_basep + idp->defn.info.data.offset;
+ stack_item_debug(itemp);
+ free(get_address(itemp));
+ }
+
+ exit_debug("free_data");
+ return;
+} /* end free_data */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* push_frame_data(int, add, add, add) Push frame data onto runtime stack */
+
+push_frame_data(ifrv, asl, adl, ara)
+int ifrv; /* function return value */
+ADDRESS asl; /* static link */
+ADDRESS adl; /* dynamic link */
+ADDRESS ara; /* return address */
+{
+ entry_debug("push_frame_data");
+ stack_debug();
+
+ push_integer(ifrv);
+ push_address(asl);
+ push_address(adl);
+ push_address(ara);
+
+ stack_debug();
+ exit_debug("push_frame_data");
+ return;
+} /* end push_frame_data */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* put_static_link(framep, address) Put static link data into frame */
+
+put_static_link(framep, address)
+STACK_ITEM_PTR framep; /* pointer to frame */
+ADDRESS address; /* static link */
+{
+ entry_debug("put_static_link");
+ put_address((framep+1), address);
+ exit_debug("put_static_link");
+
+} /* end put_static_link */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* ADDRESS get_static_link(framep) Get static link data from frame */
+
+ADDRESS get_static_link(framep)
+STACK_ITEM_PTR framep; /* pointer to frame */
+{
+ ADDRESS result;
+ entry_debug("get_static_link");
+
+ result = get_address(framep + 1);
+
+ exit_debug("get_static_link");
+ return(result);
+} /* end get_static_link */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* put_dynamic_link(framep, address) Put dynamic link data into frame */
+
+put_dynamic_link(framep, address)
+STACK_ITEM_PTR framep; /* pointer to frame */
+ADDRESS address; /* dynamic link */
+{
+ entry_debug("put_dynamic_link");
+ put_address((framep+2), address);
+ exit_debug("put_dynamic_link");
+
+} /* end put_dynamic_link */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* ADDRESS get_dynamic_link(framep) Get dynamic link data from frame */
+
+ADDRESS get_dynamic_link(framep)
+STACK_ITEM_PTR framep; /* pointer to base of frame */
+{
+ ADDRESS result;
+ entry_debug("get_dynamic_link");
+
+ result = get_address(framep + 2);
+
+ exit_debug("get_dynamic_link");
+ return(result);
+} /* end get_dynamic_link */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* put_return_address(framep, address) Put return address data into frame */
+
+put_return_address(framep, address)
+STACK_ITEM_PTR framep; /* pointer to frame */
+ADDRESS address; /* return link */
+{
+
+ entry_debug("put_return_address");
+ put_address((framep+3), address);
+ exit_debug("put_return_address");
+
+} /* end put_return_address */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* ADDRESS get_return_address(framep) Get return address data from frame */
+
+ADDRESS get_return_address(framep)
+STACK_ITEM_PTR framep; /* pointer to frame */
+{
+ ADDRESS result;
+ entry_debug("get_return_address");
+
+ result = get_address(framep + 3);
+
+ exit_debug("get_return_address");
+ return(result);
+} /* end get_return_address */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* stack_value_equal(a, b) Tests whether two stack items have the same */
+/* data value. */
+/* returns: UNKNOWN_REP if either arg is indeterminate */
+/* otherwise TRUE_REP or FALSE_REP as appropriate */
+
+LOGICAL_REP stack_value_equal(a, b)
+STACK_ITEM_PTR a;
+STACK_ITEM_PTR b;
+{
+ STACK_TYPE atype, btype;
+ int ans;
+ XPRSAINT i1, i2;
+ XPRSAREAL r1, r2;
+ LOGICAL_REP b1, b2;
+ LOGICAL_REP log = FALSE_REP;
+
+ entry_debug("stack_value_equal (l2xixutl.c)");
+
+ /* check for indeterminate values */
+ atype = get_stackval_type(a);
+ if (atype == STKUDF) log = UNKNOWN_REP;
+ btype = get_stackval_type(b);
+ if (btype == STKUDF) log = UNKNOWN_REP;
+ if (log == UNKNOWN_REP) {
+ exit_debug("stack_value_equal (indeterminate UNKNOWN_REP)");
+ return(log);
+ }
+
+
+ /* check type equality */
+ if (atype != btype) {
+ exit_debug("stack_value_equal (different types FALSE_REP)");
+ return(FALSE_REP);
+ }
+
+ switch (atype) {
+ case STKINT: {
+ i2 = get_integer(b);
+ i1 = get_integer(a);
+ sprintf(dbuffer, "Checking %d == %d\n",
+ i1, i2);
+ debug_print(dbuffer);
+ ans = (i1 == i2);
+ sprintf(dbuffer, "Checked %d == %d, with result = ",
+ i1, i2);
+ debug_print(dbuffer);
+ if (ans) sprintf(dbuffer, "TRUE\n");
+ else sprintf(dbuffer, "FALSE\n");
+ debug_print(dbuffer);
+ break;
+ }
+ case STKREA: {
+ ans = (get_real(a) == get_real(b));
+ break;
+ }
+ case STKLOG: {
+ ans = (get_logical(a) == get_logical(b));
+ break;
+ }
+ case STKSTR: {
+ ans = strcmp(get_stacked_string(a), get_stacked_string(b));
+ if (ans == 0) ans = TRUE;
+ else ans = FALSE;
+ break;
+ }
+ default: { /* for now, only test on simple types */
+ exit_debug("stack_value_equal (default UNKNOWN_REP)");
+ return(UNKNOWN_REP);
+ break;
+ }
+ } /* end switch */
+
+ if (ans) {
+ exit_debug("stack_value_equal (end switch TRUE_REP)");
+ return(TRUE_REP);
+ }
+ else {
+ exit_debug("stack_value_equal (end switch FALSE_REP)");
+ return(FALSE_REP);
+ }
+
+} /* end STACK_VALUE_EQUAL */
+/***************************************************************************/
+
+
+
diff --git a/support/ltx2x/l2xixxpr.c b/support/ltx2x/l2xixxpr.c
new file mode 100644
index 0000000000..7a97bae889
--- /dev/null
+++ b/support/ltx2x/l2xixxpr.c
@@ -0,0 +1,1234 @@
+/* l2xixxpr.c LTX2X interpreter expression executor routines */
+/* Written by: Peter Wilson, CUA pwilson@cme.nist.gov */
+/* This code is partly based on algorithms presented by Ronald Mak in */
+/* "Writing Compilers & Interpreters", John Wiley & Sons, 1991 */
+
+#include <stdio.h>
+#include <math.h>
+#include "l2xicmon.h"
+#include "l2xierr.h"
+#include "l2xiscan.h"
+#include "l2xisymt.h"
+#include "l2xiprse.h"
+#include "l2xiidbg.h"
+#include "l2xiexec.h"
+
+#include "listsetc.h"
+
+/* EXTERNALS */
+
+extern int level;
+
+extern ICT *code_segmentp; /* code segment ptr */ /* used? */
+extern TOKEN_CODE ctoken; /* token from code segment */
+
+extern STACK_ITEM *stack; /* runtime stack */
+extern STACK_ITEM_PTR tos; /* ptr to top of runtime stack */
+extern STACK_ITEM_PTR stack_frame_basep; /* ptr to stack fame base */
+
+extern BOOLEAN is_value_undef();
+extern STRING get_stacked_string();
+
+extern STACK_TYPE form2stack[]; /* map form type to stack type */
+
+/* FORWARDS */
+
+TYPE_STRUCT_PTR exec_expression(), exec_simple_expression(),
+ exec_term(), exec_factor(),
+ exec_constant(), exec_variable(),
+ exec_subscripts();
+TYPE_STRUCT_PTR exec_simple_factor(), exec_attribute();
+
+STRING concat_strings();
+
+/* MACROS */
+
+/* undef_types(tp1, tp2) TRUE if either type is undef, else FALSE */
+#define undef_types(tp1, tp2) ((tp1 == any_typep) || (tp2 == any_typep))
+
+/* undef_values(sp1, sp2) TRUE if either stack value is undef */
+#define undef_values(sp1, sp2) (is_value_undef(sp1) || is_value_undef(sp2))
+
+/* set_undef(tp1) Sets tp1 to undef type */
+#define set_undef(tp1) (tp1 = any_typep)
+
+/* is_undef(tp1) TRUE if tp1 is undef type, else FALSE */
+#define is_undef(tp1) (tp1 == any_typep)
+
+/* string_operands(tp1, tp2) TRUE iff tp1 and tp2 are string types */
+#define string_operands(tp1, tp2) ((tp1)->form == STRING_FORM && (tp2)->form == STRING_FORM)
+
+/***************************************************************************/
+/* exec_expression() Execute an expression */
+/* <sexp> [ <relop> <sexp> ] */
+/* return a pointer to the type structure. */
+
+TYPE_STRUCT_PTR exec_expression()
+{
+ STACK_ITEM_PTR operandp1, operandp2; /* ptrs to operands */
+ TYPE_STRUCT_PTR result_tp, tp1, tp2; /* ptrs to types */
+ TOKEN_CODE op; /* operator token */
+ BOOLEAN result;
+ LOGICAL_REP log;
+ entry_debug("exec_expression");
+
+ tp1 = exec_simple_expression(); /* first simple expression */
+ result_tp = tp1;
+
+ /* process relop sexp, if any */
+ if ((ctoken == EQUAL) || (ctoken == LT) || (ctoken == GT) ||
+ (ctoken == NE) || (ctoken == LE) || (ctoken == GE) ||
+ (ctoken == COLONEQUALCOLON) || (ctoken == COLONNEQCOLON) ||
+ (ctoken == IN) || (ctoken == XLIKE) ) {
+ op = ctoken;
+ tp1 = base_type(tp1);
+ result_tp = logical_typep;
+
+ get_ctoken();
+ tp2 = base_type(exec_simple_expression()); /* second simple expression */
+ /* get operands */
+ operandp1 = tos - 1;
+ operandp2 = tos;
+
+ if (undef_types(tp1, tp2) || undef_values(operandp1, operandp2)) {
+ put_unknown(operandp1);
+ pop();
+ expression_type_debug(result_tp);
+ exit_debug("exec_expression");
+ return(result_tp);
+ }
+
+ log = do_relop(operandp1, tp1, op, operandp2, tp2);
+ /* replace the two operands on the stack by the result */
+ put_logical(operandp1, log);
+ pop();
+ } /* end if on relop */
+
+
+ expression_type_debug(result_tp);
+ exit_debug("exec_expression");
+ return(result_tp);
+} /* end exec_expression */
+/***************************************************************************/
+
+
+/***************************************************************************/
+/* do_relop() execute a relop expression */
+
+LOGICAL_REP do_relop(operandp1, tp1, op, operandp2, tp2)
+STACK_ITEM_PTR operandp1, operandp2; /* the operands */
+TYPE_STRUCT_PTR tp1, tp2; /* their types */
+TOKEN_CODE op; /* the relop */
+{
+ int result;
+ LOGICAL_REP log;
+
+ entry_debug("do_relop (l2xixxpr.c)");
+
+ if (((tp1 == integer_typep) && (tp2 == integer_typep)) ||
+ (tp1->form == ENUM_FORM)) {
+ /* both operands are integer, bool or enum */
+ switch (op) {
+ case EQUAL:
+ case COLONEQUALCOLON: {
+ result = get_integer(operandp1) == get_integer(operandp2);
+ break;
+ }
+ case LT: {
+ result = get_integer(operandp1) < get_integer(operandp2);
+ break;
+ }
+ case GT: {
+ result = get_integer(operandp1) > get_integer(operandp2);
+ break;
+ }
+ case NE:
+ case COLONNEQCOLON: {
+ result = get_integer(operandp1) != get_integer(operandp2);
+ break;
+ }
+ case LE: {
+ result = get_integer(operandp1) <= get_integer(operandp2);
+ break;
+ }
+ case GE: {
+ result = get_integer(operandp1) >= get_integer(operandp2);
+ break;
+ }
+ } /* end switch on op */
+ }
+
+ else if ((tp1 == real_typep) || (tp2 == real_typep)) {
+ /* One operand real, t'other real or integer */
+ promote_operands_to_real(operandp1, tp1, operandp2, tp2);
+
+ switch (op) {
+ case EQUAL:
+ case COLONEQUALCOLON: {
+ result = get_real(operandp1) == get_real(operandp2);
+ break;
+ }
+ case LT: {
+ result = get_real(operandp1) < get_real(operandp2);
+ break;
+ }
+ case GT: {
+ result = get_real(operandp1) > get_real(operandp2);
+ break;
+ }
+ case NE:
+ case COLONNEQCOLON: {
+ result = get_real(operandp1) != get_real(operandp2);
+ break;
+ }
+ case LE: {
+ result = get_real(operandp1) <= get_real(operandp2);
+ break;
+ }
+ case GE: {
+ result = get_real(operandp1) >= get_real(operandp2);
+ break;
+ }
+ } /* end switch */
+ }
+
+ else if (string_operands(tp1, tp2)) { /* strings */
+ if (op == XLIKE) {
+ result = like_expr(get_stacked_string(operandp1),
+ get_stacked_string(operandp2));
+ if (result < 0) { /* invalid pattern */
+ runtime_error(INVALID_REGULAR_EXPRESSION);
+ log = UNKNOWN_REP;
+ }
+ else if (result == 0) {
+ log = FALSE_REP;
+ }
+ else {
+ log = TRUE_REP;
+ }
+ exit_debug("do_relop (at LIKE)");
+ return(log);
+ }
+ else { /* general relational operator */
+ int cmp = strncmp(get_stacked_string(operandp1),
+ get_stacked_string(operandp2));
+
+ result = (((cmp < 0) &&
+ ((op == NE) || (op == COLONNEQCOLON) || (op == LE) || (op == LT)))
+ || ((cmp == 0) &&
+ ((op == EQUAL) || (op == COLONEQUALCOLON) || (op == LE) || (op == GE)))
+ || ((cmp > 0) &&
+ ((op == NE) || (op == COLONNEQCOLON) || (op == GE) || (op == GT))));
+ }
+ }
+
+ else if (is_dynagg(tp1) || is_dynagg(tp2)) { /* dynamic agg */
+ log = exec_dynagg_relop(tp1, operandp1, op, tp2, operandp2);
+ exit_debug("do_relop (at dynagg)");
+ return(log);
+ }
+
+ exit_debug("do_relop");
+ if (result == TRUE) return(TRUE_REP);
+ else return(FALSE_REP);
+
+} /* end DO_RELOP */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_simple_expression() Execute a simple expression */
+/* [ <unary-op> ] <term> <pmop> <term> { <pmop> <term> } */
+/* return a pointer to the type structure. */
+
+TYPE_STRUCT_PTR exec_simple_expression()
+{
+ STACK_ITEM_PTR operandp1, operandp2; /* ptrs to operands */
+ TYPE_STRUCT_PTR result_tp, tp2; /* ptrs to types */
+ TOKEN_CODE op; /* operator token */
+ TOKEN_CODE unary_op = PLUS; /* unary op token */
+ XPRSAINT i1;
+ LOGICAL_REP b1, b2, br;
+ XPRSAREAL r1;
+ STRING str;
+ entry_debug("exec_simple_expression");
+
+ /* remember unary op */
+ if ((ctoken == PLUS) || (ctoken == MINUS)) {
+ unary_op = ctoken;
+ get_ctoken();
+ }
+
+ result_tp = exec_term(); /* first term */
+
+ /* if there was a unary MINUS, negate the top of the stack */
+ if (unary_op == MINUS) {
+ if (!is_value_undef(tos)) {
+ if (result_tp == integer_typep) put_integer(tos, -get_integer(tos));
+ else put_real(tos, -get_real(tos));
+ }
+ }
+
+ /* loop to process following terms (seperated by <op> ) */
+ while ((ctoken == PLUS) || (ctoken == MINUS) ||
+ (ctoken == OR) || (ctoken == XXOR) ) {
+ op = ctoken; /* operator */
+ result_tp = base_type(result_tp);
+
+ get_ctoken();
+ tp2 = base_type(exec_term()); /* term */
+
+ operandp1 = tos - 1;
+ operandp2 = tos;
+
+ if (undef_values(operandp1, operandp2)) {
+ put_undef(operandp1);
+ }
+
+ else if ((op == OR) || (op == XXOR)) {
+ b1 = get_logical(operandp1);
+ b2 = get_logical(operandp2);
+ br = FALSE_REP;
+ if (op == OR) { /* term OR term */
+ if (b1 == FALSE_REP && b2 == FALSE_REP) {
+ br = FALSE_REP;
+ }
+ else if (b1 == UNKNOWN_REP &&
+ (b2 == UNKNOWN_REP || b2 == FALSE_REP)) {
+ br = UNKNOWN_REP;
+ }
+ else if (b1 == FALSE_REP && b2 == UNKNOWN_REP) {
+ br = UNKNOWN_REP;
+ }
+ else {
+ br = TRUE_REP;
+ }
+ }
+ else { /* term XOR term */
+ if (b1 == TRUE_REP && b2 == TRUE_REP) {
+ br = FALSE_REP;
+ }
+ else if (b1 == TRUE_REP && b2 == FALSE_REP) {
+ br = TRUE_REP;
+ }
+ else if (b1 == FALSE_REP && b2 == TRUE_REP) {
+ br = TRUE_REP;
+ }
+ else if (b1 == FALSE_REP && b2 == FALSE_REP) {
+ br = FALSE_REP;
+ }
+ else {
+ br = UNKNOWN_REP;
+ }
+ }
+ put_logical(operandp1, br);
+ result_tp = logical_typep;
+ }
+
+ /* op is + or - */
+ else if ((result_tp == integer_typep) &&
+ (tp2 == integer_typep)) {
+ /* both operands are integer */
+ i1 = (op == PLUS)
+ ? get_integer(operandp1) + get_integer(operandp2)
+ : get_integer(operandp1) - get_integer(operandp2);
+ put_integer(operandp1, i1);
+ result_tp = integer_typep;
+ }
+ else if ((result_tp == string_typep || result_tp->form == STRING_FORM) &&
+ (tp2 == string_typep || tp2->form == STRING_FORM)) {
+ /* two strings, plus is only operator */
+ if (op == PLUS) {
+ str = concat_strings(operandp1, operandp2);
+ free(get_stacked_string(operandp1));
+ put_string(operandp1, str);
+ result_tp = string_typep;
+ result_tp->form == STRING_FORM;
+ }
+ }
+ else {
+ /* mix of real and integer */
+ promote_operands_to_real(operandp1, result_tp, operandp2, tp2);
+ r1 = (op == PLUS)
+ ? get_real(operandp1) + get_real(operandp2)
+ : get_real(operandp1) - get_real(operandp2);
+ put_real(operandp1, r1);
+ result_tp = real_typep;
+ }
+
+ /* pop off the second operand */
+ pop();
+ } /* end while over <op> <term> */
+
+ exit_debug("exec_simple_expression");
+ return(result_tp);
+} /* end exec_simple_expression */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_term() Execute a term */
+/* <factor> <multop> <factor> { <multop> <factor> } */
+/* return a pointer to the type structure. */
+
+TYPE_STRUCT_PTR exec_term()
+{
+ STACK_ITEM_PTR operandp1, operandp2; /* ptrs to operands */
+ TYPE_STRUCT_PTR result_tp, tp2; /* ptrs to types */
+ TOKEN_CODE op; /* operator token */
+ XPRSAINT i1;
+ XPRSAREAL r1;
+ LOGICAL_REP b1, b2, br;
+ entry_debug("exec_term");
+
+ result_tp = exec_factor(); /* first factor */
+
+ /* loop to process following <multop> <factor> pairs */
+ while ((ctoken == STAR) || (ctoken == SLASH) || (ctoken == DIV) ||
+ (ctoken == MOD) || (ctoken == AND) || (ctoken == BARBAR)) {
+ op = ctoken;
+ result_tp = base_type(result_tp);
+
+ get_ctoken();
+ tp2 = exec_factor(); /* next factor */
+
+ operandp1 = tos - 1;
+ operandp2 = tos;
+
+ if (undef_values(operandp1, operandp2)) {
+ put_undef(operandp1);
+ }
+
+ else if (op == AND) {
+ b1 = get_logical(operandp1);
+ b2 = get_logical(operandp2);
+ if (b1 == TRUE_REP && b2 == TRUE_REP) {
+ br = TRUE_REP;
+ }
+ else if (b1 == TRUE_REP && b2 == UNKNOWN_REP) {
+ br = UNKNOWN_REP;
+ }
+ else if (b1 == UNKNOWN_REP && b2 == TRUE_REP) {
+ br = UNKNOWN_REP;
+ }
+ else if (b1 == UNKNOWN_REP && b2 == UNKNOWN_REP) {
+ br = UNKNOWN_REP;
+ }
+ else {
+ br = FALSE_REP;
+ }
+ put_logical(operandp1, br);
+ result_tp = logical_typep;
+ }
+
+ else if (op == BARBAR) {
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+/* result_tp = &dummy_typep; */
+ }
+
+ else {
+ /* *, /, DIV or MOD */
+ switch (op) {
+ case STAR: {
+ if ((result_tp == integer_typep) && (tp2 == integer_typep)) {
+ /* integer operands */
+ i1 = get_integer(operandp1) * get_integer(operandp2);
+ put_integer(operandp1, i1);
+ result_tp = integer_typep;
+ }
+ else {
+ /* at least one real */
+ promote_operands_to_real(operandp1, result_tp, operandp2, tp2);
+ r1 = get_real(operandp1) * get_real(operandp2);
+ put_real(operandp1, r1);
+ result_tp = real_typep;
+ }
+ break;
+ }
+ case SLASH: {
+ promote_operands_to_real(operandp1, result_tp, operandp2, tp2);
+ if (get_real(operandp2) == 0.0) {
+ runtime_error(DIVISION_BY_ZERO);
+ }
+ else {
+ r1 = get_real(operandp1) / get_real(operandp2);
+ put_real(operandp1, r1);
+ }
+ result_tp = real_typep;
+ break;
+ }
+ case DIV:
+ case MOD: {
+ /* both operands integer */
+ if (get_integer(operandp2) == 0) {
+ runtime_error(DIVISION_BY_ZERO);
+ }
+ else {
+ i1 = (op == DIV)
+ ? get_integer(operandp1) / get_integer(operandp2)
+ : get_integer(operandp1) % get_integer(operandp2);
+ put_integer(operandp1, i1);
+ }
+ result_tp = integer_typep;
+ break;
+ }
+ } /* end switch */
+ }
+
+ /* pop off the second operand */
+ pop();
+
+ } /* end while over op/factor pairs */
+
+ exit_debug("exec_term");
+ return(result_tp);
+} /* end exec_term */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_factor() Execute an EXPRESS factor */
+/* <simple_factor> ** <simple_factor> */
+/* return a pointer to the type structure */
+
+TYPE_STRUCT_PTR exec_factor()
+{
+ TYPE_STRUCT_PTR result_tp; /* ptr to type */
+ STACK_ITEM_PTR operand1, operand2; /* ptrs to operands */
+ TYPE_STRUCT_PTR tp2;
+ XPRSAINT i1, i2, i;
+ XPRSAREAL r1, r2, r;
+ entry_debug("exec_factor");
+
+ result_tp = exec_simple_factor(); /* first operand */
+
+ if (ctoken == STARSTAR) { /* have an operator */
+ result_tp = base_type(result_tp);
+
+ get_ctoken();
+ tp2 = base_type(exec_simple_factor());
+
+ operand1 = tos - 1;
+ operand2 = tos;
+
+ if (undef_values(operand1, operand2)) {
+ put_undef(operand1);
+ }
+
+ else if ((result_tp == integer_typep) && (tp2 == integer_typep)) {
+ /* integer operands */
+ i1 = get_integer(operand1);
+ i2 = get_integer(operand2);
+ if ((i1 == 0) && (i2 <= 0) ) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ i = (XPRSAINT) pow((double) i1, (double) i2);
+ sprintf(dbuffer, "i1= %d, i2= %d, pow(i1, i2)= %d\n", i1, i2, i);
+ debug_print(dbuffer);
+ put_integer(operand1, i);
+ result_tp = integer_typep;
+ }
+ }
+ else {
+ /* at least one real */
+ if ((tp2 == integer_typep)) { /* first real, second int */
+ r1 = get_real(operand1);
+ i2 = get_integer(operand2);
+ if ((r1 == 0.0) && (i2 <= 0)) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ r = (XPRSAREAL) pow((double) r1, (double) i2);
+ put_real(operand1, r);
+ result_tp = real_typep;
+ }
+ }
+ else if ((result_tp == real_typep) && (tp2 == real_typep)) {
+ r1 = get_real(operand1);
+ r2 = get_real(operand2);
+ if (((r1 == 0.0) && (r2 <= 0.0)) || (r1 < 0.0)) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ r = (XPRSAREAL) pow((double) r1, (double) r2);
+ put_real(operand1, r);
+ result_tp = real_typep;
+ }
+ }
+ else { /* first int, second real */
+ i1 = get_integer(operand1);
+ r2 = get_real(operand2);
+ if ((i1 == 0) && (r2 <= 0.0)) {
+ runtime_error(INVALID_FUNCTION_ARGUMENT);
+ }
+ else {
+ r = (XPRSAREAL) pow((double) i1, (double) r2);
+ put_real(operand1, r);
+ result_tp = real_typep;
+ }
+ }
+ }
+
+ pop(); /* pop off the second operand */
+ }
+
+ exit_debug("exec_factor");
+ return(result_tp);
+} /* end EXEC_FACTOR */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_simple_factor() Execute a simple factor */
+/* <variable> | <number> | NOT <simple_factor> | ( <expression> ) */
+/* or an interval expression = {expr op expr op expr} */
+/* return a pointer to the type structure. */
+
+TYPE_STRUCT_PTR exec_simple_factor()
+{
+ TYPE_STRUCT_PTR result_tp; /* ptr to type */
+ TYPE_STRUCT_PTR tp1, tp2, tp3;
+ LOGICAL_REP b1, br;
+ TOKEN_CODE op1, op2;
+ STACK_ITEM_PTR operandp1, operandp2, operandp3;
+ STACK_TYPE t1, t2, t3;
+ entry_debug("exec_simple_factor");
+
+ switch (ctoken) {
+ case IDENTIFIER: {
+ SYMTAB_NODE_PTR idp = get_symtab_cptr();
+
+ if (idp->defn.key == FUNC_DEFN) {
+ result_tp = exec_routine_call(idp);
+ }
+ else if (idp->defn.key == CONST_DEFN) {
+ result_tp = exec_constant(idp);
+ }
+ else {
+ result_tp = exec_variable(idp, EXPR_USE);
+ }
+ break;
+ }
+ case NUMBER_LITERAL: {
+ SYMTAB_NODE_PTR np = get_symtab_cptr();
+
+ /* get the number from the symbol table and push it on the stack */
+ if (np->typep == integer_typep) {
+ push_integer(np->defn.info.constant.value.integer);
+ result_tp = integer_typep;
+ }
+ else {
+ push_real(np->defn.info.constant.value.real);
+ result_tp = real_typep;
+ }
+
+ get_ctoken();
+ break;
+ }
+
+ case STRING_LITERAL: {
+ SYMTAB_NODE_PTR np = get_symtab_cptr();
+ int length = strlen(np->name);
+ push_string((STRING) np->info);
+ result_tp = np->typep;
+ get_ctoken();
+ break;
+ }
+
+ case NOT: {
+ get_ctoken();
+ result_tp = exec_simple_factor();
+ if (is_undef(result_tp) || is_value_undef(tos)) {
+ put_undef(tos);
+ }
+ else {
+ b1 = get_logical(tos);
+ if (b1 == TRUE_REP) {
+ br = FALSE_REP;
+ }
+ else if (b1 == FALSE_REP) {
+ br = TRUE_REP;
+ }
+ else {
+ br = UNKNOWN_REP;
+ }
+ put_logical(tos, br); /* TRUE -> FALSE, FALSE -> TRUE */
+ }
+ break;
+ }
+
+ case LPAREN: {
+ get_ctoken();
+ result_tp = exec_expression();
+ get_ctoken(); /* the token after the ) */
+ break;
+ }
+
+ case LBRACE: { /* interval expression */
+ result_tp = logical_typep;
+ get_ctoken();
+ tp1 = exec_simple_expression();
+ op1 = ctoken;
+ get_ctoken();
+ tp2 = exec_simple_expression();
+ op2 = ctoken;
+ get_ctoken();
+ tp3 = exec_simple_expression();
+ get_ctoken(); /* the token after the } */
+ operandp1 = tos - 2;
+ operandp2 = tos - 1;
+ operandp3 = tos;
+ pop();
+ pop();
+ /* check if anything is indeterminate */
+ t1 = get_stackval_type(operandp1);
+ if (t1 == STKUDF) {
+ put_unknown(operandp1);
+ break;
+ }
+ t2 = get_stackval_type(operandp2);
+ if (t2 == STKUDF) {
+ put_unknown(operandp1);
+ break;
+ }
+ t3 = get_stackval_type(operandp3);
+ if (t3 == STKUDF) {
+ put_unknown(operandp1);
+ break;
+ }
+ /* check first condition */
+ b1 = do_relop(operandp1, tp1, op1, operandp2, tp2);
+ if (b1 == FALSE_REP) {
+ put_false(operandp1);
+ break;
+ }
+ /* and the second */
+ br = do_relop(operandp2, tp2, op2, operandp3, tp3);
+ if (br == FALSE_REP) {
+ put_false(operandp1);
+ break;
+ }
+ if (b1 == TRUE_REP && br == TRUE_REP) {
+ put_true(operandp1);
+ }
+ else {
+ put_unknown(operandp1);
+ }
+ break;
+ }
+
+ } /* end switch */
+
+ expression_type_debug(result_tp);
+ exit_debug("exec_simple_factor");
+ return(result_tp);
+} /* end exec_simple_factor */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_constant(idp) Push the value of a non-string constant id, */
+/* or the address of a string constant id onto the stack */
+/* return a pointer to the type structure. */
+
+TYPE_STRUCT_PTR exec_constant(idp)
+SYMTAB_NODE_PTR idp; /* constant id */
+{
+ TYPE_STRUCT_PTR tp = idp->typep; /* ptrs to types */
+ entry_debug("exec_constant");
+
+ if (base_type(tp) == logical_typep) {
+ push_logical(idp->defn.info.constant.value.integer);
+ }
+ else if ((base_type(tp) == integer_typep) || (tp->form == ENUM_FORM)) {
+ push_integer(idp->defn.info.constant.value.integer);
+ }
+ else if (tp == real_typep) {
+ push_real(idp->defn.info.constant.value.real);
+ }
+ else if (tp->form == ARRAY_FORM) {
+ push_address((ADDRESS) idp->defn.info.constant.value.stringp);
+ }
+ else if (tp->form == STRING_FORM) {
+ push_string((STRING) idp->defn.info.constant.value.stringp);
+ }
+ else if (is_undef(tp)) {
+ push_undef();
+ }
+
+ trace_data_fetch(idp, tp, tos);
+ get_ctoken();
+
+ exit_debug("exec_constant");
+ return(tp);
+} /* end exec_constant */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_variable(idp, use) Push either the variable's address or its */
+/* value onto the stack */
+/* return a pointer to the type structure. */
+
+TYPE_STRUCT_PTR exec_variable(idp, use)
+SYMTAB_NODE_PTR idp; /* variable id */
+USE use; /* how variable is used */
+{
+ int delta; /* difference in levels */
+ TYPE_STRUCT_PTR tp = idp->typep; /* ptrs to types */
+ TYPE_STRUCT_PTR base_tp; /* ptrs to types */
+ STACK_ITEM_PTR datap; /* ptr to data area */
+ STACK_ITEM_PTR hp;
+ STACK_TYPE stype;
+ entry_debug("exec_variable (l2xixxpr.c)");
+
+ /* point to the variable's stack item. If the variable's level */
+ /* is less than the current level, follow the static links to the */
+ /* appropriate stack frame base */
+ hp = (STACK_ITEM_PTR) stack_frame_basep;
+ delta = level - idp->level;
+ while (delta-- > 0) {
+ hp = (STACK_ITEM_PTR) get_static_link(hp);
+ }
+ datap = hp + idp->defn.info.data.offset;
+
+ /* If a scalar or enumeration VAR parm, that item points to the */
+ /* actual item */
+ if ((idp->defn.key == VARPARM_DEFN) &&
+ (tp->form != ARRAY_FORM) &&
+ (tp->form != ENTITY_FORM) &&
+ (tp->form != BAG_FORM) &&
+ (tp->form != LIST_FORM) &&
+ (tp->form != SET_FORM)) {
+ datap = (STACK_ITEM_PTR) get_address(datap);
+ }
+
+ /* push the address of the variables data area */
+ if ((tp->form == BAG_FORM) ||
+ (tp->form == LIST_FORM) ||
+ (tp->form == SET_FORM)) {
+ stype = form2stack[tp->form];
+ push_address_type(get_address_type(datap, stype), stype);
+ }
+ else if ((tp->form == ARRAY_FORM) ||
+ (tp->form == ENTITY_FORM)) {
+ push_address((ADDRESS) get_address(datap));
+ }
+ else {
+ push_address((ADDRESS) datap);
+ }
+
+ get_ctoken();
+
+ /* for a string, may be dealing with a substring only */
+ if (tp->form == STRING_FORM) {
+ if (ctoken == LBRACKET) {
+ exec_substring(use);
+ if (use != TARGET_USE && use != VARPARM_USE) {
+ exit_debug("exec_variable");
+ return(tp);
+ }
+ }
+ }
+ else {
+ /* if there are any subscripts or attribute designators, */
+ /* modify the address to point to the array element record field */
+ while ((ctoken == LBRACKET) || (ctoken == PERIOD)) {
+ if (ctoken == LBRACKET) tp = exec_subscripts(tp);
+ else if (ctoken == PERIOD) tp = exec_attribute();
+ }
+ }
+
+ base_tp = base_type(tp);
+
+ /* leave the modified address on top of the stack if it: */
+ /* is an assignment target */
+ /* represents a parameter passed by reference */
+ /* is the address of an array or entity */
+ /* Otherwise, replace the address with the value it points to */
+
+ if ((use != TARGET_USE) && (use != VARPARM_USE) &&
+ (tp->form != ARRAY_FORM) &&
+ (tp->form != ENTITY_FORM) &&
+ (tp->form != BAG_FORM) &&
+ (tp->form != LIST_FORM) &&
+ (tp->form != SET_FORM)) {
+ if (is_value_undef(get_address(tos))) {
+ put_undef(tos);
+ }
+ else if (base_tp == logical_typep) {
+ put_logical(tos, get_logical(get_address(tos)));
+ }
+ else if ((base_tp == integer_typep) || (tp->form == ENUM_FORM)) {
+ put_integer(tos, get_integer(get_address(tos)));
+ }
+ else if (tp->form == STRING_FORM) {
+ put_string(tos, get_stacked_string(get_address(tos)));
+ }
+ else if (tp->form == BAG_FORM ||
+ tp->form == LIST_FORM ||
+ tp->form == SET_FORM) {
+ stype = get_stackval_type(tos);
+ put_address_type(tos, get_address_type(tos, stype), stype);
+ }
+ else {
+ put_real(tos, get_real(get_address(tos)));
+ }
+ }
+
+ if ((use != TARGET_USE) && (use != VARPARM_USE)) {
+ stype = get_stackval_type(tos);
+ if ((tp->form == ARRAY_FORM) ||
+ (tp->form == ENTITY_FORM) ||
+ (tp->form == BAG_FORM) ||
+ (tp->form == LIST_FORM) ||
+ (tp->form == SET_FORM)) {
+ trace_data_fetch(idp, tp, get_address_type(tos, stype));
+ }
+ else {
+ trace_data_fetch(idp, tp, tos);
+ }
+ }
+
+ expression_type_debug(tp);
+ exit_debug("exec_variable");
+ return(tp);
+} /* end exec_variable */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_substring() Execute subscripts to modify the string on top */
+/* of the stack */
+/* at entry: ctoken is the opening [ */
+/* at exit: ctoken is after the closing ] */
+
+exec_substring(usage)
+USE usage; /* how the var is used */
+{
+ XPRSAINT subscript1_value, subscript2_value;
+ STRING strorig;
+ STRING strnew;
+ int num, i, j;
+ entry_debug("exec_substring (l2xixxpr.c)");
+
+ /* save the current string */
+ strorig = get_stacked_string(get_address(tos));
+
+ /* do first expression */
+ get_ctoken();
+ exec_expression();
+ subscript1_value = get_integer(tos);
+ pop();
+ /* check value in range */
+ if ((subscript1_value < 1) ||
+ (subscript1_value > MAX_EXPRESS_STRING)) {
+ runtime_error(VALUE_OUT_OF_RANGE);
+ }
+ subscript2_value = subscript1_value;
+
+ if (ctoken == COLON) { /* do next expression */
+ get_ctoken();
+ exec_expression();
+ subscript2_value = get_integer(tos);
+ pop();
+ /* check value in range */
+ if ((subscript2_value < subscript1_value) ||
+ (subscript2_value > MAX_EXPRESS_STRING)) {
+ runtime_error(VALUE_OUT_OF_RANGE);
+ }
+ }
+
+ get_ctoken(); /* token after closing ] */
+
+ /* now do the substring stuff */
+ num = (subscript2_value - subscript1_value + 1); /* no of chars */
+ strnew = alloc_bytes(num+1);
+ j = 0;
+ for (i = subscript1_value - 1; i < subscript2_value; i++) {
+ strnew[j] = strorig[i];
+ j++;
+ }
+ strnew[j] = '\0';
+ /* replace strorig in the stack with strnew, unless a lhs */
+ if (usage != TARGET_USE && usage != VARPARM_USE) {
+ put_string(tos, strnew);
+ }
+
+ exit_debug("exec_substring");
+ return;
+} /* end EXEC_SUBSTRING */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_subscripts(tp) Execute subscripts to modify the array data area */
+/* address on the top of the stack */
+/* return a pointer to the type of the array element */
+
+TYPE_STRUCT_PTR exec_subscripts(tp)
+TYPE_STRUCT_PTR tp; /* ptr to type structure */
+{
+ XPRSAINT subscript_value;
+ STACK_ITEM_PTR adr, dat;
+ STACK_TYPE stype;
+ LBS_PTR lbs;
+ LBS_NODE_PTR node;
+ entry_debug("exec_subscripts");
+
+ /* loop to execute bracketed subscripts */
+ if (tp->form == ARRAY_FORM) {
+ while (ctoken == LBRACKET) {
+ /* loop to execute a subscript list */
+ do {
+ get_ctoken();
+ exec_expression();
+
+ subscript_value = get_integer(tos);
+ pop();
+
+ /* range check */
+ if ((subscript_value < tp->info.array.min_index) ||
+ (subscript_value > tp->info.array.max_index)) {
+ runtime_error(VALUE_OUT_OF_RANGE);
+ }
+
+ /* modify the data area address */
+ adr = (STACK_ITEM_PTR) get_address(tos);
+ adr = adr +
+ ((subscript_value - tp->info.array.min_index) *
+ (tp->info.array.elmt_typep->size))/sizeof(STACK_ITEM);
+ put_address(tos, adr);
+
+ if (ctoken == COMMA) tp = tp->info.array.elmt_typep;
+ } while (ctoken == COMMA); /* end do */
+
+ get_ctoken();
+ if (ctoken == LBRACKET) tp = tp->info.array.elmt_typep;
+ } /* end while */
+ } /* end of array processing */
+
+ else if (tp->form == BAG_FORM ||
+ tp->form == LIST_FORM ||
+ tp->form == SET_FORM) { /* dynamic aggregate */
+ stype = form2stack[tp->form];
+ while (ctoken == LBRACKET) {
+ get_ctoken();
+ exec_expression();
+
+ subscript_value = get_integer(tos);
+ pop();
+
+ /* range check */
+ if ((subscript_value < tp->info.dynagg.min_index) ||
+ (subscript_value > tp->info.dynagg.max_index)) {
+ runtime_error(VALUE_OUT_OF_RANGE);
+ }
+
+ /* get the element from the aggregate */
+ lbs = (LBS_PTR) get_address_type(tos, stype);
+ /* outside element count? */
+ sprintf(dbuffer, "lbs = %d, el count = %d, subscript = %d\n",
+ lbs, NELS(lbs), subscript_value);
+ debug_print(dbuffer);
+ if (subscript_value > NELS(lbs)) runtime_error(VALUE_OUT_OF_RANGE);
+ node = lbs_get_nth(lbs, subscript_value);
+ sprintf(dbuffer, "node = %d\n", node);
+ debug_print(dbuffer);
+ /* put the element data on top of the stack */
+ dat = (STACK_ITEM_PTR) DATA(node);
+ sprintf(dbuffer, "data = %d\n", dat);
+ debug_print(dbuffer);
+ copy_value(tos, dat);
+
+ get_ctoken();
+ if (ctoken == LBRACKET) tp = tp->info.dynagg.elmt_typep;
+ } /* end while */
+ } /* end of dynamic aggregate processing */
+
+ exit_debug("exec_subscripts");
+ return(tp);
+} /* end exec_subscripts */
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* exec_attribute() Execute an attribute designator to modify the */
+/* entity data */
+/* address area on the top of the stack */
+/* return a pointer to the type of the attribute */
+
+TYPE_STRUCT_PTR exec_attribute()
+{
+ SYMTAB_NODE_PTR attr_idp;
+ ADDRESS adr;
+ entry_debug("exec_attribute (l2xixxpr.c)");
+
+ get_ctoken();
+ attr_idp = get_symtab_cptr();
+
+ adr = get_address(tos);
+ adr += attr_idp->defn.info.data.offset;
+ put_address(tos, adr);
+
+ get_ctoken();
+
+ exit_debug("exec_attribute");
+ return(attr_idp->typep);
+} /* end EXEC_ATTRIBUTE */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* promote_operands_to_real(operandp1, tp1, operandp2, tp2) If either */
+/* operand is integer, convert it to real */
+
+promote_operands_to_real(operandp1, tp1, operandp2, tp2)
+STACK_ITEM_PTR operandp1, operandp2; /* ptrs to operands */
+TYPE_STRUCT_PTR tp1, tp2; /* ptrs to types */
+{
+ XPRSAINT i1;
+ entry_debug("promote_operands_to_real");
+
+ if (tp1 == integer_typep) {
+ if (!is_value_undef(operandp1)) {
+ i1 = get_integer(operandp1);
+ put_real(operandp1, (XPRSAREAL) i1);
+ }
+ }
+ if (tp2 == integer_typep) {
+ if (!is_value_undef(operandp2)) {
+ i1 = get_integer(operandp2);
+ put_real(operandp2, (XPRSAREAL) i1);
+ }
+ }
+
+
+ exit_debug("promote_operands_to_real");
+ return;
+} /* end promote_operands_to_real */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* concat_strings() Concatenate two strings */
+
+STRING concat_strings(op1, op2)
+STACK_ITEM_PTR op1; /* pos of first string in the stack */
+STACK_ITEM_PTR op2; /* pos of second string in the stack */
+{
+ int n1 = strlen(get_stacked_string(op1));
+ int n2 = strlen(get_stacked_string(op2));
+ int tot, i, j;
+ STRING str = NULL;
+ STRING two;
+ entry_debug("concat_strings (l2xixxpr.c)");
+
+ tot = n1 + n2;
+ if (tot <= MAX_EXPRESS_STRING) {
+ str = alloc_bytes(n1 + n2 + 1);
+ strcpy(str, get_stacked_string(op1));
+ strcat(str, get_stacked_string(op2));
+ }
+ else {
+ runtime_error(RUNTIME_STRING_TOO_LONG);
+ tot = MAX_EXPRESS_STRING;
+ str = alloc_bytes(tot + 1);
+ strcpy(str, get_stacked_string(op1));
+ two = get_stacked_string(op2);
+ j = n1;
+ for (i = 0; j <= tot; i++) {
+ str[j++] = two[i];
+ }
+ str[j] = '\0';
+ }
+
+ exit_debug("concat_strings");
+ return(str);
+} /* end CONCAT_STRINGS */
+/***************************************************************************/
+
+
+
+/***************************************************************************/
+/* exec_dynagg_relop(t1, p1, op, t2, p2) Execute a relop on dynamic */
+/* aggregates */
+/* p1 op p2 */
+/* returns a logical result */
+
+LOGICAL_REP exec_dynagg_relop(t1, p1, op, t2, p2)
+TYPE_STRUCT_PTR t1; /* type of p1 */
+STACK_ITEM_PTR p1; /* value of p1 */
+TOKEN_CODE op; /* the operator */
+TYPE_STRUCT_PTR t2; /* type of p2 */
+STACK_ITEM_PTR p2; /* value of p2 */
+{
+ LOGICAL_REP result;
+ STACK_ITEM_PTR agg;
+ LBS_NODE_PTR nod, nextnod;
+ STACK_TYPE agtp = get_stackval_type(p2);
+ LBS_PTR head;
+
+ entry_debug("exec_dynagg_relop (l2xixxpr.c)");
+
+ sprintf(dbuffer, "t1 = %d, p1 = %d, t2 = %d, p2 = %d\n", t1, p1, t2, p2);
+ debug_print(dbuffer);
+
+ if (op == IN) { /* element IN agg */
+ if (t1 != t2->info.dynagg.elmt_typep) { /* not an element */
+ exit_debug("exec_dynagg_relop");
+ return(FALSE_REP);
+ }
+ /* get first node */
+ head = (LBS_PTR) get_address_type(p2, agtp);
+ debug_print("Getting first node\n");
+ nod = lbs_get_next_el(head, NULL);
+ sprintf(dbuffer, "nod = %d\n", nod);
+ debug_print(dbuffer);
+
+ while (nod != NULL) { /* loop over all nodes */
+ debug_print("Testing for value equality\n");
+ sprintf(dbuffer, "data = %d\n", DATA(nod));
+ debug_print(dbuffer);
+ result = stack_value_equal(p1, DATA(nod));
+ if (result == UNKNOWN_REP || result == TRUE_REP) {
+ exit_debug("exec_dynagg_relop (p1 IN p2 not FALSE)");
+ return(result);
+ }
+ debug_print("Getting next node\n");
+ nod = lbs_get_next_el(head, nod);
+ sprintf(dbuffer, "nod = %d\n", nod);
+ debug_print(dbuffer);
+ }
+ exit_debug("exec_dynagg_relop (p1 IN p2 is FALSE");
+ return(FALSE_REP);
+ }
+
+ else {
+ runtime_error(UNIMPLEMENTED_RUNTIME_FEATURE);
+ exit_debug("exec_dynagg_relop");
+ return(UNKNOWN_REP);
+ }
+
+
+} /* end EXEC_DYNAGG_RELOP */
+/***************************************************************************/
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xlexyy.c b/support/ltx2x/l2xlexyy.c
new file mode 100644
index 0000000000..9f3a1a6d4e
--- /dev/null
+++ b/support/ltx2x/l2xlexyy.c
@@ -0,0 +1,2351 @@
+/* A lexical scanner generated by flex */
+
+/* scanner skeleton version:
+ * $Header: /usr/fsys/odin/a/vern/flex/RCS/flex.skel,v 2.16 90/08/03 14:09:36 vern Exp $
+ */
+
+#define FLEX_SCANNER
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <osfcn.h>
+
+/* use prototypes in function declarations */
+#define YY_USE_PROTOS
+
+/* the "const" storage-class-modifier is valid */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#ifdef __STDC__
+
+#ifdef __GNUC__
+#include <stddef.h>
+void *malloc( size_t );
+void free( void* );
+#else
+#include <stdlib.h>
+#endif /* __GNUC__ */
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+
+#ifdef __TURBOC__
+#define YY_USE_CONST
+#endif
+
+
+#ifndef YY_USE_CONST
+#define const
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+/* we can't get here if it's an ANSI C compiler, or a C++ compiler,
+ * so it's got to be a K&R compiler, and therefore there's no standard
+ * place from which to include these definitions
+ */
+char *malloc();
+int free();
+int read();
+#endif
+
+
+/* amount of stuff to slurp up with each read */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* returned upon end-of-file */
+#define YY_END_TOK 0
+
+/* copy whatever the last rule matched to the standard output */
+
+/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */
+/* this used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite()
+ */
+#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout )
+
+/* gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#define YY_INPUT(buf,result,max_size) \
+ if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
+ YY_FATAL_ERROR( "read() in flex scanner failed" );
+#define YY_NULL 0
+
+/* no semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#define yyterminate() return ( YY_NULL )
+
+/* report a fatal error */
+
+/* The funky do-while is used to turn this macro definition into
+ * a single C statement (which needs a semi-colon terminator).
+ * This avoids problems with code like:
+ *
+ * if ( something_happens )
+ * YY_FATAL_ERROR( "oops, the something happened" );
+ * else
+ * everything_okay();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the YY_FATAL_ERROR() call.
+ */
+
+#define YY_FATAL_ERROR(msg) \
+ do \
+ { \
+ (void) fputs( msg, stderr ); \
+ (void) putc( '\n', stderr ); \
+ exit( 1 ); \
+ } \
+ while ( 0 )
+
+/* default yywrap function - always treat EOF as an EOF */
+#define yywrap() 1
+
+/* enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* action number for EOF rule of a given start state */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* special action meaning "start processing a new file" */
+#define YY_NEW_FILE \
+ do \
+ { \
+ yy_init_buffer( yy_current_buffer, yyin ); \
+ yy_load_buffer_state(); \
+ } \
+ while ( 0 )
+
+/* default declaration of generated scanner - a define so the user can
+ * easily add parameters
+ */
+#define YY_DECL int yylex YY_PROTO(( void ))
+
+/* code executed at the end of each rule */
+#define YY_BREAK break;
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */
+#endif
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+#define YY_CHAR char
+# line 1 "l2x.l"
+#define INITIAL 0
+# line 2 "l2x.l"
+/*
+ * l2x.l --- (flex) lexer for converting a LaTeX file to X
+ * Written by Peter Wilson (Catholic University and NIST)
+ * Version 0.2, January 1995
+ * Revised July 1996
+ * -- replace myprint(tag) by tag_print(tag)
+ * -- added verb(atim) like capability
+ */
+
+/* Development of this software was funded by the United States Government,
+ * and is not subject to copyright.
+ */
+
+#include <string.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xytab.h" /* token codes from parser */
+#include "l2xlib.h" /* functions and global variables */
+#include "l2xusrlb.h" /* possibly useful strings and user-defined functions */
+
+
+extern int opt_param;
+extern int all_opt;
+extern int opt_coord;
+int got_opt_item = FALSE;
+int got_a_dollar = FALSE;
+int got_opt_param = FALSE;
+int got_all_opt = FALSE;
+int got_opt_coord = FALSE;
+
+
+char verb_char; /* delimeter for \verb command */
+int result;
+int kind;
+int special_kind;
+PSENTRY ptr; /* pointer to sym entry */
+int nl_count = 0; /* number of consecutive new lines */
+char a_newline[] = "\n";
+char a_space[] = " ";
+char vlenv[80]; /* name of verbatim-like environment */
+int nopen_vbrace = 0; /* no of unmatched open braces after verb-like command */
+
+int nopen_noop = 0; /* no of unmatched openers for no_op argument */
+#define NOOPLBRAK 1
+#define NOOPRBRAK 1
+#define NOOPLBRACE 2
+#define NOOPRBRACE 2
+int noop_openc; /* noop argument opening character ( [ or { )*/
+
+#define LDA -1
+#define LD0 0
+#define LD1 1
+#define LD2 2
+#define LD3 3
+#define LD4 4
+#define LD5 5
+#define LD6 6
+/*
+ * LDEBUG > LDA: error prints:
+ * > LD0: names not in command table
+ * > LD1: newlines, returned useful tokens
+ * > LD2: general tokens
+ * > LD3: text dealt with in lexer
+ * > LD4: comments
+ * > LD5: stuff within verbatims
+ * > LD6:
+ *
+ */
+
+/* whitespace and comments */
+/* TeX comments from % through eol + any following whitespace */
+/* general REs */
+/* (La)TeX literals */
+/* general LaTeX commands */
+/* list items */
+#define VERBATIM_STATE 1
+#define VERB_STATE 2
+#define VERBATIM_LIKE 3
+#define VERB_LIKE 4
+#define NOOP 5
+# line 122 "l2x.l"
+
+/* done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext = yy_bp; \
+ yyleng = yy_cp - yy_bp; \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* return all but the first 'n' matched characters back to the input stream */
+#define yyless(n) \
+ do \
+ { \
+ /* undo effects of setting up yytext */ \
+ *yy_cp = yy_hold_char; \
+ yy_c_buf_p = yy_cp = yy_bp + n; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext )
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ YY_CHAR *yy_ch_buf; /* input buffer */
+ YY_CHAR *yy_buf_pos; /* current position in input buffer */
+
+ /* size of input buffer in bytes, not including room for EOB characters*/
+ int yy_buf_size;
+
+ /* number of characters read into yy_ch_buf, not including EOB characters */
+ int yy_n_chars;
+
+ int yy_eof_status; /* whether we've seen an EOF on this buffer */
+#define EOF_NOT_SEEN 0
+ /* "pending" happens when the EOF has been seen but there's still
+ * some text process
+ */
+#define EOF_PENDING 1
+#define EOF_DONE 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer;
+
+/* we provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state"
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed */
+static YY_CHAR yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+#ifndef YY_USER_INIT
+#define YY_USER_INIT
+#endif
+
+extern YY_CHAR *yytext;
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+YY_CHAR *yytext;
+int yyleng;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+#define YY_END_OF_BUFFER 57
+typedef int yy_state_type;
+static const short int yy_accept[171] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 57, 55, 52, 53, 38, 39, 44, 40,
+ 50, 51, 49, 55, 55, 47, 45, 46, 36, 55,
+ 37, 43, 42, 34, 35, 41, 7, 5, 6, 10,
+ 11, 18, 17, 18, 15, 14, 12, 13, 24, 23,
+ 20, 22, 19, 21, 52, 53, 53, 0, 1, 0,
+ 47, 48, 48, 46, 46, 29, 28, 27, 31, 29,
+ 31, 31, 31, 31, 7, 0, 0, 1, 48, 31,
+ 0, 30, 31, 31, 31, 31, 0, 0, 31, 31,
+ 31, 31, 0, 0, 31, 0, 0, 25, 31, 0,
+
+ 0, 0, 0, 31, 0, 0, 0, 25, 26, 9,
+ 9, 9, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 8, 0, 0, 0, 2, 0, 0, 4, 0
+ } ;
+
+static const YY_CHAR yy_ec[128] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 1, 1, 5, 6, 7, 8, 1, 9,
+ 10, 11, 1, 12, 13, 14, 1, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 1, 1, 1,
+ 1, 1, 1, 16, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 18, 19, 20, 21, 22, 1, 23, 24, 25, 26,
+
+ 27, 17, 28, 17, 29, 17, 17, 17, 30, 31,
+ 32, 17, 17, 33, 17, 34, 35, 36, 17, 17,
+ 17, 17, 37, 1, 38, 39, 1
+ } ;
+
+static const YY_CHAR yy_meta[40] =
+ { 0,
+ 1, 2, 3, 2, 1, 1, 1, 1, 1, 1,
+ 4, 1, 1, 1, 1, 1, 5, 1, 3, 1,
+ 1, 1, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 1, 1, 1
+ } ;
+
+static const short int yy_base[183] =
+ { 0,
+ 0, 0, 37, 38, 365, 362, 39, 40, 41, 43,
+ 45, 48, 364, 438, 50, 43, 438, 438, 360, 438,
+ 438, 438, 438, 35, 346, 46, 438, 349, 438, 86,
+ 438, 438, 438, 438, 438, 438, 0, 438, 330, 438,
+ 438, 438, 438, 329, 438, 438, 438, 438, 438, 438,
+ 438, 438, 438, 438, 67, 60, 70, 350, 71, 336,
+ 62, 330, 300, 438, 285, 438, 438, 438, 281, 124,
+ 116, 118, 119, 120, 0, 258, 257, 130, 259, 438,
+ 134, 438, 56, 122, 128, 126, 247, 246, 129, 140,
+ 130, 139, 150, 160, 135, 163, 166, 167, 200, 238,
+
+ 241, 242, 170, 245, 177, 246, 239, 171, 438, 438,
+ 274, 259, 250, 242, 178, 249, 257, 254, 274, 279,
+ 438, 243, 234, 291, 309, 438, 312, 316, 234, 238,
+ 229, 239, 317, 320, 438, 237, 222, 211, 176, 163,
+ 172, 168, 160, 163, 168, 159, 159, 159, 150, 149,
+ 146, 130, 128, 321, 324, 122, 25, 328, 438, 329,
+ 332, 438, 335, 338, 339, 438, 342, 348, 438, 438,
+ 386, 391, 396, 401, 406, 411, 413, 418, 420, 424,
+ 428, 432
+ } ;
+
+static const short int yy_def[183] =
+ { 0,
+ 170, 1, 171, 171, 172, 172, 173, 173, 174, 174,
+ 175, 175, 170, 170, 170, 170, 170, 170, 176, 170,
+ 170, 170, 170, 170, 170, 170, 170, 177, 170, 170,
+ 170, 170, 170, 170, 170, 170, 178, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 176, 170, 170,
+ 170, 170, 170, 170, 177, 170, 170, 170, 179, 170,
+ 179, 179, 179, 179, 178, 170, 170, 170, 170, 170,
+ 170, 170, 179, 179, 179, 179, 170, 170, 179, 179,
+ 179, 179, 170, 170, 179, 170, 180, 179, 170, 170,
+
+ 170, 170, 181, 90, 180, 180, 106, 170, 170, 170,
+ 99, 179, 170, 170, 181, 181, 170, 182, 170, 170,
+ 170, 106, 170, 170, 170, 170, 182, 182, 128, 128,
+ 106, 170, 170, 170, 170, 128, 128, 106, 170, 128,
+ 128, 106, 170, 128, 128, 106, 170, 128, 128, 106,
+ 170, 128, 128, 106, 170, 128, 128, 170, 170, 170,
+ 170, 170, 128, 128, 170, 170, 170, 170, 170, 0,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170
+ } ;
+
+static const short int yy_nxt[478] =
+ { 0,
+ 14, 15, 16, 15, 17, 18, 19, 20, 21, 22,
+ 14, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 34, 35, 36, 38,
+ 38, 43, 43, 46, 57, 46, 57, 50, 60, 61,
+ 50, 55, 56, 55, 164, 39, 39, 44, 44, 63,
+ 61, 57, 51, 57, 52, 51, 80, 52, 55, 56,
+ 55, 57, 78, 57, 78, 63, 61, 47, 48, 47,
+ 48, 53, 54, 89, 53, 54, 66, 66, 67, 68,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+
+ 66, 66, 69, 66, 70, 66, 66, 66, 69, 71,
+ 69, 69, 72, 69, 73, 69, 69, 69, 69, 69,
+ 69, 74, 66, 66, 66, 81, 80, 81, 80, 80,
+ 80, 78, 80, 78, 82, 81, 80, 81, 80, 80,
+ 80, 96, 83, 96, 82, 80, 86, 90, 84, 80,
+ 80, 100, 85, 100, 91, 163, 157, 95, 92, 98,
+ 156, 102, 99, 102, 96, 104, 96, 105, 108, 105,
+ 108, 115, 108, 115, 108, 155, 97, 80, 105, 115,
+ 105, 115, 154, 153, 109, 152, 101, 151, 109, 150,
+ 149, 107, 148, 147, 146, 145, 103, 144, 143, 97,
+
+ 110, 110, 107, 110, 110, 110, 110, 110, 110, 110,
+ 111, 110, 110, 110, 110, 110, 112, 110, 110, 110,
+ 110, 110, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 110, 110, 110, 100,
+ 142, 100, 113, 102, 113, 102, 117, 119, 117, 119,
+ 124, 113, 124, 113, 141, 127, 120, 127, 117, 125,
+ 117, 140, 139, 138, 137, 136, 132, 131, 123, 80,
+ 122, 94, 93, 79, 101, 119, 114, 119, 103, 129,
+ 119, 118, 119, 121, 110, 114, 126, 88, 87, 130,
+ 110, 80, 124, 118, 124, 64, 110, 110, 110, 110,
+
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 124, 121, 124, 127, 79, 127, 121, 133, 133, 133,
+ 133, 133, 158, 133, 158, 160, 134, 160, 126, 158,
+ 160, 158, 160, 160, 161, 160, 165, 129, 165, 167,
+ 165, 167, 165, 167, 62, 167, 126, 130, 168, 167,
+ 62, 167, 59, 135, 135, 77, 76, 135, 159, 64,
+ 62, 162, 59, 170, 41, 159, 162, 41, 170, 162,
+ 170, 170, 166, 170, 170, 169, 166, 170, 170, 169,
+ 170, 170, 170, 170, 170, 169, 37, 37, 37, 37,
+ 37, 40, 40, 40, 40, 40, 42, 42, 42, 42,
+
+ 42, 45, 45, 45, 45, 45, 49, 49, 49, 49,
+ 49, 58, 58, 58, 58, 58, 65, 65, 75, 75,
+ 170, 75, 75, 69, 69, 106, 170, 170, 106, 116,
+ 170, 170, 116, 128, 170, 170, 128, 13, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170
+ } ;
+
+static const short int yy_chk[478] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 4, 7, 8, 9, 16, 10, 16, 11, 24, 24,
+ 12, 15, 15, 15, 157, 3, 4, 7, 8, 26,
+ 26, 56, 11, 56, 11, 12, 83, 12, 55, 55,
+ 55, 57, 59, 57, 59, 61, 61, 9, 9, 10,
+ 10, 11, 11, 83, 12, 12, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 70, 71, 70, 72, 73,
+ 74, 78, 84, 78, 70, 81, 86, 81, 85, 89,
+ 91, 90, 71, 90, 81, 95, 74, 84, 72, 92,
+ 90, 93, 73, 93, 85, 156, 153, 89, 86, 91,
+ 152, 94, 92, 94, 96, 95, 96, 97, 98, 97,
+ 98, 103, 108, 103, 108, 151, 90, 98, 105, 115,
+ 105, 115, 150, 149, 98, 148, 93, 147, 108, 146,
+ 145, 97, 144, 143, 142, 141, 94, 140, 139, 96,
+
+ 99, 99, 105, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 100,
+ 138, 100, 101, 102, 101, 102, 104, 106, 104, 106,
+ 116, 113, 116, 113, 137, 118, 106, 118, 117, 116,
+ 117, 136, 132, 131, 130, 129, 123, 122, 114, 112,
+ 107, 88, 87, 79, 100, 119, 101, 119, 102, 118,
+ 120, 104, 120, 106, 111, 113, 116, 77, 76, 118,
+ 111, 69, 124, 117, 124, 65, 111, 111, 111, 111,
+
+ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
+ 125, 119, 125, 127, 63, 127, 120, 128, 133, 128,
+ 133, 134, 154, 134, 154, 155, 128, 155, 124, 158,
+ 160, 158, 160, 161, 155, 161, 163, 127, 163, 164,
+ 165, 164, 165, 167, 62, 167, 125, 127, 164, 168,
+ 60, 168, 58, 128, 133, 44, 39, 134, 154, 28,
+ 25, 155, 19, 13, 6, 158, 160, 5, 0, 161,
+ 0, 0, 163, 0, 0, 164, 165, 0, 0, 167,
+ 0, 0, 0, 0, 0, 168, 171, 171, 171, 171,
+ 171, 172, 172, 172, 172, 172, 173, 173, 173, 173,
+
+ 173, 174, 174, 174, 174, 174, 175, 175, 175, 175,
+ 175, 176, 176, 176, 176, 176, 177, 177, 178, 178,
+ 0, 178, 178, 179, 179, 180, 0, 0, 180, 181,
+ 0, 0, 181, 182, 0, 0, 182, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 170, 170, 170, 170, 170
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static YY_CHAR *yy_last_accepting_cpos;
+
+/* the intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+
+/* these variables are all declared out here so that section 3 code can
+ * manipulate them
+ */
+/* points to current character in buffer */
+static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yyunput YY_PROTO(( YY_CHAR c, YY_CHAR *buf_ptr ));
+void yyrestart YY_PROTO(( FILE *input_file ));
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+
+#define yy_new_buffer yy_create_buffer
+
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register YY_CHAR *yy_cp, *yy_bp;
+ register int yy_act;
+
+
+
+ /*------------ Comments plus start and end document ---------------*/
+
+
+ if ( yy_init )
+ {
+ YY_USER_INIT;
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( yy_current_buffer )
+ yy_init_buffer( yy_current_buffer, yyin );
+ else
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+
+ yy_init = 0;
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* support of yytext */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of the
+ * current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[*yy_cp];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = yy_def[yy_current_state];
+ if ( yy_current_state >= 171 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 170 );
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+ YY_USER_ACTION;
+
+do_action: /* this label is used only to access EOF actions */
+
+
+ switch ( yy_act )
+ {
+ case 0: /* must backtrack */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+# line 126 "l2x.l"
+{
+ if (LDEBUG > LD4) {
+ print_debug_2s("(tex_comment):", yytext);
+ }
+ catl(yyleng, yytext);
+ do_newline();
+ if (leave_comments) { /* leave in comments */
+ myprint(yytext);
+ }
+ }
+ YY_BREAK
+ /* \begin{document} */
+case 2:
+# line 139 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_BEGIN_DOCUMENT):", yytext);
+ }
+ yylval.pos = get_mode_sym(pos_bdoc);
+ return(BEGIN_DOCUMENT);
+ }
+ YY_BREAK
+ /* end of document \end{document} */
+case 3:
+# line 149 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_END_DOCUMENT):", yytext);
+ }
+ yylval.pos = get_mode_sym(pos_edoc);
+ return(END_DOCUMENT);
+ }
+ YY_BREAK
+ /*----------------- verbatims -----------------------------------------*/
+ /* Do most of the processing in the lexer */
+ /* but pass token back to parser anyway */
+ /* \begin{verbatim} */
+case 4:
+# line 166 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(begin{verbatim}):", yytext);
+ }
+ BEGIN VERBATIM_STATE;
+ yylval.pos = get_mode_sym(pos_bvbm);
+ bverb = TRUE;
+ return(BEGIN_VERBATIM);
+ }
+ YY_BREAK
+ /* newline */
+case 5:
+# line 177 "l2x.l"
+{ catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in verbatim):", yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /* backslash */
+case 6:
+# line 185 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /* any characters other than newline and backslash */
+case 7:
+# line 192 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /* \end{verbatim} */
+case 8:
+# line 199 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(end{verbatim}):", yytext);
+ }
+ BEGIN 0;
+ yylval.pos = get_mode_sym(pos_evbm);
+ return(END_VERBATIM);
+ }
+ YY_BREAK
+ /* \verb (and its trailing character) */
+case 9:
+# line 210 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(verb):", yytext);
+ }
+ BEGIN VERB_STATE;
+ verb_char = yytext[yyleng-1];
+ yylval.pos = get_mode_sym(pos_bv);
+ return(BEGIN_VERB);
+ }
+ YY_BREAK
+ /* chars inside \verb */
+case 10:
+# line 222 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (verb_char != yytext[0] ) {
+ myprint(yytext);
+ }
+ else { /* end of verb environment */
+ BEGIN 0;
+ yylval.pos = get_mode_sym(pos_ev);
+ return(END_VERB);
+ }
+ }
+ YY_BREAK
+ /* newlines not allowed within verb */
+case 11:
+# line 237 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count++;
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ BEGIN 0;
+ yyerror("Error: \"verb\" ended by a newline");
+ do_newline();
+ myprint(a_newline);
+ yylval.pos = get_mode_sym(pos_ev);
+ return(END_VERB);
+ }
+ YY_BREAK
+ /* VERB LIKE command stuff */
+ /* { (open brace) */
+case 12:
+# line 252 "l2x.l"
+{ catl(yyleng, yytext);
+ nopen_vbrace++;
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (nopen_vbrace == 1) { /* start of argument */
+ yylval.pos = get_mode_sym(pos_lbrace);
+ return(LBRACE);
+ }
+ else { /* part of argument */
+ verbatim_print(yytext);
+ }
+ }
+ YY_BREAK
+ /* } (close brace) */
+case 13:
+# line 267 "l2x.l"
+{ catl(yyleng, yytext);
+ nopen_vbrace--;
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (nopen_vbrace == 0) { /* end of argument */
+ BEGIN 0; /* change state */
+ yylval.pos = get_mode_sym(pos_rbrace);
+ return(RBRACE);
+ }
+ else { /* part of argument */
+ verbatim_print(yytext);
+ }
+ }
+ YY_BREAK
+ /* newline */
+case 14:
+# line 283 "l2x.l"
+{ catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in verb-like):", yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /* any other character */
+case 15:
+# line 292 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /* VERBATIM LIKE environment stuff */
+ /* \end{something} */
+case 16:
+# line 303 "l2x.l"
+{ catl (yyleng, yytext);
+ nl_count = 0;
+ get_env_name(yytext);
+ if (strcmp(vlenv, env_name) == 0) { /* close verbatim like */
+ if (LDEBUG > LD1) {
+ print_debug_2s("(end):", yytext);
+ print_debug_2s("env_name= ", env_name);
+ }
+ result = lookup_entry(env_name, END_VENV);
+ if (result > 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ BEGIN 0;
+ return(kind);
+ }
+ else { /* got problems, end env name not in table */
+ warning_3s("END_VENV",env_name,"not in command table. Expect input/output errors from now on");
+ BEGIN 0;
+ verbatim_print(yytext);
+ }
+ }
+ else { /* not end of verbatim-like env */
+ verbatim_print(yytext);
+ }
+ }
+ YY_BREAK
+ /* newline */
+case 17:
+# line 331 "l2x.l"
+{ catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in verbatim-like):", yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /* any other character */
+case 18:
+# line 340 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ verbatim_print(yytext);
+ }
+ YY_BREAK
+ /*---------------------------No Op processing---------------------------*/
+ /* open brace */
+case 19:
+# line 350 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRACE) {
+ nopen_noop++;
+ }
+ }
+ YY_BREAK
+ /* open bracket */
+case 20:
+# line 360 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRAK) {
+ nopen_noop++;
+ }
+ }
+ YY_BREAK
+ /* close brace */
+case 21:
+# line 370 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRACE) {
+ nopen_noop--;
+ if (nopen_noop <= 0) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Closing NO_OP on brace)");
+ }
+ nopen_noop = 0;
+ in_noop = FALSE;
+ start_noop = FALSE;
+ BEGIN 0;
+ yylval.pos = get_mode_sym(pos_rbrace);
+ return(RBRACE);
+ }
+ }
+ }
+ YY_BREAK
+ /* close bracket */
+case 22:
+# line 391 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ if (noop_openc == NOOPLBRAK) {
+ nopen_noop--;
+ if (nopen_noop <= 0) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Closing NO_OP on bracket)");
+ }
+ nopen_noop = 0;
+ in_noop = FALSE;
+ start_noop = FALSE;
+ BEGIN 0;
+ got_opt_param = FALSE;
+ return(END_ANOPT);
+ }
+ }
+ }
+ YY_BREAK
+ /* newline */
+case 23:
+# line 413 "l2x.l"
+{ catl(yyleng, yytext);
+ do_newline();
+ if (LDEBUG > LD3) {
+ print_debug_2s("(newline in a no op):", yytext);
+ }
+ }
+ YY_BREAK
+ /* any other character */
+case 24:
+# line 421 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD5) {
+ print_to_err(yytext);
+ }
+ }
+ YY_BREAK
+ /*----------------------------Default processing------------------------*/
+ /*----------------------- list items ---------------------------*/
+ /* item */
+case 25:
+# line 432 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_ITEM):", yytext);
+ }
+ return(ITEM);
+ }
+ YY_BREAK
+ /* item[ */
+case 26:
+# line 441 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_ITEM_AND_BRAK):", yytext);
+ }
+ got_opt_item = TRUE;
+ return(ITEM_AND_BRAK);
+ }
+ YY_BREAK
+ /*------------------------------ commands ------------------------------*/
+ /* (La)TeX backslash followed by a single space */
+case 27:
+# line 454 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD4) {
+ print_debug_2s("(slashspace):", yytext);
+ } /* 6/96 change myprint to tag_print */
+ ptr = get_mode_sym(pos_bss);
+ tag_print(get_t(ptr));
+ tag_print(get_et(ptr));
+ }
+ YY_BREAK
+ /* (La)TeX backslash followed by a newline */
+case 28:
+# line 465 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count++;
+ yylval.string = strsave(yytext);
+ do_newline();
+ if (LDEBUG > LD1) {
+ fprintf(filerr, "\n LD(slashnewline): next line is %d\n", lineno);
+ fflush(filerr);
+ }
+ ptr = get_mode_sym(pos_bss);
+ tag_print(get_t(ptr));
+ tag_print(get_et(ptr));
+ if (!pretty_print) {
+ myprint(a_newline);
+ }
+ }
+ YY_BREAK
+ /* \one non-alphabetic character */
+case 29:
+# line 482 "l2x.l"
+{catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(char_command):", yytext);
+ }
+ result = lookup_entry(yytext, CHAR_COMMAND);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_COMMAND)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as CHAR_COMMAND)");
+ }
+ return(OTHER_COMMAND);
+ }
+ }
+ YY_BREAK
+ /* special processing for \\* command */
+case 30:
+# line 507 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(char_command):", yytext);
+ }
+ result = lookup_entry("\\\\", CHAR_COMMAND);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_COMMAND)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as CHAR_COMMAND)");
+ }
+ return(OTHER_COMMAND);
+ }
+ }
+ YY_BREAK
+ /* a command \something or \something* */
+case 31:
+# line 534 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(command):", yytext);
+ }
+ result = lookup_entry(yytext, DONT_CARE);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ switch (get_user_type(ptr)) {
+ case SPECIAL_COMMAND: {
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_COMMAND",yytext,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(kind);
+ }
+ else {
+ return(special_kind);
+ }
+ break;
+ }
+ case SPECIAL_SECTIONING: {
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_SECTIONING",yytext,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(kind);
+ }
+ else {
+ return(special_kind);
+ }
+ break;
+ }
+ case VCOMMAND: { /* verb-like */
+ BEGIN VERB_LIKE;
+ nopen_vbrace = 0;
+ break;
+ }
+ } /* end switch */
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_COMMAND)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a command type)");
+ }
+ return(OTHER_COMMAND);
+ }
+ }
+ YY_BREAK
+ /*-------------------- Environments ---------------------------*/
+ /* \begin{something} */
+case 32:
+# line 595 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(begin):", yytext);
+ }
+ get_env_name(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_2s("env_name= ", env_name);
+ }
+ result = lookup_entry(env_name, BEGIN_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, BEGIN_LIST_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, BEGIN_PICTURE_CC);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, BEGIN_VENV);
+ if (result >= 0) { /* found it */
+ BEGIN VERBATIM_LIKE; /* switch into verbatim-like mode */
+ bverb = TRUE;
+ strcpy(vlenv, env_name); /* remember environment name */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, SPECIAL_BEGIN_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_BEGIN_ENV",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ result = lookup_entry(env_name, SPECIAL_BEGIN_LIST);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_BEGIN_LIST",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_BEGIN)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as begin something)");
+ }
+ return(OTHER_BEGIN);
+ }
+ YY_BREAK
+ /* \end{something} */
+case 33:
+# line 676 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(end):", yytext);
+ }
+ get_env_name(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_2s("env_name= ", env_name);
+ }
+ result = lookup_entry(env_name, END_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, END_LIST_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, END_PICTURE);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ result = lookup_entry(env_name, SPECIAL_END_ENV);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_END_ENV",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ result = lookup_entry(env_name, SPECIAL_END_LIST);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ special_kind = get_special_token(ptr);
+ if (special_kind == COMMAND) {
+ warning_3s("SPECIAL_END_ENV",env_name,"not yet implemented");
+ }
+ if (special_kind >= MIN_CODE_SPECIAL) {
+ return(command_type(ptr));
+ }
+ else {
+ return(special_kind);
+ }
+ }
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER_END)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as end something)");
+ }
+ return(OTHER_END);
+ }
+ YY_BREAK
+ /*--------------------- Miscellaneous stuff -----------------------*/
+ /* an open brace { */
+case 34:
+# line 751 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_LBRACE):", yytext);
+ }
+ if (start_noop) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Starting NO_OP on brace)");
+ }
+ start_noop = FALSE;
+ in_noop = TRUE;
+ nopen_noop = 1;
+ noop_openc = NOOPLBRACE;
+ BEGIN NOOP;
+ }
+ yylval.pos = get_mode_sym(pos_lbrace);
+ return(LBRACE);
+ }
+ YY_BREAK
+ /* a close brace } */
+case 35:
+# line 771 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_RBRACE):", yytext);
+ }
+ yylval.pos = get_mode_sym(pos_rbrace);
+ return(RBRACE);
+ }
+ YY_BREAK
+ /* an open bracket [ */
+case 36:
+# line 781 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_LBRAK):", yytext);
+ }
+ if (opt_param) {
+ got_opt_param = TRUE;
+ opt_param = FALSE;
+ if (start_noop) {
+ if (LDEBUG > LD3) {
+ print_to_err("(Starting NO_OP on bracket)");
+ }
+ start_noop = FALSE;
+ in_noop = TRUE;
+ noop_openc = NOOPLBRAK;
+ BEGIN NOOP;
+ }
+ return(START_ANOPT);
+ }
+ else if (all_opt) {
+ got_all_opt = TRUE;
+ all_opt = FALSE;
+ return(START_ALLOPT);
+ }
+ else {
+ return(LBRAK);
+ }
+ }
+ YY_BREAK
+ /* a close bracket ] */
+case 37:
+# line 811 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_RBRAK):", yytext);
+ }
+ if (got_opt_item) {
+ got_opt_item = FALSE;
+ return(END_ITEM_BRAK);
+ }
+ else if (got_opt_param) {
+ got_opt_param = FALSE;
+ return(END_ANOPT);
+ }
+ else if (got_all_opt) {
+ got_all_opt = FALSE;
+ return(END_ALLOPT);
+ }
+ else {
+ return(RBRAK);
+ }
+ }
+ YY_BREAK
+ /*------------------- Special characters ----------------------*/
+ /* a naked hash # */
+case 38:
+# line 836 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(hash):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* a naked dollar $ */
+case 39:
+# line 861 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(dollar):", yytext);
+ if (got_a_dollar) { print_debug_1s("(as t_END_DOLLAR)"); }
+ else { print_debug_1s("(as t_BEGIN_DOLLAR)"); }
+ }
+ if (got_a_dollar) { /* a 'closing' $ */
+ got_a_dollar = FALSE;
+ yylval.pos = get_mode_sym(pos_edol);
+ return(END_DOLLAR);
+ }
+ else { /* an 'opening' $ */
+ got_a_dollar = TRUE;
+ yylval.pos = get_mode_sym(pos_bdol);
+ return(BEGIN_DOLLAR);
+ }
+ }
+ YY_BREAK
+ /* a naked ampersand & */
+case 40:
+# line 881 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(ampersand):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ kind = command_type(ptr);
+ yylval.pos = ptr;
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* a naked twiddle ~ */
+case 41:
+# line 907 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(twiddle):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* a naked underscore _ */
+case 42:
+# line 932 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(underscore):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* a naked caret ^ */
+case 43:
+# line 957 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(caret):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* a naked percent % */
+case 44:
+# line 982 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(percent):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* a naked at @ */
+case 45:
+# line 1007 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD1) {
+ print_debug_2s("(at):", yytext);
+ }
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(as t_OTHER)");
+ }
+ if (LDEBUG > LD0) {
+ print_debug_undef(yylval.string, " (as a special character)");
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+ /* name (alphabetic string(*) ) */
+case 46:
+# line 1034 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD1) {
+ print_debug_2s("(t_NAME):", yytext);
+ }
+ return(NAME);
+ }
+ YY_BREAK
+ /* integer (digit string) */
+case 47:
+# line 1044 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_INTEGER):", yytext);
+ }
+ return(INTEGER);
+ }
+ YY_BREAK
+ /* real (digits with one period) */
+case 48:
+# line 1054 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_REAL):", yytext);
+ }
+ return(REAL);
+ }
+ YY_BREAK
+ /* a comma */
+case 49:
+# line 1065 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_COMMA):", yytext);
+ }
+ return(COMMA);
+ }
+ YY_BREAK
+ /* left parenthesis */
+case 50:
+# line 1074 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_LPAREN):", yytext);
+ }
+ if (opt_coord) {
+ got_opt_coord = TRUE;
+ opt_coord = FALSE;
+ return(START_COORD);
+ }
+ else {
+ return(LPAREN);
+ }
+ }
+ YY_BREAK
+ /* right parenthesis */
+case 51:
+# line 1090 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ if (LDEBUG > LD2) {
+ print_debug_2s("(t_RPAREN):", yytext);
+ }
+ if (got_opt_coord) {
+ got_opt_coord = FALSE;
+ return(END_COORD);
+ }
+ else {
+ return(RPAREN);
+ }
+ }
+ YY_BREAK
+ /* whitespace (except newline) print it out */
+case 52:
+# line 1107 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD4) {
+ print_debug_2s("(ws):", yytext);
+ }
+ if (collapse_ws) { /* collapse whitespace */
+ myprint(a_space);
+ }
+ else {
+ myprint(yytext);
+ }
+ }
+ YY_BREAK
+ /* newline with leading and trailing spaces */
+ /* 7/96 changed to enable paragraphs outside pretty mode */
+case 53:
+# line 1121 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count++;
+ /* yylval.string = strsave(yytext); */
+ do_newline();
+ if (LDEBUG > LD1) {
+ fprintf(filerr, "\n LD(newline): next line is %d\n", lineno);
+ fflush(filerr);
+ }
+ if (!pretty_print) { /* not pretty printing */
+ myprint(yytext);
+ if (nl_count == 2) { /* 6/96 added this */
+ yylval.pos = get_mode_sym(pos_para);
+ return(PARAGRAPH);
+ }
+ }
+ else {
+ if (nl_count == 2) { /* (6/96 changed from >= 2 to == 2) a paragraph break */
+ yylval.pos = get_mode_sym(pos_para);
+ return(PARAGRAPH);
+ }
+ else { /* treat as space */
+ myprint(a_space);
+ }
+ }
+ }
+ YY_BREAK
+ /*----------- WHEN ALL ELSE FAILS --------------------*/
+ /* end of file */
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(VERBATIM_STATE):
+case YY_STATE_EOF(VERB_STATE):
+case YY_STATE_EOF(VERBATIM_LIKE):
+case YY_STATE_EOF(VERB_LIKE):
+case YY_STATE_EOF(NOOP):
+# line 1152 "l2x.l"
+{ catl(yyleng, yytext);
+ if (LDEBUG > LD1) {
+ print_debug_1s("(end of file):\n");
+ }
+ yyerror("Lexer: Unexpected end of file");
+ return(END_OF_FILE);
+ }
+ YY_BREAK
+ /* anything else */
+case 55:
+# line 1161 "l2x.l"
+{ catl(yyleng, yytext);
+ nl_count = 0;
+ result = lookup_entry(yytext, TEX_CHAR);
+ if (result >= 0) { /* found it */
+ if (LDEBUG > LD1) {
+ print_debug_2s("(tex_char):", yytext);
+ }
+ ptr = get_mode_sym(result);
+ yylval.pos = ptr;
+ kind = command_type(ptr);
+ return(kind);
+ }
+ else {
+ yylval.string = strsave(yytext);
+ if (LDEBUG > LD4) {
+ print_debug_2s("(catch_all):", yytext);
+ }
+ return(OTHER);
+ }
+ }
+ YY_BREAK
+case 56:
+# line 1182 "l2x.l"
+ECHO;
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* amount of text matched not including the EOB char */
+ int yy_amount_of_matched_text = yy_cp - yytext - 1;
+
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+
+ /* note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the end-
+ * of-buffer state). Contrast this with the test in yyinput().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* this was really a NUL */
+ {
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* okay, we're now positioned to make the
+ * NUL transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we
+ * don't want to build jamming into it because
+ * then it will run more slowly)
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* consume the NUL */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* note: because we've taken care in
+ * yy_get_next_buffer() to have set up yytext,
+ * we can now set up yy_c_buf_p so that if some
+ * total hoser (like flex itself) wants
+ * to call the scanner after we return the
+ * YY_NULL, it'll still work - another YY_NULL
+ * will get returned.
+ */
+ yy_c_buf_p = yytext + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF((yy_start - 1) / 2);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ }
+ break;
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+#ifdef FLEX_DEBUG
+ printf( "action # %d\n", yy_act );
+#endif
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ }
+ }
+ }
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * synopsis
+ * int yy_get_next_buffer();
+ *
+ * returns a code representing an action
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+
+ {
+ register YY_CHAR *dest = yy_current_buffer->yy_ch_buf;
+ register YY_CHAR *source = yytext - 1; /* copy prev. char, too */
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ /* try to read more data */
+
+ /* first move last chars to start of buffer */
+ number_to_move = yy_c_buf_p - yytext;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ else if ( num_to_read <= 0 )
+ YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" );
+
+ /* read in more data */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == 1 )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yy_current_buffer->yy_eof_status = EOF_DONE;
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_eof_status = EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ /* yytext begins at the second character in yy_ch_buf; the first
+ * character is the one which preceded it before reading in the latest
+ * buffer; it needs to be kept around in case it's a newline, so
+ * yy_get_previous_state() will have with '^' rules active
+ */
+
+ yytext = &yy_current_buffer->yy_ch_buf[1];
+
+ return ( ret_val );
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached
+ *
+ * synopsis
+ * yy_state_type yy_get_previous_state();
+ */
+
+static yy_state_type yy_get_previous_state()
+
+ {
+ register yy_state_type yy_current_state;
+ register YY_CHAR *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[*yy_cp] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = yy_def[yy_current_state];
+ if ( yy_current_state >= 171 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return ( yy_current_state );
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+register yy_state_type yy_current_state;
+#endif
+
+ {
+ register int yy_is_jam;
+ register YY_CHAR *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = yy_def[yy_current_state];
+ if ( yy_current_state >= 171 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 170);
+
+ return ( yy_is_jam ? 0 : yy_current_state );
+ }
+
+
+#ifdef YY_USE_PROTOS
+static void yyunput( YY_CHAR c, register YY_CHAR *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+YY_CHAR c;
+register YY_CHAR *yy_bp;
+#endif
+
+ {
+ register YY_CHAR *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
+ register YY_CHAR *dest =
+ &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2];
+ register YY_CHAR *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += dest - source;
+ yy_bp += dest - source;
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
+ yy_cp[-2] = '\n';
+
+ *--yy_cp = c;
+
+ /* note: the formal parameter *must* be called "yy_bp" for this
+ * macro to now work correctly
+ */
+ YY_DO_BEFORE_ACTION; /* set up yytext again */
+ }
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+
+ {
+ int c;
+ YY_CHAR *yy_cp = yy_c_buf_p;
+
+ *yy_cp = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* this was really a NUL */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ yytext = yy_c_buf_p;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ {
+ yy_c_buf_p = yytext + YY_MORE_ADJ;
+ return ( EOF );
+ }
+
+ YY_NEW_FILE;
+
+#ifdef __cplusplus
+ return ( yyinput() );
+#else
+ return ( input() );
+#endif
+ }
+ break;
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext + YY_MORE_ADJ;
+ break;
+
+ case EOB_ACT_LAST_MATCH:
+#ifdef __cplusplus
+ YY_FATAL_ERROR( "unexpected last match in yyinput()" );
+#else
+ YY_FATAL_ERROR( "unexpected last match in input()" );
+#endif
+ }
+ }
+ }
+
+ c = *yy_c_buf_p;
+ yy_hold_char = *++yy_c_buf_p;
+
+ return ( c );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+
+ {
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* flush out information for old buffer */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* we don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) );
+
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) );
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ yy_init_buffer( b, file );
+
+ return ( b );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ free( (char *) b->yy_ch_buf );
+ free( (char *) b );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+ {
+ b->yy_input_file = file;
+
+ /* we put in the '\n' and start reading from [1] so that an
+ * initial match-at-newline will be true.
+ */
+
+ b->yy_ch_buf[0] = '\n';
+ b->yy_n_chars = 1;
+
+ /* we always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[1];
+
+ b->yy_eof_status = EOF_NOT_SEEN;
+ }
+# line 1182 "l2x.l"
+
+
+
diff --git a/support/ltx2x/l2xlib.c b/support/ltx2x/l2xlib.c
new file mode 100644
index 0000000000..6b33afde39
--- /dev/null
+++ b/support/ltx2x/l2xlib.c
@@ -0,0 +1,5629 @@
+/* l2xlib.c Main and support routines for ltx2x LaTeX to X translator */
+/* Written by Peter Wilson (ex Catholic University and NIST) */
+/* ex pwilson@cme.nist.gov */
+/* Now at: peter.r.wilson@boeing.com */
+/* Version 0.5, October 1995 */
+/* Extended July 1996 */
+/* Extended November 1996 */
+/* Extended January 1997 */
+/* Extended March 1999 */
+/* Fixed CHAR_COMMAND bug November 1999 */
+/* Eliminated some gcc whines November 1999 */
+/*-----------------------------------------------------------------------*/
+
+char FILE_VERSION[] = "Version 0.92";
+char FILE_DATE[] = "November 1999";
+
+/* VERSION HISTORY:
+ * Version 0.2 (January 1995): First alpha release
+ * Patch 1 (April 1995): Fixed problem with the hex escape sequence
+ * in function "delete_quotes"
+ * NB. gcc compiler gives warnings, but cc does not.
+ * Version 0.5 (October 1995): Beta release
+ * Added capability for TEX_CHAR commands to take parameters
+ * -- this was requested for processing super- and sub-scripts.
+ * Changed calling parameters of functions get_opttag_t and
+ * get_opttag_et from (pos,num) to (pos).
+ * Major restructuring and renaming of source files.
+ * Added capability for a second method of specifying SPECIALs
+ * -- now either in the grammer (as before), or via code additions
+ * to the provided grammer actions. This later avoids re-yaccing
+ * the grammer. Both require recompilation.
+ * Version 0.6 (July 1996)
+ * Added capability for read/write to external files and user buffers
+ * Version 0.7 (November 1996)
+ * Added the SWITCH_XXX capability
+ * Version 0.8 (January 1997)
+ * Added code capability
+ * Replaced the most of the tedious enumeration/string mappings
+ * by cunning use of the l2xlibtc.h include file and defines.
+ * Version 0.9 (March 1999)
+ * Changed the close_down procedure
+ * Version 0.91 (November 1999)
+ * Fixed bug in CHAR_COMMAND processing (ignored parameters)
+ * Version 0.92 (November 1999)
+ * (at request of Thomas Ruedas ruedas@geophysik.uni-frankfurt.de)
+ * Added -h option (some getopts don't return ? if unknown option)
+ * Deleted unused init_page_header and print_page_header from l2xiscan.c
+ * Changed SR order in l2xirexp to stop gcc whine
+ */
+
+/* Development of this software upto and including version 0.7
+ * (November 1996) was funded by the United States Government,
+ * and is not subject to copyright. This version is released
+ * under the LaTeX Project Public License.
+ */
+
+/* National Institute of Standards and Technology (NIST)
+ * Manufacturing Engineering Laboratory (MEL)
+ * Manufacturing Systems Integration Division (MSID)
+ * ********************************************************************
+ * D I S C L A I M E R
+ *
+ * There is no warranty for the LTX2X software.
+ * If the LTX2X software is modified by someone else and passed on,
+ * NIST wants the software's recipients to know that what they
+ * have is not what NIST distributed.
+ *
+ * Policies
+ *
+ * 1. Anyone may copy and distribute verbatim copies of the
+ * source code as received in any medium.
+ *
+ * 2. Anyone may modify your copy or copies of the LTX2X source
+ * code or any portion of it, and copy and distribute such modifications
+ * provided that all modifications are clearly associated with the entity
+ * that performs the modifications.
+ *
+ * NO WARRANTY
+ * ===========
+ *
+ * NIST PROVIDES ABSOLUTELY NO WARRANTY. THE LTX2X SOFTWARE
+ * IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
+ * WITH YOU. SHOULD ANY PORTION OF THE LTX2X SOFTWARE PROVE DEFECTIVE,
+ * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+ *
+ * IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES,
+ * INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
+ * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+ * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+ * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
+ * FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
+ * NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+ */
+
+#include <string.h>
+#include "getopt.h"
+#include <stdio.h>
+#include <ctype.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+/* typedef char *STRING; A pointer-to-a-char */
+/* typedef STRING *PTRADR; A pointer-to-a-pointer-to-a-char */
+/* define SNUL '\0' end of a string */
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xytab.h"
+
+ /* the symbol table typedefs */
+#ifndef licomsym_h
+#include "licomsym.h"
+#endif
+
+# define MAX_ERRORS 10
+
+FILE *yyin; /* Lexer input file */
+FILE *filerr; /* Error file */
+FILE *yyout; /* Lexer/Parser output file */
+FILE *filtabin; /* Table input file */
+FILE *filtabout; /* Table output file */
+
+int MIN_GRAMM_SPECIAL = 10000; /* min code number for grammer special */
+int MIN_CODE_SPECIAL = 50000; /* min code number for code special */
+
+int LDEBUG = 0; /* >0 for debugging lexer */
+int TDEBUG = FALSE; /* for debugging command table */
+int YDEBUG = 0; /* >0 for debugging parser */
+int DEBUG = 0; /* >0 for debugging interpreter */
+int cdebug = TRUE; /* set FALSE to disable inteprreter Code debug */
+int edebug = TRUE; /* set FALSE to disable interpreter Execution debug */
+int cl_debug = 0; /* command line value for DEBUG */
+int SLD_OFF = TRUE; /* set FALSE to enable interpreter SLD */
+
+
+int num_errors = 0; /* number of errors */
+int lineno = 1; /* input file line number */
+# define MAX_LINE 2000
+# define MAX_BUFFER 2000
+char linebuf[MAX_LINE]; /* buffer for input line */
+int linlen = 0; /* current no of chars in linebuf */
+int line_count = 0; /* count of line printing */
+# define EVERY_N_LINES 100
+int darray[10]; /* dummy array for something */
+
+int leave_comments = FALSE; /* control for leaving in TeX comments */
+int collapse_ws = FALSE; /* control for collapsing whitespace */
+int pretty_print = FALSE; /* control for pretty-printing */
+int max_pretty_line = MAX_BUFFER; /* max length of pretty-print line */
+char pretty_line[MAX_BUFFER]; /* char buffer for pretty-printing */
+
+int no_print = FALSE; /* a control for myprint */
+int print_to_buffer = FALSE; /* a control for myprint */
+char buffer[MAX_BUFFER]; /* character buffer for myprint */
+
+
+/*---------------------6/96 extensions-----------------------------*/
+
+ /* number of user's string buffers */
+# define MAX_USER_BUFFS 64
+ /* max number of user's files */
+# define MAX_USER_FILES 16
+ /* length of a user buffer */
+/* # define MAX_UBUFF_LEN 514 */
+# define MAX_UBUFF_LEN 1026
+
+typedef char UBUFF[MAX_UBUFF_LEN];
+UBUFF user_buffs[MAX_USER_BUFFS]; /* array of user buffers */
+char errstr[MAX_UBUFF_LEN]; /* buffer for assembling error/warning text */
+
+int cur_user_buf = 0; /* number of current user buffer for writing to */
+int num_ubufwrite = 0; /* number of open write to user buffer calls */
+int num_ubuff[MAX_USER_BUFFS]; /* no of times user buffer opened */
+int used_rubuff[MAX_USER_BUFFS]; /* >0 if used_ubuff[N] has been read */
+int used_wubuff[MAX_USER_BUFFS]; /* >0 if used_ubuff[N] has been written */
+int written_from_buff[MAX_USER_BUFFS]; /* TRUE if read from user buffer */
+
+STRING cur_user_fn = NULL; /* name of current user file for writing to */
+int num_fileprint = 0; /* number of open write to file calls */
+int num_filep[MAX_USER_FILES]; /* number of opened to write for file */
+FILE *ufp[MAX_USER_FILES]; /* user file pointer */
+STRING ufn[MAX_USER_FILES]; /* user file name */
+int cur_user_fpos = 0; /* current pos in file array */
+FILE *cur_user_fileid = NULL; /* current user file id */
+
+int num_otherprint = 0; /* total number of non-default open write calls */
+# define SET_NUM_OTHERPRINT (num_noprint + num_bufprint + num_ubufwrite + num_fileprint)
+PSTRWC cur_printc = NULL; /* current print control */
+
+int bverb = FALSE; /* TRUE if starting verbatim print */
+
+int in_noop = FALSE; /* TRUE if doing a no op */
+int start_noop = FALSE; /* TRUE if start of a no op */
+
+#define MAX_MODES 32
+STRING mode_names[MAX_MODES]; /* unordered list of mode names */
+int num_modes = 0; /* number of mode names */
+#define MAX_MODE_STACK 20
+int mode_stack[MAX_MODE_STACK]; /* stack for mode ids */
+int top_mode = 0; /* empty top of mode stack */
+
+/* keywords */
+
+ /* command table commands */
+enum key_word{
+#define kwtc(a, b) a,
+#define lctc(a, b)
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+int max_keystr = MAX_KEYSTR;
+
+ /* map from keyword enum to string representation */
+STRING key_array[] = {
+#define kwtc(a, b) b,
+#define lctc(a, b)
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+ /* map from print control enum to string representation */
+int max_pcstr = MAX_PCSTR;
+
+STRING pc_array[] = {
+#define kwtc(a, b)
+#define lctc(a, b)
+#define pctc(a, b) b,
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+
+/* the types of LaTeX commands */
+
+#define UNKNOWN_CTYPE -10
+/* number of names/enums in command types, update when ctnames changes!! */
+#define NUM_CTIDS 50
+ /* ctnames[] is an alphabetical array of command type strings */
+STRING ctnames[] = {
+#define kwtc(a, b)
+#define lctc(a, b) b,
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+ /* ctenums[] is an array of command type enums to match ctnames[] */
+int ctenums[] = {
+#define kwtc(a, b)
+#define lctc(a, b) a,
+#define pctc(a, b)
+#include "l2xlibtc.h"
+#undef kwtc
+#undef lctc
+#undef pctc
+};
+
+
+
+
+ /* pointers to fixed, predefined print control structs */
+PSTRWC p_default_print; /* default printing i.e., DEFAULT_PRINT */
+PSTRWC p_no_print; /* no printing i.e., NO_PRINT */
+PSTRWC p_print_to_sysbuf; /* print to system buffer i.e., TO_SYSBUF */
+PSTRWC p_print_underflow; /* underflow i.e., PRINT_UNDERFLOW */
+PSTRWC p_unknown_print; /* unknown print i.e., UNKNOWN_PRINT */
+PSTRWC p_print_from_sysbuf; /* print from system buffer i.e., SYSBUF */
+PSTRWC p_print_null; /* print null string i.e., */
+PSTRWC p_reset_print; /* reset printing i.e., RESET */
+PSTRWC p_noop_print; /* no-op i.e., NO_OP */
+
+/* new functions */
+PSTRWC create_st_rwc();
+void init_common_print();
+PSTRWC create_print_tag();
+PSTRWC create_print_source();
+PSTRWC parse_pc();
+void tprint_st_rwc();
+void tprint_tag();
+void set_pc_enum();
+int get_pc_enum();
+void set_pcdata_num();
+int get_pcdata_num();
+void set_pcdata_name();
+STRING get_pcdata_name();
+PSTRWC get_next_write();
+PSTRWC append_to_write();
+PSTRWC initialise_pc();
+FILE *ufopenr();
+FILE *ufopenw();
+int ufclose();
+PSTRWC get_start_pc();
+PSTRWC get_end_pc();
+void flush_pretty();
+int pretty_empty();
+void strtouc(); /* convert string to upper case */
+void tprint_str();
+int lookup_string(); /* finds posn. of string in an ordered array of strings */
+void init_print_control();
+int key_to_int();
+STRING key_to_string();
+void set_pc_cmd();
+int get_pc_cmd();
+int chk_bufnum();
+STRING chk_ufname();
+void init_ubuff(); /* initialises a user buffer */
+void init_ufile(); /* initialise a user file */
+STRING get_mode_str(); /* returns string name of a mode */
+void add_to_modelist(); /* adds a mode to the mode list */
+void set_mode_name(); /* puts mode id into sym entry */
+int get_mode(); /* gets mode id from sym entry */
+PSENTRY get_next_mode(); /* gets next mode of a sym entry */
+int isempty(); /* TRUE if an empty string */
+void push_mode(); /* pushes mode onto stack */
+int pop_mode(); /* pops mode from stack */
+int reset_mode(); /* resets the mode */
+int get_current_mode(); /* gets the current mode */
+PSENTRY get_mode_sym(); /* gets sym entry matching current mode */
+void tag_print(); /* print a tag */
+
+
+ /*-------- 7/96 statistics stuff ---------------------------*/
+
+int used_ubuff_chars = 0; /* max # of chars attempted for buffer storage */
+int used_sbuff_chars = 0; /* max # of chars attempted for system buffer */
+int used_files = 0; /* # of user files used */
+
+int used_clause_stack = 0; /* max clause stack depth usage */
+int used_list_stack = 0; /* list stack */
+
+int used_table_line = 0; /* max length of a table line */
+int used_table_entries = 0; /* # of entries in command table */
+
+int used_print_stack = 0; /* max depth of print stack */
+
+int used_ct_file_stack = 0; /* max depth of command table stack */
+
+void write_stats(); /* write statistics */
+int maxof(); /* max of two integers */
+
+
+/*--------------------------------------------------------------*/
+
+# define CLAUSE_STACK_SIZE 10
+int clause_depth = 0;
+/* 6/96 changed STRING to PSTRWC */
+PSTRWC clause_str_stack[CLAUSE_STACK_SIZE];
+int base_level = CLAUSE_STACK_SIZE - 1; /* Highest doc level not closed off */
+ /* Section is highest and s4clause lowest */
+int current_level = 0; /* level of current doc division */
+int new_level = 0;
+
+# define DEF_LIST_STACK_SIZE 10
+int LIST_STACK_SIZE = DEF_LIST_STACK_SIZE;
+int list_level = 0;
+int num_items[DEF_LIST_STACK_SIZE]; /* holds number of current items in a list */
+/* 6/96 in following changed STRING to PSTRWC */
+PSTRWC list_str_stack[DEF_LIST_STACK_SIZE]; /* holds closing string for an item */
+PSTRWC list_item_start[DEF_LIST_STACK_SIZE]; /* holds start string for an item */
+PSTRWC list_descitemp_start[DEF_LIST_STACK_SIZE]; /* holds start string for the */
+ /* parameter of a descriptive list item */
+PSTRWC list_descitemp_end[DEF_LIST_STACK_SIZE]; /* holds corresponding end string */
+
+
+
+char *strsave();
+void myprint();
+void pprint();
+void verbatim_print();
+void initialise_clause_stack();
+void set_clause_stack();
+void close_all_divs();
+void close_doc_divs();
+void close_down();
+void set_list_stack();
+void print_end_item();
+void yyerror();
+void warning();
+void catl();
+void do_newline();
+void initialise_sysbuf();
+void print_sysbuf();
+void copy_sysbuf();
+void initialise_string();
+
+
+ /* new stuff for l2x */
+
+
+enum opt_pos_enum {NO_OPT_PARAM = -1, FIRST = 0, LAST};
+enum sect_level_enum {UNKNOWN_LEVEL, PARTM2, PARTM1, PART,
+ CHAPTER, SECT, SUBSECT, SUBSUBSECT, PARA, SUBPARA,
+ SUBPARAP1, SUBPARAP2};
+enum cont_enum {CONT_UNKNOWN_ENUM,
+ CONT_TAG,
+ CONT_START_TAG, CONT_END_TAG,
+ CONT_START_OPT, CONT_END_OPT,
+ CONT_START_TAG_1, CONT_END_TAG_1,
+ CONT_START_TAG_2, CONT_END_TAG_2,
+ CONT_START_TAG_3, CONT_END_TAG_3,
+ CONT_START_TAG_4, CONT_END_TAG_4,
+ CONT_START_TAG_5, CONT_END_TAG_5,
+ CONT_START_TAG_6, CONT_END_TAG_6,
+ CONT_START_TAG_7, CONT_END_TAG_7,
+ CONT_START_TAG_8, CONT_END_TAG_8,
+ CONT_START_TAG_9, CONT_END_TAG_9 };
+
+#define MAX_TABLE_LINE 1000
+char table_line[MAX_TABLE_LINE];
+#define MAX_TABLE_ENTRIES 1000
+PSENTRY symbol_table[MAX_TABLE_ENTRIES];
+int num_table_entries = 0;
+int num_table_errors = 0;
+char env_name[MAX_TABLE_LINE];
+
+int DONT_CARE = -100;
+STRING dont_care_str = "!@#$%^&*";
+
+int command_types[] = {COMMAND, COMMAND_1, COMMAND_2, COMMAND_3, COMMAND_4,
+ COMMAND_5, COMMAND_6, COMMAND_7, COMMAND_8, COMMAND_9};
+int command_opt_types[] = {COMMAND_OPT, COMMAND_1_OPT, COMMAND_2_OPT, COMMAND_3_OPT,
+ COMMAND_4_OPT, COMMAND_5_OPT, COMMAND_6_OPT, COMMAND_7_OPT,
+ COMMAND_8_OPT, COMMAND_9};
+
+char escape_char = '\\';
+char newline_char = 'n';
+char horizontal_tab_char = 't';
+char vertical_tab_char = 'v';
+char backspace_char = 'b';
+char carriage_return_char = 'r';
+char formfeed_char = 'f';
+char audible_alert_char = 'a';
+char hex_char = 'x';
+
+
+/* Extended 6/96 */
+STRING unk = "ERROR";
+
+
+int num_print = 0;
+int num_noprint = 0;
+int num_bufprint = 0;
+#define MAX_PRINT_STACK 100
+PSTRWC print_control_stack[MAX_PRINT_STACK]; /* (6/96 changed from int) */
+
+
+ /* positions in command table */
+int pos_bdoc; /* BEGIN_DOCUMENT */
+int pos_edoc; /* END_DOCUMENT */
+int pos_bvbm; /* BEGIN_VERBATIM */
+int pos_evbm; /* END_VERBATIM */
+int pos_bv; /* BEGIN_VERB */
+int pos_ev; /* END_VERB */
+int pos_oc; /* OTHER_COMMAND */
+int pos_ob; /* OTHER_BEGIN */
+int pos_oe; /* OTHER_END */
+int pos_lbrace; /* LEFT_BRACE */
+int pos_rbrace; /* RIGHT_BRACE */
+int pos_para; /* PARAGRAPH */
+int pos_bdol; /* 'begin' $ */
+int pos_edol; /* 'end' $ */
+int pos_bss; /* SLASH_SPACE */
+
+PSENTRY new_table_entry();
+void create_def_reqentry();
+void read_table();
+void print_table();
+int check_table();
+void delete_to_chars();
+int delete_quotes();
+void twarn_noline();
+void table_error();
+void terror_noline();
+void tdebug_tline();
+void tdebug_str_int();
+void tdebug_str();
+void tdebug_char();
+int ctype_to_int();
+char *ctype_to_string();
+int pos_to_int();
+char *pos_to_string();
+int level_to_int();
+char *level_to_string();
+int printc_to_int();
+char *printc_to_string();
+void sort_table();
+int compare_st_entry();
+int lookup_entry();
+void get_env_name();
+void print_to_err();
+void print_debug_1s();
+void print_debug_2s();
+void print_debug_undef();
+void complete_table_entry();
+void complete_entry();
+int command_type();
+int get_user_type();
+int get_special_token();
+/* 6/96 changed following from STRING to PSTRWC */
+PSTRWC get_t();
+PSTRWC get_et();
+PSTRWC get_tag_t();
+PSTRWC get_tag_et();
+PSTRWC get_opttag_t();
+PSTRWC get_opttag_et();
+int get_level();
+PSTRWC get_item_t();
+PSTRWC get_item_et();
+PSTRWC get_itemopt_t();
+PSTRWC get_itemopt_et();
+void warning_3s();
+void set_print();
+void reset_print();
+void push_print_control();
+PSTRWC pop_print_control();
+PSTRWC peek_print_control(); /* added 6/96 */
+/* 6/96 changed following from int to PSTRWC */
+PSTRWC get_com_print();
+PSTRWC get_param_print();
+PSTRWC get_opt_print();
+
+/* Command table file stack stuff */
+# define MAX_CT_STACK 20
+FILE *ct_fp_stack[MAX_CT_STACK]; /* ct file pointers */
+STRING ct_fn_stack[MAX_CT_STACK]; /* ct file names */
+int ct_ln_stack[MAX_CT_STACK]; /* ct line numbers */
+int ct_file_num; /* current ct file */
+
+void initialise_ct_files();
+int set_ct_file();
+int reset_ct_file();
+FILE *get_ct_filep();
+STRING get_ct_filen();
+int get_ct_linenum();
+void incr_ct_linenum();
+
+/* Environment variable defined search path stuff */
+void initialise_senv();
+char path_name[257]; /* name of a path */
+char sys_envname[20]; /* name of environment variable */
+char path_sep[10]; /* path name seperators */
+char dir_cat; /* directory catenation char */
+int senv_debug; /* =1 for debug searchenv() */
+
+
+/*------------------- Additions for interpreting procedural code ------*/
+
+SYMTAB_NODE_PTR code_root; /* where the initial compiled code is stored */
+
+ /* EXTERNALS */
+extern SYMTAB_NODE_PTR code_setup();
+extern int isynt_error_count;
+extern int isynt_warn_count;
+extern int irun_error_count;
+extern int irun_warn_count;
+
+ /* FORWARDS */
+void print_usage(); /* how to call the program */
+void set_pc_code(); /* store a code segment */
+
+/*******************************************************************/
+/* */
+/* MAIN the main program ----------------------------------------- */
+/* */
+/*******************************************************************/
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int optchar;
+ int n;
+ FILE *file;
+ int result;
+ char tabnam[100];
+
+ /* print banner */
+ fprintf(stdout, "\n ltx2x: A LaTeX to X autotagger\n");
+ fprintf(stdout, "\n (%s, %s)\n", FILE_VERSION, FILE_DATE);
+
+ /* open error log file */
+ file = fopen("ltx2x.err", "w");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file ltx2x.err\n");
+ exit(1);
+ }
+ filerr = file;
+ fprintf(stdout, "Error file is ltx2x.err\n");
+ fprintf(filerr, "Error file for program ltx2x (%s, %s)\n", FILE_VERSION, FILE_DATE);
+ fprintf(filerr, "Author: Peter Wilson (ex Catholic University and NIST)\n");
+ fprintf(filerr, "Email any comments or suggestions to peter.r.wilson@boeing.com\n\n");
+ /* open Table output file */
+ file = fopen("ltx2xct.lis", "w");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file ltx2xct.lis\n");
+ exit(1);
+ }
+ filtabout = file;
+ fprintf(stdout, "Table output file is ltx2xct.lis\n");
+ fprintf(filerr, "Table output file is ltx2xct.lis\n");
+
+ /* set up for Table input file */
+ strcpy(tabnam, "ltx2x.ct");
+ initialise_senv(); /* initialise directory searching */
+
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv,"htcwCESl:y:f:p:P:D:i:"))) {
+ /*
+ * Uwe Sassenberg <sassen@hal1.physik.uni-dortmund.de> found
+ * that he had to add this next line of code to stop an infinite
+ * loop of this while (It did not seem to recognise EOF!!)
+ * If it compiles but just sits there chewing CPU cycles, try
+ * uncommenting the next line of code
+ */
+ /* if (optchar == 255) break; */
+ switch(optchar) {
+ case '?': { /* command line error */
+ print_usage();
+ break;
+ }
+ case 'h': { /* command line help */
+ print_usage();
+ break;
+ }
+ case 'l': { /* lexer debugging >0 */
+ LDEBUG = atoi(optarg);
+ if (LDEBUG <= 0) {
+ LDEBUG = 0;
+ }
+ fprintf(stdout, "Lexer debugging set to %d\n", LDEBUG);
+ fprintf(filerr, "Lexer debugging set to %d\n", LDEBUG);
+ break;
+ }
+ case 't': { /* switch on command table & SEARCHENV debugging */
+ TDEBUG = TRUE;
+ senv_debug = 1;
+ fprintf(stdout, "Command table debugging set ON\n");
+ fprintf(filerr, "Command table debugging set ON\n");
+ break;
+ }
+ case 'y': { /* yacc parser debugging >0 */
+ YDEBUG = atoi(optarg);
+ if (YDEBUG <= 0) {
+ YDEBUG = 0;
+ }
+ fprintf(stdout, "Parser debugging set to %d\n", YDEBUG);
+ fprintf(filerr, "Parser debugging set to %d\n", YDEBUG);
+ break;
+ }
+ case 'f': { /* special Table input file */
+ strcpy(tabnam, optarg);
+ break;
+ }
+ case 'c': { /* leave in TeX comments */
+ leave_comments = TRUE;
+ fprintf(stdout, "Print TeX comments set ON\n");
+ fprintf(filerr, "Print TeX comments set ON\n");
+ break;
+ }
+ case 'w': { /* collapse whitespace */
+ collapse_ws = TRUE;
+ fprintf(stdout, "Collapse whitespace set ON\n");
+ fprintf(filerr, "Collapse whitespace set ON\n");
+ break;
+ }
+ case 'P': { /* pathname seperators */
+ strcpy(path_sep, optarg);
+ strcat(path_sep, " ");
+ fprintf(stdout, "Pathname seperators set to (%s)\n", path_sep);
+ fprintf(filerr, "Pathname seperators set to (%s)\n", path_sep);
+ break;
+ }
+ case 'D': { /* directory catenation char */
+ dir_cat = optarg[0];
+ fprintf(stdout, "Directory catenation character set to %c\n", dir_cat);
+ fprintf(filerr, "Directory catenation character set to %c\n", dir_cat);
+ break;
+ }
+ case 'p': { /* pretty-print line length */
+ pretty_print = TRUE;
+ collapse_ws = TRUE;
+ max_pretty_line = atoi(optarg);
+ if (max_pretty_line > MAX_BUFFER) {
+ max_pretty_line = MAX_BUFFER;
+ fprintf(stdout, "Line length too long. Set to %d\n", max_pretty_line);
+ fprintf(filerr, "Line length too long. Set to %d\n", max_pretty_line);
+ }
+ else if (max_pretty_line <= 10) {
+ max_pretty_line = 70;
+ fprintf(stdout, "Line length too short. Set to %d\n", max_pretty_line);
+ fprintf(filerr, "Line length too short. Set to %d\n", max_pretty_line);
+ }
+ else {
+ fprintf(stdout, "Line length set to %d\n", max_pretty_line);
+ fprintf(filerr, "Line length set to %d\n", max_pretty_line);
+ fflush(stdout);
+ fflush(filerr);
+ }
+ break;
+ }
+ case 'i': { /* interpreter code debugging */
+ cl_debug = atoi(optarg);
+ if (cl_debug <= 0) {
+ cl_debug = 0;
+ }
+ fprintf(stdout, "Interpreter debugging set to %d\n", cl_debug);
+ fprintf(filerr, "Interpreter debugging set to %d\n", cl_debug);
+ break;
+ }
+ case 'C': { /* disable any interpreter source Code debug */
+ cdebug = FALSE;
+ fprintf(stdout, "Interpreter source Code debugging disabled\n");
+ fprintf(filerr, "Interpreter source Code debugging disabled\n");
+ break;
+ }
+ case 'E': { /* disable any interpreter Execution debug */
+ edebug = FALSE;
+ fprintf(stdout, "Interpreter Execution debugging disabled\n");
+ fprintf(filerr, "Interpreter Execution debugging disabled\n");
+ break;
+ }
+ case 'S': { /* enable interpreter Source Level Debugger */
+ SLD_OFF = FALSE;
+ fprintf(stdout, "Interpreter Source Level Debugger set ON\n");
+ fprintf(filerr, "Interpreter Source Level Debugger set ON\n");
+ break;
+ }
+ } /* end switch */
+ } /* end of optional parameter processing */
+
+ /* open Table file */
+ if (!searchenv(tabnam, sys_envname, path_name, path_sep, dir_cat, senv_debug)) {
+ fprintf(stderr, "Fatal Error: Could not find file %s\n", tabnam);
+ exit(1);
+ }
+ file = fopen(path_name, "r");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file %s\n", path_name);
+ exit(1);
+ }
+ filtabin = file;
+ fprintf(stdout, "Table input file is %s\n", path_name);
+ fprintf(filerr, "Table input file is %s\n", path_name);
+
+ /* rest of parameters are file names (input and output) */
+ n = 0;
+ for (;optind < argc; optind++) {
+ n++;
+ if (n == 1) {
+ file = fopen(argv[optind], "r");
+ if (!file) {
+ fprintf(stderr,"Fatal Error: Could not open input file %s\n",argv[optind]);
+ fprintf(filerr,"Fatal Error: Could not open input file %s\n",argv[optind]);
+ exit(1);
+ }
+ fprintf(stdout,"Reading file %s", argv[optind]);
+ fprintf(filerr,"Reading file %s", argv[optind]);
+ yyin = file;
+ }
+ else { if (n == 2) {
+ file = fopen(argv[optind], "w");
+ if (!file) {
+ fprintf(stderr,"Fatal Error: Could not open output file %s\n",argv[optind]);
+ fprintf(filerr,"Fatal Error: Could not open output file %s\n",argv[optind]);
+ exit(1);
+ }
+ fprintf(stdout," and writing to file %s\n",argv[optind]);
+ fprintf(filerr," and writing to file %s\n",argv[optind]);
+ yyout = file;
+ }
+ else {
+ fprintf(stderr,"Warning: Only two files permitted. File %s ignored\n",argv[optind]);
+ fprintf(filerr,"Warning: Only two files permitted. File %s ignored\n",argv[optind]);
+ }
+ }
+ }
+ if (n == 0) {
+ fprintf(stderr,"Fatal Error: An input and an output file are required.\n");
+ fprintf(filerr,"Fatal Error: An input and an output file are required.\n");
+ exit(1);
+ }
+
+ /* do some initialisations */
+ print_to_err("\n > Starting initialisations\n");
+ initialise_clause_stack();
+ darray[0] = 0;
+ initialise_sysbuf();
+ init_common_print(); /* 6/96 common print structs */
+ init_print_control(); /* 6/96 initialise print control */
+
+ code_root = NULL; /* code interp, initialise to no-code */
+
+ print_to_err(" > Reading command table(s)\n");
+ initialise_ct_files(path_name);
+ read_table();
+ if (TDEBUG) {
+ print_table(filerr);
+ }
+ print_to_err(" > Sorting table\n");
+ sort_table();
+ print_to_err(" > Checking table\n");
+ if (check_table()) {
+ print_to_err(" > Re-sorting table\n");
+ sort_table();
+ print_to_err(" > Re-checking table\n");
+ check_table();
+ }
+ print_to_err(" > Printing table\n");
+ print_table(filtabout);
+ fclose(filtabout);
+
+ /* added for code interp */
+ /* execute initial code */
+ if (code_root != NULL) { /* only process initial code if there is any */
+ exec_startup(code_root);
+ }
+
+ /* process input */
+ print_to_err(" > Processing source file\n");
+ while(!feof(yyin)) {
+ result = yyparse();
+ if (result == 0) {
+ write_stats(" (end of parsing)");
+ exit(0);
+ }
+ }
+ write_stats(" (end of program)");
+ exit(0);
+} /* end MAIN */
+/*------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*/
+/* print_usage Prints the command line parameters */
+
+void print_usage()
+{
+ fprintf(stderr, "\nUsage: [options] infile outfile\n");
+ fprintf(stderr, " Options for the general user\n");
+ fprintf(stderr, " [-c] include LaTeX comments in the output\n");
+ fprintf(stderr, " [-f tablename] use tablename as the command file instead of ltx2x.ct\n");
+ fprintf(stderr, " [-h] print usage (this message)\n");
+ fprintf(stderr, " [-p num] set pretty printing with num characters per line\n");
+ fprintf(stderr, " [-w] collapse whitespace in the output\n");
+ fprintf(stderr, " [-D char] directory catenation character\n");
+ fprintf(stderr, " [-P string] pathname seperator characters\n");
+ fprintf(stderr, " [-S] enable the interpreter's source level debugger\n");
+ fprintf(stderr, " Options for the system developer\n");
+ fprintf(stderr, " [-i num] set level of interpreter debug print output\n");
+ fprintf(stderr, " [-l num] set level of lexer debug print output\n");
+ fprintf(stderr, " [-t] enable command table debug print output\n");
+ fprintf(stderr, " [-y num] unused at present\n");
+ fprintf(stderr, " [-C] disable any interpreter source code debug print\n");
+ fprintf(stderr, " [-E] disable any interpreter execution code debug print\n");
+
+ fprintf(filerr, "\nUsage: [options] infile outfile\n");
+ fprintf(filerr, " Options for the general user\n");
+ fprintf(filerr, " [-c] include LaTeX comments in the output\n");
+ fprintf(filerr, " [-f tablename] use tablename as the command file instead of ltx2x.ct\n");
+ fprintf(filerr, " [-h] print usage (this message)\n");
+ fprintf(filerr, " [-p num] set pretty printing with num characters per line\n");
+ fprintf(filerr, " [-w] collapse whitespace in the output\n");
+ fprintf(filerr, " [-D char] directory catenation character\n");
+ fprintf(filerr, " [-P string] pathname seperator characters\n");
+ fprintf(filerr, " [-S] enable the interpreter's source level debugger\n");
+ fprintf(filerr, " Options for the system developer\n");
+ fprintf(filerr, " [-i num] set level of interpreter debug print output\n");
+ fprintf(filerr, " [-l num] set level of lexer debug print output\n");
+ fprintf(filerr, " [-t] enable command table debug print output\n");
+ fprintf(filerr, " [-y num] unused at present\n");
+ fprintf(filerr, " [-C] disable any interpreter source code debug print\n");
+ fprintf(filerr, " [-E] disable any interpreter execution code debug print\n");
+
+exit(0);
+} /* end PRINT_USAGE */
+/*------------------------------------------------------------------------*/
+
+
+
+
+ /*-----------STRING FUNCTIONS-------------------------*/
+
+/* STRSAVE saves a string somewhere */
+char *strsave(s)
+char *s;
+{
+/* char *p, *malloc(); */
+ char *p;
+
+/* if ((p = malloc(strlen(s)+1)) != NULL) { */
+ if ((p = (char *) malloc(strlen(s)+1)) != NULL) {
+ strcpy(p, s);
+ }
+ else {
+ yyerror("FATAL ERROR: No memory left for STRSAVE");
+ exit(1);
+ }
+ return(p);
+} /* end STRSAVE */
+
+
+/* GET_ENV_NAME puts ...{ name } name into env_name */
+void get_env_name(str)
+char str[];
+{
+ int first, last, i, n;
+ int c;
+ int top;
+
+ top = MAX_TABLE_LINE + 10;
+ first = top;
+ n = 0;
+ env_name[0] = '\0';
+
+ for (i = 0; (c = str[i]) != '\0'; i++) { /* look for opening brace */
+ if (c == '{') {
+ first = i+1;
+ break;
+ }
+ }
+ if (first == top) { /* opening brace not found */
+ yyerror("get_env_name: opening brace not found");
+ return;
+ }
+ last = first;
+ first = top;
+ for (i = last; (c = str[i]) != '\0'; i++) { /* look for start of name */
+ if (!isspace(c)) { /* found it */
+ first = i;
+ break;
+ }
+ }
+ if (first == top) { /* name not found */
+ yyerror("get_env_name: name not found");
+ return;
+ }
+ for (i = first; (c = str[i]) != '\0'; i++) {
+ if (!isspace(c)) { /* a part of the name */
+ if (c == '}') { /* name ended */
+ break;
+ }
+ env_name[n] = c;
+ n++;
+ }
+ }
+ env_name[n] = '\0';
+} /* end GET_ENV_NAME */
+
+
+/* DELETE_TO_CHARS deletes all chars through first occurrence of "c" */
+void delete_to_chars(c,s)
+char c[];
+char s[];
+{
+ int len;
+ int pos;
+ int i, n;
+
+ len = strlen(s);
+ pos = strcspn(s, c);
+ if (pos > 0 && pos < len) { /* = found */
+ n = 0;
+ for (i = (pos+1); i <= len; i++ ) {
+ s[n] = s[i];
+ n++;
+ }
+ }
+} /* end DELETE_TO_CHARS */
+
+
+/* DELETE_QUOTES deletes leading and trailing " and replaces
+ escaped character pairs. Returns # of chars */
+int delete_quotes(s,sout)
+char s[];
+char sout[];
+{
+ int first, last, len;
+ int i, n, j, k;
+ char last_char, this_char;
+ char hex_str[20];
+
+ len = strlen(s);
+ for (i=0; i < len; i++) {
+ first = i;
+ if (s[i] == '"') {
+ break;
+ }
+ }
+ last = first;
+ for (i = (first + 1); i < len; i++) {
+ if (s[i] == '"') {
+ last = i;
+ }
+ }
+ if (first == last) { /* zero or one quote */
+ sout[0] = SNUL;
+ if (first != (len -1) ) { /* one quote */
+ table_error("ERROR: string not enclosed in quotes");
+ }
+ return(0);
+ }
+ n = 0;
+ last_char = '"';
+ for (i= (first+1); i < last; i++) {
+ this_char = s[i];
+ sout[n] = this_char;
+ if (last_char == escape_char) { /* possibly an escaped pair */
+ if (this_char == newline_char) {
+ n--;
+ sout[n] = '\n';
+ }
+ else if (this_char == horizontal_tab_char) {
+ n--;
+ sout[n] = '\t';
+ }
+ else if (this_char == vertical_tab_char) {
+ n--;
+ sout[n] = '\v';
+ }
+ else if (this_char == backspace_char) {
+ n--;
+ sout[n] = '\b';
+ }
+ else if (this_char == carriage_return_char) {
+ n--;
+ sout[n] = '\r';
+ }
+ else if (this_char == formfeed_char) {
+ n--;
+ sout[n] = '\f';
+ }
+ else if (this_char == audible_alert_char) {
+ n--;
+ sout[n] = '\a';
+ }
+ else if (this_char == hex_char) { /* do hex stuff */
+ k = 0;
+ hex_str[k] = '\0';
+ for (j = i+1; j < last; j++) { /* get hex chars */
+ if (isxdigit(s[j])) { /* got hex digit */
+ hex_str[k] = s[j];
+ k++;
+ }
+ else { /* end of hex digits */
+ hex_str[k] = '\0';
+ break;
+ }
+ } /* got all hex digits */
+ n--;
+ sout[n] = strtoul(hex_str, NULL, 16);
+ i = i + k; /* shift i to end of hex digits */
+ }
+ else if (this_char == escape_char) {
+ if (escape_char == '\\' ) { /* default */
+ n--;
+ sout[n] = '\\';
+ this_char = '"';
+ }
+ else {
+ n--;
+ this_char = '"';
+ }
+ }
+ }
+ n++;
+ last_char = this_char;
+ }
+ sout[n] = SNUL;
+ return(n);
+} /* end DELETE_QUOTES */
+
+
+/* STRTOUC converts a string in place to upper case */
+void strtouc(str)
+char str[];
+{
+ int i;
+ for (i = 0; str[i] != SNUL; i++) {
+ str[i] = toupper(str[i]);
+ }
+ return;
+} /* end STRTOUC */
+
+
+
+ /*------------PRINT FUNCTIONS-----------------------*/
+
+/* MYPRINT output to file, buffer or black hole */
+void myprint(s)
+char s[];
+{
+ PSTRWC ptr;
+ int num;
+ int n;
+ int k;
+
+ ptr = cur_printc;
+ if (ptr == NULL) { /* should not be null */
+ yyerror("internal error: cur_printc is NULL in MYPRINT");
+ return;
+ }
+
+ if (s == NULL) { /* nothing to print */
+ return;
+ }
+ if (s[0] == SNUL) { /* nothing to print */
+ return;
+ }
+
+ k = get_pc_enum(ptr);
+ switch (k) {
+ case NO_PRINT: { /* do nothing */
+ return;
+ break;
+ }
+ case NO_OP: { /* do nothing */
+ return;
+ break;
+ }
+ case TO_SYSBUF: { /* store string in system buffer */
+ /* check buffer overflow */
+ n = strlen(buffer) + strlen(s);
+ used_sbuff_chars = maxof(n, used_sbuff_chars);
+ if (n >= MAX_BUFFER - 2) {
+ warning("Unpredictable results due to system buffer overflow");
+ }
+ else { /* add to buffer */
+ strcat(buffer, s);
+ }
+ break;
+ }
+ case TO_BUFFER: { /* store string in user buffer */
+ num = get_pcdata_num(ptr);
+ if ( num < 0 || num > MAX_USER_BUFFS ) { /* buffer out of range */
+ sprintf(errstr, "in MYPRINT user buffer %d is out of range", num);
+ warning(errstr);
+ break;
+ }
+ n = strlen(user_buffs[num]) + strlen(s);
+ used_ubuff_chars = maxof(n, used_ubuff_chars);
+ if (n >= MAX_UBUFF_LEN - 2) {
+ sprintf(errstr, "Unpredictable results; User buffer %d overflowed", num);
+ warning(errstr);
+ }
+ else { /* add to buffer */
+ strcat(user_buffs[num], s);
+ }
+ break;
+ }
+ case TO_FILE: { /* write to file */
+/* name = get_pcdata_name(ptr); */
+ fprintf(cur_user_fileid, "%s", s);
+ fflush(cur_user_fileid);
+ break;
+ }
+ case DEFAULT_PRINT: {
+ if (pretty_print) { /* pretty printing */
+ pprint(s);
+ }
+ else {
+ fprintf(yyout, "%s", s);
+ fflush(yyout);
+ }
+ break;
+ }
+ default: { /* should not be here */
+ sprintf(errstr, "Illegal print option (%d %s) in MYPRINT",
+ k, printc_to_string(k));
+ warning(errstr);
+ return;
+ break;
+ }
+ } /* end switch */
+ return;
+} /* end MYPRINT */
+
+
+int pprint_top = 0; /* pointer into pretty_line */
+int last_space = 0; /* posn of last space in pretty_line */
+int ppoverflow = FALSE; /* pretty_line buffer overflow */
+
+/* PRETTY_EMPTY checks if the pretty line is empty */
+int pretty_empty()
+{
+ return((pretty_line[0] == SNUL));
+} /* end PRETTY_EMPTY */
+
+
+/* FLUSH_PRETTY flushes pretty line buffer and resets it */
+void flush_pretty()
+{
+
+ pretty_line[pprint_top] = SNUL;
+ fprintf(yyout, "%s\n", pretty_line);
+ pprint_top = 0;
+ pretty_line[pprint_top] = SNUL;
+ last_space = 0;
+ ppoverflow = FALSE;
+ return;
+} /* end FLUSH_PRETTY */
+
+
+/* PPRINT pretty printing */
+void pprint(s)
+char s[];
+{
+
+ char c;
+ int i,n,j;
+ int start;
+
+ start = 0;
+ /* add characters from s into pretty_line until overflow. */
+ /* back off to last space. Flush at newline. */
+
+ for (i = start; (c = s[i]) != SNUL; i++) {
+ if (c == '\n') { /* newline, flush */
+ flush_pretty();
+ ppoverflow = FALSE;
+ }
+ else {
+ if (c == ' ' || c == '\t') { /* whitespace */
+ last_space = pprint_top;
+ if (ppoverflow) { /* overflow, flush on whitespace */
+ flush_pretty();
+ ppoverflow = FALSE;
+ }
+ }
+ pretty_line[pprint_top] = c;
+ pprint_top++;
+ if (pprint_top >= (max_pretty_line - 1)) { /* buffer is full, back off */
+ if (last_space > 0) { /* but only if there is a prior space */
+ pretty_line[last_space] = SNUL;
+ fprintf(yyout, "%s\n", pretty_line);
+ j = 0;
+ for (n = last_space + 1; n < pprint_top; n++) { /* move final chars down */
+ pretty_line[j] = pretty_line[n];
+ j++;
+ }
+ pprint_top = j;
+ last_space = 0;
+ ppoverflow = FALSE;
+ }
+ else { /* overflow, print the buffer */
+ flush_pretty();
+ ppoverflow = TRUE;
+ }
+ }
+ }
+ } /* end for loop */
+} /* end PPRINT */
+
+
+/* VERBATIM_PRINT output to file, buffer or black hole (almost identical to myprint ) */
+void verbatim_print(s)
+char s[];
+{
+ PSTRWC ptr;
+ int num;
+ int n;
+ int k;
+
+ ptr = cur_printc;
+ if (ptr == NULL) { /* should not be null */
+ yyerror("internal error: cur_printc is NULL in VERBATIM_PRINT");
+ return;
+ }
+
+ if (s == NULL) { /* nothing to print */
+ return;
+ }
+ if (s[0] == SNUL) { /* nothing to print */
+ return;
+ }
+
+ k = get_pc_enum(ptr);
+ switch (k) {
+ case NO_PRINT: { /* do nothing */
+ return;
+ break;
+ }
+ case NO_OP: { /* do nothing */
+ return;
+ break;
+ }
+ case TO_SYSBUF: { /* store string in system buffer */
+ /* check buffer overflow */
+ n = strlen(buffer) + strlen(s);
+ used_sbuff_chars = maxof(n, used_sbuff_chars);
+ if (n >= MAX_BUFFER - 2) {
+ warning("Unpredictable results due to system buffer overflow");
+ }
+ else { /* add to buffer */
+ strcat(buffer, s);
+ }
+ break;
+ }
+ case TO_BUFFER: { /* store string in user buffer */
+ num = get_pcdata_num(ptr);
+ if ( num < 0 || num > MAX_USER_BUFFS ) { /* buffer out of range */
+ sprintf(errstr, "in VERBATIM_PRINT user buffer %d is out of range", num);
+ warning(errstr);
+ break;
+ }
+ n = strlen(user_buffs[num]) + strlen(s);
+ used_ubuff_chars = maxof(n, used_ubuff_chars);
+ if (n >= MAX_UBUFF_LEN - 2) {
+ sprintf(errstr, "Unpredictable results; User buffer %d overflowed", num);
+ warning(errstr);
+ }
+ else { /* add to buffer */
+ strcat(user_buffs[num], s);
+ }
+ break;
+ }
+ case TO_FILE: { /* write to file */
+ fprintf(cur_user_fileid, "%s", s);
+ fflush(cur_user_fileid);
+ break;
+ }
+ case DEFAULT_PRINT: {
+ if (bverb && pretty_print) { /* at start of verbatim */
+ if (!pretty_empty()) {
+ flush_pretty(); /* flush the current pretty line */
+ }
+ bverb = FALSE;
+ }
+ fprintf(yyout, "%s", s);
+ fflush(yyout);
+ break;
+ }
+ default: { /* should not be here */
+ sprintf(errstr, "Illegal print option (%d %s) in VERBATIM_PRINT",
+ k, printc_to_string(k));
+ warning(errstr);
+ return;
+ break;
+ }
+ } /* end switch */
+ return;
+} /* end VERBATIM_PRINT */
+
+
+/* PRINT_SYSBUF prints system buffer */
+void print_sysbuf()
+{
+ fprintf(yyout, "%s", buffer);
+ fflush(yyout);
+} /* end PRINT_SYSBUF */
+
+
+/* INITIALISE_SYSBUF clears system buffer */
+void initialise_sysbuf()
+{
+ buffer[0] = SNUL;
+} /* end INITIALISE_SYSBUF */
+
+
+/* COPY_SYSBUF copies system buffer to S */
+void copy_sysbuf(s)
+char s[];
+{
+ strcat(s, buffer);
+} /* end COPY_SYSBUF */
+
+
+/* INITIALISE_STRING clears a string S */
+void initialise_string(s)
+char s[];
+{
+ s[0] = SNUL;
+} /* end INITIALISE_STRING */
+
+
+/* INITIALISE_PC initialises print control */
+PSTRWC initialise_pc()
+{
+
+ /* set counters to zero */
+ num_print = 0; /* (empty) top of stack */
+ num_noprint = 0; /* # of open no prints */
+ num_bufprint = 0; /* # of open sys buff prints */
+ num_ubufwrite = 0; /* # of open user buff writes */
+ num_fileprint = 0; /* # of open file writes */
+ num_otherprint = 0; /* # of open non-default prints */
+ /* set flags */
+ no_print = FALSE; /* we are printing */
+ print_to_buffer = FALSE; /* not printing to sys buffer */
+ /* set stack for default printing */
+ push_print_control(p_default_print);
+ cur_printc = p_default_print;
+/* set_print(p_default_print); */
+ return(p_default_print);
+} /* end INITIALISE_PC */
+
+/* SET_PRINT sets myprint and other print behaviours */
+/* 6/96 changed pswitch from int to PSTRWC */
+void set_print(pswitch)
+PSTRWC pswitch;
+{
+ int num;
+ PSTRWC ptr;
+ int k;
+ STRING str;
+ int curpc;
+
+ if (pswitch == NULL) { /* got a problem! */
+ yyerror("internal error: SET_PRINT called with NULL value (setting it to the default)");
+ initialise_pc();
+ return;
+ }
+
+ k = get_pc_enum(pswitch);
+
+ switch (k) { /* check on pswitch */
+ case DEFAULT_PRINT :
+ case NO_PRINT :
+ case TO_SYSBUF :
+ case TO_BUFFER :
+ case NO_OP :
+ case TO_FILE : { /* pswitch is OK */
+ ptr = pswitch;
+ break;
+ }
+ default : { /* should not be here */
+ sprintf(errstr,
+"internal error: SET_PRINT called with illegal value (%d %s), setting it to the default",
+ k, printc_to_string(k));
+ yyerror(errstr);
+ ptr = p_default_print;
+ k = DEFAULT_PRINT;
+ break;
+ }
+ } /* end of switch on pswitch */
+
+ /* possibly start a no op */
+ if (k == NO_OP && !in_noop) {
+ start_noop = TRUE;
+ push_print_control(ptr);
+ cur_printc = ptr;
+ return;
+ }
+
+ curpc = get_pc_enum(cur_printc);
+ switch(curpc) { /* action depends on current state */
+ case DEFAULT_PRINT: { /* default is almost a non-event */
+ push_print_control(ptr);
+ cur_printc = ptr;
+ break;
+ }
+ case NO_PRINT: { /* carry on with no printing */
+ push_print_control(cur_printc);
+ break;
+ }
+ case TO_SYSBUF :
+ case TO_BUFFER :
+ case TO_FILE : {
+ if (k == DEFAULT_PRINT) { /* default doesn't change anything */
+ push_print_control(cur_printc);
+ }
+ else { /* a change */
+ push_print_control(ptr);
+ cur_printc = ptr;
+ }
+ break;
+ }
+ default : { /* should not be here */
+ sprintf(errstr,
+"internal error: SET_PRINT has illegal value (%d %s) for cur_printc, setting it to the default",
+ curpc, printc_to_string(curpc));
+ warning(errstr);
+ cur_printc = p_default_print;
+ break;
+ }
+ } /* end switch on cur_printc */
+
+ switch (get_pc_enum(cur_printc)) { /* finally update counters, etc */
+ case DEFAULT_PRINT : {
+ break;
+ }
+ case NO_PRINT : {
+ num_noprint++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ no_print = TRUE;
+ break;
+ }
+ case TO_SYSBUF : {
+ num_bufprint++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ print_to_buffer = TRUE;
+ break;
+ }
+ case TO_BUFFER : {
+ num_ubufwrite++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ num = get_pcdata_num(cur_printc);
+ num_ubuff[num]++;
+ cur_user_buf = num;
+ if (written_from_buff[num]) { /* have written from this buffer */
+ initialise_string(user_buffs[num]);
+ written_from_buff[num] = FALSE;
+ }
+ break;
+ }
+ case TO_FILE : {
+ num_fileprint++;
+ num_otherprint = SET_NUM_OTHERPRINT;
+ str = get_pcdata_name(cur_printc);
+ num = get_fpos(str);
+ num_filep[num]++;
+ cur_user_fn = str;
+ cur_user_fpos = num;
+ if (num_filep[num] == 1) { /* a first write call to this file */
+ ufp[num] = ufopenw(str);
+ }
+ cur_user_fileid = ufp[num];
+ break;
+ }
+ default : { /* should not be here */
+ sprintf(errstr,
+"internal error: SET_PRINT has set illegal value (%d %s) for cur_printc",
+ curpc, printc_to_string(curpc));
+ yyerror(errstr);
+ break;
+ }
+ } /* end of switch over cur_printc */
+ return;
+} /* end SET_PRINT */
+
+
+/* RESET_PRINT resets myprint, etc behaviour */
+void reset_print()
+{
+
+ PSTRWC ptr;
+ int num;
+ STRING fn;
+ int file_pos; /* pos of file in file list */
+ int k;
+
+ ptr = pop_print_control();
+ k = get_pc_enum(ptr);
+ switch (k) { /* close off the popped print control */
+ case DEFAULT_PRINT : { /* nothing special to do */
+ break;
+ }
+ case NO_PRINT: {
+ num_noprint--;
+ if (num_noprint < 0) {
+ yyerror("at least one too many calls to reset_print after NO_PRINT");
+ num_noprint = 0;
+ }
+ if (num_noprint <= 0) { /* back to some output */
+ no_print = FALSE;
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case TO_SYSBUF: {
+ num_bufprint--;
+ if (num_bufprint < 0) {
+ yyerror("at least one too many calls to reset_print after PRINT_TO_BUFFER");
+ num_bufprint = 0;
+ }
+ if (num_bufprint <= 0) {
+ print_to_buffer = FALSE;
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case TO_BUFFER: {
+ num = get_pcdata_num(ptr);
+ num_ubufwrite--;
+ num_ubuff[num]--;
+ if (num_ubufwrite < 0) {
+ yyerror("at least one too many calls to reset_print after WRITE_TO_BUFFER");
+ num_ubufwrite = 0;
+ num_ubuff[num] = 0;
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case TO_FILE: { /* close file */
+ fn = get_pcdata_name(ptr);
+ num_fileprint--;
+ file_pos = get_fpos(fn);
+/* num_filep[file_pos]--; 10/96 */
+ if (num_fileprint < 0) {
+ yyerror("at least one too many calls to reset_print after WRITE_TO_FILE");
+ num_fileprint = 0;
+ num_filep[file_pos] = 0;
+ }
+ if (num_filep[file_pos] == 0) { /* close the file */
+/* ufclose(fn); 10/96 */
+ }
+ num_otherprint = SET_NUM_OTHERPRINT;
+ break;
+ }
+ case NO_OP: { /* reset flags */
+ start_noop = FALSE;
+ in_noop = FALSE;
+ break;
+ }
+ default: { /* stack underflow */
+ sprintf(errstr,
+"internal error: RESET_PRINT called with illegal value (%d %s), setting it to the default",
+ k, printc_to_string(k));
+ warning(errstr);
+ initialise_pc();
+ break;
+ }
+ } /* end of switch on popped */
+ cur_printc = peek_print_control();
+
+ switch (get_pc_enum(cur_printc)) {
+ case DEFAULT_PRINT : { /* nothing to do */
+ break;
+ }
+ case NO_PRINT : { /* done already */
+ break;
+ }
+ case TO_SYSBUF : { /* done already */
+ break;
+ }
+ case TO_BUFFER : { /* set current buffer */
+ cur_user_buf = get_pcdata_num(cur_printc);
+ break;
+ }
+ case TO_FILE : { /* set current file name */
+ cur_user_fn = get_pcdata_name(cur_printc);
+ break;
+ }
+ default : { /* should not be here, but do nothing */
+ sprintf(errstr,
+"internal error: RESET_PRINT peeked at illegal value (%d %s)",
+ k, printc_to_string(k));
+ yyerror(errstr);
+ break;
+ }
+ } /* end of switch on peeked */
+ return;
+} /* end RESET_PRINT */
+
+
+/* PUSH_PRINT_CONTROL */
+void push_print_control(kind)
+PSTRWC kind;
+{
+
+ used_print_stack = maxof(num_print, used_print_stack);
+ if (num_print >= MAX_PRINT_STACK) { /* stack overflow */
+ yyerror("Somethings wrong: print stack overflow");
+ return;
+ }
+ print_control_stack[num_print] = kind;
+ num_print++;
+} /* end PUSH_PRINT_CONTROL */
+
+
+/* POP_PRINT_CONTROL returns top of print control stack and pops it */
+PSTRWC pop_print_control()
+{
+ PSTRWC item;
+
+ if (num_print < 0) { /* stack underflow */
+ yyerror("Somethings wrong: print stack underflow");
+ return(p_print_underflow);
+ }
+ num_print--;
+ item = print_control_stack[num_print];
+ return(item);
+} /* end POP_PRINT_CONTROL */
+
+
+/* PEEK_PRINT_CONTROL returns top of print control stack */
+PSTRWC peek_print_control()
+{
+ if (num_print < 0) { /* stack underflow */
+ yyerror("Somethings wrong: print stack underflow");
+ return(p_print_underflow);
+ }
+ return(print_control_stack[num_print - 1]);
+} /* end PEEK_PRINT_CONTROL */
+
+
+
+ /*---------------ERROR AND DEBUG PRINTING-------------*/
+
+/* YYERROR prints error message */
+void yyerror(s)
+char *s;
+{
+ fprintf(stderr, "\n%s in line\n%d: %s\n", s, lineno, linebuf);
+ fprintf(filerr, "\n%s in line\n%d: %s\n", s, lineno, linebuf);
+ fflush(stderr);
+ fflush(filerr);
+ num_errors++;
+ if (num_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Translation ended with at least %d errors **\n", num_errors);
+ fprintf(filerr, "\n** Translation ended with at least %d errors **\n", num_errors);
+ fprintf(yyout, "\n** Translation ended with at least %d errors **\n", num_errors);
+ write_stats(" (at error failure)");
+ exit(1);
+ }
+} /* end YYERROR */
+
+
+/* WARNING prints warning message */
+void warning(s)
+char *s;
+{
+ fprintf(stderr, "\nWARNING: %s in line\n%d: %s\n", s, lineno, linebuf);
+ fprintf(filerr, "\nWARNING: %s in line\n%d: %s\n", s, lineno, linebuf);
+ fflush(stderr);
+ fflush(filerr);
+} /* end WARNING */
+
+
+/* WARNING_3S prints 3 warning strings */
+void warning_3s(s1, s2, s3)
+char *s1;
+char *s2;
+char *s3;
+{
+
+ fprintf(stderr, "\nWarning: %s %s %s in line\n%d: %s\n",
+ s1, s2, s3, lineno, linebuf);
+ fprintf(filerr, "\nWarning: %s %s %s in line\n%d: %s\n",
+ s1, s2, s3, lineno, linebuf);
+ fflush(stderr);
+ fflush(filerr);
+} /* end WARNING_3S */
+
+
+/* PRINT_TO_ERR prints one string to error file */
+void print_to_err(s1)
+char s1[];
+{
+ fprintf(filerr, "%s", s1);
+ fflush(filerr);
+} /* end PRINT_TO_ERR */
+
+
+/* PRINT_DEBUG_1S prints LD string to error file */
+void print_debug_1s(s1)
+char s1[];
+{
+ fprintf(filerr, " LD%s", s1);
+ fflush(filerr);
+} /* end PRINT_DEBUG_1S */
+
+
+/* PRINT_DEBUG_2S prints LD two strings to error file */
+void print_debug_2s(s1, s2)
+char s1[];
+char s2[];
+{
+ fprintf(filerr, " LD%s %s", s1, s2);
+ fflush(filerr);
+} /* end PRINT_DEBUG_2S */
+
+/* PRINT_DEBUG_UNDEF prints "undefined table entry" to error file */
+void print_debug_undef(s1, s2)
+char s1[];
+char s2[];
+{
+ fprintf(filerr, "\n %s on line %d not in command table. %s",
+ s1, lineno, s2);
+ fflush(filerr);
+} /* end PRINT_DEBUG_UNDEF */
+
+
+
+/* TABLE_ERROR prints Command table error message */
+void table_error(s)
+char *s;
+{
+ fprintf(stderr, "\nCommand table: %s in file %s line\n%d: %s\n",
+ s, get_ct_filen(), get_ct_linenum(), table_line);
+ fprintf(filerr, "\nCommand table: %s in file %s line\n%d: %s\n",
+ s, get_ct_filen(), get_ct_linenum(), table_line);
+ fflush(stderr);
+ fflush(filerr);
+ num_table_errors++;
+ if (num_table_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ fprintf(filerr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ exit(1);
+ }
+} /* end TABLE_ERROR */
+
+
+/* TERROR_NOLINE prints error message without source line id */
+void terror_noline(s)
+char *s;
+{
+ fprintf(stderr, "\nCommand table error: %s\n", s);
+ fprintf(filerr, "\nCommand table error: %s\n", s);
+ fflush(stderr);
+ fflush(filerr);
+ num_table_errors++;
+ if (num_table_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ fprintf(filerr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ exit(1);
+ }
+} /* end TERROR_NOLINE */
+
+
+/* TWARN_NOLINE prints table warning */
+void twarn_noline(str)
+char str[];
+{
+/* fprintf(stderr, "\nTable Warning: %s\n", str); */
+ fprintf(filerr, "\nTable Warning: %s\n", str);
+/* fflush(stderr); */
+ fflush(filerr);
+} /* end TWARN_NOLINE */
+
+
+/* TDEBUG_TLINE prints table line */
+void tdebug_tline(str)
+char str[];
+{
+ fprintf(stderr, "\n%s line %d: %s", get_ct_filen(), get_ct_linenum(), str);
+ fprintf(filerr, "\n%s line %d: %s", get_ct_filen(), get_ct_linenum(), str);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_TLINE */
+
+
+/* TDEBUG_STR_INT prints diagnostics */
+void tdebug_str_int(str, num)
+char str[];
+int num;
+{
+ fprintf(stderr, "LD: %s %d\n", str, num);
+ fprintf(filerr, "LD: %s %d\n", str, num);
+ fflush(stderr);
+ fflush(filerr);
+ return;
+} /* end TDEBUG_STR_INT */
+
+
+/* TDEBUG_STR prints diagnostics */
+void tdebug_str(str)
+char str[];
+{
+ fprintf(stderr, "LD: (Read_table) %s", str);
+ fprintf(filerr, "LD: (Read_table) %s", str);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_STR */
+
+
+/* TDEBUG_CHAR prints diagnostics */
+void tdebug_char(c)
+char c;
+{
+ fprintf(stderr, "%c\n", c);
+ fprintf(filerr, "%c\n", c);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_CHAR */
+
+
+
+
+
+ /*----------MISCELLANEOUS (PARSER) FUNCTIONS-----------------*/
+
+
+/* INITIALISE_CLAUSE_STACK */
+void initialise_clause_stack()
+{
+ int i;
+ for (i = 0; i < CLAUSE_STACK_SIZE; i++ ) {
+ clause_str_stack[i] = p_print_null;
+ }
+ clause_depth = 0;
+ base_level = CLAUSE_STACK_SIZE - 1;
+ current_level = 0;
+ new_level = 0;
+} /* end INITIALISE_CLAUSE_STACK */
+
+
+/* SET_CLAUSE_STACK */
+void set_clause_stack(lev, str)
+int lev;
+PSTRWC str;
+{
+ int limit;
+
+ limit = lev;
+ used_clause_stack = maxof(limit, used_clause_stack);
+
+ if (lev < 0) { /* underflow */
+ yyerror("Somethings wrong (set_clause_stack); underflow");
+ limit = 0;
+ }
+ else if (lev >= CLAUSE_STACK_SIZE) { /* overflow */
+ yyerror("Somethings wrong (set_clause_stack): overflow");
+ limit = CLAUSE_STACK_SIZE - 1;
+ }
+ clause_str_stack[limit] = str;
+} /* end SET_CLAUSE_STACK */
+
+
+/* CLOSE_DOC_DIVS Close off prior divisions */
+void close_doc_divs(level)
+int level;
+{
+ int i;
+ int temp_level;
+ int limit;
+
+ myprint("\n");
+ limit = level;
+ if (level < 0) { /* underflow */
+ yyerror("Somethings wrong (close_docs_div); underflow");
+ limit = 0;
+ }
+ else if (level >= CLAUSE_STACK_SIZE) { /* overflow */
+ yyerror("Somethings wrong (close_docs_div): overflow");
+ limit = CLAUSE_STACK_SIZE - 1;
+ }
+ temp_level = limit;
+ if (base_level > limit) {
+ temp_level = base_level;
+ }
+ if (temp_level <= current_level) {
+ for (i = current_level; i >= temp_level; i--) {
+ tag_print(clause_str_stack[i]);
+ }
+ }
+ if (base_level > limit) {
+ base_level = limit;
+ }
+} /* end CLOSE_DOC_DIVS */
+
+
+/* CLOSE_ALL_DIVS closes all open divisions */
+void close_all_divs()
+{
+ close_doc_divs(base_level);
+ initialise_clause_stack();
+} /* end CLOSE_ALL_DIVS */
+
+
+/* CLOSE_DOWN finish off the document */
+void close_down(s)
+STRING s;
+{
+ PSENTRY sym = get_mode_sym(pos_edoc);
+
+ /* this is the original code
+ close_all_divs();
+ myprint("\n");
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ printf("\n");
+ write_stats(s);
+ */
+
+ myprint("\n");
+ tag_print(get_t(sym));
+ close_all_divs();
+ tag_print(get_et(sym));
+ printf("\n");
+ write_stats(s);
+
+} /* end CLOSE_DOWN */
+
+
+/* SET_LIST_STACK sets up list stack */
+/* 6/96 changed from STRING to PSTRWC */
+void set_list_stack(istart, iend, pstart, pend)
+PSTRWC istart; /* start tag for item */
+PSTRWC iend; /* end tag for item */
+PSTRWC pstart; /* start tag for parameter */
+PSTRWC pend; /* end tag for parameter */
+{
+ if (list_level < -1) { /* underflow */
+ yyerror("Somethings wrong (set_list_stack): underflow");
+ list_level = -1;
+ }
+ else if (list_level >= (LIST_STACK_SIZE - 1)) { /* overflow */
+ yyerror("Somethings wrong (set_list_stack): overflow");
+ list_level = LIST_STACK_SIZE - 2;
+ }
+ list_level++;
+ used_list_stack = maxof(list_level, used_list_stack);
+ num_items[list_level] = 0;
+ list_item_start[list_level] = istart;
+ list_str_stack[list_level] = iend;
+ list_descitemp_start[list_level] = pstart;
+ list_descitemp_end[list_level] = pend;
+} /* end SET_LIST_STACK */
+
+
+/* PRINT_END_ITEM closes off an item */
+void print_end_item()
+{
+ if (list_level < 0) { /* underflow */
+ yyerror("Somethings wrong (print_end_item): underflow");
+ }
+ else if (list_level >= LIST_STACK_SIZE) { /* overflow */
+ yyerror("Somethings wrong (print_end_item): overflow");
+ }
+ else if (num_items[list_level] > 0) { /* close off last item */
+ tag_print(list_str_stack[list_level]);
+ }
+} /* end PRINT_END_ITEM */
+
+
+/* CATL concatenates S to line buffer */
+void catl(n,s)
+int n; /* no of chars in s */
+char *s;
+{
+ linlen = linlen + n; /* current chars to be in linebuf */
+ if (linlen >= MAX_LINE) { /* linebuf will overflow */
+ warning("A very long line. Internal buffer size exceeded");
+ linebuf[0] = SNUL;
+ linlen = n;
+ }
+ strcat(linebuf, s);
+} /* end CATL */
+
+
+/* DO_NEWLINE does stuff at start of each line */
+void do_newline()
+{
+ lineno++;
+ linlen = 0;
+ linebuf[0] = SNUL;
+ if ((lineno % EVERY_N_LINES) == 0) {
+ line_count++;
+ fprintf(stdout, "[%d] ", line_count);
+ fflush(stdout);
+ if ((line_count % 10) == 0) {
+ fprintf(stdout, "\n");
+ }
+ }
+} /* end DO_NEWLINE */
+
+
+/*-----------------------------------------------------------------------*/
+/* void read_table() */
+/* keywords are: */
+/* COMMENT= anything */
+/* C= comment (added 6/96) */
+/* ESCAPE_CHAR= single char (default \ ) */
+/* NEWLINE_CHAR= single char (default n ) */
+/* HORIZONTAL_TAB_CHAR= single char (default t ) */
+/* VERTICAL_TAB_CHAR= single char (default v ) */
+/* BACKSPACE_CHAR= single char (default b ) */
+/* CARRIAGE_RETURN_CHAR= single char (default r ) */
+/* FORMFEED_CHAR= single char (default f ) */
+/* AUDIBLE_ALERT_CHAR= single char (default a ) */
+/* HEX_CHAR= single char (default x ) */
+/* INCLUDE= file name for inclusion */
+/* TYPE= command type keyword */
+/* NAME= LaTeX command or environment name */
+/* START_TAG= " print this before NAME " */
+/* END_TAG= " print this after all processing " */
+/* PRINT_CONTROL= NO_PRINT (or maybe extended later) */
+/* OPT_PARAM= FIRST or LAST (position of optional param) */
+/* START_OPT= " print this before optional param " */
+/* END_OPT= " print this after optional param */
+/* PRINT_OPT= NO_PRINT ing of the parameter text */
+/* REQPARAMS= 0 through 9 (number of required params) */
+/* START_TAG_1= " print before req. param 1 " */
+/* END_TAG_1= " print after req. param 1 " */
+/* PRINT_P1= NO_PRINT ing of the parameter text */
+/* ... */
+/* START_TAG_9= " print before req. param 9 " */
+/* END_TAG_9= " print after req. param 9 " */
+/* PRINT_P9= NO_PRINT ing of the parameter text */
+/* SECTIONING_LEVEL keyword describing the level */
+/* START_ITEM= " print before \item " */
+/* END_ITEM= " print after processing \item text " */
+/* START_ITEM_PARAM= " print before \item opt. param " */
+/* END_ITEM_PARAM= " print after \item opt. param " */
+/* CONTINUE= " continuation of previous string " */
+/* SPECIAL_TOKEN= integer (pre-defined as a yac token) */
+/* END_TYPE must be last entry to close off TYPE= */
+/* END_CTFILE= anything, ends file */
+/* OTHER_SOURCE= o/p printing (added 6/96) */
+/* PC_AT_START= (added 6/96) */
+/* PC_AT_END= (added 6/96) */
+/*-----------------------------------------------------------------------*/
+/* READ_TABLE reads command table */
+void read_table()
+{
+
+ char line[MAX_TABLE_LINE];
+ char code_name[MAX_TABLE_LINE];
+ char noquotes[MAX_TABLE_LINE];
+ int num_names;
+ int num;
+ PSENTRY entry;
+ PSENTRY last_entry = NULL; /* last command entry */
+ char str[MAX_TABLE_LINE];
+ int last_string = CONT_UNKNOWN_ENUM;
+ FILE *filtabin; /* input file */
+ char *cin;
+ int endit;
+ PSTRWC lastp = NULL; /* last print control */
+ int key; /* command keyword */
+ int numbuf;
+
+ filtabin = get_ct_filep(); /* get root file */
+
+ for (;;) { /* loop over all files */
+ line[0] = SNUL;
+ cin = fgets(line, MAX_TABLE_LINE, filtabin); /* read a line */
+ used_table_line = maxof(strlen(line), used_table_line);
+ incr_ct_linenum();
+ if (TDEBUG) {
+ tdebug_tline(line);
+ }
+ if (feof(filtabin) != 0) { /* end of this file */
+ if (TDEBUG) {
+ tdebug_str_int("Calling RESET_CT_FILE with ct_file_num=", ct_file_num);
+ }
+ endit = reset_ct_file();
+ if (TDEBUG) {
+ tdebug_str_int("Called RESET_CT_FILE and ct_file_num now=", ct_file_num);
+ tdebug_str_int(" END OF FILE, endit = (reset_ct_file) = ", endit);
+ }
+ filtabin = get_ct_filep();
+ if (endit == EOF) { /* end of all files */
+ break;
+ }
+ continue; /* skip rest of this line processing */
+ }
+ strcpy(table_line, line);
+ /* get first name on line */
+ num_names = sscanf(line, "%s", code_name);
+ if (num_names <= 0) { /* blank line */
+ continue; /* ignore */
+ }
+ strtouc(code_name); /* convert to upper case for comparisons */
+ key = key_to_int(code_name);
+ switch (key) {
+ case END_CTFILE : { /* end of file */
+ if (TDEBUG) {
+ tdebug_str("END_CTFILE=\n");
+ }
+ if (TDEBUG) {
+ tdebug_str_int("Calling RESET_CT_FILE with ct_file_num=", ct_file_num);
+ }
+ endit = reset_ct_file();
+ if (TDEBUG) {
+ tdebug_str_int("Called RESET_CT_FILE and ct_file_num now=", ct_file_num);
+ tdebug_str_int(" END OF FILE, endit = (reset_ct_file) = ", endit);
+ }
+ filtabin = get_ct_filep();
+ if (endit == EOF) { /* end of all files */
+ return;
+ }
+ continue; /* skip rest of this line processing */
+ }
+ case CA :
+ case COMMENT : { /* comment line */
+ if (TDEBUG) {
+ tdebug_str("C=\n");
+ }
+ continue; /* ignore */
+ }
+ case INCLUDE : { /* file inclusion */
+ if (TDEBUG) {
+ tdebug_str("INCLUDE= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str );
+ if (TDEBUG) {
+ tdebug_str(str);
+ tdebug_str("\n");
+ tdebug_str_int("Calling SET_CT_FILE with ct_file_num=", ct_file_num);
+ }
+ set_ct_file(str);
+ if (TDEBUG) {
+ tdebug_str_int(" SET_CT_FILE changed ct_file_num to ", ct_file_num);
+ }
+ filtabin = get_ct_filep();
+ break;
+ }
+ case TYPE : { /* start of a record */
+ last_string = CONT_UNKNOWN_ENUM;
+ entry = new_table_entry();
+ last_entry = entry;
+ if (num_table_entries >= MAX_TABLE_ENTRIES) {
+ table_error("FATAL ERROR: Too many table entries");
+ exit(0);
+ }
+ symbol_table[num_table_entries] = entry;
+ num_table_entries++;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ strtouc(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry->kind = ctype_to_int(str);
+ break;
+ }
+ case END_TYPE : { /* end of a record */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name );
+ tdebug_str(errstr);
+ }
+ lastp = NULL;
+ last_string = CONT_UNKNOWN_ENUM;
+ complete_entry(last_entry);
+ break;
+ }
+ case NAMEK : { /* process NAME= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ entry->command = strsave(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, entry->command);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_CONTROL : { /* process PRINT_CONTROL= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->printing = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case START_TAG : { /* process START_TAG= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ /* 6/96 this, and all like it changed */
+ lastp = create_print_tag(strsave(noquotes));
+ entry->command_t = lastp;
+ break;
+ }
+ case END_TAG : { /* process END_TAG= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->command_et = lastp;
+ break;
+ }
+ case OPT_PARAM : { /* process OPT_PARAM= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ strtouc(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry->opt_param_pos = pos_to_int(str);
+ break;
+ }
+ case PRINT_OPT : { /* process PRINT_OPT= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_opt[1] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case START_OPT : { /* process START_OPT= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->opt_param_t = lastp;
+ break;
+ }
+ case END_OPT : { /* process END_OPT= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->opt_param_et = lastp;
+ break;
+ }
+ case REQPARAMS : { /* process REQPARAMS= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%d", &num);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, num);
+ tdebug_str(errstr);
+ }
+ if (num >= 0 && num <= 9 ) {
+ entry->numparams = num;
+ }
+ else {
+ table_error("REQPARAMS out of range (0-9)");
+ }
+ break;
+ }
+ case START_TAG_1 : { /* process START_TAG_1= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[0] = lastp;
+ break;
+ }
+ case END_TAG_1 : { /* process END_TAG_1= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[0] = lastp;
+ break;
+ }
+ case START_TAG_2 : { /* process START_TAG_2= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[1] =lastp;
+ break;
+ }
+ case END_TAG_2 : { /* process END_TAG_2= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[1] = lastp;
+ break;
+ }
+ case START_TAG_3 : { /* process START_TAG_3= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[2] = lastp;
+ break;
+ }
+ case END_TAG_3 : { /* process END_TAG_3= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[2] = lastp;
+ break;
+ }
+ case START_TAG_4 : { /* process START_TAG_4= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[3] = lastp;
+ break;
+ }
+ case END_TAG_4 : { /* process END_TAG_4= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[3] = lastp;
+ break;
+ }
+ case START_TAG_5 : { /* process START_TAG_5= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[4] = lastp;
+ break;
+ }
+ case END_TAG_5 : { /* process END_TAG_5= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[4] = lastp;
+ break;
+ }
+ case START_TAG_6 : { /* process START_TAG_6= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[5] = lastp;
+ break;
+ }
+ case END_TAG_6 : { /* process END_TAG_6= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[5] = lastp;
+ break;
+ }
+ case START_TAG_7 : { /* process START_TAG_7= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[6] = lastp;
+ break;
+ }
+ case END_TAG_7 : { /* process END_TAG_7= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[6] = lastp;
+ break;
+ }
+ case START_TAG_8 : { /* process START_TAG_8= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[7] = lastp;
+ break;
+ }
+ case END_TAG_8 : { /* process END_TAG_8= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[7] = lastp;
+ break;
+ }
+ case START_TAG_9 : { /* process START_TAG_9= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[8] = lastp;
+ break;
+ }
+ case END_TAG_9 : { /* process END_TAG_9= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[8] = lastp;
+ break;
+ }
+ case PRINT_P1 : { /* process PRINT_P1= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[0] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P2 : { /* process PRINT_P2= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[1] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P3 : { /* process PRINT_P3= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[2] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P4 : { /* process PRINT_P4= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[3] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P5 : { /* process PRINT_P5= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[4] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P6 : { /* process PRINT_P6= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[5] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P7 : { /* process PRINT_P7= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[6] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P8 : { /* process PRINT_P8= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[7] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case PRINT_P9 : { /* process PRINT_P9= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ /* changed 6/96 */
+ entry->print_param[8] = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+ case START_ITEM : { /* process START_ITEM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[7] = lastp;
+ break;
+ }
+ case END_ITEM : { /* process END_ITEM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[7] = lastp;
+ break;
+ }
+ case START_ITEM_PARAM : { /* process START_ITEM_PARAM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_t[8] = lastp;
+ break;
+ }
+ case END_ITEM_PARAM : { /* process END_ITEM_PARAM= */
+ last_string = CONT_TAG;
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = create_print_tag(strsave(noquotes));
+ entry->param_et[8] = lastp;
+ break;
+ }
+
+ case CONTINUE : /* process CONTINUE= */
+ case STRINGG : { /* process STRING= */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else {
+ delete_quotes(line,noquotes);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, noquotes);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_print_source(strsave(noquotes)));
+ set_pc_cmd(lastp, STRINGG);
+ }
+ break;
+ }
+
+ case SOURCE : { /* 6/96 process SOURCE= */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else {
+ delete_to_chars("=:", line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, parse_pc(line));
+ set_pc_cmd(lastp, SOURCE);
+ }
+ break;
+ }
+
+ case PC_AT_START : { /* 6/96 process PC_AT_START= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ entry->start_pc = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+
+ case PC_AT_END : { /* 6/96 process PC_AT_END= */
+ if (TDEBUG) {
+ tdebug_str("PC_AT_END=\n");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ entry->end_pc = parse_pc(line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+
+ case SECTIONING_LEVEL : { /* process SECTIONING_LEVEL= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ strtouc(str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry->sectioning_level = level_to_int(str);
+ break;
+ }
+
+ case RESET_SYSBUF : { /* 6/96 process RESET_SYSBUF= */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_SYSBUF);
+ }
+ break;
+ }
+
+ case RESET_BUFFER : { /* 6/96 process RESET_BUFFER */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get buffer number */
+ numbuf = 0;
+ sscanf(line, "%s %d", str, &numbuf);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, numbuf);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_BUFFER);
+ set_pc_enum(lastp, BUFFER);
+ set_pcdata_num(lastp, chk_bufnum(numbuf));
+ }
+ break;
+ }
+
+ case RESET_FILE : { /* 6/96 process RESET_FILE */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get file name */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_FILE);
+ set_pc_enum(lastp, FFILE);
+ set_pcdata_name(lastp, chk_ufname(str));
+ }
+ break;
+ }
+
+ case SWITCH_BACK : { /* 11/96 process SWITCH_BACK */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_BACK);
+ set_pc_enum(lastp, RESET);
+ }
+ break;
+ }
+
+ case SWITCH_TO_BUFFER : { /* 11/96 process SWITCH_TO_BUFFER */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get buffer number */
+ numbuf = 0;
+ sscanf(line, "%s %d", str, &numbuf);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, numbuf);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_TO_BUFFER);
+ set_pc_enum(lastp, TO_BUFFER);
+ set_pcdata_num(lastp, chk_bufnum(numbuf));
+ }
+ break;
+ }
+
+ case SWITCH_TO_FILE : { /* 11/96 process SWITCH_TO_FILE */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get file name */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_TO_FILE);
+ set_pc_enum(lastp, TO_FILE);
+ set_pcdata_name(lastp, chk_ufname(str));
+ }
+ break;
+ }
+
+ case SWITCH_TO_SYSBUF : { /* 11/96 process SWITCH_TO_SYSBUF */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SWITCH_TO_SYSBUF);
+ set_pc_enum(lastp, TO_SYSBUF);
+ }
+ break;
+ }
+
+ case SET_MODE : { /* 6/96 process SET_MODE */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* get mode name */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ numbuf = add_mode(str);
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, SET_MODE);
+ set_pc_enum(lastp, MODE);
+ set_pcdata_num(lastp, numbuf);
+ }
+ break;
+ }
+
+ case RESET_MODE : { /* 6/96 process RESET_MODE */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else { /* takes no value */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_cmd(lastp, RESET_MODE);
+ }
+ break;
+ }
+
+ case IN_MODE : { /* 6/96 process IN_MODE */
+ complete_entry(last_entry); /* complete prior defn */
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ entry = new_table_entry(); /* create new symbol entry */
+ add_to_modelist(last_entry, entry); /* add it to the list of modes */
+ set_mode_name(str, entry); /* set the mode name in the new entry */
+ last_entry = entry; /* update last entry pointer */
+ break;
+ }
+
+ case END_MODE : { /* 6/96 process END_MODE */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ /* PERHAPS DO STUFF HERE LATER */
+ break;
+ }
+
+
+ case SPECIAL_TOKEN : { /* process SPECIAL_TOKEN= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%d", &num);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, num);
+ tdebug_str(errstr);
+ }
+ if (num < MIN_GRAMM_SPECIAL) {
+ table_error("SPECIAL_TOKEN value too small");
+ tdebug_str_int("Value sould be at least",MIN_GRAMM_SPECIAL);
+ }
+ entry->special_token = num;
+ break;
+ }
+
+
+ case ESCAPE_CHAR : { /* escape char */
+ if (TDEBUG) {
+ tdebug_str("ESCAPE_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str );
+ escape_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(escape_char);
+ }
+ break;
+ }
+ case NEWLINE_CHAR : { /* newline char */
+ if (TDEBUG) {
+ tdebug_str("NEWLINE_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str );
+ newline_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(newline_char);
+ }
+ break;
+ }
+ case HORIZONTAL_TAB_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("HORIZONTAL_TAB_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ horizontal_tab_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(horizontal_tab_char);
+ }
+ break;
+ }
+ case VERTICAL_TAB_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("VERTICAL_TAB_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ vertical_tab_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(vertical_tab_char);
+ }
+ break;
+ }
+ case BACKSPACE_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("BACKSPACE_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ backspace_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(backspace_char);
+ }
+ break;
+ }
+ case CARRIAGE_RETURN_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("CARRIAGE_RETURN_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ carriage_return_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(carriage_return_char);
+ }
+ break;
+ }
+ case FORMFEED_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("FORMFEED_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ formfeed_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(formfeed_char);
+ }
+ break;
+ }
+ case AUDIBLE_ALERT_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("AUDIBLE_ALERT_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ audible_alert_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(audible_alert_char);
+ }
+ break;
+ }
+ case HEX_CHAR : { /* char */
+ if (TDEBUG) {
+ tdebug_str("HEX_CHAR= ");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%s", str);
+ hex_char = str[0];
+ if (TDEBUG) {
+ tdebug_char(hex_char);
+ }
+ break;
+ }
+
+ case CODE_SETUP : { /* CODE_SETUP added for code interp */
+ last_string = CONT_UNKNOWN_ENUM;
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ code_root = code_setup(filtabin); /* parse code and store symtab */
+ break;
+ }
+
+ case CODE : { /* CODE added for code interp */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ else {
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ /* set up new action, parse code and store code segment */
+ lastp = append_to_write(lastp, create_st_rwc());
+ set_pc_code(lastp, code_action(filtabin));
+ }
+ break;
+ }
+
+
+ default : { /* unrecognised */
+ if (TDEBUG) {
+ tdebug_str("UNRECOGNISED CODE NAME\n");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ table_error("Unrecognised code");
+ break;
+ }
+ } /* end of switch */
+ } /* end of loop over all files */
+} /* end READ_TABLE */
+
+
+/* NEW_TABLE_ENTRY creates new entry for symbol table */
+/* changed 6/96 */
+struct st_entry *new_table_entry()
+{
+ struct st_entry *p;
+ int i;
+
+
+ if ((p = (struct st_entry *) malloc(sizeof(struct st_entry))) != NULL) {
+ p->command = dont_care_str; /* user defined command string */
+ p->kind = UNKNOWN_CTYPE; /* user defined kind of command */
+ p->parse_kind = UNKNOWN_CTYPE; /* system defined kind of command */
+ p->mode = IERR; /* name of mode for this command */
+ p->next_mode = NULL; /* next mode */
+ p->printing = p_default_print; /* print control (changed 6/96) */
+ p->command_t = NULL; /* start tag: nothing to print */
+ p->command_et = NULL; /* end tag: nothing to print */
+ p->numparams = 0; /* number of params */
+ p->opt_param_pos = NO_OPT_PARAM; /* position of optional param */
+ p->opt_param_t = NULL; /* opt start tag: nothing to print */
+ p->opt_param_et = NULL; /* opt end tag: nothing to print */
+ for (i = 0; i <= 1; i++) {
+ p->popt_param_t[i] = NULL; /* opt param start tags: */
+ p->popt_param_et[i] = NULL; /* opt param end tags: */
+ }
+ p->print_opt[0] = p_no_print; /* print control for opt param */
+ p->print_opt[1] = p_default_print; /* print control for opt param */
+ p->sectioning_level = UNKNOWN_LEVEL; /* sectioning level */
+ for (i = 0; i <= 8; i++) {
+ p->param_t[i] = NULL; /* start param tags: */
+ p->param_et[i] = NULL; /* end param tags: */
+ p->print_param[i] = p_default_print; /* print control for params */
+ }
+ p->start_pc = p_default_print; /* start pc (added 6/96) */
+ p->end_pc = p_default_print; /* end pc (added 6/96) */
+ p->special_token = COMMAND; /* user defined special token */
+ return(p);
+ }
+ yyerror("FATAL ERROR: No memory left for NEW_TABLE_ENTRY");
+ exit(1);
+} /* end NEW_TABLE_ENTRY */
+
+
+/* CREATE_DEF_REQENTRY new default required comm */
+void create_def_reqentry(name)
+int name;
+{
+ struct st_entry *entry;
+
+ entry = new_table_entry();
+ if (num_table_entries >= MAX_TABLE_ENTRIES) {
+ terror_noline("FATAL ERROR: Too many table entries");
+ exit(0);
+ }
+ entry->kind = name;
+ symbol_table[num_table_entries] = entry;
+ complete_table_entry(num_table_entries);
+ num_table_entries++;
+} /* end CREATE_DEF_REQENTRY */
+
+/* COMPLETE_TABLE_ENTRY of an entry in the command table */
+void complete_table_entry(ctpos)
+int ctpos; /* position in comand table */
+{
+ complete_entry(symbol_table[ctpos]);
+ return;
+} /* end COMPLETE_TABLE_ENTRY */
+
+
+/* COMPLETE_ENTRY of a symbol entry */
+void complete_entry(pos)
+PSENTRY pos;
+{
+ int num, user_kind, popt_pos;
+
+ num = pos->numparams;
+ user_kind = pos->kind;
+ popt_pos = pos->opt_param_pos;
+
+ /* do default stuff */
+ pos->parse_kind = user_kind;
+ if (popt_pos != NO_OPT_PARAM) { /* fix up optional parameter stuff */
+ pos->popt_param_t[popt_pos] = pos->opt_param_t;
+ pos->popt_param_et[popt_pos] = pos->opt_param_et;
+ pos->print_opt[0] = pos->print_opt[1];
+ }
+ /* do specific stuff */
+ switch (user_kind) {
+ case COMMAND:
+ case CHAR_COMMAND: /* PRW added 11/99 for version 0.91 */
+ case SPECIAL_COMMAND:
+ case BEGIN_ENV:
+ case SPECIAL_BEGIN_ENV:
+ case END_ENV:
+ case SPECIAL_END_ENV:
+ case BEGIN_LIST_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case END_LIST_ENV:
+ case SPECIAL_END_LIST:
+ case SECTIONING:
+ case SPECIAL_SECTIONING:
+ case BEGIN_VENV:
+ case END_VENV:
+ case VCOMMAND: {
+ if ((popt_pos == LAST) || (popt_pos == FIRST && num == 0)) {
+ pos->parse_kind = command_opt_types[num];
+ }
+ else {
+ pos->parse_kind = command_types[num];
+ }
+ break;
+ }
+/* added 10/95 for TEX_CHAR taking parameters */
+/* If parameters are specified, treat it like a command */
+ case TEX_CHAR: {
+ if ((popt_pos == LAST) || (popt_pos == FIRST && num == 0)) {
+ pos->parse_kind = command_opt_types[num];
+ }
+ else if (num > 0) {
+ pos->parse_kind = command_types[num];
+ }
+ break;
+ }
+/* end of 10/95 TEX_CHAR addition */
+ case BEGIN_PICTURE_CC: {
+ pos->numparams = 2;
+ break;
+ }
+ case END_PICTURE: {
+ pos->numparams = 0;
+ break;
+ }
+ case PICTURE_CCPP: {
+ pos->numparams = 4;
+ break;
+ }
+ case PICTURE_CO: {
+ pos->numparams = 2;
+ break;
+ }
+ case PICTURE_COP: {
+ pos->numparams = 3;
+ break;
+ }
+ case PICTURE_CP: {
+ pos->numparams = 2;
+ break;
+ }
+ case PICTURE_OCC: {
+ pos->numparams = 3;
+ break;
+ }
+ case PICTURE_OCCC: {
+ pos->numparams = 4;
+ break;
+ }
+ case PICTURE_OCO: {
+ pos->numparams = 3;
+ break;
+ }
+ case PICTURE_PCOP: {
+ pos->numparams = 4;
+ break;
+ }
+/* July 1996 additions */
+ case COMMAND_OOP: {
+ pos->numparams = 3;
+ break;
+ }
+ case COMMAND_OOOPP: {
+ pos->numparams = 5;
+ break;
+ }
+ case COMMAND_OPO: {
+ pos->numparams = 3;
+ break;
+ }
+ case COMMAND_POOOP: {
+ pos->numparams = 5;
+ break;
+ }
+ case COMMAND_POOP: {
+ pos->numparams = 4;
+ break;
+ }
+ case COMMAND_POOPP: {
+ pos->numparams = 5;
+ break;
+ }
+ } /* end SWITCH */
+} /* end COMPLETE_ENTRY */
+
+
+/* PRINT_TABLE prints symbol table */
+/* many changes 6/96 */
+void print_table(fout)
+FILE *fout;
+{
+ int i, n, num;
+ PSTRWC ptr;
+ PSENTRY symbol;
+ STRING com = key_to_string(CA); /* comment string */
+ STRING spaces = " ";
+ int pmode;
+
+
+ fprintf(fout, "%s generated command table\n\n", com);
+
+ fprintf(fout, "%s special printing characters\n\n", com);
+ fprintf(fout, "%s %c\n", key_to_string(ESCAPE_CHAR), escape_char);
+ fprintf(fout, "%s %c\n", key_to_string(AUDIBLE_ALERT_CHAR), audible_alert_char);
+ fprintf(fout, "%s %c\n", key_to_string(BACKSPACE_CHAR), backspace_char);
+ fprintf(fout, "%s %c\n", key_to_string(CARRIAGE_RETURN_CHAR), carriage_return_char);
+ fprintf(fout, "%s %c\n", key_to_string(FORMFEED_CHAR), formfeed_char);
+ fprintf(fout, "%s %c\n", key_to_string(HEX_CHAR), hex_char);
+ fprintf(fout, "%s %c\n", key_to_string(HORIZONTAL_TAB_CHAR), horizontal_tab_char);
+ fprintf(fout, "%s %c\n", key_to_string(NEWLINE_CHAR), newline_char);
+ fprintf(fout, "%s %c\n", key_to_string(VERTICAL_TAB_CHAR), vertical_tab_char);
+
+
+ fprintf(fout, "\n\n%s the commands (in the internal ordering)\n\n", com);
+ for (i=0; i < num_table_entries; i++) {
+ symbol = symbol_table[i];
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ tdebug_str_int("Print_table entry", i);
+ }
+ /* print TYPE= kind */
+ fprintf(fout, "%s %s\n", key_to_string(TYPE), ctype_to_string(symbol->kind) );
+ pmode = 0; /* start of command, so no modes yet */
+ if (TDEBUG) {
+ fprintf(fout, " %s Type stored internally as %d\n",
+ com, symbol->kind);
+ }
+ /* print NAME= command */
+ if (symbol->command != dont_care_str) {
+ fprintf(fout, "%s %s\n", key_to_string(NAMEK), symbol->command );
+ }
+ else {
+ fprintf(fout, "%s %s %s\n", com, key_to_string(NAMEK), symbol->command );
+
+ }
+
+ /* NOTE USE OF GOTO/LABEL HERE */
+ domode:
+
+ /* print PC_AT_START= command */
+ ptr = symbol->start_pc;
+ fprintf(fout, "%s%s ", spaces, key_to_string(PC_AT_START));
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, get_pc_enum(ptr) );
+ }
+
+ /* print PRINT_CONTROL= command */
+ ptr = symbol->printing;
+ fprintf(fout, "%s%s ", spaces, key_to_string(PRINT_CONTROL));
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, ptr->pcenum);
+ }
+
+ /* print START_TAG= command_t */
+ ptr = symbol->command_t;
+ fprintf(fout, "%s%s ", spaces, key_to_string(START_TAG));
+ tprint_tag(fout, ptr);
+
+ /* print END_TAG= command_et */
+ ptr = symbol->command_et;
+ fprintf(fout, "%s%s ", spaces, key_to_string(END_TAG));
+ tprint_tag(fout, ptr);
+
+ /* print OPT_PARAM= opt_param_pos */
+ if (symbol->opt_param_pos != NO_OPT_PARAM) { /* opt param */
+ fprintf(fout, "%s%s %s\n", spaces, key_to_string(OPT_PARAM),
+ pos_to_string(symbol->opt_param_pos) );
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, symbol->opt_param_pos);
+ }
+
+ /* print PRINT_OPT= command */
+ ptr = symbol->print_opt[0];
+ fprintf(fout, "%s%s ", spaces, key_to_string(PRINT_OPT));
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, get_pc_enum(ptr));
+ }
+
+ /* print START_OPT= opt_param_t */
+ ptr = symbol->opt_param_t;
+ fprintf(fout, "%s%s ", spaces, key_to_string(START_OPT));
+ tprint_tag(fout, ptr);
+
+
+ /* print END_OPT= opt_param_et */
+ ptr = symbol->opt_param_et;
+ fprintf(fout, "%s%s ", spaces, key_to_string(END_OPT));
+ tprint_tag(fout, ptr);
+ } /* end of if over OPT_PARAM */
+
+ /* print parameter info, if any */
+ num = symbol->numparams;
+ if (num > 0) { /* are parameters */
+
+ /* print REQPARAMS= numparams */
+ fprintf(fout, "%sREQPARAMS= %d\n", spaces, num );
+ for (n = 0; n < num; n++) {
+
+ /* print START_TAG_N= param_t[n] */
+ ptr = symbol->param_t[n];
+ fprintf(fout, "%sSTART_TAG_%d= ", spaces, (n+1) );
+ tprint_tag(fout, ptr);
+
+ /* print END_TAG_N= param_et[n] */
+ ptr = symbol->param_et[n];
+ fprintf(fout, "%sEND_TAG_%d= ", spaces, (n+1) );
+ tprint_tag(fout, ptr);
+
+ /* print PRINT_Pn= print_param[n] */
+ ptr = symbol->print_param[n];
+ fprintf(fout, "%sPRINT_P%d= ", spaces, (n+1) );
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s PRINT_P%d stored internally as %d\n",
+ com, (n+1), get_pc_enum(ptr));
+ }
+ } /* end loop over nunparams */
+ } /* end if num > 0 */
+
+ /* print SECTIONING_LEVEL= sectioning_level */
+ if (symbol_table[i]->kind == SECTIONING) { /* sectioning command */
+ fprintf(fout, "%s%s %s\n", spaces, key_to_string(SECTIONING_LEVEL),
+ level_to_string(symbol->sectioning_level) );
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, symbol->sectioning_level);
+ }
+ }
+
+ /* print SPECIAL_TOKEN= token number */
+ if ((TDEBUG) || (symbol->special_token != COMMAND)) {
+ fprintf(fout, "%s%s %d\n", spaces,
+ key_to_string(SPECIAL_TOKEN), get_special_token(symbol) );
+ }
+
+ /* extra debug printing */
+ if (TDEBUG) {
+ /* print internal kind */
+ fprintf(fout, " %s parse_kind= %d\n",
+ com, symbol->parse_kind);
+ }
+
+ /* print PC_AT_END= command */
+ ptr = symbol->end_pc;
+ fprintf(fout, "%s%s ", spaces, key_to_string(PC_AT_END) );
+ tprint_st_rwc(fout, ptr);
+ fprintf(fout, "\n");
+ if (TDEBUG) {
+ fprintf(fout, " %s value stored internally as %d\n",
+ com, get_pc_enum(ptr) );
+ }
+
+ /* do next mode for this entry */
+ if (pmode > 0) { /* not the first */
+ fprintf(fout, "%s\n", key_to_string(END_MODE));
+ }
+ if ((symbol = get_next_mode(symbol)) != NULL) { /* there is another mode */
+ pmode++;
+ fprintf(fout, "%s %s\n",
+ key_to_string(IN_MODE), get_mode_str(get_mode(symbol)));
+ goto domode; /* GOTO print the mode's actions */
+ }
+
+ /* print END_TYPE at end of entry */
+ fprintf(fout, "%s\n", key_to_string(END_TYPE));
+ }
+} /* end PRINT_TABLE */
+
+
+/* CHECK_TABLE = TRUE if missing entries and fixes them up */
+int check_table()
+{
+ int res = FALSE;
+
+ pos_bdoc = lookup_entry(dont_care_str, BEGIN_DOCUMENT);
+ if (pos_bdoc < 0) {
+ twarn_noline("BEGIN_DOCUMENT required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_DOCUMENT);
+ }
+ pos_edoc = lookup_entry(dont_care_str, END_DOCUMENT);
+ if (pos_edoc < 0) {
+ twarn_noline("END_DOCUMENT required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_DOCUMENT);
+ }
+ pos_bvbm = lookup_entry(dont_care_str, BEGIN_VERBATIM);
+ if (pos_bvbm < 0) {
+ twarn_noline("BEGIN_VERBATIM required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_VERBATIM);
+ }
+ pos_evbm = lookup_entry(dont_care_str, END_VERBATIM);
+ if (pos_evbm < 0) {
+ twarn_noline("END_VERBATIM required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_VERBATIM);
+ }
+ pos_bv = lookup_entry(dont_care_str, BEGIN_VERB );
+ if (pos_bv < 0) {
+ twarn_noline("BEGIN_VERB required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_VERB);
+ }
+ pos_ev = lookup_entry(dont_care_str, END_VERB);
+ if (pos_ev < 0) {
+ twarn_noline("END_VERB required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_VERB);
+ }
+ pos_oc = lookup_entry(dont_care_str, OTHER_COMMAND);
+ if (pos_oc < 0) {
+ twarn_noline("OTHER_COMMAND required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(OTHER_COMMAND);
+ }
+ pos_ob = lookup_entry(dont_care_str, OTHER_BEGIN );
+ if (pos_ob < 0) {
+ twarn_noline("OTHER_BEGIN required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(OTHER_BEGIN);
+ }
+ pos_oe = lookup_entry(dont_care_str, OTHER_END );
+ if (pos_oe < 0) {
+ twarn_noline("OTHER_END required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(OTHER_END);
+ }
+ pos_lbrace = lookup_entry(dont_care_str, LBRACE);
+ if (pos_lbrace < 0) {
+ twarn_noline("LBRACE required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(LBRACE);
+ }
+ pos_rbrace = lookup_entry(dont_care_str, RBRACE);
+ if (pos_rbrace < 0) {
+ twarn_noline("RBRACE required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(RBRACE);
+ }
+ pos_para = lookup_entry(dont_care_str, PARAGRAPH);
+ if (pos_para < 0) {
+ twarn_noline("PARAGRAPH required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(PARAGRAPH);
+ }
+ pos_bdol = lookup_entry(dont_care_str, BEGIN_DOLLAR);
+ if (pos_bdol < 0) {
+ twarn_noline("BEGIN_DOLLAR required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(BEGIN_DOLLAR);
+ }
+ pos_edol = lookup_entry(dont_care_str, END_DOLLAR);
+ if (pos_bdol < 0) {
+ twarn_noline("END_DOLLAR required but not found. Defaulted to null tags.");
+ res = TRUE;
+ create_def_reqentry(END_DOLLAR);
+ }
+ pos_bss = lookup_entry(dont_care_str, SLASH_SPACE);
+ if (pos_bss < 0) {
+ twarn_noline("SLASH_SPACE required but not found. Defaulted to a space tag.");
+ res = TRUE;
+ create_def_reqentry(SLASH_SPACE);
+ symbol_table[num_table_entries - 1]->command_t = create_print_tag(" ");
+ }
+
+ return(res);
+} /* end CHECK_TABLE */
+
+
+
+/* CTYPE_TO_INT returns enum value corrsponding to a command type string */
+int ctype_to_int(s)
+STRING s;
+{
+ int pos;
+ pos = lookup_string(s, ctnames, NUM_CTIDS);
+ if (pos == -1) {
+ table_error("TYPE entry is unrecognised");
+ return(UNKNOWN_CTYPE);
+ }
+ return(ctenums[pos]);
+} /* end CTYPE_TO_INT */
+
+/* CTYPE_TO_STRING returns enum string (the inverse of CTYPE_TO_INT) */
+char *ctype_to_string(ienum)
+int ienum;
+{
+
+ switch (ienum) {
+ case UNKNOWN_CTYPE: {
+ return("UNKNOWN_CTYPE");
+ }
+ case TEX_CHAR: {
+ return("TEX_CHAR");
+ }
+ case CHAR_COMMAND: {
+ return("CHAR_COMMAND");
+ }
+ case COMMAND: {
+ return("COMMAND");
+ }
+ case BEGIN_ENV: {
+ return("BEGIN_ENV");
+ }
+ case END_ENV: {
+ return("END_ENV");
+ }
+ case BEGIN_LIST_ENV: {
+ return("BEGIN_LIST_ENV");
+ }
+ case END_LIST_ENV: {
+ return("END_LIST_ENV");
+ }
+ case BEGIN_VERBATIM: {
+ return("BEGIN_VERBATIM");
+ }
+ case END_VERBATIM: {
+ return("END_VERBATIM");
+ }
+ case BEGIN_VERB: {
+ return("BEGIN_VERB");
+ }
+ case END_VERB: {
+ return("END_VERB");
+ }
+ case SECTIONING: {
+ return("SECTIONING");
+ }
+ case SPECIAL: {
+ return("SPECIAL");
+ }
+ case SPECIAL_COMMAND: {
+ return("SPECIAL_COMMAND");
+ }
+ case SPECIAL_BEGIN_ENV: {
+ return("SPECIAL_BEGIN_ENV");
+ }
+ case SPECIAL_END_ENV: {
+ return("SPECIAL_END_ENV");
+ }
+ case SPECIAL_BEGIN_LIST: {
+ return("SPECIAL_BEGIN_LIST");
+ }
+ case SPECIAL_END_LIST: {
+ return("SPECIAL_END_LIST");
+ }
+ case SPECIAL_SECTIONING: {
+ return("SPECIAL_SECTIONING");
+ }
+ case OTHER_COMMAND: {
+ return("OTHER_COMMAND");
+ }
+ case OTHER_BEGIN: {
+ return("OTHER_BEGIN");
+ }
+ case OTHER_END: {
+ return("OTHER_END");
+ }
+ case LBRACE: {
+ return("LBRACE");
+ }
+ case RBRACE: {
+ return("RBRACE");
+ }
+ case BEGIN_PICTURE_CC: {
+ return("BEGIN_PICTURE_CC");
+ }
+ case END_PICTURE: {
+ return("END_PICTURE");
+ }
+ case PICTURE_CCPP: {
+ return("PICTURE_CCPP");
+ }
+ case PICTURE_CO: {
+ return("PICTURE_CO");
+ }
+ case PICTURE_COP: {
+ return("PICTURE_COP");
+ }
+ case PICTURE_CP: {
+ return("PICTURE_CP");
+ }
+ case PICTURE_OCC: {
+ return("PICTURE_OCC");
+ }
+ case PICTURE_OCCC: {
+ return("PICTURE_OCCC");
+ }
+ case PICTURE_OCO: {
+ return("PICTURE_OCO");
+ }
+ case PICTURE_PCOP: {
+ return("PICTURE_PCOP");
+ }
+ case BEGIN_VENV: {
+ return("BEGIN_VENV");
+ }
+ case END_VENV: {
+ return("END_VENV");
+ }
+ case VCOMMAND: {
+ return("VCOMMAND");
+ }
+ case BEGIN_DOCUMENT: {
+ return("BEGIN_DOCUMENT");
+ }
+ case END_DOCUMENT: {
+ return("END_DOCUMENT");
+ }
+ case PARAGRAPH: {
+ return("PARAGRAPH");
+ }
+ case BEGIN_DOLLAR: {
+ return("BEGIN_DOLLAR");
+ }
+ case END_DOLLAR: {
+ return("END_DOLLAR");
+ }
+ case SLASH_SPACE: {
+ return("SLASH_SPACE");
+ }
+ case COMMAND_OOP: {
+ return("COMMAND_OOP");
+ }
+ case COMMAND_OOOPP: {
+ return("COMMAND_OOOPP");
+ }
+ case COMMAND_OPO: {
+ return("COMMAND_OPO");
+ }
+ case COMMAND_POOOP: {
+ return("COMMAND_POOOP");
+ }
+ case COMMAND_POOP: {
+ return("COMMAND_POOP");
+ }
+ case COMMAND_POOPP: {
+ return("COMMAND_POOPP");
+ }
+ default: {
+ return("UNKNOWN_CTYPE");
+ }
+ }
+} /* end CTYPE_TO_STRING */
+
+
+/* POS_TO_INT converts an opt_pos_enum enum string to an int */
+int pos_to_int(s)
+char s[];
+{
+
+ if (strcmp(s, "NO_OPT_PARAM") == 0) {
+ return(NO_OPT_PARAM);
+ }
+ else if (strcmp(s, "FIRST") == 0) {
+ return(FIRST);
+ }
+ else if (strcmp(s, "LAST") == 0) {
+ return(LAST);
+ }
+ else {
+ table_error("OPT_PARAM entry is unrecognised");
+ return(NO_OPT_PARAM);
+ }
+} /* end POS_TO_INT */
+
+
+/* POS_TO_STRING returns enum string (the inverse of POS_TO_INT) */
+char *pos_to_string(ienum)
+int ienum;
+{
+
+ switch (ienum) {
+ case NO_OPT_PARAM: {
+ return("NO_OPT_PARAM");
+ }
+ case FIRST: {
+ return("FIRST");
+ }
+ case LAST: {
+ return("LAST");
+ }
+ default: {
+ return("NO_OPT_PARAM");
+ }
+ }
+} /* end POS_TO_STRING */
+
+
+/* LEVEL_TO_INT converts an sect_level_enum enum string to an int */
+int level_to_int(s)
+char s[];
+{
+
+ if (strcmp(s, "UNKNOWN_LEVEL") == 0) {
+ return(UNKNOWN_LEVEL);
+ }
+ else if (strcmp(s, "PARTM2") == 0) {
+ return(PARTM2);
+ }
+ else if (strcmp(s, "PARTM1") == 0) {
+ return(PARTM1);
+ }
+ else if (strcmp(s, "PART") == 0) {
+ return(PART);
+ }
+ else if (strcmp(s, "CHAPTER") == 0) {
+ return(CHAPTER);
+ }
+ else if (strcmp(s, "SECT") == 0) {
+ return(SECT);
+ }
+ else if (strcmp(s, "SUBSECT") == 0) {
+ return(SUBSECT);
+ }
+ else if (strcmp(s, "SUBSUBSECT") == 0) {
+ return(SUBSUBSECT);
+ }
+ else if (strcmp(s, "PARA") == 0) {
+ return(PARA);
+ }
+ else if (strcmp(s, "SUBPARA") == 0) {
+ return(SUBPARA);
+ }
+ else if (strcmp(s, "SUBPARAP1") == 0) {
+ return(SUBPARAP1);
+ }
+ else if (strcmp(s, "SUBPARAP2") == 0) {
+ return(SUBPARAP2);
+ }
+ else {
+ table_error("SECTIONING_LEVEL entry is unrecognised");
+ return(UNKNOWN_LEVEL);
+ }
+} /* end LEVEL_TO_INT */
+
+
+/* LEVEL_TO_STRING returns enum string (the inverse of LEVEL_TO_INT) */
+char *level_to_string(ienum)
+int ienum;
+{
+
+ switch (ienum) {
+ case UNKNOWN_LEVEL: {
+ return("UNKNOWN_LEVEL");
+ }
+ case PARTM2: {
+ return("PARTM2");
+ }
+ case PARTM1: {
+ return("PARTM1");
+ }
+ case PART: {
+ return("PART");
+ }
+ case CHAPTER: {
+ return("CHAPTER");
+ }
+ case SECT: {
+ return("SECT");
+ }
+ case SUBSECT: {
+ return("SUBSECT");
+ }
+ case SUBSUBSECT: {
+ return("SUBSUBSECT");
+ }
+ case PARA: {
+ return("PARA");
+ }
+ case SUBPARA: {
+ return("SUBPARA");
+ }
+ case SUBPARAP1: {
+ return("SUBPARAP1");
+ }
+ case SUBPARAP2: {
+ return("SUBPARAP2");
+ }
+ default: {
+ return("UNKNOWN_LEVEL");
+ }
+ }
+} /* end LEVEL_TO_STRING */
+
+
+
+
+/* SORT_TABLE sorts command table. From K&R Ed 2, p 62 */
+void sort_table()
+{
+
+ int gap, i, j;
+ struct st_entry *temp;
+
+ for (gap = num_table_entries/2; gap > 0; gap /= 2) {
+ for (i = gap; i < num_table_entries; i++) {
+ for (j = (i-gap);
+ j >= 0 && compare_st_entry(symbol_table[j], symbol_table[j+gap]) > 0;
+ j-=gap) {
+ temp = symbol_table[j];
+ symbol_table[j] = symbol_table[j+gap];
+ symbol_table[j+gap] = temp;
+ }
+ }
+ }
+} /* end SORT_TABLE */
+
+
+/* COMPARE_ST_ENTRY compares two st_entry */
+int compare_st_entry(e1, e2)
+struct st_entry *e1;
+struct st_entry *e2;
+{
+ int result;
+
+ /* compare on command name */
+ result = strcmp(e1->command, e2->command);
+ if (result != 0) {
+ return(result);
+ }
+ /* compare on kind */
+ return(e1->kind - e2->kind);
+} /* end COMPARE_ST_ENTRY */
+
+
+/* LOOKUP_ENTRY searches for command s in table. From K&R 2 Ed, p 58 */
+int lookup_entry(s,k)
+char s[];
+int k;
+{
+ int low, mid, high, result;
+
+ low = 0;
+ high = num_table_entries - 1;
+ while (low <= high) {
+ mid = (low + high)/2;
+ result = compare_id_to_entry(s,k,symbol_table[mid]);
+ if (result < 0) {
+ high = mid - 1;
+ }
+ else if (result > 0) {
+ low = mid + 1;
+ }
+ else { /* found a match */
+ return(mid);
+ }
+ }
+ return(-1); /* not found */
+} /* end LOOKUP_ENTRY */
+
+
+/* COMPARE_ID_TO_ENTRY similar to COMPARE_ST_ENTRY */
+int compare_id_to_entry(s,k,e)
+char s[];
+int k;
+struct st_entry *e;
+{
+ int result;
+
+ /* compare on command name */
+ result = strcmp(s, e->command);
+ if (result != 0) {
+ return(result);
+ }
+ if (k == DONT_CARE) {
+ return(result);
+ }
+ else { /* compare on kind */
+ return(k - e->kind);
+ }
+} /* end COMPARE_ID_TO_ENTRY */
+
+
+ /*-----------------GET_ FUNCTIONS-----------------------------*/
+
+
+
+/* COMMAND_TYPE returns system-assigned kind of command */
+int command_type(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(IERR);
+ }
+ return(pos->parse_kind);
+} /* end COMMAND_TYPE */
+
+/* 6/96 changed STRING to PSTRWC and pos to PSENTRY in following */
+/* GET_T returns command start tag */
+PSTRWC get_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->command_t);
+} /* end GET_T */
+
+
+/* GET_ET returns command end tag */
+PSTRWC get_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->command_et);
+} /* end GET_ET */
+
+
+/* GET_TAG_T returns param start tag for n'th req param */
+PSTRWC get_tag_t(pos,num)
+PSENTRY pos;
+int num;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ if (num < 1 || num > 9) { /* out of range */
+ yyerror("Tag number out of range");
+ return(NULL);
+ }
+ return(pos->param_t[num-1]);
+} /* end GET_TAG_T */
+
+
+/* GET_TAG_ET returns param end tag for n'th req param */
+PSTRWC get_tag_et(pos,num)
+PSENTRY pos;
+int num;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ if (num < 1 || num > 9) { /* out of range */
+ yyerror("Tag number out of range");
+ return(NULL);
+ }
+ return(pos->param_et[num-1]);
+} /* end GET_TAG_ET */
+
+
+/* GET_OPTTAG_T returns opt param start tag */
+PSTRWC get_opttag_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->opt_param_t);
+} /* end GET_OPTTAG_T */
+
+/* GET_OPTTAG_ET returns param end tag */
+PSTRWC get_opttag_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->opt_param_et);
+} /* end GET_OPTTAG_ET */
+
+
+/* GET_LEVEL returns sectioning level */
+int get_level(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(IERR);
+ }
+ return(pos->sectioning_level);
+} /* end GET_LEVEL */
+
+
+/* GET_ITEM_T returns item start tag */
+PSTRWC get_item_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_t[7]);
+} /* end GET_ITEM_T */
+
+
+/* GET_ITEM_ET returns item end tag */
+PSTRWC get_item_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_et[7]);
+} /* end GET_ITEM_ET */
+
+
+/* GET_ITEMOPT_T returns item optional param start tag */
+PSTRWC get_itemopt_t(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_t[8]);
+} /* end GET_ITEMOPT_T */
+
+
+/* GET_ITEMOPT_ET returns item optional param end tag */
+PSTRWC get_itemopt_et(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->param_et[8]);
+} /* end GET_ITEMOPT_ET */
+
+
+/* GET_USER_TYPE returns user's command type */
+int get_user_type(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(IERR);
+ }
+ return(pos->kind);
+} /* end GET_USER_TYPE */
+
+
+/* GET_SPECIAL_TOKEN returns special token */
+int get_special_token(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(OTHER);
+ }
+ return(pos->special_token);
+} /* end GET_SPECIAL_TOKEN */
+
+
+/* GET_COM_PRINT returns command print control */
+PSTRWC get_com_print(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->printing);
+} /* end GET_COM_PRINT */
+
+
+/* GET_PARAM_PRINT returns param print control */
+PSTRWC get_param_print(pos,num)
+PSENTRY pos;
+int num;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ if (num < 1 || num > 9) { /* out of range */
+ yyerror("Parameter number out of range");
+ return(NULL);
+ }
+ return(pos->print_param[num-1]);
+} /* end GET_PARAM_PRINT */
+
+
+/* GET_OPT_PRINT returns opt param print control */
+PSTRWC get_opt_print(pos)
+PSENTRY pos;
+{
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->print_opt[0]);
+} /* end GET_PARAM_PRINT */
+
+
+ /*---------------FILE INCLUSION-------------------*/
+
+/* INITIALISE_SENV initialises path searching */
+void initialise_senv()
+{
+ strcpy(sys_envname,"LTX2XTABLES"); /* environment variable name */
+ strcpy(path_sep," :;"); /* path seperators */
+ dir_cat = '/'; /* dir catenation char */
+ senv_debug = 0; /* debugging off */
+} /* end INITIALISE_SENV */
+
+
+/* INITIALISE_CT_FILES */
+void initialise_ct_files(tabnam)
+char tabnam[];
+{
+ ct_file_num = 0;
+ ct_fp_stack[ct_file_num] = filtabin;
+ ct_fn_stack[ct_file_num] = strsave(tabnam);
+ ct_ln_stack[ct_file_num] = 0;
+ fprintf(stdout, "\nReading command table file %s\n", tabnam);
+ fprintf(filerr, "\nReading command table file %s\n", tabnam);
+} /* end INITIALISE_CT_FILES */
+
+
+/* SET_CT_FILE opens new ct file */
+int set_ct_file(str)
+char str[];
+{
+ FILE *file;
+ char answer[MAX_TABLE_LINE];
+ char path[257];
+ int i;
+
+ if (ct_file_num >= MAX_CT_STACK - 1) { /* overflow */
+ table_error("FATAL ERROR: Attempting to open too many files");
+ exit(1);
+ }
+
+ strcpy(answer, str);
+ for (i = 1; i <= 4; i++) { /* 4 attempts to open a file */
+ if (searchenv(answer, sys_envname, path, path_sep, dir_cat, senv_debug)) {
+ file = fopen(path, "r");
+ if (file) { /* file is opened */
+ break;
+ }
+ }
+ if (i == 3) { /* last attempt failed */
+ fprintf(stdout, "\nLast attempt. Can't open file %s. I'm giving up.\n", answer);
+ exit(0);
+ }
+ fprintf(stdout, "\nCan't open file %s\n", answer);
+ fprintf(filerr, "\nCan't open file %s\n", answer);
+ fprintf(stdout, "Enter new file name, or I to ignore, or Q to quit\n: ");
+ fflush(stdout);
+ scanf("%s", answer);
+ if (strcmp("Q", answer) == 0 || strcmp("q", answer) == 0) {
+ exit(0);
+ }
+ else if (strcmp("I", answer) == 0 || strcmp("i", answer) == 0) {
+ return(FALSE);
+ }
+ }
+ /* file has been opened sucessfully */
+ ct_file_num++;
+ used_ct_file_stack = maxof(ct_file_num, used_ct_file_stack);
+ ct_fp_stack[ct_file_num] = file;
+ ct_fn_stack[ct_file_num] = strsave(path);
+ ct_ln_stack[ct_file_num] = 0;
+ fprintf(stdout, "\nReading command table file %s\n", path);
+ fprintf(filerr, "\nReading command table file %s\n", path);
+ return(TRUE);
+} /* end SET_CT_FILE */
+
+
+/* RESET_CT_FILE pops file stack */
+int reset_ct_file()
+{
+
+ if (ct_file_num < 0) { /* underflow */
+ table_error("Command table stack underflow");
+ return(EOF);
+ }
+ fclose(ct_fp_stack[ct_file_num]);
+ fprintf(stdout, "\n Closing command table file %s\n", ct_fn_stack[ct_file_num]);
+ fprintf(filerr, "\n Closing command table file %s\n", ct_fn_stack[ct_file_num]);
+ free(ct_fn_stack[ct_file_num]);
+ ct_fp_stack[ct_file_num] = NULL;
+ ct_fn_stack[ct_file_num] = NULL;
+ ct_ln_stack[ct_file_num] = 0;
+ ct_file_num--;
+ if (ct_file_num < 0) { /* empty stack, end of files */
+ return(EOF);
+ }
+ else {
+ return(ct_file_num);
+ }
+} /* end RESET_CT_FILE */
+
+
+/* GET_CT_FILEP returns file pointer */
+FILE *get_ct_filep()
+{
+ return(ct_fp_stack[ct_file_num]);
+} /* end GET_CT_FILEP */
+
+
+/* GET_CT_FILEN returns file name */
+STRING get_ct_filen()
+{
+ return(ct_fn_stack[ct_file_num]);
+} /* end GET_CT_FILEN */
+
+
+/* GET_CT_LINENUM returns line number */
+int get_ct_linenum()
+{
+ return(ct_ln_stack[ct_file_num]);
+} /* end GET_CT_LINENUM */
+
+
+/* INCR_CT_LINENUM increments line number */
+void incr_ct_linenum()
+{
+ ct_ln_stack[ct_file_num]++;
+} /* end INCR_CT_LINENUM */
+
+/* SET_CT_LINENUM sets command table line number */
+void set_ct_linenum(linenum)
+int linenum; /* the line number */
+{
+ ct_ln_stack[ct_file_num] = linenum;
+} /* end SET_CT_LINENUM */
+
+
+/*---------------------------------------------------------------*/
+/* 6/96 extras */
+
+/* CREATE_ST_RWC creates new struct */
+PSTRWC create_st_rwc()
+{
+ PSTRWC p;
+
+ if ((p = (PSTRWC ) malloc(sizeof(struct st_rwc))) != NULL) {
+ p->next = NULL;
+ p->cmd = -1;
+ p->pcenum = UNKNOWN_PRINT;
+ p->rwcode.bfnum = 0;
+ return(p);
+ }
+ yyerror("FATAL ERROR: No memory left for CREATE_ST_RWC");
+ exit(1);
+} /* end CREATE_ST_RWC */
+
+/* INIT_COMMON_PRINT initialises common print structures */
+void init_common_print()
+{
+ PSTRWC p;
+
+ /* default print */
+ p = create_st_rwc();
+ set_pc_enum(p, DEFAULT_PRINT);
+ p_default_print = p;
+
+ /* no print */
+ p = create_st_rwc();
+ set_pc_enum(p, NO_PRINT);
+ p_no_print = p;
+
+ /* print to buffer */
+ p = create_st_rwc();
+ set_pc_enum(p, TO_SYSBUF);
+ p_print_to_sysbuf = p;
+
+ /* print_underflow */
+ p = create_st_rwc();
+ set_pc_enum(p, PRINT_UNDERFLOW);
+ p_print_underflow = p;
+
+
+ /* unknown print */
+ p = create_st_rwc();
+ set_pc_enum(p, UNKNOWN_PRINT);
+ p_unknown_print = p;
+
+
+ /* print from buffer */
+ p = create_st_rwc();
+ set_pc_enum(p, SYSBUF);
+ p_print_from_sysbuf = p;
+
+ /* print null string */
+ p = create_st_rwc();
+ set_pc_enum(p, FIRST_STRING);
+ set_pcdata_name(p, "");
+ p_print_null = p;
+
+ /* reset print */
+ p = create_st_rwc();
+ set_pc_enum(p, RESET);
+ p_reset_print = p;
+
+ /* no op */
+ p = create_st_rwc();
+ set_pc_enum(p, NO_OP);
+ p_noop_print = p;
+
+} /* end INIT_COMMON_PRINT */
+
+/* CREATE_PRINT_TAG creates a tag print string structure */
+PSTRWC create_print_tag(a_str)
+ char a_str[]; /* a string */
+{
+ PSTRWC p;
+
+ p = create_st_rwc();
+ set_pc_enum(p, FIRST_STRING);
+ set_pcdata_name(p, a_str);
+ return(p);
+} /* end CREATE_PRINT_TAG */
+
+/* CREATE_PRINT_SOURCE creates a source print string structure */
+PSTRWC create_print_source(a_str)
+ char a_str[]; /* a string */
+{
+ PSTRWC p;
+
+ p = create_st_rwc();
+ set_pc_enum(p, SOURCE_STRING);
+ set_pcdata_name(p, a_str);
+ set_pc_cmd(p, SOURCE);
+ return(p);
+} /* end CREATE_PRINT_SOURCE */
+
+
+
+/* PARSE_PC parses print control and returns new structure */
+PSTRWC parse_pc(a_line)
+ char a_line[];
+{
+ char key_name[MAX_TABLE_LINE];
+ int key_enum;
+ int num;
+ char name[MAX_TABLE_LINE];
+ PSTRWC p;
+
+
+ /* get first keyword on line */
+ sscanf(a_line, "%s", key_name);
+ strtouc(key_name);
+ /* convert to enumeration type */
+ key_enum = printc_to_int(key_name);
+ /* switch to get all the data */
+ switch (key_enum) {
+ case DEFAULT_PRINT: { /* got it all */
+ return(p_default_print);
+ }
+ case NO_PRINT: { /* got it all */
+ return(p_no_print);
+ }
+ case TO_SYSBUF: { /* got it all */
+ return(p_print_to_sysbuf);
+ }
+ case PRINT_UNDERFLOW: { /* got it all */
+ return(p_print_underflow);
+ }
+ case UNKNOWN_PRINT: { /* got it all */
+ return(p_unknown_print);
+ }
+
+ case TO_BUFFER: { /* get buffer number */
+ sscanf(a_line, "%s %d", key_name, &num);
+ p = create_st_rwc();
+ set_pc_enum(p, TO_BUFFER);
+ set_pcdata_num(p, chk_bufnum(num));
+ used_wubuff[num]++;
+ return(p);
+ }
+
+ case TO_FILE: { /* get file */
+ sscanf(a_line, "%s %s", key_name, name);
+ p = create_st_rwc();
+ set_pc_enum(p, TO_FILE);
+ /* do file name stuff, adding it to the file array */
+ set_pcdata_name(p, chk_ufname(name));
+ return(p);
+ }
+
+ case SYSBUF: { /* got it all */
+ return(p_print_from_sysbuf);
+ }
+
+ case BUFFER: { /* get buffer number */
+ sscanf(a_line, "%s %d", key_name, &num);
+ p = create_st_rwc();
+ set_pc_enum(p, BUFFER);
+ set_pcdata_num(p, chk_bufnum(num));
+ used_rubuff[num]++;
+ return(p);
+ }
+
+ case FFILE: { /* get file */
+ sscanf(a_line, "%s %s", key_name, name);
+ p = create_st_rwc();
+ set_pc_enum(p, FFILE);
+ /* do file name stuff, adding it to the file array */
+ set_pcdata_name(p, chk_ufname(name));
+ return(p);
+ }
+
+ case FIRST_STRING: { /* get string */
+ return(p_unknown_print);
+ }
+
+ case RESET: { /* got it all */
+ return(p_reset_print);
+ }
+
+ case NO_OP: { /* got it all */
+ return(p_noop_print);
+ }
+
+ default: {
+ return(p_unknown_print);
+ }
+ }
+} /* end PARSE_PC */
+
+
+/* TPRINT_ST_RWC print out the st_rwc structure */
+void tprint_st_rwc(fout, prwc)
+FILE *fout;
+PSTRWC prwc;
+{
+
+ STRING str;
+ int kind;
+ STRING indent = " ";
+
+ if (prwc == NULL) { /* nothing to print */
+ return;
+ }
+
+ kind = get_pc_enum(prwc);
+ str = printc_to_string(kind);
+ switch (kind) {
+ case DEFAULT_PRINT: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case NO_PRINT: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case TO_SYSBUF: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case PRINT_UNDERFLOW: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case UNKNOWN_PRINT: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case TO_BUFFER: { /* write buffer number */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %d", get_pcdata_num(prwc));
+ return;
+ }
+ case TO_FILE: { /* write file id */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %s", get_pcdata_name(prwc));
+ return;
+ }
+ case SYSBUF: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ case BUFFER: { /* write buffer number */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %d", get_pcdata_num(prwc));
+ return;
+ }
+ case FFILE: { /* write file id */
+ fprintf(fout, "%s", str);
+ fprintf(fout, " %s", get_pcdata_name(prwc));
+ return;
+ }
+ case FIRST_STRING: { /* write the string only */
+ tprint_str(fout, get_pcdata_name(prwc));
+ return;
+ }
+ case SOURCE_STRING: { /* write the string only */
+ tprint_str(fout, get_pcdata_name(prwc));
+ return;
+ }
+ case RESET: { /* got it all */
+ fprintf(fout, "%s", str);
+ return;
+ }
+ default: { /* should not be here */
+ }
+ }
+} /* end TPRINT_ST_RWC */
+
+
+/* TPRINT_TAG prints tag data from table */
+void tprint_tag(fout, prwc)
+FILE *fout;
+PSTRWC prwc;
+{
+
+ PSTRWC ptr;
+ int kmd;
+ STRING indent = " ";
+
+ if (prwc == NULL) { /* nothing, so just do a new line */
+ fprintf(fout, "\n");
+ return;
+ }
+
+ ptr = prwc;
+ while (ptr != NULL) {
+ kmd = get_pc_cmd(ptr);
+ switch (kmd) { /* some are special, need to add command */
+ case SOURCE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(SOURCE));
+ tprint_st_rwc(fout, ptr);
+ break;
+ }
+ case STRINGG : {
+ fprintf(fout, "%s %s ", indent, key_to_string(STRINGG));
+ tprint_st_rwc(fout, ptr);
+ break;
+ }
+ case RESET_SYSBUF : {
+ fprintf(fout, "%s %s", indent, key_to_string(RESET_SYSBUF));
+ break;
+ }
+ case RESET_BUFFER : {
+ fprintf(fout, "%s %s ", indent, key_to_string(RESET_BUFFER));
+ fprintf(fout, "%d", get_pcdata_num(ptr));
+ break;
+ }
+ case RESET_FILE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(RESET_FILE));
+ fprintf(fout, "%s", get_pcdata_name(ptr));
+ break;
+ }
+ case SET_MODE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(SET_MODE));
+ fprintf(fout, "%s", get_mode_str(get_pcdata_num(ptr)));
+ break;
+ }
+ case RESET_MODE : {
+ fprintf(fout, "%s %s ", indent, key_to_string(RESET_MODE));
+ break;
+ }
+ case SWITCH_BACK : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_BACK));
+ break;
+ }
+ case SWITCH_TO_BUFFER : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_TO_BUFFER));
+ fprintf(fout, "%d", get_pcdata_num(ptr));
+ break;
+ }
+ case SWITCH_TO_FILE : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_TO_FILE));
+ fprintf(fout, "%s", get_pcdata_name(ptr));
+ break;
+ }
+ case SWITCH_TO_SYSBUF : {
+ fprintf(fout, "%s%s ", indent, key_to_string(SWITCH_TO_SYSBUF));
+ break;
+ }
+
+ default : {
+ tprint_st_rwc(fout, ptr);
+ break;
+ }
+ } /* end switch */
+ fprintf(fout, "\n");
+ ptr = ptr->next;
+ } /* end loop */
+} /* end TPRINT_TAG */
+
+
+/* GET_PC_ENUM returns the control code from printing data */
+int get_pc_enum(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(UNKNOWN_PRINT);
+ }
+ return(ptr->pcenum);
+
+} /* end GET_PC_ENUM */
+
+/* SET_PC_ENUM sets the control code for printing data */
+void set_pc_enum(ptr, cenum)
+PSTRWC ptr;
+int cenum;
+{
+ if (ptr != NULL) {
+ ptr->pcenum = cenum;
+ }
+ return;
+} /* end SET_PC_ENUM */
+
+
+/* GET_PCDATA_NUM returns the number code from printing data */
+int get_pcdata_num(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(0);
+ }
+ return(ptr->rwcode.bfnum);
+
+} /* end GET_PCDATA_NUM */
+
+/* SET_PCDATA_NUM sets the number code for printing data */
+void set_pcdata_num(ptr, num)
+PSTRWC ptr;
+int num;
+{
+ if (ptr != NULL) {
+ ptr->rwcode.bfnum = num;
+ }
+ return;
+} /* end SET_PCDATA_NUM */
+
+/* GET_PCDATA_NAME returns the string code from printing data */
+STRING get_pcdata_name(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(NULL);
+ }
+ return(ptr->rwcode.defstr);
+
+} /* end GET_PCDATA_NAME */
+
+/* SET_PCDATA_NAME sets the number code for printing data */
+void set_pcdata_name(ptr, str)
+PSTRWC ptr;
+STRING str;
+{
+ if (ptr != NULL) {
+ ptr->rwcode.defstr = str;
+ }
+ return;
+} /* end SET_PCDATA_NAME */
+
+/* GET_PC_CMD returns command name from print control */
+int get_pc_cmd(ptr)
+PSTRWC ptr;
+{
+ if (ptr == NULL) {
+ return(IERR);
+ }
+ return(ptr->cmd);
+} /* end GET_PC_CMD */
+
+
+/* SET_PC_CMD sets command name in print control */
+void set_pc_cmd(ptr, kmd)
+PSTRWC ptr;
+int kmd;
+{
+ if (ptr != NULL) {
+ ptr->cmd = kmd;
+ }
+ return;
+} /* end SET_PC_CMD */
+
+ /* next two added for code interp */
+/* SET_PC_CODE sets print control for compiled code */
+void set_pc_code(ptr, code_seg)
+PSTRWC ptr;
+ICT *code_seg;
+{
+
+ if (ptr == NULL) return;
+ set_pc_cmd(ptr, CODE);
+ ptr->rwcode.bytecode = code_seg;
+ return;
+} /* end SET_PC_CODE */
+
+/* GET_PC_CODE gets compiled code from print control */
+ICT *get_pc_code(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) return(NULL);
+ return(ptr->rwcode.bytecode);
+} /* end GET_PC_CODE */
+
+
+/* GET_NEXT_WRITE returns the next output instruction */
+PSTRWC get_next_write(ptr)
+PSTRWC ptr;
+{
+
+ if (ptr == NULL) {
+ return(NULL);
+ }
+ return(ptr->next);
+} /* end GET_NEXT_WRITE */
+
+
+/* APPEND_TO_WRITE adds the next output instruction */
+PSTRWC append_to_write(list, new)
+PSTRWC list;
+PSTRWC new;
+{
+
+ if (list != NULL) {
+ list->next = new;
+ }
+ return(new);
+
+} /* end APPEND_TO_WRITE */
+
+
+/* TAG_PRINT passes off tag strings to myprint for printing */
+void tag_print(ptr)
+PSTRWC ptr;
+{
+
+ char temp[MAX_UBUFF_LEN];
+ STRING fname;
+ int num;
+ FILE *fin;
+ int opt;
+ int kmd;
+
+ if (ptr == NULL) { /* nothing there */
+ return;
+ }
+ while (ptr != NULL) {
+ kmd = get_pc_cmd(ptr); /* do special command types first */
+ switch (kmd) {
+ case RESET_SYSBUF : { /* reset system buffer */
+ initialise_sysbuf();
+ break;
+ }
+ case RESET_BUFFER : { /* reset user buffer */
+ num = get_pcdata_num(ptr);
+ init_ubuff(num);
+ break;
+ }
+ case RESET_FILE : { /* reset file */
+ fname = get_pcdata_name(ptr);
+ init_ufile(fname);
+ break;
+ }
+ case SET_MODE : { /* set the mode */
+ num = get_pcdata_num(ptr);
+ push_mode(num);
+ break;
+ }
+ case RESET_MODE : { /* reset the mode */
+ reset_mode();
+ break;
+ }
+ /* 10/96 extensions */
+ case SWITCH_BACK : {
+ reset_print(); /* reset the print mode */
+ break;
+ }
+ case SWITCH_TO_BUFFER : {
+ set_print(ptr);
+ break;
+ }
+ case SWITCH_TO_FILE : {
+ set_print(ptr);
+ break;
+ }
+ case SWITCH_TO_SYSBUF : {
+ set_print(ptr);
+ break;
+ }
+ case CODE : { /* added for code interp */
+ exec_statements(get_pc_code(ptr)); /* execute code */
+ break;
+ }
+ default : { /* now "ordinary " commands */
+ opt = get_pc_enum(ptr);
+ switch (opt) {
+ case FIRST_STRING: { /* get the specified string */
+ myprint(get_pcdata_name(ptr));
+ break;
+ }
+ case STRINGG: {
+ myprint(get_pcdata_name(ptr));
+ break;
+ }
+ case SOURCE_STRING : {
+ myprint(get_pcdata_name(ptr));
+ break;
+ }
+ case SYSBUF: { /* get the system buffer */
+ myprint(buffer);
+ break;
+ }
+ case BUFFER: { /* get users buffer */
+ num = get_pcdata_num(ptr);
+ written_from_buff[num] = TRUE;
+ myprint(user_buffs[num]);
+ break;
+ }
+ case FFILE: { /* get file */
+ fname = get_pcdata_name(ptr);
+ fin = ufopenr(fname);
+ if (fin == NULL) {
+ warning_3s("In TAG_PRINT could not open file ", fname, " for reading.");
+ }
+ else {
+ temp[0] = SNUL;
+ while (fgets(temp, MAX_UBUFF_LEN - 2, fin) != NULL) {
+ myprint(temp);
+ temp[0] = SNUL;
+ } /* end loop */
+ ufclose(fname); /* close file */
+ }
+ break;
+ }
+ default: { /* should not be here */
+ sprintf(errstr,
+ "internal error: Illegal print option (%d %s) in TAG_PRINT",
+ opt, printc_to_string(opt));
+ yyerror(errstr);
+ break;
+ }
+ } /* end (opt) switch */
+ break;
+ } /* end kmd default */
+ } /* end (kmd) switch */
+ ptr = get_next_write(ptr);
+ } /* end while */
+
+} /* end TAG_PRINT */
+
+
+/* GET_FPOS given a name, returns position in file array */
+int get_fpos(str)
+STRING str;
+{
+ int i;
+
+ for (i = 0; i < used_files; i++) { /* search along array */
+ if (ufn[i] == str) { /* got it */
+ return(i);
+ }
+ }
+ /* should not be here, file not in array */
+ sprintf(errstr, "Unknown user file %s (list follows in error file)", str);
+ yyerror(errstr);
+ ufn[MAX_USER_FILES - 1] = str;
+ for (i = 0; i < used_files; i++) {
+ sprintf(errstr, "(%d) File %s\n", i, ufn[i]);
+ print_to_err(errstr);
+ }
+ return(MAX_USER_FILES - 1);
+} /* end GET_FPOS */
+
+
+/* UFOPENR function to open user file "name" for reading */
+FILE *ufopenr(name)
+STRING name;
+{
+ FILE *fil;
+ int i;
+
+ i = get_fpos(name);
+ /* 10/96 if already open then close it */
+ if (num_filep[i] > 0) {
+ ufclose(name);
+ }
+ sprintf(errstr, "Opening file %s number %d for reading\n", name, i);
+ print_to_err(errstr);
+ fil = fopen(name, "r");
+ if (fil == NULL) { /* can't open the file */
+ sprintf(errstr, "Cannot open file %s for reading", name);
+ yyerror(errstr);
+ ufp[i] = NULL;
+ }
+ else {
+ ufp[i] = fil; /* set it in the file array */
+ num_filep[i] = 0; /* 10/96 */
+ }
+ return(fil);
+} /* end UFOPENR */
+
+
+/* UFOPENW function to open user file "name" for writing */
+FILE *ufopenw(name)
+STRING name;
+{
+ FILE *fil;
+ int i;
+
+ i = get_fpos(name);
+ sprintf(errstr, "Opening file %s number %d for writing\n", name, i);
+ print_to_err(errstr);
+ fil = fopen(name, "w");
+ if (fil == NULL) { /* can't open the file */
+ sprintf(errstr, "Cannot open file %s for writing", name);
+ yyerror(errstr);
+ ufp[i] = NULL;
+ }
+ else {
+ ufp[i] = fil; /* set it in the file array */
+ }
+ return(fil);
+} /* end UFOPENW */
+
+
+/* UFCLOSE function to close user file "name" */
+int ufclose(name)
+STRING name;
+{
+ int i;
+ FILE *fil;
+
+ i = get_fpos(name);
+ sprintf(errstr, " Closing file %s numbered %d\n", name, i);
+ print_to_err(errstr);
+ fil = ufp[i];
+ num_filep[i] = 0; /* 10/96 set to closed */
+
+ i = fclose(fil);
+ if (i == EOF) { /* error in closing file */
+ sprintf(errstr, "Cannot close file %s", name);
+ yyerror(errstr);
+ }
+ return(i);
+} /* end UFCLOSE */
+
+
+/* WRITE_STATS writes statistics to error file */
+void write_stats(s)
+STRING s;
+{
+
+ int num;
+ int i;
+
+ print_to_err("\n STATISTICS");
+ print_to_err(s);
+ print_to_err("\n\n");
+
+ num = MAX_TABLE_ENTRIES;
+ used_table_entries = num_table_entries;
+ sprintf(errstr, "Used %d table entries out of %d (MAX_TABLE_ENTRIES)\n",
+ used_table_entries, num);
+ print_to_err(errstr);
+
+ num = MAX_TABLE_LINE;
+ sprintf(errstr, "Max table line %d characters out of %d (MAX_TABLE_LINE)\n",
+ used_table_line, num);
+ print_to_err(errstr);
+
+ num = MAX_USER_BUFFS;
+ sprintf(errstr, "Max number of user buffers %d (MAX_USER_BUFFS)\n",
+ num);
+ print_to_err(errstr);
+ print_to_err(" Written to buffers: ");
+ for (i = 0; i < MAX_USER_BUFFS; i++) {
+ if (used_wubuff[i] >= 0) {
+ sprintf(errstr,"%d ",i);
+ print_to_err(errstr);
+ }
+ }
+ print_to_err("\n Read from buffers: ");
+ for (i = 0; i < MAX_USER_BUFFS; i++) {
+ if (used_rubuff[i] > 0) {
+ sprintf(errstr,"%d ",i);
+ print_to_err(errstr);
+ }
+ }
+ print_to_err("\n");
+
+ num = MAX_UBUFF_LEN;
+ sprintf(errstr, "Max user buffer %d characters out of %d (MAX_UBUFF_LEN)\n",
+ used_ubuff_chars, num);
+ print_to_err(errstr);
+
+ num = MAX_BUFFER;
+ sprintf(errstr, "Used system buffer %d characters out of %d (MAX_BUFFER)\n",
+ used_sbuff_chars, num);
+ print_to_err(errstr);
+
+ num = MAX_USER_FILES;
+ sprintf(errstr, "Used %d user files out of %d (MAX_USER_FILES)\n",
+ used_files, num);
+ print_to_err(errstr);
+
+ num = EVERY_N_LINES;
+ sprintf(errstr, "Progress reported every %d (EVERY_N_LINES) lines\n",
+ num);
+ print_to_err(errstr);
+
+ num = CLAUSE_STACK_SIZE;
+ sprintf(errstr, "Max clause nesting depth %d out of %d (CLAUSE_STACK_SIZE)\n",
+ used_clause_stack, num);
+ print_to_err(errstr);
+
+ num = DEF_LIST_STACK_SIZE;
+ sprintf(errstr, "Max list nesting depth %d out of %d (DEF_LIST_STACK_SIZE)\n",
+ used_list_stack, num);
+ print_to_err(errstr);
+
+ num = MAX_PRINT_STACK;
+ sprintf(errstr, "Max print stack depth %d out of %d (MAX_PRINT_STACK)\n",
+ used_print_stack, num);
+ print_to_err(errstr);
+
+ num = MAX_CT_STACK;
+ sprintf(errstr, "Max command table stack depth %d out of %d (MAX_CT_STACK)\n",
+ used_ct_file_stack, num);
+ print_to_err(errstr);
+
+ /* interpreter statistics */
+ sprintf(errstr, "\nNumber of interpreter syntax errors: %d\n", isynt_error_count);
+ print_to_err(errstr);
+
+ sprintf(errstr, "Number of interpreter syntax warnings: %d\n", isynt_warn_count);
+ print_to_err(errstr);
+
+ sprintf(errstr, "Number of interpreter runtime errors: %d\n", irun_error_count);
+ print_to_err(errstr);
+
+ sprintf(errstr, "Number of interpreter runtime warnings: %d\n", irun_warn_count);
+ print_to_err(errstr);
+
+ return;
+} /* end WRITE_STATS */
+
+
+/* MAXOF returns the maximum of two integers */
+int maxof(n,m)
+int n;
+int m;
+{
+ if (n >= m) {
+ return(n);
+ }
+ return(m);
+} /* end MAXOF */
+
+
+/* GET_START_PC returns start pc struct */
+PSTRWC get_start_pc(pos)
+PSENTRY pos;
+{
+
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->start_pc);
+} /* end GET_START_PC */
+
+
+/* GET_END_PC returns end pc struct */
+PSTRWC get_end_pc(pos)
+PSENTRY pos;
+{
+
+ if (pos == NULL) { /* out of range */
+ return(NULL);
+ }
+ return(pos->end_pc);
+} /* end GET_START_PC */
+
+
+/* TPRINT_STR prints string from command table */
+void tprint_str(fout, str)
+FILE *fout;
+char str[];
+{
+ int i;
+ char c, k;
+
+ if (isempty(str)) { /* empty string */
+ return;
+ }
+
+ fputc('"', fout); /* write starting quote */
+ for (i = 0; (c = str[i]) != SNUL; i++) { /* loop over all characters */
+ if (iscntrl(c)) { /* treat controls specially */
+ fputc(escape_char, fout); /* write table escape char */
+ switch (c) {
+ case '\n' : {
+ k = newline_char;
+ break;
+ }
+ case '\t' : {
+ k = horizontal_tab_char;
+ break;
+ }
+ case '\v' : {
+ k = vertical_tab_char;
+ break;
+ }
+ case '\b' : {
+ k = backspace_char;
+ break;
+ }
+ case '\r' : {
+ k = carriage_return_char;
+ break;
+ }
+ case '\f' : {
+ k = formfeed_char;
+ break;
+ }
+ case '\a' : {
+ k = audible_alert_char;
+ break;
+ }
+ default : { /* should not be here */
+ k = escape_char;
+ break;
+ }
+ } /* end switch */
+ fputc(k, fout);
+ }
+ else { /* normal character for printing */
+ fputc(c, fout); /* DO HEX LATER */
+ }
+ } /* all charcters processed */
+ fputc('"', fout); /* add closing quote */
+ return;
+} /* end TPRINT_STR */
+
+
+
+/* LOOKUP_STRING returns position of string in an array of strings */
+int lookup_string(str, array, numstr)
+STRING str; /* string to search for */
+STRING array[]; /* array of strings */
+int numstr; /* number of strings in array */
+{
+ int low, mid, high, result;
+
+ low = 0;
+ high = numstr - 1;
+ while (low <= high) {
+ mid = (low + high)/2;
+ result = strcmp(str, array[mid]);
+ if (result < 0) { /* not in top half */
+ high = mid - 1;
+ }
+ else if (result > 0) { /* not in bottom half */
+ low = mid + 1;
+ }
+ else { /* found it */
+ return(mid);
+ }
+ }
+ return(-1); /* str not in array */
+} /* end LOOKUP_STRING */
+
+/* INIT_PRINT_CONTROL initialises print control stuff */
+void init_print_control()
+{
+
+ int n;
+
+ initialise_pc(); /* set default printing */
+
+ /* initialise buffers */
+ for (n = 0; n < MAX_USER_BUFFS; n++) {
+ num_ubuff[n] = 0;
+ used_wubuff[n] = -1;
+ used_rubuff[n] = 0;
+ written_from_buff[n] = FALSE;
+ initialise_string(user_buffs[n]);
+ }
+ /* initialise files */
+ for (n = 0; n < MAX_USER_FILES; n++) {
+ num_filep[n] = 0;
+ ufp[n] = NULL;
+ ufn[n] = NULL;
+ }
+ /* initialise modes */
+ for (n = 0; n < MAX_MODES; n++) {
+ mode_names[n] = NULL;
+ }
+ num_modes = 0; /* no modes defined */
+ top_mode = 0; /* empty mode stack */
+} /* end INIT_PRINT_CONTROL */
+
+/* PRINTC_TO_INT converts print control string to enum */
+int printc_to_int(s)
+STRING s;
+{
+ int pos;
+
+ pos = lookup_string(s, pc_array, max_pcstr);
+ if (pos == -1) { /* unknown string */
+ table_error("PRINT_CONTROL unrecognised");
+ return(UNKNOWN_PRINT);
+ }
+ return(pos);
+} /* end PRINTC_TO_INT */
+
+
+/* PRINTC_TO_STRING converts print control enum to a string */
+STRING printc_to_string(pos)
+int pos;
+{
+ if (pos >= 0 && pos < max_pcstr) {
+ return(pc_array[pos]);
+ }
+ table_error("PRINT_CONTROL out of range");
+ return(unk);
+} /* end PRINTC_TO_STRING */
+
+
+
+/* KEY_TO_INT converts a keyword string to an integer */
+int key_to_int(s)
+STRING s;
+{
+ int pos;
+
+ pos = lookup_string(s, key_array, max_keystr);
+ if (pos == -1) { /* unknown string */
+ table_error("KEYWORD unrecognised");
+ }
+ return(pos);
+} /* end KEY_TO_INT */
+
+
+/* KEY_TO_STRING converts a keyword integer to a string */
+STRING key_to_string(pos)
+int pos;
+{
+ if (pos >= 0 && pos < max_keystr) {
+ return(key_array[pos]);
+ }
+ table_error("KEYWORD out of range");
+ return(unk);
+} /* end KEY_TO_STRING */
+
+
+/* CHK_BUFNUM returns a valid user buffer number */
+int chk_bufnum(num)
+int num;
+{
+
+ if (num < 0 || num > MAX_USER_BUFFS) {
+ table_error("User buffer number out of range (I have set it to 0)");
+ num = 0;
+ }
+ return(num);
+} /* end CHK_BUFNUM */
+
+/* CHK_UFNAME checks the name of a user's file */
+STRING chk_ufname(name)
+char name[];
+{
+ int i;
+ STRING str;
+
+ for (i = 0; i < used_files; i++) { /* check existing names */
+ if (strcmp(name, ufn[i]) == 0) { /* already in array */
+ return(ufn[i]);
+ }
+ } /* not in array, so add it */
+ if (used_files == MAX_USER_FILES) { /* array overflow */
+ table_error("Too many file names (I have set this one to NULL)");
+ return(NULL);
+ }
+ str = strsave(name);
+ ufn[used_files] = str;
+ used_files++;
+ return(str);
+} /* end CHK_UFNAME */
+
+
+/* INIT_UBUFF initialises a user buffer */
+void init_ubuff(bufnum)
+int bufnum;
+{
+ int n;
+ n = chk_bufnum(bufnum);
+ initialise_string(user_buffs[n]);
+ return;
+} /* end INIT_UBUFF */
+
+/* INIT_UFILE initialises a user file */
+void init_ufile(name)
+STRING name;
+{
+ int i;
+ FILE *fil;
+
+ i = get_fpos(name);
+ fil = ufp[i];
+
+ if (fil == NULL) { /* unknown or closed file */
+ return;
+ }
+ fclose(fil); /* close it */
+ ufp[i] = NULL; /* and set to NULL in file array */
+ num_filep[i] = 0; /* 10/96 flag as closed */
+ return;
+} /* end INIT_UFILE */
+
+
+/* ADD_MODE checks mode name and adds to list if necessary */
+int add_mode(str)
+char str[];
+{
+
+ int i;
+
+ for (i = 0; i < num_modes; i++) {
+ if (strcmp(mode_names[i], str) == 0) { /* in the list */
+ return(i);
+ }
+ } /* not in the list */
+ if (num_modes >= MAX_MODES) { /* list is full */
+ table_error("Too many mode names");
+ return(-1);
+ }
+ mode_names[num_modes] = strsave(str);
+ num_modes++;
+ return(num_modes - 1);
+} /* end ADD_MODE */
+
+/* CHK_MODE_NUM checks if mode number is in range */
+int chk_mode_num(num)
+int num;
+{
+ if (num < 0 || num >= num_modes) { /* out of range */
+ sprintf(errstr,
+ "internal error: mode number %d out of range (0 to %d)",
+ num, (num_modes - 1) );
+ yyerror(errstr);
+ return(-1);
+ }
+ return(num);
+} /* end CHK_MODE_NUM */
+
+
+/* GET_MODE_STR returns string corresponding to a mode */
+STRING get_mode_str(pos)
+int pos;
+{
+ if (chk_mode_num(pos) < 0) { /* out of range */
+ return(NULL);
+ }
+ return(mode_names[pos]);
+} /* end GET_MODE_STR */
+
+
+/* ADD_TO_MODELIST adds a new mode into a list of modes */
+void add_to_modelist(last, new)
+PSENTRY last;
+PSENTRY new;
+{
+
+ if (last == NULL) {
+ return;
+ }
+ last->next_mode = new; /* attach new to last */
+ new->kind = last->kind;
+ new->command = last->command;
+ return;
+} /* end ADD_TO_MODELIST */
+
+
+/* SET_MODE_NAME sets the mode name in an entry */
+void set_mode_name(str, entry)
+char str[];
+PSENTRY entry;
+{
+ int pos;
+
+ pos = add_mode(str);
+ entry->mode = pos;
+ return;
+} /* end SET_MODE_NAME */
+
+/* GET_MODE gets the mode code from an entry */
+int get_mode(sym)
+PSENTRY sym;
+{
+
+ if (sym == NULL) {
+ return(IERR);
+ }
+ return(sym->mode);
+} /* end GET_MODE */
+
+
+/* GET_NEXT_MODE gets the next mode from an entry */
+PSENTRY get_next_mode(sym)
+PSENTRY sym;
+{
+
+ if (sym == NULL) {
+ return(NULL);
+ }
+ return(sym->next_mode);
+} /* end GET_NEXT_MODE */
+
+
+/* ISEMPTY returns TRUE if string is empty */
+int isempty(str)
+char str[];
+{
+ if (str == NULL) {
+ return(TRUE);
+ }
+ if (str[0] == SNUL) {
+ return(TRUE);
+ }
+ return(FALSE);
+} /* end ISEMPTY */
+
+
+/* PUSH_MODE pushes mode onto the stack */
+void push_mode(id)
+int id;
+{
+
+ if (top_mode >= MAX_MODE_STACK) { /* overflow */
+ yyerror("Something is wrong: mode stack overflow when pushing");
+ return;
+ }
+ mode_stack[top_mode] = id;
+ top_mode++;
+ return;
+} /* end PUSH_MODE */
+
+
+/* POP_MODE returns top of mode stack and pops it */
+int pop_mode()
+{
+
+ if (top_mode <= 0) { /* underflow */
+ yyerror("Something is wrong: mode stack underflow when popping");
+ top_mode = 0;
+ return(IERR);
+ }
+ top_mode--;
+ return(mode_stack[top_mode]);
+} /* end POP_MODE */
+
+
+/* GET_CURRENT_MODE returns the current mode */
+int get_current_mode()
+{
+
+ if (top_mode <= 0) { /* underflow, but its OK */
+ return(IERR);
+ }
+ return(mode_stack[top_mode - 1]);
+} /* end GET_CURRENT_MODE */
+
+/* RESET_MODE resets the current mode */
+int reset_mode()
+{
+ return(pop_mode());
+} /* end RESET_MODE */
+
+
+/* GET_MODE_SYM returns the sym entry for the current mode */
+PSENTRY get_mode_sym(pos)
+int pos; /* position in command table */
+{
+
+ PSENTRY start = symbol_table[pos]; /* default mode defn */
+ int cur_mode = get_current_mode();
+ PSENTRY next;
+
+ if (cur_mode == IERR) { /* unknown or default mode */
+ return(start);
+ }
+ if (get_mode(start) == cur_mode) { /* modes match */
+ return(start);
+ }
+ next = get_next_mode(start); /* look for next in the list */
+ while (next != NULL) {
+ if (get_mode(next) == cur_mode) { /* modes match */
+ return(next);
+ }
+ next = get_next_mode(next); /* repeat */
+ } /* no mode match, return non-mode entry */
+ return(start);
+} /* end GET_MODE_SYM */
+
diff --git a/support/ltx2x/l2xlib.h b/support/ltx2x/l2xlib.h
new file mode 100644
index 0000000000..21c5312c59
--- /dev/null
+++ b/support/ltx2x/l2xlib.h
@@ -0,0 +1,155 @@
+/* l2xlib.h Header for support routines for l2x LaTeX to X translator */
+
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+/* extern char *STRING; A pointer-to-char */
+/* extern STRING *PTRADR; A pointer-to-pointer-to-char */
+
+extern FILE *filerr;
+extern FILE *yyin;
+extern FILE *filerr;
+extern FILE *yyout;
+
+extern int MIN_GRAMM_SPECIAL;
+extern int MIN_CODE_SPECIAL;
+
+extern int LDEBUG;
+extern int YDEBUG;
+
+extern int num_errors;
+extern int lineno;
+extern char linebuf[];
+extern int linlen;
+
+extern int leave_comments;
+extern int collapse_ws;
+extern int pretty_print;
+
+extern int darray[];
+
+extern int no_print;
+extern int print_to_buffer;
+
+extern PSTRWC clause_str_stack[];
+extern int base_level;
+extern int current_level;
+extern int new_level;
+
+extern int LIST_STACK_SIZE;
+extern int list_level;
+extern int num_items[];
+extern PSTRWC list_str_stack[];
+extern PSTRWC list_item_start[];
+extern PSTRWC list_descitemp_start[];
+extern PSTRWC list_descitemp_end[];
+extern void set_list_stack();
+
+extern char *strsave();
+extern void myprint();
+extern void verbatim_print();
+extern void set_clause_stack();
+extern void close_doc_divs();
+extern void close_down();
+extern void yyerror();
+extern void warning();
+extern void catl();
+extern void do_newline();
+extern void initialise_sysbuf();
+extern void print_sysbuf();
+extern void copy_sysbuf();
+extern void initialise_string();
+
+ /* extra stuff for l2x */
+
+/* extern struct st_entry; */
+extern struct st_entry *symbol_table[];
+extern int num_table_entries;
+
+extern char env_name[];
+extern int DONT_CARE;
+extern STRING dont_care_str;
+
+/* extern struct PSTRWC; */
+
+extern int pos_bdoc;
+extern int pos_edoc;
+extern int pos_bvbm;
+extern int pos_evbm;
+extern int pos_bv;
+extern int pos_ev;
+extern int pos_oc;
+extern int pos_ob;
+extern int pos_oe;
+extern int pos_lbrace;
+extern int pos_rbrace;
+extern int pos_para;
+extern int pos_bdol;
+extern int pos_edol;
+extern int pos_bss;
+
+/* extern enum sect_level_enum; */
+extern int lookup_entry();
+extern void print_to_err();
+extern void print_debug_1s();
+extern void print_debug_2s();
+extern void print_debug_undef();
+extern int command_type();
+extern int get_user_type();
+extern int get_special_token();
+extern PSTRWC get_t();
+extern PSTRWC get_et();
+extern PSTRWC get_tag_t();
+extern PSTRWC get_tag_et();
+extern PSTRWC get_opttag_t();
+extern PSTRWC get_opttag_et();
+extern int get_level();
+extern PSTRWC get_item_t();
+extern PSTRWC get_item_et();
+extern PSTRWC get_itemopt_t();
+extern PSTRWC get_itemopt_et();
+extern void warning_3s();
+extern PSTRWC get_com_print();
+extern PSTRWC get_param_print();
+extern PSTRWC get_opt_print();
+
+/* ------------------ 6/96 additions --------------------- */
+extern void tag_print();
+extern int get_pc_enum();
+extern PSENTRY get_mode_sym(); /* gets sym entry for command & current mode */
+extern int bverb; /* TRUE if starting begin{verbatim} */
+
+extern int in_noop; /* TRUE if procesing a no op */
+extern int start_noop; /* TRUE if starting a no op */
+
+
+extern void set_print();
+extern void reset_print();
+
+
+
+extern void tdebug_str_int();
+extern void print_end_item();
+extern void get_env_name();
+extern PSTRWC get_start_pc();
+extern PSTRWC get_end_pc();
+
+
+ /* pointers to fixed, predefined print control structs */
+extern PSTRWC p_default_print; /* default printing i.e., DEFAULT_PRINT */
+extern PSTRWC p_no_print; /* no printing i.e., NO_PRINT */
+extern PSTRWC p_print_to_sysbuf; /* print to system buffer i.e., TO_SYSBUF */
+extern PSTRWC p_print_underflow; /* underflow i.e., PRINT_UNDERFLOW */
+extern PSTRWC p_unknown_print; /* unknown print i.e., UNKNOWN_PRINT */
+extern PSTRWC p_print_from_sysbuf; /* print from system buffer i.e., SYSBUF */
+extern PSTRWC p_print_null; /* print null string i.e., */
+extern PSTRWC p_reset_print; /* reset printing i.e., RESET */
+extern PSTRWC p_noop_print; /* no-op i.e., NO_OP */
diff --git a/support/ltx2x/l2xlibtc.h b/support/ltx2x/l2xlibtc.h
new file mode 100644
index 0000000000..9ad5024002
--- /dev/null
+++ b/support/ltx2x/l2xlibtc.h
@@ -0,0 +1,153 @@
+/* l2xlibtc.h token codes and strings */
+
+ /* command table commands and strings in alphabetical string order */
+kwtc(AUDIBLE_ALERT_CHAR, "AUDIBLE_ALERT_CHAR=")
+kwtc(BACKSPACE_CHAR, "BACKSPACE_CHAR=")
+kwtc(CA, "C=")
+kwtc(CARRIAGE_RETURN_CHAR, "CARRIAGE_RETURN_CHAR")
+kwtc(CODE, "CODE")
+kwtc(CODE_SETUP, "CODE_SETUP=")
+kwtc(COMMENT, "COMMENT=")
+kwtc(CONTINUE, "CONTINUE=")
+kwtc(END_CODE, "END_CODE:")
+kwtc(END_CTFILE, "END_CTFILE=")
+kwtc(END_ITEM, "END_ITEM=")
+kwtc(END_ITEM_PARAM, "END_ITEM_PARAM=")
+kwtc(END_MODE, "END_MODE")
+kwtc(END_OPT, "END_OPT=")
+kwtc(END_TAG, "END_TAG=")
+kwtc(END_TAG_1, "END_TAG_1=")
+kwtc(END_TAG_2, "END_TAG_2=")
+kwtc(END_TAG_3, "END_TAG_3=")
+kwtc(END_TAG_4, "END_TAG_4=")
+kwtc(END_TAG_5, "END_TAG_5=")
+kwtc(END_TAG_6, "END_TAG_6=")
+kwtc(END_TAG_7, "END_TAG_7=")
+kwtc(END_TAG_8, "END_TAG_8=")
+kwtc(END_TAG_9, "END_TAG_9=")
+kwtc(END_TYPE, "END_TYPE")
+kwtc(ESCAPE_CHAR, "ESCAPE_CHAR=")
+kwtc(FORMFEED_CHAR, "FORMFEED_CHAR=")
+kwtc(HEX_CHAR, "HEX_CHAR=")
+kwtc(HORIZONTAL_TAB_CHAR, "HORIZONTAL_TAB_CHAR=")
+kwtc(INCLUDE, "INCLUDE=")
+kwtc(IN_MODE, "IN_MODE=")
+kwtc(NAMEK, "NAME=")
+kwtc(NEWLINE_CHAR, "NEWLINE_CHAR=")
+kwtc(OPT_PARAM, "OPT_PARAM=")
+kwtc(PC_AT_END, "PC_AT_END=")
+kwtc(PC_AT_START, "PC_AT_START=")
+kwtc(PRINT_CONTROL, "PRINT_CONTROL=")
+kwtc(PRINT_OPT, "PRINT_OPT=")
+kwtc(PRINT_P1, "PRINT_P1=")
+kwtc(PRINT_P2, "PRINT_P2=")
+kwtc(PRINT_P3, "PRINT_P3=")
+kwtc(PRINT_P4, "PRINT_P4=")
+kwtc(PRINT_P5, "PRINT_P5=")
+kwtc(PRINT_P6, "PRINT_P6=")
+kwtc(PRINT_P7, "PRINT_P7=")
+kwtc(PRINT_P8, "PRINT_P8=")
+kwtc(PRINT_P9, "PRINT_P9=")
+kwtc(REQPARAMS, "REQPARAMS=")
+kwtc(RESET_BUFFER, "RESET_BUFFER:")
+kwtc(RESET_FILE, "RESET_FILE:")
+kwtc(RESET_MODE, "RESET_MODE:")
+kwtc(RESET_SYSBUF, "RESET_SYSBUF:")
+kwtc(SECTIONING_LEVEL, "SECTIONING_LEVEL=")
+kwtc(SET_MODE, "SET_MODE:")
+kwtc(SOURCE, "SOURCE:")
+kwtc(SPECIAL_TOKEN, "SPECIAL_TOKEN=")
+kwtc(START_ITEM, "START_ITEM=")
+kwtc(START_ITEM_PARAM, "START_ITEM_PARAM=")
+kwtc(START_OPT, "START_OPT=")
+kwtc(START_TAG, "START_TAG=")
+kwtc(START_TAG_1, "START_TAG_1=")
+kwtc(START_TAG_2, "START_TAG_2=")
+kwtc(START_TAG_3, "START_TAG_3=")
+kwtc(START_TAG_4, "START_TAG_4=")
+kwtc(START_TAG_5, "START_TAG_5=")
+kwtc(START_TAG_6, "START_TAG_6=")
+kwtc(START_TAG_7, "START_TAG_7=")
+kwtc(START_TAG_8, "START_TAG_8=")
+kwtc(START_TAG_9, "START_TAG_9=")
+kwtc(STRINGG, "STRING:")
+kwtc(SWITCH_BACK, "SWITCH_BACK:")
+kwtc(SWITCH_TO_BUFFER, "SWITCH_TO_BUFFER:")
+kwtc(SWITCH_TO_FILE, "SWITCH_TO_FILE:")
+kwtc(SWITCH_TO_SYSBUF, "SWITCH_TO_SYSBUF:")
+kwtc(TYPE, "TYPE=")
+kwtc(VERTICAL_TAB_CHAR, "VERTICAL_TAB_CHAR=")
+kwtc(MAX_KEYSTR, "ZZZZZZZZZZZZZZZ") /* this must be last!!! */
+
+ /* LaTeX command type enums and strings in alphabetical string order */
+lctc(BEGIN_DOCUMENT, "BEGIN_DOCUMENT")
+lctc(BEGIN_DOLLAR, "BEGIN_DOLLAR")
+lctc(BEGIN_ENV, "BEGIN_ENV")
+lctc(BEGIN_LIST_ENV, "BEGIN_LIST_ENV")
+lctc(BEGIN_PICTURE_CC, "BEGIN_PICTURE_CC")
+lctc(BEGIN_VENV, "BEGIN_VENV")
+lctc(BEGIN_VERB, "BEGIN_VERB")
+lctc(BEGIN_VERBATIM, "BEGIN_VERBATIM")
+lctc(CHAR_COMMAND, "CHAR_COMMAND")
+lctc(COMMAND, "COMMAND")
+lctc(COMMAND_OOP, "COMMAND_OOP")
+lctc(COMMAND_OOOPP, "COMMAND_OOOPP")
+lctc(COMMAND_OPO, "COMMAND_OPO")
+lctc(COMMAND_POOOP, "COMMAND_POOOP")
+lctc(COMMAND_POOP, "COMMAND_POOP")
+lctc(COMMAND_POOPP, "COMMAND_POOPP")
+lctc(END_DOCUMENT, "END_DOCUMENT")
+lctc(END_DOLLAR, "END_DOLLAR")
+lctc(END_ENV, "END_ENV")
+lctc(END_LIST_ENV, "END_LIST_ENV")
+lctc(END_PICTURE, "END_PICTURE")
+lctc(END_VENV, "END_VENV")
+lctc(END_VERB, "END_VERB")
+lctc(END_VERBATIM, "END_VERBATIM")
+lctc(LBRACE, "LBRACE")
+lctc(OTHER_BEGIN, "OTHER_BEGIN")
+lctc(OTHER_COMMAND, "OTHER_COMMAND")
+lctc(OTHER_END, "OTHER_END")
+lctc(PARAGRAPH, "PARAGRAPH")
+lctc(PICTURE_CCPP, "PICTURE_CCPP")
+lctc(PICTURE_CO, "PICTURE_CO")
+lctc(PICTURE_COP, "PICTURE_COP")
+lctc(PICTURE_CP, "PICTURE_CP")
+lctc(PICTURE_OCC, "PICTURE_OCC")
+lctc(PICTURE_OCCC, "PICTURE_OCCC")
+lctc(PICTURE_OCO, "PICTURE_OCO")
+lctc(PICTURE_PCOP, "PICTURE_PCOP")
+lctc(RBRACE, "RBRACE")
+lctc(SECTIONING, "SECTIONING")
+lctc(SLASH_SPACE, "SLASH_SPACE")
+lctc(SPECIAL, "SPECIAL")
+lctc(SPECIAL_BEGIN_ENV, "SPECIAL_BEGIN_ENV")
+lctc(SPECIAL_BEGIN_LIST, "SPECIAL_BEGIN_LIST")
+lctc(SPECIAL_COMMAND, "SPECIAL_COMMAND")
+lctc(SPECIAL_END_ENV, "SPECIAL_END_ENV")
+lctc(SPECIAL_END_LIST, "SPECIAL_END_LIST")
+lctc(SPECIAL_SECTIONING, "SPECIAL_SECTIONING")
+lctc(TEX_CHAR, "TEX_CHAR")
+lctc(UNKNOWN_CTYPE, "UNKNOWN_CTYPE")
+lctc(VCOMMAND, "VCOMMAND")
+lctc(NUM_CTIDS, "ZZZZZZZZZZZZZ") /* this must be last!!! */
+
+
+ /* print control enums and strings in alphabetical string order */
+pctc(BUFFER, "BUFFER")
+pctc(DEFAULT_PRINT, "DEFAULT_PRINT")
+pctc(FFILE, "FILE")
+pctc(FIRST_STRING, "FIRST_STRING")
+pctc(MODE, "MODE")
+pctc(NO_OP, "NO_OP")
+pctc(NO_PRINT, "NO_PRINT")
+pctc(PRINT_UNDERFLOW, "PRINT_UNDERFLOW")
+pctc(RESET, "RESET")
+pctc(SOURCE_STRING, "SOURCE_STRING")
+pctc(SYSBUF, "SYSBUF")
+pctc(TO_BUFFER, "TO_BUFFER")
+pctc(TO_FILE, "TO_FILE")
+pctc(TO_SYSBUF, "TO_SYSBUF")
+pctc(UNKNOWN_PRINT, "UNKNOWN_PRINT")
+pctc(MAX_PCSTR, "ZZZZZZZZZZZZ") /* this must be last!!!!!!!! */
+
diff --git a/support/ltx2x/l2xusrlb.c b/support/ltx2x/l2xusrlb.c
new file mode 100644
index 0000000000..c4d2b98bc3
--- /dev/null
+++ b/support/ltx2x/l2xusrlb.c
@@ -0,0 +1,290 @@
+/* l2xusrlb.c user-defined support functions for l2x actions */
+/* Written by Peter Wilson (Catholic University and NIST) */
+
+/* Development of this software was funded by the United States Government,
+ * and is not subject to copyright.
+ */
+
+
+#include <stdio.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xytab.h" /* parser communication */
+#include "l2xlib.h" /* l2x system library functions */
+#include "l2xacts.h" /* l2x standard actions */
+
+/* lexer/parser communication */
+extern int opt_param;
+
+/* In general, actions are specified via case statements
+ * in the special_ functions at the end of this file. The
+ * special actions must be provided by the extender.
+ */
+
+/* The system special_ functions */
+void special_start_with_req();
+void special_action_p_p1();
+void special_action_last_p();
+void special_start_with_opt();
+void special_action_opt_first();
+void special_action_p_opt();
+void special_action_last_opt();
+void special_action_no_param();
+
+/* extender-provided functions */
+void prwboiler1();
+void prwboiler2();
+void prwboiler3();
+void codespecial_start();
+void codespecial_p1();
+void codespecial_end();
+
+
+
+ /* FUNCTIONS, ETC. TO BE PROVIDED BY THE EXTENDER */
+
+ /* demonstration string definition */
+STRING boiler_string_3 = "\nin the middle of it.\n\n";
+
+ /* demonstration functions */
+
+char codebuf[80]; /* a string buffer */
+
+/* PRWBOILER1 print some demonstration boilerplate */
+void prwboiler1()
+{
+ myprint("\nSome boilerplate text with ");
+} /* end PRWBOILER1 */
+
+/* PRWBOILER2 print some demonstration boilerplate */
+void prwboiler2()
+{
+ myprint("\nin the middle. Now there is\n");
+ myprint("some more boilerplate with ");
+} /* end PRWBOILER2 */
+
+/* PRWBOILER3 yet more demonstration boilerplate */
+void prwboiler3()
+{
+ myprint(boiler_string_3);
+} /* end PRWBOILER1 */
+
+/* CODESPECIAL_START actions for start of CODEspecial command */
+void codespecial_start(pos)
+PSENTRY pos; /* symbol entry */
+{
+ start_section(pos); /* do start of sectioning */
+ tag_print(get_t(pos)); /* print start tag */
+} /* end CODESPECIAL_START */
+
+
+/* CODESPECIAL_P1 actions at stast of CODEspecial param 1 */
+void codespecial_p1(pos)
+PSENTRY pos; /* symbol entry */
+{
+ tag_print(get_tag_t(pos,1)); /* print 1st param start tag */
+ initialise_sysbuf(); /* clear system string buffer */
+ set_print(p_print_to_sysbuf); /* put param text into system buffer */
+} /* end CODESPECIAL_P1 */
+
+/* CODESPECIAL_END actions at end of CODEspecial command */
+void codespecial_end(pos)
+PSENTRY pos; /* symbol entry */
+{
+ initialise_string(codebuf); /* clear this string buffer */
+ copy_sysbuf(codebuf); /* copy system buffer into this buffer */
+ reset_print(); /* normal printing */
+ prwboiler1(); /* print some boilerplate */
+ print_sysbuf(); /* print system buffer */
+ prwboiler2(); /* print more boilerplate */
+ myprint(codebuf); /* print this buffer */
+ prwboiler3(); /* print yet more boilerplate */
+ start_list(pos); /* start a list environment */
+} /* end CODESPECIAL_END */
+
+
+
+/*==================================================================*/
+ /* SYSTEM SPECIAL_ FUNCTIONS FOR INCORPORATING EXTENDER */
+ /* SPECIFIED CASE STATEMENTS FOR USER-DEFINED SPECIAL COMMANDS */
+
+
+/* SPECIAL_START_WITH_REQ special action at start of command with req param */
+void special_start_with_req(pos)
+PSENTRY pos; /* symbol entry */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_req) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_REQ */
+
+
+/* SPECIAL_ACTION_P_P1 special action between p'th and (p+1)'th req params */
+void special_action_p_p1(pos,p)
+PSENTRY pos; /* symbol entry */
+int p; /* number of p'th req param */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_action_p_p1) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_ACTION_P_P1 */
+
+
+/* SPECIAL_ACTION_LAST_P special action after last req param */
+void special_action_last_p(pos,p)
+PSENTRY pos; /* symbol entry */
+int p; /* number of last req param */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ if (p == 1) { /* has only 1 req param */
+ codespecial_end(pos);
+ }
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_action_last_p) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_ACTION_LAST_P */
+
+
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+PSENTRY pos; /* symbol entry */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ codespecial_start(pos);
+ default_start_with_opt(pos);
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+
+
+/* SPECIAL_ACTION_OPT_FIRST special action between opt and 1st param */
+void special_action_opt_first(pos)
+PSENTRY pos; /* symbol entry */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ default_end_start_opt(pos);
+ codespecial_p1(pos);
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_action_opt_first) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_ACTION_OPT_FIRST */
+
+
+/* SPECIAL_ACTION_P_OPT special action between param p and opt */
+void special_action_p_opt(pos,p)
+PSENTRY pos; /* symbol entry */
+int p; /* number of p'th req param */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_action_p_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_ACTION_P_OPT */
+
+
+/* SPECIAL_ACTION_LAST_OPT special action after last opt param */
+void special_action_last_opt(pos)
+PSENTRY pos; /* symbol entry */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_action_last_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_ACTION_LAST_OPT */
+
+
+/* SPECIAL_ACTION_NO_PARAM special action for command with no params */
+void special_action_no_param(pos)
+PSENTRY pos; /* symbol entry */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_action_no_param) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_ACTION_NO_PARAM */
+
diff --git a/support/ltx2x/l2xusrlb.h b/support/ltx2x/l2xusrlb.h
new file mode 100644
index 0000000000..cff86e79aa
--- /dev/null
+++ b/support/ltx2x/l2xusrlb.h
@@ -0,0 +1,22 @@
+/* l2xusrlb.h .h file for l2xusrlb.c */
+
+extern void special_start_with_req();
+extern void special_action_p_p1();
+extern void special_action_last_p();
+extern void special_start_with_opt();
+extern void special_action_opt_first();
+extern void special_action_p_opt();
+extern void special_action_last_opt();
+extern void special_action_no_param();
+
+ /* demonstration functions */
+
+extern void prwboiler1();
+extern void prwboiler2();
+extern void prwboiler3();
+
+ /* add further stuff below as l2xusrlb.c is modified */
+
+
+
+
diff --git a/support/ltx2x/l2xytab.c b/support/ltx2x/l2xytab.c
new file mode 100644
index 0000000000..f142a3d050
--- /dev/null
+++ b/support/ltx2x/l2xytab.c
@@ -0,0 +1,6405 @@
+
+/* A Bison parser, made from l2x.y */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define END_OF_FILE 258
+#define TEX_CHAR 259
+#define CHAR_COMMAND 260
+#define BEGIN_DOCUMENT 261
+#define END_DOCUMENT 262
+#define BEGIN_VERBATIM 263
+#define END_VERBATIM 264
+#define BEGIN_VERB 265
+#define END_VERB 266
+#define BEGIN_DOLLAR 267
+#define END_DOLLAR 268
+#define COMMAND 269
+#define COMMAND_OPT 270
+#define COMMAND_1 271
+#define COMMAND_2 272
+#define COMMAND_3 273
+#define COMMAND_4 274
+#define COMMAND_5 275
+#define COMMAND_6 276
+#define COMMAND_7 277
+#define COMMAND_8 278
+#define COMMAND_9 279
+#define COMMAND_1_OPT 280
+#define COMMAND_2_OPT 281
+#define COMMAND_3_OPT 282
+#define COMMAND_4_OPT 283
+#define COMMAND_5_OPT 284
+#define COMMAND_6_OPT 285
+#define COMMAND_7_OPT 286
+#define COMMAND_8_OPT 287
+#define BEGIN_ENV 288
+#define END_ENV 289
+#define BEGIN_LIST_ENV 290
+#define END_LIST_ENV 291
+#define SECTIONING 292
+#define BEGIN_PICTURE_CC 293
+#define END_PICTURE 294
+#define PICTURE_CCPP 295
+#define PICTURE_CO 296
+#define PICTURE_COP 297
+#define PICTURE_CP 298
+#define PICTURE_OCC 299
+#define PICTURE_OCCC 300
+#define PICTURE_OCO 301
+#define PICTURE_PCOP 302
+#define SPECIAL 303
+#define SPECIAL_COMMAND 304
+#define SPECIAL_BEGIN_ENV 305
+#define SPECIAL_END_ENV 306
+#define SPECIAL_BEGIN_LIST 307
+#define SPECIAL_END_LIST 308
+#define SPECIAL_SECTIONING 309
+#define BEGIN_VENV 310
+#define END_VENV 311
+#define VCOMMAND 312
+#define COMMAND_OOP 313
+#define COMMAND_OOOPP 314
+#define COMMAND_OPO 315
+#define COMMAND_POOOP 316
+#define COMMAND_POOP 317
+#define COMMAND_POOPP 318
+#define OTHER_COMMAND 319
+#define OTHER_BEGIN 320
+#define OTHER_END 321
+#define PRINT_CONTROLLED_COMMAND 322
+#define NAME 323
+#define INTEGER 324
+#define REAL 325
+#define OTHER 326
+#define ITEM 327
+#define ITEM_AND_BRAK 328
+#define END_ITEM_BRAK 329
+#define LBRACE 330
+#define RBRACE 331
+#define PARAGRAPH 332
+#define SLASH_SPACE 333
+#define LBRAK 334
+#define RBRAK 335
+#define COMMA 336
+#define LPAREN 337
+#define RPAREN 338
+#define START_ANOPT 339
+#define START_COORD 340
+#define START_ALLOPT 341
+#define END_ANOPT 342
+#define END_COORD 343
+#define END_ALLOPT 344
+#define GRAMMSPECIAL 32767
+
+#line 1 "l2x.y"
+
+/*
+ * l2x.y A (bison) parser to convert LaTeX source to X
+ * Written by Peter Wilson (Catholic University and NIST)
+ * Version 0.2, January 1995
+ * revised 6/96 replacing myprint(tag) by tag_print(tag)
+ */
+
+/* Development of this software was funded by the United States Government,
+ * and is not subject to copyright.
+ */
+
+/****************************************************************************/
+/* WARNING: This file is intended to be processed by bison. If it is so */
+/* processed, then the resulting output is subject to the Free */
+/* Software Foundation GNU "copyleft" software license. */
+/* A copy of this license can be obtained by writing to: */
+/* Free Software Foundation, Inc. */
+/* 675 Massachusetts Avenue */
+/* Cambridge, MA 02139 */
+/* +1 (617) 876-3296 */
+/****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+#ifndef L2XCOM_H
+#include "l2xcom.h"
+#endif
+#include "l2xacts.h" /* system provided action functions */
+#include "l2xusrlb.h" /* user defined action functions, etc */
+#include "l2xlib.h" /* functions and global variables */
+
+
+ /* lexer communication */
+int opt_param = FALSE;
+int all_opt = FALSE;
+int opt_coord = FALSE;
+
+ /* parser variables */
+int yacresult;
+int yackind;
+PSENTRY sym;
+char grammbuf[80]; /* for example grammar-based special */
+
+
+#line 51 "l2x.y"
+typedef union {
+ char *string; /* string buffer */
+ /* int pos; command table position */
+ PSENTRY pos; /* pointer to sym entry */
+} YYSTYPE;
+
+#ifndef YYLTYPE
+typedef
+ struct yyltype
+ {
+ int timestamp;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ char *text;
+ }
+ yyltype;
+
+#define YYLTYPE yyltype
+#endif
+
+#include <stdio.h>
+
+#ifndef __STDC__
+#define const
+#endif
+
+
+
+#define YYFINAL 480
+#define YYFLAG -32768
+#define YYNTBASE 91
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 32767 ? yytranslate[x] : 322)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 90
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 2, 4, 7, 9, 11, 13, 15, 17, 19,
+ 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
+ 41, 42, 46, 47, 52, 54, 56, 58, 60, 62,
+ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82,
+ 84, 86, 88, 90, 92, 94, 96, 98, 101, 105,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 191,
+ 192, 193, 194, 195, 196, 197, 198, 214, 215, 216,
+ 217, 218, 219, 220, 234, 235, 236, 237, 238, 239,
+ 251, 252, 253, 254, 255, 265, 266, 267, 268, 276,
+ 277, 278, 284, 286, 287, 288, 289, 290, 291, 292,
+ 293, 294, 295, 315, 316, 317, 318, 319, 320, 321,
+ 322, 323, 341, 342, 343, 344, 345, 346, 347, 348,
+ 364, 365, 366, 367, 368, 369, 370, 384, 385, 386,
+ 387, 388, 389, 401, 402, 403, 404, 405, 415, 416,
+ 417, 418, 426, 427, 428, 434, 435, 439, 442, 446,
+ 447, 449, 451, 453, 455, 457, 459, 461, 463, 465,
+ 467, 468, 469, 475, 477, 478, 479, 480, 481, 491,
+ 492, 493, 499, 500, 501, 502, 510, 511, 512, 518,
+ 519, 520, 521, 529, 530, 531, 532, 533, 543, 544,
+ 545, 546, 554, 555, 556, 557, 558, 568, 570, 572,
+ 574, 576, 578, 580, 581, 582, 583, 591, 592, 593,
+ 594, 595, 596, 608, 609, 610, 611, 619, 620, 621,
+ 622, 623, 624, 636, 637, 638, 639, 640, 650, 651,
+ 652, 653, 654, 655, 667, 669, 671, 673, 675, 677,
+ 679, 681, 683, 685, 687, 688, 692, 693, 697, 698,
+ 702, 704, 706, 708, 710, 712, 718, 719, 725, 727,
+ 729, 731, 733, 735, 736, 737, 738, 745, 746, 748,
+ 751, 754, 758, 759, 763, 764, 769, 770, 772, 774,
+ 776, 778, 780, 782, 783
+};
+
+#endif
+
+static const short yyrhs[] = { 92,
+ 0, 93, 0, 92, 93, 0, 96, 0, 94, 0,
+ 95, 0, 293, 0, 294, 0, 311, 0, 101, 0,
+ 102, 0, 103, 0, 319, 0, 295, 0, 223, 0,
+ 6, 0, 7, 0, 3, 0, 97, 0, 100, 0,
+ 0, 73, 98, 74, 0, 0, 73, 99, 92, 74,
+ 0, 72, 0, 4, 0, 5, 0, 167, 0, 164,
+ 0, 160, 0, 155, 0, 149, 0, 142, 0, 134,
+ 0, 125, 0, 115, 0, 105, 0, 220, 0, 217,
+ 0, 213, 0, 208, 0, 202, 0, 195, 0, 187,
+ 0, 178, 0, 168, 0, 261, 0, 75, 76, 0,
+ 75, 92, 76, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 24, 106, 104, 107, 104,
+ 108, 104, 109, 104, 110, 104, 111, 104, 112, 104,
+ 113, 104, 114, 104, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 23, 116, 222, 117, 104, 118,
+ 104, 119, 104, 120, 104, 121, 104, 122, 104, 123,
+ 104, 124, 104, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 22, 126, 222, 127, 104, 128, 104, 129,
+ 104, 130, 104, 131, 104, 132, 104, 133, 104, 0,
+ 0, 0, 0, 0, 0, 0, 0, 21, 135, 222,
+ 136, 104, 137, 104, 138, 104, 139, 104, 140, 104,
+ 141, 104, 0, 0, 0, 0, 0, 0, 0, 20,
+ 143, 222, 144, 104, 145, 104, 146, 104, 147, 104,
+ 148, 104, 0, 0, 0, 0, 0, 0, 19, 150,
+ 222, 151, 104, 152, 104, 153, 104, 154, 104, 0,
+ 0, 0, 0, 0, 18, 156, 222, 157, 104, 158,
+ 104, 159, 104, 0, 0, 0, 0, 17, 161, 222,
+ 162, 104, 163, 104, 0, 0, 0, 16, 165, 222,
+ 166, 104, 0, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 32, 169, 104, 170, 104, 171,
+ 104, 172, 104, 173, 104, 174, 104, 175, 104, 176,
+ 104, 177, 222, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 31, 179, 104, 180, 104, 181, 104, 182,
+ 104, 183, 104, 184, 104, 185, 104, 186, 222, 0,
+ 0, 0, 0, 0, 0, 0, 0, 30, 188, 104,
+ 189, 104, 190, 104, 191, 104, 192, 104, 193, 104,
+ 194, 222, 0, 0, 0, 0, 0, 0, 0, 29,
+ 196, 104, 197, 104, 198, 104, 199, 104, 200, 104,
+ 201, 222, 0, 0, 0, 0, 0, 0, 28, 203,
+ 104, 204, 104, 205, 104, 206, 104, 207, 222, 0,
+ 0, 0, 0, 0, 27, 209, 104, 210, 104, 211,
+ 104, 212, 222, 0, 0, 0, 0, 26, 214, 104,
+ 215, 104, 216, 222, 0, 0, 0, 25, 218, 104,
+ 219, 222, 0, 0, 15, 221, 222, 0, 84, 87,
+ 0, 84, 92, 87, 0, 0, 224, 0, 227, 0,
+ 228, 0, 233, 0, 236, 0, 240, 0, 243, 0,
+ 247, 0, 252, 0, 256, 0, 0, 0, 38, 225,
+ 303, 226, 304, 0, 39, 0, 0, 0, 0, 0,
+ 40, 229, 303, 230, 303, 231, 104, 232, 104, 0,
+ 0, 0, 41, 234, 303, 235, 222, 0, 0, 0,
+ 0, 42, 237, 303, 238, 222, 239, 104, 0, 0,
+ 0, 43, 241, 303, 242, 104, 0, 0, 0, 0,
+ 44, 244, 222, 245, 303, 246, 303, 0, 0, 0,
+ 0, 0, 45, 248, 222, 249, 303, 250, 303, 251,
+ 303, 0, 0, 0, 0, 46, 253, 222, 254, 303,
+ 255, 222, 0, 0, 0, 0, 0, 47, 257, 104,
+ 258, 303, 259, 222, 260, 104, 0, 262, 0, 266,
+ 0, 272, 0, 276, 0, 282, 0, 287, 0, 0,
+ 0, 0, 58, 263, 222, 264, 222, 265, 104, 0,
+ 0, 0, 0, 0, 0, 59, 267, 222, 268, 222,
+ 269, 222, 270, 104, 271, 104, 0, 0, 0, 0,
+ 60, 273, 222, 274, 104, 275, 222, 0, 0, 0,
+ 0, 0, 0, 61, 277, 104, 278, 222, 279, 222,
+ 280, 222, 281, 104, 0, 0, 0, 0, 0, 62,
+ 283, 104, 284, 222, 285, 222, 286, 104, 0, 0,
+ 0, 0, 0, 0, 63, 288, 104, 289, 222, 290,
+ 222, 291, 104, 292, 104, 0, 68, 0, 71, 0,
+ 69, 0, 70, 0, 296, 0, 298, 0, 300, 0,
+ 318, 0, 305, 0, 302, 0, 0, 64, 297, 306,
+ 0, 0, 65, 299, 306, 0, 0, 66, 301, 306,
+ 0, 8, 0, 9, 0, 10, 0, 11, 0, 77,
+ 0, 82, 294, 81, 294, 83, 0, 0, 85, 294,
+ 81, 294, 88, 0, 81, 0, 82, 0, 83, 0,
+ 79, 0, 80, 0, 0, 0, 0, 307, 315, 308,
+ 310, 309, 315, 0, 0, 311, 0, 310, 311, 0,
+ 316, 317, 0, 316, 92, 317, 0, 0, 86, 313,
+ 89, 0, 0, 86, 314, 92, 89, 0, 0, 312,
+ 0, 75, 0, 76, 0, 12, 0, 13, 0, 320,
+ 0, 0, 90, 321, 75, 92, 76, 0
+};
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 119, 122, 123, 126, 127, 128, 129, 132, 135, 136,
+ 137, 138, 139, 140, 141, 146, 152, 155, 162, 163,
+ 166, 174, 177, 184, 190, 202, 209, 217, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
+ 230, 231, 232, 233, 234, 235, 236, 239, 240, 241,
+ 246, 251, 255, 259, 263, 267, 271, 275, 279, 283,
+ 288, 293, 297, 301, 305, 309, 313, 317, 321, 325,
+ 330, 335, 339, 343, 347, 351, 355, 359, 363, 368,
+ 373, 377, 381, 385, 389, 393, 397, 402, 407, 411,
+ 415, 419, 423, 427, 432, 437, 441, 445, 449, 453,
+ 458, 463, 467, 471, 475, 480, 485, 489, 493, 498,
+ 503, 507, 513, 521, 526, 530, 534, 538, 542, 546,
+ 550, 554, 558, 563, 568, 572, 576, 580, 584, 588,
+ 592, 596, 601, 606, 610, 614, 618, 622, 626, 630,
+ 635, 640, 644, 648, 652, 656, 660, 665, 670, 674,
+ 678, 682, 686, 691, 696, 700, 704, 708, 713, 718,
+ 722, 726, 731, 736, 740, 745, 750, 755, 756, 757,
+ 762, 763, 764, 765, 766, 767, 768, 769, 770, 771,
+ 774, 781, 789, 797, 804, 811, 818, 825, 832, 839,
+ 846, 854, 862, 869, 877, 885, 892, 899, 906, 913,
+ 921, 929, 936, 943, 951, 959, 966, 973, 980, 988,
+ 996, 1004, 1012, 1019, 1026, 1034, 1042, 1051, 1052, 1053,
+ 1054, 1055, 1056, 1059, 1067, 1076, 1084, 1091, 1099, 1108,
+ 1117, 1125, 1132, 1139, 1147, 1155, 1163, 1171, 1178, 1186,
+ 1195, 1204, 1212, 1219, 1226, 1234, 1243, 1251, 1258, 1265,
+ 1273, 1282, 1290, 1297, 1306, 1307, 1310, 1311, 1314, 1315,
+ 1316, 1317, 1318, 1319, 1326, 1334, 1342, 1350, 1358, 1366,
+ 1374, 1375, 1376, 1377, 1378, 1381, 1393, 1394, 1406, 1407,
+ 1408, 1409, 1410, 1413, 1413, 1415, 1415, 1418, 1419, 1420,
+ 1423, 1424, 1427, 1427, 1428, 1428, 1431, 1432, 1435, 1443,
+ 1451, 1457, 1467, 1473, 1481
+};
+
+static const char * const yytname[] = { "$","error","$illegal.","END_OF_FILE",
+"TEX_CHAR","CHAR_COMMAND","BEGIN_DOCUMENT","END_DOCUMENT","BEGIN_VERBATIM","END_VERBATIM",
+"BEGIN_VERB","END_VERB","BEGIN_DOLLAR","END_DOLLAR","COMMAND","COMMAND_OPT",
+"COMMAND_1","COMMAND_2","COMMAND_3","COMMAND_4","COMMAND_5","COMMAND_6","COMMAND_7",
+"COMMAND_8","COMMAND_9","COMMAND_1_OPT","COMMAND_2_OPT","COMMAND_3_OPT","COMMAND_4_OPT",
+"COMMAND_5_OPT","COMMAND_6_OPT","COMMAND_7_OPT","COMMAND_8_OPT","BEGIN_ENV",
+"END_ENV","BEGIN_LIST_ENV","END_LIST_ENV","SECTIONING","BEGIN_PICTURE_CC","END_PICTURE",
+"PICTURE_CCPP","PICTURE_CO","PICTURE_COP","PICTURE_CP","PICTURE_OCC","PICTURE_OCCC",
+"PICTURE_OCO","PICTURE_PCOP","SPECIAL","SPECIAL_COMMAND","SPECIAL_BEGIN_ENV",
+"SPECIAL_END_ENV","SPECIAL_BEGIN_LIST","SPECIAL_END_LIST","SPECIAL_SECTIONING",
+"BEGIN_VENV","END_VENV","VCOMMAND","COMMAND_OOP","COMMAND_OOOPP","COMMAND_OPO",
+"COMMAND_POOOP","COMMAND_POOP","COMMAND_POOPP","OTHER_COMMAND","OTHER_BEGIN",
+"OTHER_END","PRINT_CONTROLLED_COMMAND","NAME","INTEGER","REAL","OTHER","ITEM",
+"ITEM_AND_BRAK","END_ITEM_BRAK","LBRACE","RBRACE","PARAGRAPH","SLASH_SPACE",
+"LBRAK","RBRAK","COMMA","LPAREN","RPAREN","START_ANOPT","START_COORD","START_ALLOPT",
+"END_ANOPT","END_COORD","END_ALLOPT","GRAMMSPECIAL","Document","StuffList","Stuff",
+"StartDoc","EndDoc","AnItem","DescItem","@1","@2","NdItem","l2xSpecialChar",
+"l2xCharCommand","l2xCommands","ReqParam","l2xComm9","@3","@4","@5","@6","@7",
+"@8","@9","@10","@11","l2xComm8","@12","@13","@14","@15","@16","@17","@18","@19",
+"@20","l2xComm7","@21","@22","@23","@24","@25","@26","@27","@28","l2xComm6",
+"@29","@30","@31","@32","@33","@34","@35","l2xComm5","@36","@37","@38","@39",
+"@40","@41","l2xComm4","@42","@43","@44","@45","@46","l2xComm3","@47","@48",
+"@49","@50","l2xComm2","@51","@52","@53","l2xComm1","@54","@55","l2xCommand",
+"l2xComm8Opt","@56","@57","@58","@59","@60","@61","@62","@63","@64","l2xComm7Opt",
+"@65","@66","@67","@68","@69","@70","@71","@72","l2xComm6Opt","@73","@74","@75",
+"@76","@77","@78","@79","l2xComm5Opt","@80","@81","@82","@83","@84","@85","l2xComm4Opt",
+"@86","@87","@88","@89","@90","l2xComm3Opt","@91","@92","@93","@94","l2xComm2Opt",
+"@95","@96","@97","l2xComm1Opt","@98","@99","l2xCommandOpt","@100","OptParam",
+"l2xPictures","BeginPicCC","@101","@102","EndPic","PicCCPP","@103","@104","@105",
+"@106","PicCO","@107","@108","PicCOP","@109","@110","@111","PicCP","@112","@113",
+"PicOCC","@114","@115","@116","PicOCCC","@117","@118","@119","@120","PicOCO",
+"@121","@122","@123","PicPCOP","@124","@125","@126","@127","l2xCommOddP","ltxCommandOOP",
+"@128","@129","@130","ltxCommandOOOPP","@131","@132","@133","@134","@135","ltxCommandOPO",
+"@136","@137","@138","ltxCommandPOOOP","@139","@140","@141","@142","@143","ltxCommandPOOP",
+"@144","@145","@146","@147","ltxCommandPOOPP","@148","@149","@150","@151","@152",
+"Words","Numbers","l2xOthers","l2xOtherCommand","@153","l2xOtherBegin","@154",
+"l2xOtherEnd","@155","l2xNoOps","Coord","OptCoord","CoordStuff","AllParameters",
+"@156","@157","@158","ParamList","BracedStuff","BracketedStuff","@159","@160",
+"OptBracketedStuff","Lbrace","Rbrace","l2xDollars","l2xSpecials","GrammSpecial",
+"@161",""
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 91, 92, 92, 93, 93, 93, 93, 93, 93, 93,
+ 93, 93, 93, 93, 93, 94, 95, 95, 96, 96,
+ 98, 97, 99, 97, 100, 101, 102, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 104, 104, 104,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 105,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 115,
+ 126, 127, 128, 129, 130, 131, 132, 133, 125, 135,
+ 136, 137, 138, 139, 140, 141, 134, 143, 144, 145,
+ 146, 147, 148, 142, 150, 151, 152, 153, 154, 149,
+ 156, 157, 158, 159, 155, 161, 162, 163, 160, 165,
+ 166, 164, 167, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 168, 179, 180, 181, 182, 183, 184, 185,
+ 186, 178, 188, 189, 190, 191, 192, 193, 194, 187,
+ 196, 197, 198, 199, 200, 201, 195, 203, 204, 205,
+ 206, 207, 202, 209, 210, 211, 212, 208, 214, 215,
+ 216, 213, 218, 219, 217, 221, 220, 222, 222, 222,
+ 223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
+ 225, 226, 224, 227, 229, 230, 231, 232, 228, 234,
+ 235, 233, 237, 238, 239, 236, 241, 242, 240, 244,
+ 245, 246, 243, 248, 249, 250, 251, 247, 253, 254,
+ 255, 252, 257, 258, 259, 260, 256, 261, 261, 261,
+ 261, 261, 261, 263, 264, 265, 262, 267, 268, 269,
+ 270, 271, 266, 273, 274, 275, 272, 277, 278, 279,
+ 280, 281, 276, 283, 284, 285, 286, 282, 288, 289,
+ 290, 291, 292, 287, 293, 293, 294, 294, 295, 295,
+ 295, 295, 295, 295, 297, 296, 299, 298, 301, 300,
+ 302, 302, 302, 302, 302, 303, 304, 304, 305, 305,
+ 305, 305, 305, 307, 308, 309, 306, 310, 310, 310,
+ 311, 311, 313, 312, 314, 312, 315, 315, 316, 317,
+ 318, 318, 319, 321, 320
+};
+
+static const short yyr2[] = { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 3, 0, 4, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 3, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 15, 0, 0, 0,
+ 0, 0, 0, 13, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 0, 9, 0, 0, 0, 7, 0,
+ 0, 5, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 19, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 0, 0, 0, 13, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 0, 9, 0, 0,
+ 0, 7, 0, 0, 5, 0, 3, 2, 3, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 5, 1, 0, 0, 0, 0, 9, 0,
+ 0, 5, 0, 0, 0, 7, 0, 0, 5, 0,
+ 0, 0, 7, 0, 0, 0, 0, 9, 0, 0,
+ 0, 7, 0, 0, 0, 0, 9, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 11, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 3, 0, 3, 0, 3,
+ 1, 1, 1, 1, 1, 5, 0, 5, 1, 1,
+ 1, 1, 1, 0, 0, 0, 6, 0, 1, 2,
+ 2, 3, 0, 3, 0, 4, 0, 1, 1, 1,
+ 1, 1, 1, 0, 5
+};
+
+static const short yydefact[] = { 0,
+ 18, 26, 27, 16, 17, 271, 272, 273, 274, 301,
+ 302, 113, 166, 110, 106, 101, 95, 88, 80, 71,
+ 61, 51, 163, 159, 154, 148, 141, 133, 124, 114,
+ 181, 184, 185, 190, 193, 197, 200, 204, 209, 213,
+ 224, 228, 234, 238, 244, 249, 265, 267, 269, 255,
+ 257, 258, 256, 25, 23, 299, 275, 282, 283, 279,
+ 280, 281, 304, 1, 2, 5, 6, 4, 19, 20,
+ 10, 11, 12, 37, 36, 35, 34, 33, 32, 31,
+ 30, 29, 28, 46, 45, 44, 43, 42, 41, 40,
+ 39, 38, 15, 171, 172, 173, 174, 175, 176, 177,
+ 178, 179, 180, 47, 218, 219, 220, 221, 222, 223,
+ 7, 8, 14, 259, 260, 261, 264, 263, 9, 0,
+ 262, 13, 303, 170, 170, 170, 170, 170, 170, 170,
+ 170, 170, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 170, 170, 170, 0,
+ 170, 170, 170, 0, 0, 0, 284, 284, 284, 0,
+ 0, 0, 3, 300, 0, 291, 0, 167, 111, 107,
+ 102, 96, 89, 81, 72, 62, 50, 0, 52, 164,
+ 160, 155, 149, 142, 134, 125, 115, 0, 182, 186,
+ 191, 194, 198, 201, 205, 210, 214, 225, 229, 235,
+ 239, 245, 250, 266, 297, 268, 270, 22, 0, 0,
+ 292, 168, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 48, 0, 0, 170, 0, 0, 0, 0, 0,
+ 0, 0, 0, 277, 0, 170, 170, 0, 0, 0,
+ 0, 0, 170, 170, 0, 170, 170, 170, 295, 298,
+ 285, 24, 0, 169, 112, 108, 103, 97, 90, 82,
+ 73, 63, 49, 53, 165, 161, 156, 150, 143, 135,
+ 126, 116, 0, 0, 183, 187, 192, 195, 199, 202,
+ 206, 211, 215, 226, 230, 236, 240, 246, 251, 0,
+ 0, 288, 305, 0, 0, 0, 0, 0, 0, 0,
+ 0, 170, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 170, 170, 0, 170, 170, 170,
+ 170, 170, 294, 0, 286, 289, 109, 104, 98, 91,
+ 83, 74, 64, 54, 162, 157, 151, 144, 136, 127,
+ 117, 276, 0, 188, 196, 203, 207, 212, 216, 227,
+ 231, 237, 241, 247, 252, 296, 297, 290, 0, 0,
+ 0, 0, 0, 0, 0, 170, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 170, 0, 0, 287,
+ 105, 99, 92, 84, 75, 65, 55, 158, 152, 145,
+ 137, 128, 118, 278, 189, 208, 217, 232, 242, 248,
+ 253, 0, 0, 0, 0, 0, 0, 170, 0, 0,
+ 0, 0, 0, 0, 0, 100, 93, 85, 76, 66,
+ 56, 153, 146, 138, 129, 119, 233, 243, 254, 0,
+ 0, 0, 0, 0, 170, 0, 0, 0, 94, 86,
+ 77, 67, 57, 147, 139, 130, 120, 0, 0, 0,
+ 0, 170, 0, 0, 87, 78, 68, 58, 140, 131,
+ 121, 0, 0, 0, 170, 0, 79, 69, 59, 132,
+ 122, 0, 0, 170, 70, 60, 123, 0, 0, 0
+};
+
+static const short yydefgoto[] = { 478,
+ 64, 65, 66, 67, 68, 69, 160, 161, 70, 71,
+ 72, 73, 179, 74, 133, 224, 301, 365, 407, 434,
+ 451, 464, 473, 75, 132, 221, 300, 364, 406, 433,
+ 450, 463, 472, 76, 131, 220, 299, 363, 405, 432,
+ 449, 462, 77, 130, 219, 298, 362, 404, 431, 448,
+ 78, 129, 218, 297, 361, 403, 430, 79, 128, 217,
+ 296, 360, 402, 80, 127, 216, 295, 359, 81, 126,
+ 215, 294, 82, 125, 214, 83, 84, 141, 232, 308,
+ 371, 412, 438, 454, 466, 474, 85, 140, 231, 307,
+ 370, 411, 437, 453, 465, 86, 139, 230, 306, 369,
+ 410, 436, 452, 87, 138, 229, 305, 368, 409, 435,
+ 88, 137, 228, 304, 367, 408, 89, 136, 227, 303,
+ 366, 90, 135, 226, 302, 91, 134, 225, 92, 124,
+ 168, 93, 94, 142, 234, 95, 96, 143, 235, 311,
+ 373, 97, 144, 236, 98, 145, 237, 312, 99, 146,
+ 238, 100, 147, 239, 313, 101, 148, 240, 314, 374,
+ 102, 149, 241, 315, 103, 150, 242, 316, 375, 104,
+ 105, 151, 243, 317, 106, 152, 244, 318, 376, 413,
+ 107, 153, 245, 319, 108, 154, 246, 320, 377, 414,
+ 109, 155, 247, 321, 378, 110, 156, 248, 322, 379,
+ 415, 111, 112, 113, 114, 157, 115, 158, 116, 159,
+ 117, 189, 275, 118, 204, 205, 292, 357, 325, 119,
+ 250, 290, 291, 251, 120, 166, 121, 122, 123, 162
+};
+
+static const short yypact[] = { 1166,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, -53,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768, 1166,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 462,
+-32768,-32768,-32768, -59, -59, -59, -59, -59, -59, -59,
+ -59, -59, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, -52, -52, -52, -52, -52, -59, -59, -59, 10,
+ -59, -59, -59, 10, 10, 10,-32768,-32768,-32768, -45,
+ 1166, -44,-32768,-32768, 462,-32768, 550,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 638,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, -56,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, -54,-32768,-32768,-32768, 726, 1166,
+-32768,-32768, 814, 10, 10, 10, 10, 10, 10, 10,
+ 10,-32768, 902, 10, -59, 10, 10, 10, 10, 10,
+ 10, 10, -48, -51, -52, -59, -59, 10, -52, -52,
+ -52, -52, -59, -59, 10, -59, -59, -59, -50,-32768,
+-32768,-32768, 990,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -56, -56,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -49,
+ 1166, -40,-32768, 10, 10, 10, 10, 10, 10, 10,
+ 10, -59, 10, 10, 10, 10, 10, 10, -47, -43,
+ 10, 10, -52, -52, -59, -59, 10, -59, -59, -59,
+ -59, -59,-32768, 1078, -40,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -56,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768, -54,-32768, 10, 10,
+ 10, 10, 10, 10, 10, -59, 10, 10, 10, 10,
+ 10, -46, 10, -52, 10, 10, -59, 10, 10,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 10, 10, 10, 10, 10, 10, -59, 10, 10,
+ 10, 10, 10, 10, 10,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 10,
+ 10, 10, 10, 10, -59, 10, 10, 10,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 10, 10, 10,
+ 10, -59, 10, 10,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, 10, 10, 10, -59, 10,-32768,-32768,-32768,-32768,
+-32768, 10, 10, -59,-32768,-32768,-32768, 37, 41,-32768
+};
+
+static const short yypgoto[] = {-32768,
+ -112, -55,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -9,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ -125,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -178,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768, -126,-32768,-32768, -143,-32768,-32768,-32768,-32768, -280,
+-32768,-32768,-32768, -314,-32768, -121,-32768,-32768,-32768,-32768
+};
+
+
+#define YYLAST 1256
+
+
+static const short yytable[] = { 169,
+ 170, 171, 172, 173, 174, 175, 176, 165, 163, 233,
+ 177, 326, 51, 52, 206, 207, 190, 191, 192, 193,
+ -21, 194, 195, 196, 167, 198, 199, 200, 208, 188,
+ 210, 249, 273, 274, 56, 342, 479, 343, -293, 323,
+ 480, 394, 380, 211, 358, 0, 0, 0, 209, 0,
+ 0, 0, 0, 0, 213, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 223, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 178, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 309, 310, 0, 253, 0, 265,
+ 0, 0, 0, 0, 0, 0, 0, 0, 276, 163,
+ 277, 278, 280, 281, 282, 283, 0, 284, 285, 0,
+ 287, 288, 289, 0, 180, 181, 182, 183, 184, 185,
+ 186, 187, 0, 0, 0, 0, 0, 0, 0, 0,
+ 197, 0, 0, 0, 201, 202, 203, 0, 0, 0,
+ 0, 0, 0, 163, 0, 0, 0, 163, 0, 0,
+ 0, 0, 0, 0, 372, 0, 0, 163, 0, 0,
+ 0, 0, 0, 0, 0, 0, 335, 0, 324, 0,
+ 0, 0, 0, 0, 0, 0, 346, 347, 0, 348,
+ 349, 0, 351, 352, 353, 354, 355, 163, 0, 0,
+ 0, 0, 0, 0, 255, 256, 257, 258, 259, 260,
+ 261, 262, 0, 0, 264, 0, 266, 267, 268, 269,
+ 270, 271, 272, 0, 0, 0, 0, 0, 279, 0,
+ 0, 0, 0, 0, 0, 286, 0, 0, 0, 0,
+ 388, 0, 0, 0, 0, 0, 0, 396, 0, 0,
+ 0, 399, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 163, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 422, 0, 327, 328, 329, 330, 331, 332,
+ 333, 334, 0, 336, 337, 338, 339, 340, 341, 0,
+ 0, 344, 345, 0, 0, 0, 0, 350, 0, 444,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 459, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 470,
+ 0, 0, 0, 0, 0, 0, 0, 0, 477, 381,
+ 382, 383, 384, 385, 386, 387, 0, 389, 390, 391,
+ 392, 393, 0, 395, 0, 397, 398, 0, 400, 401,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 416, 417, 418, 419, 420, 421, 0, 423,
+ 424, 425, 426, 427, 428, 429, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 439, 440, 441, 442, 443, 0, 445, 446, 447, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 455, 456,
+ 457, 458, 0, 460, 461, 0, 0, 0, 0, 0,
+ 0, 0, 467, 468, 469, 0, 471, 0, 0, 0,
+ 0, 0, 475, 476, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 0, 0, 0, 0, 0, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 0, 50,
+ 51, 52, 53, 54, 55, 0, 56, 164, 57, 0,
+ 58, 59, 60, 61, 62, 0, 0, 0, 0, 0,
+ 0, 63, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 0, 0, 0, 0, 0, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 0, 50, 51, 52,
+ 53, 54, 55, 0, 56, 0, 57, 0, 58, 59,
+ 60, 61, 62, 0, 0, 0, 212, 0, 0, 63,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 0, 0, 0, 0, 0, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 0, 50, 51, 52, 53, 54,
+ 55, 0, 56, 222, 57, 0, 58, 59, 60, 61,
+ 62, 0, 0, 0, 0, 0, 0, 63, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 0, 0,
+ 0, 0, 0, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 0, 50, 51, 52, 53, 54, 55, 252,
+ 56, 0, 57, 0, 58, 59, 60, 61, 62, 0,
+ 0, 0, 0, 0, 0, 63, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 0, 0, 0, 0,
+ 0, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 0, 50, 51, 52, 53, 54, 55, 0, 56, 0,
+ 57, 0, 58, 59, 60, 61, 62, 0, 0, 0,
+ 254, 0, 0, 63, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 0, 0, 0, 0, 0, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 0, 50,
+ 51, 52, 53, 54, 55, 0, 56, 263, 57, 0,
+ 58, 59, 60, 61, 62, 0, 0, 0, 0, 0,
+ 0, 63, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 0, 0, 0, 0, 0, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 0, 50, 51, 52,
+ 53, 54, 55, 0, 56, 293, 57, 0, 58, 59,
+ 60, 61, 62, 0, 0, 0, 0, 0, 0, 63,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 0, 0, 0, 0, 0, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 0, 50, 51, 52, 53, 54,
+ 55, 0, 56, 0, 57, 0, 58, 59, 60, 61,
+ 62, 0, 0, 0, 0, 0, 356, 63, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 0, 0,
+ 0, 0, 0, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 0, 50, 51, 52, 53, 54, 55, 0,
+ 56, 0, 57, 0, 58, 59, 60, 61, 62, 0,
+ 0, 0, 0, 0, 0, 63
+};
+
+static const short yycheck[] = { 125,
+ 126, 127, 128, 129, 130, 131, 132, 120, 64, 188,
+ 1, 292, 69, 70, 158, 159, 143, 144, 145, 146,
+ 74, 147, 148, 149, 84, 151, 152, 153, 74, 82,
+ 75, 86, 81, 85, 75, 83, 0, 81, 89, 89,
+ 0, 88, 357, 165, 325, -1, -1, -1, 161, -1,
+ -1, -1, -1, -1, 167, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 178, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 75, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 273, 274, -1, 210, -1, 225,
+ -1, -1, -1, -1, -1, -1, -1, -1, 235, 165,
+ 236, 237, 239, 240, 241, 242, -1, 243, 244, -1,
+ 246, 247, 248, -1, 134, 135, 136, 137, 138, 139,
+ 140, 141, -1, -1, -1, -1, -1, -1, -1, -1,
+ 150, -1, -1, -1, 154, 155, 156, -1, -1, -1,
+ -1, -1, -1, 209, -1, -1, -1, 213, -1, -1,
+ -1, -1, -1, -1, 343, -1, -1, 223, -1, -1,
+ -1, -1, -1, -1, -1, -1, 302, -1, 291, -1,
+ -1, -1, -1, -1, -1, -1, 313, 314, -1, 315,
+ 316, -1, 318, 319, 320, 321, 322, 253, -1, -1,
+ -1, -1, -1, -1, 214, 215, 216, 217, 218, 219,
+ 220, 221, -1, -1, 224, -1, 226, 227, 228, 229,
+ 230, 231, 232, -1, -1, -1, -1, -1, 238, -1,
+ -1, -1, -1, -1, -1, 245, -1, -1, -1, -1,
+ 366, -1, -1, -1, -1, -1, -1, 374, -1, -1,
+ -1, 377, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 324, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 408, -1, 294, 295, 296, 297, 298, 299,
+ 300, 301, -1, 303, 304, 305, 306, 307, 308, -1,
+ -1, 311, 312, -1, -1, -1, -1, 317, -1, 435,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 452, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 465,
+ -1, -1, -1, -1, -1, -1, -1, -1, 474, 359,
+ 360, 361, 362, 363, 364, 365, -1, 367, 368, 369,
+ 370, 371, -1, 373, -1, 375, 376, -1, 378, 379,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 402, 403, 404, 405, 406, 407, -1, 409,
+ 410, 411, 412, 413, 414, 415, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 430, 431, 432, 433, 434, -1, 436, 437, 438, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 448, 449,
+ 450, 451, -1, 453, 454, -1, -1, -1, -1, -1,
+ -1, -1, 462, 463, 464, -1, 466, -1, -1, -1,
+ -1, -1, 472, 473, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, -1, -1, -1, -1, -1, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, -1, 68,
+ 69, 70, 71, 72, 73, -1, 75, 76, 77, -1,
+ 79, 80, 81, 82, 83, -1, -1, -1, -1, -1,
+ -1, 90, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, -1, -1, -1, -1, -1, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, -1, 68, 69, 70,
+ 71, 72, 73, -1, 75, -1, 77, -1, 79, 80,
+ 81, 82, 83, -1, -1, -1, 87, -1, -1, 90,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, -1, -1, -1, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, -1, 68, 69, 70, 71, 72,
+ 73, -1, 75, 76, 77, -1, 79, 80, 81, 82,
+ 83, -1, -1, -1, -1, -1, -1, 90, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, -1,
+ -1, -1, -1, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, -1, 68, 69, 70, 71, 72, 73, 74,
+ 75, -1, 77, -1, 79, 80, 81, 82, 83, -1,
+ -1, -1, -1, -1, -1, 90, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, -1, -1, -1, -1,
+ -1, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+ -1, 68, 69, 70, 71, 72, 73, -1, 75, -1,
+ 77, -1, 79, 80, 81, 82, 83, -1, -1, -1,
+ 87, -1, -1, 90, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, -1, -1, -1, -1, -1, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, -1, 68,
+ 69, 70, 71, 72, 73, -1, 75, 76, 77, -1,
+ 79, 80, 81, 82, 83, -1, -1, -1, -1, -1,
+ -1, 90, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, -1, -1, -1, -1, -1, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, -1, 68, 69, 70,
+ 71, 72, 73, -1, 75, 76, 77, -1, 79, 80,
+ 81, 82, 83, -1, -1, -1, -1, -1, -1, 90,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, -1, -1, -1, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, -1, 68, 69, 70, 71, 72,
+ 73, -1, 75, -1, 77, -1, 79, 80, 81, 82,
+ 83, -1, -1, -1, -1, -1, 89, 90, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, -1,
+ -1, -1, -1, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, -1, 68, 69, 70, 71, 72, 73, -1,
+ 75, -1, 77, -1, 79, 80, 81, 82, 83, -1,
+ -1, -1, -1, -1, -1, 90
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/depot/gnu/lib/bison.simple"
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
+
+ This program 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 1, or (at your option)
+ any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#define YYLEX yylex(&yylval, &yylloc)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_bcopy (from, to, count)
+ char *from;
+ char *to;
+ int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_bcopy (char *from, char *to, int count)
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 169 "/depot/gnu/lib/bison.simple"
+int
+yyparse()
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+#ifdef YYLSP_NEEDED
+ &yyls1, size * sizeof (*yylsp),
+#endif
+ &yystacksize);
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symboles being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 7:
+#line 129 "l2x.y"
+{ myprint(yyvsp[0].string);
+ free(yyvsp[0].string);
+ ;
+ break;}
+case 8:
+#line 132 "l2x.y"
+{ myprint(yyvsp[0].string);
+ free(yyvsp[0].string);
+ ;
+ break;}
+case 16:
+#line 147 "l2x.y"
+{
+ action_no_param(yyvsp[0].pos);
+ ;
+ break;}
+case 17:
+#line 152 "l2x.y"
+{ action_no_param(yyvsp[0].pos);
+ close_down(" (at end of document)");
+ exit(0); ;
+ break;}
+case 18:
+#line 155 "l2x.y"
+{ close_down(" (at unexpected end of file)");
+ exit(1); ;
+ break;}
+case 21:
+#line 167 "l2x.y"
+{
+ print_end_item();
+ num_items[list_level]++;
+ tag_print(list_item_start[list_level]);
+ tag_print(list_descitemp_start[list_level]);
+ ;
+ break;}
+case 22:
+#line 174 "l2x.y"
+{
+ tag_print(list_descitemp_end[list_level]);
+ ;
+ break;}
+case 23:
+#line 178 "l2x.y"
+{
+ print_end_item();
+ num_items[list_level]++;
+ tag_print(list_item_start[list_level]);
+ tag_print(list_descitemp_start[list_level]);
+ ;
+ break;}
+case 24:
+#line 185 "l2x.y"
+{
+ tag_print(list_descitemp_end[list_level]);
+ ;
+ break;}
+case 25:
+#line 191 "l2x.y"
+{
+ print_end_item();
+ num_items[list_level]++;
+ tag_print(list_item_start[list_level]);
+ ;
+ break;}
+case 26:
+#line 203 "l2x.y"
+{
+ action_no_param(yyvsp[0].pos);
+ ;
+ break;}
+case 27:
+#line 210 "l2x.y"
+{
+ action_no_param(yyvsp[0].pos);
+ ;
+ break;}
+case 50:
+#line 242 "l2x.y"
+{yyerror("Syntax error: Required parameter expected");;
+ break;}
+case 51:
+#line 247 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 52:
+#line 251 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 53:
+#line 255 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 54:
+#line 259 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 55:
+#line 263 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,4);
+ ;
+ break;}
+case 56:
+#line 267 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,5);
+ ;
+ break;}
+case 57:
+#line 271 "l2x.y"
+{
+ action_p_p1(yyvsp[-12].pos,6);
+ ;
+ break;}
+case 58:
+#line 275 "l2x.y"
+{
+ action_p_p1(yyvsp[-14].pos,7);
+ ;
+ break;}
+case 59:
+#line 279 "l2x.y"
+{
+ action_p_p1(yyvsp[-16].pos,8);
+ ;
+ break;}
+case 60:
+#line 283 "l2x.y"
+{
+ action_last_p(yyvsp[-18].pos,9);
+ ;
+ break;}
+case 61:
+#line 289 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 62:
+#line 293 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 63:
+#line 297 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 64:
+#line 301 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 65:
+#line 305 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,3);
+ ;
+ break;}
+case 66:
+#line 309 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,4);
+ ;
+ break;}
+case 67:
+#line 313 "l2x.y"
+{
+ action_p_p1(yyvsp[-12].pos,5);
+ ;
+ break;}
+case 68:
+#line 317 "l2x.y"
+{
+ action_p_p1(yyvsp[-14].pos,6);
+ ;
+ break;}
+case 69:
+#line 321 "l2x.y"
+{
+ action_p_p1(yyvsp[-16].pos,7);
+ ;
+ break;}
+case 70:
+#line 325 "l2x.y"
+{
+ action_last_p(yyvsp[-18].pos,8);
+ ;
+ break;}
+case 71:
+#line 331 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 72:
+#line 335 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 73:
+#line 339 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 74:
+#line 343 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 75:
+#line 347 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,3);
+ ;
+ break;}
+case 76:
+#line 351 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,4);
+ ;
+ break;}
+case 77:
+#line 355 "l2x.y"
+{
+ action_p_p1(yyvsp[-12].pos,5);
+ ;
+ break;}
+case 78:
+#line 359 "l2x.y"
+{
+ action_p_p1(yyvsp[-14].pos,6);
+ ;
+ break;}
+case 79:
+#line 363 "l2x.y"
+{
+ action_last_p(yyvsp[-16].pos,7);
+ ;
+ break;}
+case 80:
+#line 369 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 81:
+#line 373 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 82:
+#line 377 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 83:
+#line 381 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 84:
+#line 385 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,3);
+ ;
+ break;}
+case 85:
+#line 389 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,4);
+ ;
+ break;}
+case 86:
+#line 393 "l2x.y"
+{
+ action_p_p1(yyvsp[-12].pos,5);
+ ;
+ break;}
+case 87:
+#line 397 "l2x.y"
+{
+ action_last_p(yyvsp[-14].pos,6);
+ ;
+ break;}
+case 88:
+#line 403 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 89:
+#line 407 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 90:
+#line 411 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 91:
+#line 415 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 92:
+#line 419 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,3);
+ ;
+ break;}
+case 93:
+#line 423 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,4);
+ ;
+ break;}
+case 94:
+#line 427 "l2x.y"
+{
+ action_last_p(yyvsp[-12].pos,5);
+ ;
+ break;}
+case 95:
+#line 433 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 96:
+#line 437 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 97:
+#line 441 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 98:
+#line 445 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 99:
+#line 449 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,3);
+ ;
+ break;}
+case 100:
+#line 453 "l2x.y"
+{
+ action_last_p(yyvsp[-10].pos,4);
+ ;
+ break;}
+case 101:
+#line 459 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 102:
+#line 463 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 103:
+#line 467 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 104:
+#line 471 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 105:
+#line 475 "l2x.y"
+{
+ action_last_p(yyvsp[-8].pos,3);
+ ;
+ break;}
+case 106:
+#line 481 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 107:
+#line 485 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 108:
+#line 489 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 109:
+#line 493 "l2x.y"
+{
+ action_last_p(yyvsp[-6].pos,2);
+ ;
+ break;}
+case 110:
+#line 499 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 111:
+#line 503 "l2x.y"
+{
+ action_opt_first(yyvsp[-2].pos);
+ ;
+ break;}
+case 112:
+#line 507 "l2x.y"
+{
+ action_last_p(yyvsp[-4].pos,1);
+ ;
+ break;}
+case 113:
+#line 514 "l2x.y"
+{
+ action_no_param(yyvsp[0].pos);
+ ;
+ break;}
+case 114:
+#line 522 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 115:
+#line 526 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 116:
+#line 530 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 117:
+#line 534 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 118:
+#line 538 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,4);
+ ;
+ break;}
+case 119:
+#line 542 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,5);
+ ;
+ break;}
+case 120:
+#line 546 "l2x.y"
+{
+ action_p_p1(yyvsp[-12].pos,6);
+ ;
+ break;}
+case 121:
+#line 550 "l2x.y"
+{
+ action_p_p1(yyvsp[-14].pos,7);
+ ;
+ break;}
+case 122:
+#line 554 "l2x.y"
+{
+ action_p_opt(yyvsp[-16].pos,8);
+ ;
+ break;}
+case 123:
+#line 558 "l2x.y"
+{
+ action_last_opt(yyvsp[-18].pos);
+ ;
+ break;}
+case 124:
+#line 564 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 125:
+#line 568 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 126:
+#line 572 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 127:
+#line 576 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 128:
+#line 580 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,4);
+ ;
+ break;}
+case 129:
+#line 584 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,5);
+ ;
+ break;}
+case 130:
+#line 588 "l2x.y"
+{
+ action_p_p1(yyvsp[-12].pos,6);
+ ;
+ break;}
+case 131:
+#line 592 "l2x.y"
+{
+ action_p_opt(yyvsp[-14].pos,7);
+ ;
+ break;}
+case 132:
+#line 596 "l2x.y"
+{
+ action_last_opt(yyvsp[-16].pos);
+ ;
+ break;}
+case 133:
+#line 602 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 134:
+#line 606 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 135:
+#line 610 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 136:
+#line 614 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 137:
+#line 618 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,4);
+ ;
+ break;}
+case 138:
+#line 622 "l2x.y"
+{
+ action_p_p1(yyvsp[-10].pos,5);
+ ;
+ break;}
+case 139:
+#line 626 "l2x.y"
+{
+ action_p_opt(yyvsp[-12].pos,6);
+ ;
+ break;}
+case 140:
+#line 630 "l2x.y"
+{
+ action_last_opt(yyvsp[-14].pos);
+ ;
+ break;}
+case 141:
+#line 636 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 142:
+#line 640 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 143:
+#line 644 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 144:
+#line 648 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 145:
+#line 652 "l2x.y"
+{
+ action_p_p1(yyvsp[-8].pos,4);
+ ;
+ break;}
+case 146:
+#line 656 "l2x.y"
+{
+ action_p_opt(yyvsp[-10].pos,5);
+ ;
+ break;}
+case 147:
+#line 660 "l2x.y"
+{
+ action_last_opt(yyvsp[-12].pos);
+ ;
+ break;}
+case 148:
+#line 666 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 149:
+#line 670 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 150:
+#line 674 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 151:
+#line 678 "l2x.y"
+{
+ action_p_p1(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 152:
+#line 682 "l2x.y"
+{
+ action_p_opt(yyvsp[-8].pos,4);
+ ;
+ break;}
+case 153:
+#line 686 "l2x.y"
+{
+ action_last_opt(yyvsp[-10].pos);
+ ;
+ break;}
+case 154:
+#line 692 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 155:
+#line 696 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 156:
+#line 700 "l2x.y"
+{
+ action_p_p1(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 157:
+#line 704 "l2x.y"
+{
+ action_p_opt(yyvsp[-6].pos,3);
+ ;
+ break;}
+case 158:
+#line 708 "l2x.y"
+{
+ action_last_opt(yyvsp[-8].pos);
+ ;
+ break;}
+case 159:
+#line 714 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 160:
+#line 718 "l2x.y"
+{
+ action_p_p1(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 161:
+#line 722 "l2x.y"
+{
+ action_p_opt(yyvsp[-4].pos,2);
+ ;
+ break;}
+case 162:
+#line 726 "l2x.y"
+{
+ action_last_opt(yyvsp[-6].pos);
+ ;
+ break;}
+case 163:
+#line 732 "l2x.y"
+{
+ start_with_req(yyvsp[0].pos);
+ ;
+ break;}
+case 164:
+#line 736 "l2x.y"
+{
+ action_p_opt(yyvsp[-2].pos,1);
+ ;
+ break;}
+case 165:
+#line 740 "l2x.y"
+{
+ action_last_opt(yyvsp[-4].pos);
+ ;
+ break;}
+case 166:
+#line 746 "l2x.y"
+{
+ start_with_opt(yyvsp[0].pos);
+ ;
+ break;}
+case 167:
+#line 750 "l2x.y"
+{
+ action_last_opt(yyvsp[-2].pos);
+ ;
+ break;}
+case 181:
+#line 775 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 182:
+#line 781 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_coord = TRUE;
+ ;
+ break;}
+case 183:
+#line 789 "l2x.y"
+{
+ opt_coord = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ end_it(yyvsp[-4].pos);
+ ;
+ break;}
+case 184:
+#line 798 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ end_it(yyvsp[0].pos);
+ ;
+ break;}
+case 185:
+#line 805 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 186:
+#line 811 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 187:
+#line 818 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ ;
+ break;}
+case 188:
+#line 825 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ ;
+ break;}
+case 189:
+#line 832 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ end_it(yyvsp[-8].pos);
+ ;
+ break;}
+case 190:
+#line 840 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 191:
+#line 846 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 192:
+#line 854 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ end_it(yyvsp[-4].pos);
+ ;
+ break;}
+case 193:
+#line 863 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 194:
+#line 869 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 195:
+#line 877 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ ;
+ break;}
+case 196:
+#line 885 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ end_it(yyvsp[-6].pos);
+ ;
+ break;}
+case 197:
+#line 893 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 198:
+#line 899 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 199:
+#line 906 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ end_it(yyvsp[-4].pos);
+ ;
+ break;}
+case 200:
+#line 914 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ opt_param = TRUE;
+ ;
+ break;}
+case 201:
+#line 921 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 202:
+#line 929 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ ;
+ break;}
+case 203:
+#line 936 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ end_it(yyvsp[-6].pos);
+ ;
+ break;}
+case 204:
+#line 944 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ opt_param = TRUE;
+ ;
+ break;}
+case 205:
+#line 951 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 206:
+#line 959 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ ;
+ break;}
+case 207:
+#line 966 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ ;
+ break;}
+case 208:
+#line 973 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ end_it(yyvsp[-8].pos);
+ ;
+ break;}
+case 209:
+#line 981 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ opt_param = TRUE;
+ ;
+ break;}
+case 210:
+#line 988 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 211:
+#line 996 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 212:
+#line 1004 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ end_it(yyvsp[-6].pos);
+ ;
+ break;}
+case 213:
+#line 1013 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 214:
+#line 1019 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 215:
+#line 1026 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 216:
+#line 1034 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ ;
+ break;}
+case 217:
+#line 1042 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ end_it(yyvsp[-8].pos);
+ ;
+ break;}
+case 224:
+#line 1060 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ opt_param = TRUE;
+ ;
+ break;}
+case 225:
+#line 1067 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 226:
+#line 1076 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ ;
+ break;}
+case 227:
+#line 1084 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ end_it(yyvsp[-6].pos);
+ ;
+ break;}
+case 228:
+#line 1092 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ opt_param = TRUE;
+ ;
+ break;}
+case 229:
+#line 1099 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 230:
+#line 1108 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 231:
+#line 1117 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ ;
+ break;}
+case 232:
+#line 1125 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ tag_print(get_tag_t(yyvsp[-8].pos,5));
+ set_print(get_param_print(yyvsp[-8].pos,5));
+ ;
+ break;}
+case 233:
+#line 1132 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-10].pos,5));
+ end_it(yyvsp[-10].pos);
+ ;
+ break;}
+case 234:
+#line 1140 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ opt_param = TRUE;
+ ;
+ break;}
+case 235:
+#line 1147 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ ;
+ break;}
+case 236:
+#line 1155 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 237:
+#line 1163 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ end_it(yyvsp[-6].pos);
+ ;
+ break;}
+case 238:
+#line 1172 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 239:
+#line 1178 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 240:
+#line 1186 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 241:
+#line 1195 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ opt_param = TRUE;
+ ;
+ break;}
+case 242:
+#line 1204 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ tag_print(get_tag_t(yyvsp[-8].pos,5));
+ set_print(get_param_print(yyvsp[-8].pos,5));
+ ;
+ break;}
+case 243:
+#line 1212 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-10].pos,5));
+ end_it(yyvsp[-10].pos);
+ ;
+ break;}
+case 244:
+#line 1220 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 245:
+#line 1226 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 246:
+#line 1234 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 247:
+#line 1243 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ ;
+ break;}
+case 248:
+#line 1251 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ end_it(yyvsp[-8].pos);
+ ;
+ break;}
+case 249:
+#line 1259 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ set_print(get_param_print(yyvsp[0].pos,1));
+ ;
+ break;}
+case 250:
+#line 1265 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-2].pos,1));
+ tag_print(get_tag_t(yyvsp[-2].pos,2));
+ set_print(get_param_print(yyvsp[-2].pos,2));
+ opt_param = TRUE;
+ ;
+ break;}
+case 251:
+#line 1273 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-4].pos,2));
+ tag_print(get_tag_t(yyvsp[-4].pos,3));
+ set_print(get_param_print(yyvsp[-4].pos,3));
+ opt_param = TRUE;
+ ;
+ break;}
+case 252:
+#line 1282 "l2x.y"
+{
+ opt_param = FALSE;
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-6].pos,3));
+ tag_print(get_tag_t(yyvsp[-6].pos,4));
+ set_print(get_param_print(yyvsp[-6].pos,4));
+ ;
+ break;}
+case 253:
+#line 1290 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-8].pos,4));
+ tag_print(get_tag_t(yyvsp[-8].pos,5));
+ set_print(get_param_print(yyvsp[-8].pos,5));
+ ;
+ break;}
+case 254:
+#line 1297 "l2x.y"
+{
+ reset_print();
+ tag_print(get_tag_et(yyvsp[-10].pos,5));
+ end_it(yyvsp[-10].pos);
+ ;
+ break;}
+case 255:
+#line 1306 "l2x.y"
+{ yyval.string = yyvsp[0].string; ;
+ break;}
+case 256:
+#line 1307 "l2x.y"
+{ yyval.string = yyvsp[0].string; ;
+ break;}
+case 257:
+#line 1310 "l2x.y"
+{ yyval.string = yyvsp[0].string; ;
+ break;}
+case 258:
+#line 1311 "l2x.y"
+{ yyval.string = yyvsp[0].string; ;
+ break;}
+case 263:
+#line 1318 "l2x.y"
+{ ; ;
+ break;}
+case 264:
+#line 1320 "l2x.y"
+{
+ start_it(yyvsp[0].pos);
+ end_it(yyvsp[0].pos);
+ ;
+ break;}
+case 265:
+#line 1327 "l2x.y"
+{
+ sym = get_mode_sym(pos_oc);
+ tag_print(get_t(sym));
+ set_print(get_com_print(sym));
+ myprint(yyvsp[0].pos);
+ ;
+ break;}
+case 266:
+#line 1334 "l2x.y"
+{
+ reset_print();
+ free(yyvsp[-2].pos);
+ sym = get_mode_sym(pos_oc);
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 267:
+#line 1343 "l2x.y"
+{
+ sym = get_mode_sym(pos_ob);
+ tag_print(get_t(sym));
+ set_print(get_com_print(sym));
+ myprint(yyvsp[0].pos);
+ ;
+ break;}
+case 268:
+#line 1350 "l2x.y"
+{
+ reset_print();
+ free(yyvsp[-2].pos);
+ sym = get_mode_sym(pos_ob);
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 269:
+#line 1359 "l2x.y"
+{
+ sym = get_mode_sym(pos_oe);
+ tag_print(get_t(sym));
+ set_print(get_com_print(sym));
+ myprint(yyvsp[0].pos);
+ ;
+ break;}
+case 270:
+#line 1366 "l2x.y"
+{
+ reset_print();
+ free(yyvsp[-2].pos);
+ sym = get_mode_sym(pos_oe);
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 276:
+#line 1382 "l2x.y"
+{
+ myprint("(");
+ myprint(yyvsp[-3].string);
+ free(yyvsp[-3].string);
+ myprint(",");
+ myprint(yyvsp[-1].string);
+ free(yyvsp[-1].string);
+ myprint(")");
+ ;
+ break;}
+case 278:
+#line 1395 "l2x.y"
+{
+ myprint("(");
+ myprint(yyvsp[-3].string);
+ free(yyvsp[-3].string);
+ myprint(",");
+ myprint(yyvsp[-1].string);
+ free(yyvsp[-1].string);
+ myprint(")");
+ ;
+ break;}
+case 279:
+#line 1406 "l2x.y"
+{ myprint(","); ;
+ break;}
+case 280:
+#line 1407 "l2x.y"
+{ myprint("("); ;
+ break;}
+case 281:
+#line 1408 "l2x.y"
+{ myprint(")"); ;
+ break;}
+case 282:
+#line 1409 "l2x.y"
+{ myprint("["); ;
+ break;}
+case 283:
+#line 1410 "l2x.y"
+{ myprint("]"); ;
+ break;}
+case 284:
+#line 1413 "l2x.y"
+{all_opt = TRUE;;
+ break;}
+case 285:
+#line 1413 "l2x.y"
+{all_opt = FALSE;;
+ break;}
+case 286:
+#line 1415 "l2x.y"
+{all_opt = TRUE;;
+ break;}
+case 287:
+#line 1415 "l2x.y"
+{all_opt = FALSE;;
+ break;}
+case 293:
+#line 1427 "l2x.y"
+{myprint("[");;
+ break;}
+case 294:
+#line 1427 "l2x.y"
+{myprint("]");;
+ break;}
+case 295:
+#line 1428 "l2x.y"
+{myprint("[");;
+ break;}
+case 296:
+#line 1428 "l2x.y"
+{myprint("]");;
+ break;}
+case 299:
+#line 1436 "l2x.y"
+{
+ sym = get_mode_sym(pos_lbrace);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 300:
+#line 1444 "l2x.y"
+{
+ sym = get_mode_sym(pos_rbrace);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 301:
+#line 1452 "l2x.y"
+{
+ sym = get_mode_sym(pos_bdol);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 302:
+#line 1458 "l2x.y"
+{
+ sym = get_mode_sym(pos_edol);
+ tag_print(get_t(sym));
+ tag_print(get_et(sym));
+ ;
+ break;}
+case 304:
+#line 1474 "l2x.y"
+{
+ start_section(yyvsp[0].pos);
+ tag_print(get_t(yyvsp[0].pos));
+ tag_print(get_tag_t(yyvsp[0].pos,1));
+ initialise_sysbuf();
+ set_print(p_print_to_sysbuf);
+ ;
+ break;}
+case 305:
+#line 1482 "l2x.y"
+{
+ initialise_string(grammbuf);
+ copy_sysbuf(grammbuf);
+ reset_print();
+ prwboiler1();
+ print_sysbuf();
+ prwboiler2();
+ myprint(grammbuf);
+ prwboiler3();
+ start_list(yyvsp[-4].pos);
+ ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 440 "/depot/gnu/lib/bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
+#line 1496 "l2x.y"
+
+
+
+
+
+
+
diff --git a/support/ltx2x/l2xytab.h b/support/ltx2x/l2xytab.h
new file mode 100644
index 0000000000..6a47fc0ede
--- /dev/null
+++ b/support/ltx2x/l2xytab.h
@@ -0,0 +1,96 @@
+typedef union {
+ char *string; /* string buffer */
+ /* int pos; command table position */
+ PSENTRY pos; /* pointer to sym entry */
+} YYSTYPE;
+#define END_OF_FILE 258
+#define TEX_CHAR 259
+#define CHAR_COMMAND 260
+#define BEGIN_DOCUMENT 261
+#define END_DOCUMENT 262
+#define BEGIN_VERBATIM 263
+#define END_VERBATIM 264
+#define BEGIN_VERB 265
+#define END_VERB 266
+#define BEGIN_DOLLAR 267
+#define END_DOLLAR 268
+#define COMMAND 269
+#define COMMAND_OPT 270
+#define COMMAND_1 271
+#define COMMAND_2 272
+#define COMMAND_3 273
+#define COMMAND_4 274
+#define COMMAND_5 275
+#define COMMAND_6 276
+#define COMMAND_7 277
+#define COMMAND_8 278
+#define COMMAND_9 279
+#define COMMAND_1_OPT 280
+#define COMMAND_2_OPT 281
+#define COMMAND_3_OPT 282
+#define COMMAND_4_OPT 283
+#define COMMAND_5_OPT 284
+#define COMMAND_6_OPT 285
+#define COMMAND_7_OPT 286
+#define COMMAND_8_OPT 287
+#define BEGIN_ENV 288
+#define END_ENV 289
+#define BEGIN_LIST_ENV 290
+#define END_LIST_ENV 291
+#define SECTIONING 292
+#define BEGIN_PICTURE_CC 293
+#define END_PICTURE 294
+#define PICTURE_CCPP 295
+#define PICTURE_CO 296
+#define PICTURE_COP 297
+#define PICTURE_CP 298
+#define PICTURE_OCC 299
+#define PICTURE_OCCC 300
+#define PICTURE_OCO 301
+#define PICTURE_PCOP 302
+#define SPECIAL 303
+#define SPECIAL_COMMAND 304
+#define SPECIAL_BEGIN_ENV 305
+#define SPECIAL_END_ENV 306
+#define SPECIAL_BEGIN_LIST 307
+#define SPECIAL_END_LIST 308
+#define SPECIAL_SECTIONING 309
+#define BEGIN_VENV 310
+#define END_VENV 311
+#define VCOMMAND 312
+#define COMMAND_OOP 313
+#define COMMAND_OOOPP 314
+#define COMMAND_OPO 315
+#define COMMAND_POOOP 316
+#define COMMAND_POOP 317
+#define COMMAND_POOPP 318
+#define OTHER_COMMAND 319
+#define OTHER_BEGIN 320
+#define OTHER_END 321
+#define PRINT_CONTROLLED_COMMAND 322
+#define NAME 323
+#define INTEGER 324
+#define REAL 325
+#define OTHER 326
+#define ITEM 327
+#define ITEM_AND_BRAK 328
+#define END_ITEM_BRAK 329
+#define LBRACE 330
+#define RBRACE 331
+#define PARAGRAPH 332
+#define SLASH_SPACE 333
+#define LBRAK 334
+#define RBRAK 335
+#define COMMA 336
+#define LPAREN 337
+#define RPAREN 338
+#define START_ANOPT 339
+#define START_COORD 340
+#define START_ALLOPT 341
+#define END_ANOPT 342
+#define END_COORD 343
+#define END_ALLOPT 344
+#define GRAMMSPECIAL 32767
+
+
+extern YYSTYPE yylval;
diff --git a/support/ltx2x/licomsym.h b/support/ltx2x/licomsym.h
new file mode 100644
index 0000000000..eb1b39adcf
--- /dev/null
+++ b/support/ltx2x/licomsym.h
@@ -0,0 +1,175 @@
+/* licomsym.h Symbol table common for sharing between LTX2X & code interp */
+
+#ifndef licomsym_h
+#define licomsym_h
+
+#include "l2xicmon.h"
+
+/* value structure */
+typedef union {
+ XPRSAINT integer;
+ XPRSAREAL real;
+ char character;
+ char *stringp;
+} VALUE;
+
+/* definition structure */
+
+typedef enum {
+#define dfntc(a, b) a,
+#include "l2xidftc.h"
+#undef dfntc
+} DEFN_KEY;
+
+
+
+typedef enum {
+ DECLARED,
+ FORWARD,
+ READ,
+ READLN,
+ WRITE,
+ WRITELN,
+ ABS,
+ COS,
+ EOFF,
+ EOLN,
+ EXP,
+ ODD,
+ ROUND,
+ SIN,
+ SQRT,
+ TRUNC,
+ L2XPRINT,
+ L2XPRINTLN,
+ L2XSYSTEM,
+ L2XREXPR,
+ XACOS,
+ XASIN,
+ XATAN,
+ XBLENGTH,
+ XEXISTS,
+ XFORMAT,
+ XHIBOUND,
+ XHIINDEX,
+ XLENGTH,
+ XLOBOUND,
+ XLOG,
+ XLOG2,
+ XLOG10,
+ XLOINDEX,
+ XNVL,
+ XROLESOF,
+ XSIZEOF,
+ XTAN,
+ XTYPEOF,
+ XUSEDIN,
+ XVALUE,
+ XVALUE_IN,
+ XVALUE_UNIQUE,
+ XINSERT,
+ XREMOVE,
+} ROUTINE_KEY;
+
+typedef struct {
+ DEFN_KEY key;
+ union {
+ struct {
+ VALUE value;
+ } constant;
+
+ struct {
+ ROUTINE_KEY key;
+ int parm_count;
+ int total_parm_size;
+ int total_local_size;
+ struct symtab_node *parms;
+ struct symtab_node *locals;
+ struct symtab_node *local_symtab;
+ ICT *code_segment;
+ } routine;
+
+ struct {
+ int offset;
+ struct symtab_node *entity_idp;
+ } data;
+ } info;
+} DEFN_STRUCT;
+
+/* type structure */
+
+typedef enum {
+#define fotc(a, b, c, d) c,
+#define sotc(a, b, c, d)
+#define sftc(a, b, c, d) c,
+#include "l2xisftc.h"
+#undef fotc
+#undef sotc
+#undef sftc
+} TYPE_FORM;
+
+typedef struct type_struct {
+ TYPE_FORM form;
+ int size;
+ struct symtab_node *type_idp;
+ union {
+ struct {
+ struct symtab_node *const_idp;
+ int max;
+ } enumeration;
+
+ struct {
+ struct type_struct *range_typep;
+ int min;
+ int max;
+ } subrange;
+
+ struct {
+ struct type_struct *bound_typep;
+ int min;
+ int max;
+ } bound;
+
+ struct {
+ struct type_struct *index_typep;
+ struct type_struct *elmt_typep;
+ int min_index;
+ int max_index;
+ int elmt_count;
+ } array;
+
+ struct {
+ struct type_struct *index_typep;
+ struct type_struct *elmt_typep;
+ int min_index;
+ int max_index;
+ int elmt_count;
+ } dynagg;
+
+ struct {
+ struct symtab_node *attribute_symtab;
+ } entity;
+
+ struct {
+ int max_length;
+ int length;
+ } string;
+ } info;
+} TYPE_STRUCT, *TYPE_STRUCT_PTR;
+
+/* symbol table node */
+typedef struct symtab_node {
+ struct symtab_node *left, *right; /* ptrs to subtrees */
+ struct symtab_node *next; /* for chaining nodes */
+ char *name; /* name string */
+ char *info; /* ptr to generic info */
+ DEFN_STRUCT defn; /* definition struct */
+ TYPE_STRUCT_PTR typep; /* ptr to type struct */
+ int level; /* nesting level */
+ int label_index; /* index for code label */
+} SYMTAB_NODE, *SYMTAB_NODE_PTR;
+
+typedef int LOGICAL_REP;
+
+#endif
+
diff --git a/support/ltx2x/listsetc.c b/support/ltx2x/listsetc.c
new file mode 100644
index 0000000000..2aa39d24cc
--- /dev/null
+++ b/support/ltx2x/listsetc.c
@@ -0,0 +1,355 @@
+/* listsetc.c General routines for lists, etc */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "listsetc.h"
+
+
+/**********************************************************************/
+/* lbs_init() create and initialise a list/bag/set */
+/* return a pointer to the new list */
+
+LBS_PTR lbs_init()
+{
+ LBS_PTR newlist; /* pointer to new list */
+
+ /* create the list */
+ newlist = (LBS *) malloc(sizeof(LBS));
+ if (newlist == NULL) {
+ return(NULL);
+ }
+
+ /* initialise the list */
+ FRONT(newlist) = NULL;
+ BACK(newlist) = NULL;
+ NELS(newlist) = 0;
+ return(newlist);
+} /* end LBS_INIT */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* alloc_lbsnode() allocate space for a (list) node */
+/* return a pointer to the node structure */
+
+LBS_NODE_PTR alloc_lbsnode()
+{
+ LBS_NODE_PTR newnode;
+
+ /* create the node */
+ newnode = (LBS_NODE *) malloc(sizeof(LBS_NODE));
+ if (newnode == NULL) {
+ return(NULL);
+ }
+
+ DATA(newnode) = NULL;
+ NEXTEL(newnode) = NULL;
+ return(newnode);
+} /* end ALLOC_LBSNODE */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* free_lbsnode() free a (list) node */
+
+void free_lbsnode(pN)
+LBS_NODE_PTR pN;
+{
+ free(pN);
+ pN = NULL;
+} /* end FREE_LBSNODE */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_empty(pL) TRUE iff list is empty */
+
+int lbs_empty(pL)
+LBS_PTR pL;
+{
+ if (pL == NULL) return(TRUE);
+ if (FRONT(pL) == NULL) {
+ return(TRUE);
+ }
+ else {
+ return(FALSE);
+ }
+} /* end LBS_EMPTY */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_prepend() add an element to the front of a list */
+/* return pointer to new element node */
+
+LBS_NODE_PTR lbs_prepend(pL, data)
+LBS_PTR pL;
+genptr data;
+{
+ LBS_NODE_PTR newnode;
+
+ if (pL == NULL) return(NULL);
+
+ /* allocate a new node */
+ if ((newnode = alloc_lbsnode()) == NULL) {
+ return(NULL);
+ }
+
+ /* put the data into the node */
+ DATA(newnode) = data;
+
+ if (lbs_empty(pL)) {
+ FRONT(pL) = newnode;
+ BACK(pL) = newnode;
+ }
+ else {
+ NEXTEL(newnode) = FRONT(pL);
+ FRONT(pL) = newnode;
+ }
+ NELS(pL) = NELS(pL) + 1;
+
+ return(newnode);
+} /* end LBS_PREPEND */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_append() add an element at the end of a list */
+/* return pointer to new node */
+
+LBS_NODE_PTR lbs_append(pL, data)
+LBS_PTR pL;
+genptr data;
+{
+ LBS_NODE_PTR newnode;
+
+ if (pL == NULL) return(NULL);
+
+ /* allocate a new node */
+ if ((newnode = alloc_lbsnode()) == NULL) {
+ return(NULL);
+ }
+
+ /* put the data into the node */
+ DATA(newnode) = data;
+
+ if (lbs_empty(pL)) {
+ FRONT(pL) = newnode;
+ BACK(pL) = newnode;
+ }
+ else {
+ NEXTEL(BACK(pL)) = newnode;
+ BACK(pL) = newnode;
+ }
+ NELS(pL) = NELS(pL) + 1;
+
+ return(newnode);
+} /* end LBS_APPEND */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_insert() inserts a new element after the pos'th element */
+/* return pointer to the new node */
+
+LBS_NODE_PTR lbs_insert(pL, data, pos)
+LBS_PTR pL; /* the list */
+genptr data; /* the data */
+int pos; /* the position, starting from 1 */
+{
+ LBS_NODE_PTR nod, previous, next;
+ LBS_NODE_PTR newnode;
+ int i;
+ int loc = pos;
+
+ if (pL == NULL) return(NULL);
+
+ if (pos <= 0) loc = 0;
+
+ /* allocate a new node */
+ if ((newnode = alloc_lbsnode()) == NULL) {
+ return(NULL);
+ }
+ /* put the data into the node */
+ DATA(newnode) = data;
+
+ if (lbs_empty(pL)) { /* easy */
+ FRONT(pL) = newnode;
+ BACK(pL) = newnode;
+ NELS(pL) = NELS(pL) + 1;
+ return(newnode);
+ }
+
+ if (loc == 0) { /* easy */
+ NEXTEL(newnode) = FRONT(pL);
+ FRONT(pL) = newnode;
+ NELS(pL) = NELS(pL) + 1;
+ return(newnode);
+ }
+
+ if (loc >= NELS(pL)) { /* add at end */
+ NEXTEL(BACK(pL)) = newnode;
+ BACK(pL) = newnode;
+ NELS(pL) = NELS(pL) + 1;
+ return(newnode);
+ }
+
+ nod = FRONT(pL);
+ previous = nod;
+ for (i = 1; i <= pos; i++) { /* traverse the list */
+ if (NEXTEL(nod) == NULL) { /* going past end of the list */
+ break;
+ }
+ previous = nod;
+ nod = NEXTEL(previous);
+ }
+ /* previous is the node to be added after */
+
+ if (previous == BACK(pL)) { /* at the end */
+ NEXTEL(previous) = newnode;
+ BACK(pL) = newnode;
+ }
+ else { /* in the middle */
+ NEXTEL(newnode) = NEXTEL(previous);
+ NEXTEL(previous) = newnode;
+ }
+ NELS(pL) = NELS(pL) + 1;
+ return(newnode);
+
+} /* end LBS_INSERT */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_remove() deletes the pos'th element from a list */
+/* returns pointer to removed node */
+
+LBS_NODE_PTR lbs_remove(pL, pos)
+LBS_PTR pL; /* the list */
+int pos; /* the position, starting from 1 */
+{
+ LBS_NODE_PTR nod, previous, next;
+ int i;
+
+ if (pL == NULL) return(NULL);
+ if (lbs_empty(pL)) { /* nothing to delete */
+ return(NULL);
+ }
+
+ nod = FRONT(pL);
+ previous = nod;
+ for (i = 1; i < pos; i++) { /* traverse the list */
+ if (NEXTEL(nod) == NULL) { /* going past end of the list */
+ return(NULL);
+ }
+ previous = nod;
+ nod = NEXTEL(previous);
+ }
+ /* nod is the node to be removed */
+
+ if (nod == FRONT(pL)) { /* deleting first in the list */
+ if (nod == BACK(pL)) { /* deleting the only member */
+ FRONT(pL) = NULL;
+ BACK(pL) = NULL;
+ }
+ else {
+ FRONT(pL) = NEXTEL(nod);
+ }
+ }
+ else if (nod == BACK(pL)) { /* deleting last element */
+ NEXTEL(previous) = NULL;
+ BACK(pL) = previous;
+ }
+ else { /* deleting in the middle */
+ NEXTEL(previous) = NEXTEL(nod);
+ }
+ NELS(pL) = NELS(pL) - 1;
+ return(nod);
+} /* end LBS_REMOVE */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_get_first get first element */
+/* returns pointer to the node */
+
+LBS_NODE_PTR lbs_get_first(pL)
+LBS_PTR pL;
+{
+ if (pL == NULL) return(NULL);
+ return(FRONT(pL));
+} /* end LBS_GET_FIRST */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_get_last get last element */
+/* returns pointer to the node */
+
+LBS_NODE_PTR get_last(pL)
+LBS_PTR pL;
+{
+ if (pL == NULL) return(NULL);
+ return(BACK(pL));
+} /* end LBS_GET_LAST */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_get_nth get n'th element */
+/* returns pointer to the node */
+
+LBS_NODE_PTR lbs_get_nth(pL, n)
+LBS_PTR pL;
+int n;
+{
+ LBS_NODE_PTR nth;
+ int i;
+
+ if (pL == NULL) return(NULL);
+ if (n <= 0) return(NULL);
+ if (n == 1) return(FRONT(pL));
+ if (n == NELS(pL)) return(BACK(pL));
+
+ nth = FRONT(pL);
+ for (i = 1; i < n; i++) {
+ nth = NEXTEL(nth);
+ if (nth == NULL) { /* past the end */
+ return(NULL);
+ }
+ }
+
+ return(nth);
+} /* end LBS_GET_NTH */
+/**********************************************************************/
+
+
+
+/**********************************************************************/
+/* lbs_get_next_el get next element */
+/* returns pointer to the node */
+
+LBS_NODE_PTR lbs_get_next_el(pL, this)
+LBS_PTR pL;
+LBS_NODE_PTR this; /* current node, NULL to start off */
+{
+
+ if (pL == NULL) return(NULL);
+ if (this == NULL) return(FRONT(pL));
+
+ return(NEXTEL(this));
+} /* end LBS_GET_NEXT_EL */
+/**********************************************************************/
+
+
+
diff --git a/support/ltx2x/listsetc.h b/support/ltx2x/listsetc.h
new file mode 100644
index 0000000000..d9c7bd0750
--- /dev/null
+++ b/support/ltx2x/listsetc.h
@@ -0,0 +1,49 @@
+/* listsetc.h include file for lists, etc */
+
+#ifndef LISTSETC_H
+#define LISTSETC_H
+
+typedef char *genptr; /* a generic pointer */
+
+typedef struct lbs_node_struct { /* a listset node */
+ genptr dataptr;
+ struct lbs_node_struct *next;
+} LBS_NODE, *LBS_NODE_PTR;
+
+typedef struct dynagg { /* a listset header */
+ LBS_NODE_PTR front; /* first element */
+ LBS_NODE_PTR back; /* last element */
+ int numel; /* number of elements */
+} LBS, *LBS_PTR;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* MACROS */
+
+#define DATA(e) ((e)->dataptr)
+#define NEXTEL(e) ((e)->next)
+#define FRONT(d) ((d)->front)
+#define BACK(d) ((d)->back)
+#define NELS(d) ((d)->numel)
+
+
+/* Supplied functions */
+
+extern LBS_PTR lbs_init(); /* create an empty list/bag/set */
+extern int lbs_empty(); /* TRUE iff arg is empty */
+extern LBS_NODE_PTR lbs_prepend(); /* add element at front */
+extern LBS_NODE_PTR lbs_append(); /* add element at back */
+extern LBS_NODE_PTR lbs_insert(); /* add element after */
+extern LBS_NODE_PTR lbs_remove(); /* remove el at pos */
+extern LBS_NODE_PTR lbs_get_first(); /* the first el */
+extern LBS_NODE_PTR lbs_get_last(); /* the last el */
+extern LBS_NODE_PTR lbs_get_nth(); /* the n'th el */
+extern LBS_NODE_PTR lbs_get_next_el(); /* the next el */
+extern void free_lbsnode(); /* free an el */
+
+#endif
diff --git a/support/ltx2x/ltx2html.sty b/support/ltx2x/ltx2html.sty
new file mode 100644
index 0000000000..963b4e40a2
--- /dev/null
+++ b/support/ltx2x/ltx2html.sty
@@ -0,0 +1,38 @@
+% ltx2html.sty --- Some useful commands and environments when using
+% ltx2x to convert from LaTeX to HTML tagging.
+%
+% Author: Peter Wilson August 1996
+%
+\ProvidesPackage{ltx2html}[1996/08/29 ltx2x HTMLing]
+% \typeout{ltx2html.sty [1996/08/29 ltx2x HTMLing]}
+\RequirePackage{html} % the package file for the Perl program
+ % latex2html
+
+% The document title for the WWW browser.
+% If used, must be placed in the preamble.
+\newcommand{\mltitle}[1]{}
+
+% argument is for processing by LaTeX only
+\providecommand{\latex}[1]{#1}
+
+% argument is for HTML processing only
+\providecommand{\html}[1]{}
+
+% print argument as an SGML/HTML start tag
+\newcommand{\ST}[1]{\texttt{<#1>}}
+
+% print argument as an SGML/HTML end tag
+\newcommand{\ET}[1]{\texttt{</#1>}}
+
+% print HTML special characters
+\newcommand{\Amp}{\&}
+\newcommand{\GT}{\texttt{>}}
+\newcommand{\LT}{\texttt{<}}
+\newcommand{\HASH}{\#}
+
+% treat contents as a LaTeX comment but
+% translate contents into an HTML "verbatim" environment
+% Use as: \begin{htmlverbatim} ... \end{htmlverbatim}
+\excludecomment{htmlverbatim}
+
+\endinput \ No newline at end of file
diff --git a/support/ltx2x/ltx2x.ct b/support/ltx2x/ltx2x.ct
new file mode 100644
index 0000000000..9e4b0dac44
--- /dev/null
+++ b/support/ltx2x/ltx2x.ct
@@ -0,0 +1,7 @@
+ c= ltx2x.ct skeleton file for ltx2x to search for another
+ c= command table file
+ c= Author: Peter Wilson (pwilson@cme.nist.gov) August 1996
+
+INCLUDE= ZiLcH
+
+END_CTFILE= end of ltx2x.ct
diff --git a/support/ltx2x/ltx2x.html b/support/ltx2x/ltx2x.html
new file mode 100644
index 0000000000..cd87b79c50
--- /dev/null
+++ b/support/ltx2x/ltx2x.html
@@ -0,0 +1,8107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+(This document was automatically generated from LaTeX source by the ltx2x program.)
+<a name="HtMlSoD"></a><a href="#HtMlEoD">To the end</a>
+
+
+
+
+
+
+<p>
+
+
+<h1 align=center>
+ <i>LTX2X:</i> A LaTeX to X Auto-tagger
+</h1>
+<h3 align=center>
+Peter R. Wilson <br>
+ Catholic University of America<br><font size=-1>(This work was performed
+while a Guest Researcher at the National Institute of Standards and
+Technology)</font><br> <br>
+ Email: <tt>pwilson@cme.nist.gov</tt>
+</h3>
+<h3 align=center>
+January 1997
+</h3>
+
+
+
+<p><h4>Abstract</h4>
+<blockquote>
+
+ LTX2X is a table-driven program that will replace LaTeX commands
+by user defined text. This report describes the beta version of the system.
+LTX2X supports both a declaritive command style and an interpreted
+procedural language tentatively called EXPRESS-A.
+Details are given of the program functionality including examples.
+System installation instructions are provided.
+</blockquote>
+
+
+
+<p>
+
+
+
+<p>
+
+
+
+<p>
+<h2>Introduction</h2>
+ <a name="sec:introduction"></a>
+
+
+<p>LaTeX [<a href="#LAMPORT94">LAMPORT94</a>], which is built on top of TeX [<a href="#KNUTH84a">KNUTH84a</a>],
+is a document tagging system
+that is very popular in the academic and scientific publishing communities
+because of the high quality typeset material that the system outputs
+for normal text and especially for mathematics.
+
+
+<p>In particular, many of the documents forming the
+International Standard ISO 10303, commonly referred to as STEP [<a href="#STEPIS">STEPIS</a>],
+have been written using LaTeX as
+the document tagging language. Lately there have been moves towards converting
+the STEP documents to embody SGML [<a href="#GOLDFARB90">GOLDFARB90</a>]
+rather than LaTeX markup. This has led
+to an interest in the automatic conversion from LaTeX to SGML
+documents.
+The LTX2X system is an initial attempt to provide a generic capability for
+converting LaTeX tags into other kinds of tags.
+
+
+<p>The LTX2X system described below is in a beta release state. That is, there
+is probably some more work to be done on it but experience from use is
+needed to determine desirable additional functionality. However, the code
+has been stable for some time.
+Bug reports or suggested
+enhancements (especially if the suggestions are accompanied by working code)
+are encouraged, as are constructive comments about this document.
+
+
+<p>Essentially, LTX2X reads a file containing LaTeX markup,
+replaces the LaTeX commands by user-defined text, and writes the result
+out to another file. The program operates from a command table that specifies
+the replacement text. In general, no programming knowledge or skills are
+required to write a command table, which LTX2X will then interpret.
+Some knowledge of LaTeX is required, but no more than is necessary
+for authoring a LaTeX document.
+
+
+<p>LTX2X has proved capable of performing such functions as:
+<ul>
+
+
+ <li> Conversion of documents marked up according to a specific LaTeX
+ documentclass to documents tagged according to a specific SGML DTD.
+
+ <li> Removal of LaTeX commands to produce deTeXed source.
+
+ <li> Conversion of simple LaTeX documents to
+ HTML [<a href="#MUSCIANO96">MUSCIANO96</a>] tagged documents for publication on the
+ World Wide Web.
+</ul>
+
+
+
+<p>The remainder of this introduction gives an overview of the LTX2X program.
+The command table is described in more detail in section <a href="#sec:command-table">sec:command-table</a>
+and information on running the LTX2X program is provided in
+section <a href="#sec:program">sec:program</a>. Section <a href="#sec:expressa">sec:expressa</a> gives an
+overview
+of the EXPRESS-A language. (Footnote: The overview is necessarily
+rather brief as I am shortly moving to a new place of employment and
+EXPRESS-A is the latest addition to the system.)
+Although the functionality available through the command table facility is
+suitable for many tasks, especially since an interpreter for the EXPRESS-A
+general programming language is included within LTX2X,
+section <a href="#sec:special">sec:special</a> gives details on how the system can
+be extended for cases where this proves to be inadequate.
+
+
+<p>The report ends with several appendices. An example command table for
+deTeXing a document is reproduced in <a href="#sec:detexing">sec:detexing</a> and some of
+the issues in converting from LaTeX to HTML are discussed
+in <a href="#sec:htmling">sec:htmling</a>. The known limitations
+of LTX2X are listed in <a href="#sec:limitations">sec:limitations</a> and a summary of the command
+table facilities are given in <a href="#sec:summary">sec:summary</a>. Appendix <a href="#sec:install">sec:install</a>
+provides instructions on installing the LTX2X program, together with copyright
+and warranty information. Finally, <a href="#sec:ctabgrammar">sec:ctabgrammar</a> and <a href="#sec:expgrammar">sec:expgrammar</a>provide grammars for the command table and EXPRESS-A, respectively.
+
+
+<p>
+<h3>Overview</h3>
+
+
+
+<p>The intent of Leslie Lamport, the author of LaTeX, was to provide a document
+tagging system that enabled the capture of the logical structure of a document.
+This system uses Donald Knuth's TeX system as its typesetting engine [<a href="#KNUTH84a">KNUTH84a</a>],
+and thus has an inherent capability for high quality typesetting.
+
+
+<p>All LaTeX commands are distinguished by starting with a backslash (<samp>\</samp>).
+Generally speaking, the name of a command is a string of alphabetic characters
+(e.g. <samp>\acommand</samp>). Commands may take arguments. Required arguments are
+enclosed in curly braces (i.e. <samp>{</samp> and <samp>}</samp>). Optional arguments
+are enclosed in square brackets (i.e. <samp>[</samp> and <samp>]</samp>). The general syntax
+for a command is the command name (preceded by a backslash) followed by the
+argument list with a maximum (Footnote: Under very unusual
+circumstances this limit may be exceeded.) of nine arguments.
+
+
+<p>The LTX2X program reads a LaTeX document file and outputs a
+transformation of this file. By default it outputs the normal text
+while for each LaTeX command and argument performs some
+user-specified actions; typically these actions involve the output
+of specific text corresponding to the particular command.
+The actions are specified in a <em>command table</em> file, written by the user,
+which is read into the LTX2X system before document processing is
+begun. A command table consists of a listing of the LaTeX commands of interest
+together with the desired actiond for each of these commands and their
+arguments.
+Different effects may be easily obtained by changing the command table
+file. For example, a simple command table file may be written that will delete
+all the LaTeX commands from a document, resulting in a plain ASCII file
+with no embedded markup. (Footnote: To afficionados,
+this process is known as de-TeX ing.)
+A more complex command table may be written that will replace LaTeX tags
+with appropriate SGML tags.
+
+
+<p>In some circles it is traditional to introduce a programming
+language by providing an example program that prints `Hello world'.
+In contrast, the following command table file called <tt>bye.ct</tt>,
+when used in conjunction
+with a typical vanilla LaTeX file, will transform the LaTeX file
+to a file that consists only of the words `Goodbye document'.
+
+
+<p><pre>
+C= bye.ct "Goodbye document" for ltx2x
+
+TYPE= COMMAND
+NAME= \documentclass
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case a LaTeX v2.09 document
+TYPE= COMMAND
+NAME= \documentstyle
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case there is no \documentclass/style command
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+END_CTFILE= end of bye.ct
+</pre>
+
+<p>Essentially the command table instructs LTX2X what to print for each LaTeX
+command. A command table file consists of a series of commands, one per line
+and introduced by a keyword such as <samp>TYPE=</samp>. Keywords are case
+insensitive but by convention are written in upper case. Comments in
+a command table are introduced by the keyword <samp>C=</samp>.
+
+
+<p>The main body of a command table consists of the specification of
+LaTeX commands of interest and the actions to be taken for these.
+Each specification commences with the keyword <samp>TYPE=</samp> and is
+completed by the keyword <samp>END_TYPE</samp>, the relevant actions
+being listed between these two keywords.
+
+
+<p>LTX2X treats some LaTeX commands specially; among these are
+<samp>\begin{document}</samp> and <samp>\end{document}</samp>. In a command table
+these are specified by the types <samp>TYPE= BEGIN_DOCUMENT</samp> and
+<samp>TYPE= END_DOCUMENT</samp>. The actions at
+<samp>\begin{document}</samp> are firstly to print the string `Goodbye document'
+(specified in the line <samp>START_TAG= "Goodbye document"</samp>) and
+secondly to stop printing any output (specified in the line
+<samp>PC_AT_END= NO_PRINT</samp>).
+
+
+<p>By not specifying the <samp>END_DOCUMENT</samp> entry, the default
+action is used for the <samp>\end{document}</samp> command.
+
+
+<p>The command table entries for the commands <samp>\documentclass</samp> and
+<samp>\documentstyle</samp> specify that, if either of these is in the
+source document, then it is to be replaced by the text string
+<samp>"Goodbye document"</samp>, and then all further printing is to
+be switched off.
+
+
+<p>The other three entries in the command table specify the actions for any
+other kind of LaTeX command. The keyword <samp>OTHER_BEGIN</samp>
+signifies a LaTeX command of the form <samp>\begin{name}</samp> and
+<samp>OTHER_END</samp> signifies a command of the form <samp>\end{name}</samp>.
+The keyword <samp>OTHER_COMMAND</samp> signifies any other kind of
+LaTeX command (e.g., <samp>\acommand ... </samp>). The actions declared
+for these are all <samp>PRINT_CONTROL= NO_PRINT</samp> which shuts off
+any printing of the command or its arguments. In the command table <tt>bye.ct</tt>
+these are only included to prevent printing before the
+<samp>\begin{document}</samp>.
+
+
+<p>To run LTX2X with the above command table, type the following (where <samp>></samp>
+is assumed to be the system prompt):
+<pre>
+> ltx2x -f bye.ct input.tex output.tex
+</pre>
+where <tt>bye.ct</tt> is the name of the command table, and
+<tt>input.tex</tt> and <tt>output.tex</tt> are the names of the input LaTeX
+file and the resulting processed file respectively.
+
+
+<p>
+ As an example of a more useful command table file, the following one called
+<tt>decomm.ct</tt> will remove all LaTeX comments from a typical
+LaTeX source file.
+
+
+<p><pre>
+C= decomm.ct Command table file for ltx2x to de-comment LaTeX source
+
+C= ------------------------------------ set newline characters
+ESCAPE_CHAR= ?
+NEWLINE_CHAR= N
+
+C= ----------------------------------- built in commands
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "\begin{document}"
+END_TYPE
+
+TYPE= END_DOCUMENT
+ START_TAG= "\end{document}"
+END_TYPE
+
+TYPE= BEGIN_VERB
+ START_TAG= "\verb|"
+END_TYPE
+
+TYPE= END_VERB
+ START_TAG= "|"
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "\begin{verbatim}"
+END_TYPE
+</pre>
+<samp>TYPE= END_VERBATIM</samp> <br>
+<samp> START_TAG= "\end{verbatim}"</samp> <br>
+<samp>END_TYPE</samp>
+<pre>
+TYPE= LBRACE
+ START_TAG= "{"
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= "}"
+END_TYPE
+
+TYPE= PARAGRAPH
+ START_TAG= "?N?N "
+END_TYPE
+
+C= ------------------- define '\item' tags within lists
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "\begin{itemize}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "\begin{enumerate}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "\begin{description}"
+ START_ITEM= "\item"
+ START_ITEM_PARAM= "["
+ END_ITEM_PARAM= "] "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= itemize
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= enumerate
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+END_TYPE
+
+C= --------------------- pass through all other LaTeX commands
+
+TYPE= OTHER_COMMAND
+END_TYPE
+
+TYPE= OTHER_BEGIN
+END_TYPE
+
+TYPE= OTHER_END
+END_TYPE
+
+END_CTFILE= end of file decomm.ct
+</pre>
+In the above command table file, the first pair of commands (<samp>ESCAPE_CHAR=</samp>
+and <samp>NEWLINE_CHAR=</samp>) define the character pair that are to be used to
+signify a `newline' within a tag. An example of their use is later in the
+file in the <samp>PARAGRAPH</samp> command type.
+
+
+<p>As indicated above, LTX2X treats some LaTeX commands specially.
+These are listed next in the
+command table. The special LaTeX commands are the begin and end of the
+<samp>document</samp> and <samp>verbatim</samp>
+environments, together with the <samp>\verb</samp> command, left and right braces,
+the <samp>\ </samp> command, and the LTX2X <samp>PARAGRAPH</samp> specification.
+There are default actions for these, but apart from the <samp>\ </samp> command
+the defaults are not appropriate in this case.
+Above, the actions are to replace the
+LaTeX command by the string forming the LaTeX command. The exception
+is that paragraphs (the <samp>PARAGRAPH</samp> specification) should start
+with at least one blank line and be indented some spaces.
+
+
+<p>The LaTeX <samp>\item</samp> command is used within lists. LTX2X has to be
+told how to treat the <samp>\item</samp> command within each kind of list. This
+has been done above for the <samp>itemize</samp>, <samp>enumerate</samp> and
+<samp>description</samp> environments.
+
+
+<p>The final instructions in the command table file tell LTX2X to pass through the
+text of all other commands and their arguments. The end of the command table file
+is either the physical end of the file or the command <samp>END_CTFILE=</samp>,
+whichever comes first. The <samp>END_CTFILE=</samp> command acts like the
+<samp>C=</samp> command in that arbitrary text can be put after the command.
+
+
+<p>To use the <tt>decomm.ct</tt> command table to de-comment a LaTeX file, type
+the following (where <samp>></samp> is assumed to be the system prompt):
+<pre>
+> ltx2x -f decomm.ct input.tex output.tex
+</pre>
+where <tt>input.tex</tt> and <tt>output.tex</tt> are the names of the input LaTeX
+file for de-commenting and the resulting de-commented version respectively.
+
+
+<p>
+<h2>The command table file</h2>
+ <a name="sec:command-table"></a>
+
+
+<p>By default, LTX2X does not output any LaTeX comments.
+Otherwise, whenever it comes
+across a LaTeX command it looks at the data in the command table file to determine
+what actions it should take. The two most typical actions are either
+to print out the command as read in, or to replace the command by some (possibly
+empty) text.
+
+
+<p>Each line in a command table file is either blank or starts with a keyword followed
+by one or more blanks. For
+example, a comment in the file is a line that starts with <samp>C= </samp>;
+the remainder of the line is any comment text. Comments may be placed anywhere
+in the file.
+
+
+<p>
+
+<h3>Special print characters in tags</h3>
+
+
+
+<p>LTX2X is written in C [<a href="#KERNIGHAN88">KERNIGHAN88</a>].
+The C language enables certain non-printing characters
+to be defined. These are typically written in the form <samp>\c</samp> where <samp>\</samp>
+is the C escape character and <samp>c</samp>
+is a particular character. LTX2X understands some of these special printing
+characters and the command table enables these to be given non-default values.
+
+
+<p>The default escape character (<samp>\</samp>) may be redefined via the
+<samp>ESCAPE_CHAR=</samp> command. For example,
+<pre>
+ESCAPE_CHAR= ?
+</pre>
+will make the question mark character the escape character. Typically, the escape
+character is changed in most command table s to avoid clashing with the LaTeX <samp>\</samp>
+character.
+The following commands
+can be used to redefine the C special characters. Each of these commands takes
+a single character as its value. If a relevant command is not given, then the
+default value is used.
+<dl>
+<dt><samp>NEWLINE_CHAR=</samp>
+<dd> a new line (default is <samp>n</samp>) <br>
+<dt><samp>HORIZONTAL_TAB_CHAR=</samp>
+<dd> horizontal tab (default is <samp>t</samp>) <br>
+<dt><samp>VERTICAL_TAB_CHAR=</samp>
+<dd> vertical tab (default is <samp>v</samp>) <br>
+<dt><samp>BACKSPACE_CHAR=</samp>
+<dd> backspace (default is <samp>b</samp>) <br>
+<dt><samp>CARRIAGE_RETURN_CHAR=</samp>
+<dd> carriage return (default is <samp>r</samp>) <br>
+<dt><samp>FORMFEED_CHAR=</samp>
+<dd> formfeed (default is <samp>f</samp>) <br>
+<dt><samp>AUDIBLE_ALLERT_CHAR=</samp>
+<dd> beep the terminal (default is <samp>a</samp>) <br>
+<dt><samp>HEX_CHAR=</samp>
+<dd> following characters form the hexadecimal number of
+ the character
+ to be printed (default is <samp>x</samp>) (e.g. <samp>?xA3</samp>) <br>
+</dl>
+ These command lines are all optional within a command table and their ordering is
+immaterial. However, if any are present then they must be at the beginning of
+the command table.
+
+
+<p>The above special characters are useful when specifying the replacement text
+for LaTeX commands.
+
+
+<p>
+
+<h3>LaTeX command types</h3>
+
+
+
+<p>The commands for controlling the actions performed on LaTeX commands
+are enclosed between the command lines <samp>TYPE= </samp> and <samp>END_TYPE</samp>,
+as below.
+<pre>
+TYPE= CommandType
+ C= a possibly empty set of commands
+END_TYPE
+</pre>
+where <samp>CommandType</samp> is an LTX2X keyword signifying the kind of LaTeX
+command being specified.
+
+
+<p>
+<h4>Built in command types</h4>
+
+
+<p>Some LaTeX commands are pre-defined within LTX2X. Default actions
+are provided for these but it is recommended that type specifications
+for each of these commands be put in the command table anyway. The keywords for
+these commands are:
+<dl>
+<dt><samp>BEGIN_DOCUMENT</samp>
+<dd> Corresponds to the LaTeX command
+ <samp>\begin{document}</samp>.
+<dt><samp>END_DOCUMENT</samp>
+<dd> Corresponds to the LaTeX command
+ <samp>\end{document}</samp>.
+<dt><samp>BEGIN_VERBATIM</samp>
+<dd> Corresponds to the LaTeX commands
+ <samp>\begin{verbatim}</samp> and <br>
+ <samp>\begin{verbatim*}</samp>.
+<dt><samp>END_VERBATIM</samp>
+<dd> Corresponds to the LaTeX commands
+ <samp>\end{verbatim}</samp> and <samp>\end{verbatim*}</samp>.
+<dt><samp>BEGIN_VERB</samp>
+<dd> Corresponds to the LaTeX commands
+ <samp>\verb</samp> and <samp>\verb*</samp>, together with the succeeding character.
+<dt><samp>END_VERB</samp>
+<dd> Corresponds to the appearance of the character
+ that completes the LaTeX commands
+ <samp>\verb</samp> and <samp>\verb*</samp>.
+<dt><samp>LBRACE</samp>
+<dd> Corresponds to the LaTeX left brace character
+ <samp>{</samp>.
+<dt><samp>RBRACE</samp>
+<dd> Corresponds to the LaTeX right brace character
+ <samp>}</samp>.
+<dt><samp>BEGIN_DOLLAR</samp>
+<dd> Corresponds to the LaTeX <samp>$</samp> symbol signalling the
+ start of an in-text math formula.
+<dt><samp>END_DOLLAR</samp>
+<dd> Corresponds to the LaTeX <samp>$</samp> symbol signalling the
+ end of an in-text math formula.
+<dt><samp>PARAGRAPH</samp>
+<dd> Corresponds to the LaTeX protocol of a blank
+ line signalling the start/end of a paragraph.
+<dt><samp>SLASH_SPACE</samp>
+<dd> Corresponds to the LaTeX <samp>\ </samp> command.
+<dt><samp>OTHER_COMMAND</samp>
+<dd> Corresponds to any LaTeX command of the form
+ <samp>\command</samp> not specified elsewhere within the command table.
+<dt><samp>OTHER_BEGIN</samp>
+<dd> Corresponds to any LaTeX command of the form
+ <samp>\begin{environment}</samp> not specified elsewhere within the command table.
+<dt><samp>OTHER_END</samp>
+<dd> Corresponds to any LaTeX command of the form
+ <samp>\end{environment}</samp> not specified elsewhere within the command table.
+</dl>
+
+
+<p>
+ The ordering of these built in type specifications is immaterial. If
+any of the above are not specified within the command table then LTX2X will use
+their default action.
+ With the exception of the <samp>SLASH_SPACE</samp> command type, the
+default action is to do nothing (i.e., produce no output).
+The default action for the <samp>SLASH_SPACE</samp>
+command type is to output a space.
+
+
+<p>
+<h4>Optional command types</h4>
+
+
+<p>For the purposes of LTX2X, LaTeX commands are divided into various classes.
+The keywords for these clases, and the class descriptions, are listed below.
+
+
+<p><dl>
+<dt><samp>TEX_CHAR</samp>
+<dd> Corresponding to LaTeX's special characters (with the exception
+ of the $, { and } characters).
+<dt><samp>CHAR_COMMAND</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\c</samp> where <samp>c</samp> is a single non-alphabetic character.
+<dt><samp>COMMAND</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\command</samp>, where <samp>command</samp> is the name of the command (except for
+ <samp>\begin</samp>, <samp>\end</samp> and <samp>\item</samp>).
+<dt><samp>BEGIN_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\begin{environment}</samp> where <samp>environment</samp> is the name of the
+ environment, except for those list environments whose bodies
+ consist of <samp>\item</samp> commands.
+<dt><samp>END_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\end{environment}</samp>, with the same restrictions as for <samp>BEGIN_ENV</samp>.
+<dt><samp>BEGIN_LIST_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\begin{environment}</samp> where <samp>environment</samp> is the name of an
+ environment whose body consists of <samp>\item</samp> commands.
+<dt><samp>END_LIST_ENV</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\end{environment}</samp> to match <samp>BEGIN_LIST_ENV</samp>.
+<dt><samp>VCOMMAND</samp>
+<dd> Corresponding to a LaTeX <samp>\verb</samp>-like command.
+<dt><samp>BEGIN_VENV</samp>
+<dd> Corresponding to the start of a verbatim-like
+ environment.
+<dt><samp>END_VENV</samp>
+<dd> Corresponding to the end of a verbatim-like
+ environment.
+<dt><samp>SECTIONING</samp>
+<dd> Corresponding to LaTeX commands of the type
+ <samp>\command</samp>, where <samp>command</samp> is a document sectioning command
+ such as <samp>chapter</samp> or <samp>subsection</samp>.
+<dt><samp>SPECIAL</samp>
+<dd> Reserved for possible future use.
+<dt><samp>SPECIAL_COMMAND</samp>
+<dd> Corresponding to the <samp>COMMAND</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_BEGIN_ENV</samp>
+<dd> Corresponding to the <samp>BEGIN_ENV</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_END_ENV</samp>
+<dd> Corresponding to the <samp>END_ENV</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_BEGIN_LIST</samp>
+<dd> Corresponding to the <samp>BEGIN_LIST_ENV</samp>
+ keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_END_LIST</samp>
+<dd> Corresponding to the <samp>END_LIST_ENV</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>SPECIAL_SECTIONING</samp>
+<dd> Corresponding to the <samp>SECTIONING</samp> keyword,
+ except that some special output processing is to be defined.
+<dt><samp>_PICTURE_</samp>
+<dd> Corresponding to some of the LaTeX picture
+ drawing commands.
+<dt><samp>COMMAND_...</samp>
+<dd> Corresponding to some of the LaTeX commands
+ whose arrangements of required and optional arguments are untypical.
+</dl>
+
+
+<p>The ordering of these types within a command table is immaterial.
+
+
+<p>Each of the above type specifications requires a <samp>NAME=</samp> command,
+whose value is the
+name of the relevant command or environment being specified. For example, the
+following is a (partial) specification of the figure environment and the caption
+command.
+
+
+<p><pre>
+TYPE= BEGIN_ENV
+NAME= figure
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+END_TYPE
+
+TYPE= COMMAND
+NAME= \caption
+END_TYPE
+</pre>
+
+<p>
+<h3>Command action tags</h3>
+
+
+
+<p>When LTX2X reads a LaTeX command it performs the following actions:
+<ol>
+
+
+ <li> Looks up the name of the command or environment in the command table. If
+ it is not found, then the appropriate default type is used.
+
+ <li> Sets the printing mode according to the <samp>PC_AT_START=</samp>
+ command.
+
+ <li> Performs the actions specified in the command table by the
+ <samp>START_TAG=</samp> command.
+
+ <li> Processes any specified arguments to the command.
+
+ <li> Performs the actions specified in the command table by the <samp>END_TAG=</samp>
+ command.
+
+ <li> Sets the printing mode according to the <samp>PC_AT_END=</samp> command.
+</ol>
+
+
+
+<p><dl>
+<dt>NOTES
+<dd>:
+<ol>
+
+
+ <li> Except for the default processing of <samp>OTHER_</samp> types, it does not
+ output the command itself.
+
+ <li> If a tag action is not specified, then the default action is null (e.g.,
+ nothing will appear in the output).
+</ol>
+
+</dl>
+
+
+<p>Within a command table all text strings for output are enclosed within double
+quotes. For example:
+<pre>
+START_TAG= "Some "text" string\n another line of text."
+</pre>
+
+<p>Assuming that <samp>\n</samp> means a newline, when this string action is performed
+by LTX2X it will appear in the output file as:
+<pre>
+Some "text" string
+another line of text.
+</pre>
+
+<p>A text string starts with the first double quote and ends with the last double
+quote on the command line. A text string has to be written on a single line
+within the command table. C language special print characters can be embedded within the
+text string (e.g. the <samp>\n</samp> for a newline in the above example). Remember
+that the first section of the command table is used for specifying the
+particular command table version of these.
+
+
+<p>If a text string is too long to fit comfortably on a single line in the
+command table, it may be continued via the <samp>STRING:</samp> command. As many of these
+can be used in succession as required (subject to internal limitations within LTX2X).
+
+
+<p>For instance,
+<pre>
+START_TAG= "Some "text" string\n"
+ STRING: "another line of text."
+</pre>
+has the same effect as the previous example.
+
+
+<p>The following specification is designed to write out the contents of the
+<samp>\caption</samp> command (Footnote: Strictly speaking, the specification does not
+do this exactly, but this simplified illustration will be corrected in
+the next sections.) ,
+preceded by the word `CAPTION' and followed by at least one
+blank line (assuming that the escape character has been set to <samp>?</samp>).
+
+
+<p><pre>
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+END_TYPE
+</pre>
+Assuming that somewhere in a LaTeX file there is the command
+<pre>
+stuff
+\caption{This is a caption.}
+more stuff
+</pre>
+then the expected effect (see footnote) is
+<pre>
+stuff
+
+ CAPTION This is a caption.
+
+more stuff
+</pre>
+
+<p>
+<h3>Argument actions</h3>
+
+
+
+<p>LaTeX commands can take arguments. The text for a required argument is
+enclosed in curly braces, while the text for an optional argument is enclosed
+in square brackets. LTX2X can be directed to perform actions at the start and end
+of each argument.
+
+
+<p>The number of required arguments is specified by the command line
+<samp>REQPARAMS=</samp>
+where the value of the command is a digit between 1 and 9 inclusive.
+
+
+<p>LTX2X assumes that a command can have only one optional argument, and that this
+is either first or last in the argument list. The potential presence of an
+optional argument is indicated by the command line <samp>OPT_PARAM=</samp>,
+where the
+value is either the keyword <samp>FIRST</samp> (for first in the list) or
+<samp>LAST</samp> (for last in the list).
+
+
+<p>The actions to be performed at the start and end of each required argument
+are specified via the commands <samp>START_TAG_1=</samp> and <samp>END_TAG_1=</samp>
+for the first required argument, through <samp>START_TAG_9=</samp> and
+<samp>END_TAG_9=</samp> for the ninth argument.
+The actions to be performed at the start and end of the optional argument
+are specified by the command lines <samp>START_OPT=</samp> and <samp>END_OPT=</samp>.
+
+
+<p>The argument delimiters (the braces or brackets) are not printed.
+
+
+<p>In the simplest case, the action is to print a specified text string
+(enclosed in double quotes, and continued with <samp>STRING:</samp> commands
+if necessary). Other kinds of actions are also possible.
+An unspecified tag defaults to doing no action.
+
+
+<p>
+<h4>Print options</h4>
+
+
+<p>
+<h5>Argument processing</h5>
+
+
+
+<p>By default, LTX2X processes (i.e. outputs as appropriate)
+the text of a argument.
+Printing of the argument text may be disabled, if required. The command line
+that controls argument printing is of the form <samp>PRINT_P1=</samp> through
+<samp>PRINT_P9=</samp> for required arguments and
+<samp>PRINT_OPT=</samp> for the optional
+argument. The value of these commands is one from several keywords,
+the most common being <samp>NO_PRINT</samp>; this
+switches off printing of the text of the indicated argument.
+Default printing is resumed after the indicated argument.
+
+
+<p>Continuing the caption example from earlier, we can now complete it. The full
+syntax of the LaTeX command is:
+<pre>
+\caption[optional table of contents entry]{Caption in the text}
+</pre>
+That is, it has one required argument, which prints the caption text both in
+the body of the document and in the table of contents, unless the first optional
+argument is present, in which case its value gets printed in the table of
+contents instead.
+
+
+<p>Assume that an instance of the caption command in a document is:
+<pre>
+Some stuff
+\caption[Short caption]{Long caption for the body of the text.}
+More stuff
+</pre>
+Recall the previous command table caption specification. The actual output from
+processing this would be
+<pre>
+Some stuff
+
+ CAPTION [Short caption]{Long caption for the body of the text.}
+
+More stuff
+</pre>
+because, unless LTX2X is told that there are command arguments and how they should
+be treated, it will just print them out together with their surrounding
+delimiters.
+
+
+<p>The following command table entry will give more acceptable results.
+<pre>
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+</pre>
+
+<p>For the above captioning instance, the output will now be:
+<pre>
+Some stuff
+
+ CAPTION Long caption for the body of the text.
+
+More stuff
+</pre>
+
+<p>The default print mode is to print text to the output file.
+
+
+<p>The keywords that can be used to control argument printing are:
+<dl>
+<dt><samp>NO_PRINT</samp>
+<dd> Do not print anything.
+<dt><samp>TO_SYSBUF</samp>
+<dd> Print to the LTX2X system buffer.
+<dt><samp>TO_BUFFER num</samp>
+<dd> Print to the LTX2X buffer
+ number <samp>num</samp>.
+<dt><samp>TO_FILE name</samp>
+<dd> Print to the file called <samp>name</samp>.
+<dt><samp>NO_OP</samp>
+<dd> Skip all processing of the argument.
+</dl>
+Note that even if the print mode is set to <samp>NO_PRINT</samp>, the
+argument text will still be processed. Only the <samp>NO_OP</samp>
+specification temporarly turns off the processing.
+
+
+<p>
+
+<h5>General printing</h5>
+
+
+
+<p>Just as the printing mode can be set for each argument, it can also be
+set at the start and end of processing a LaTeX command or environment.
+
+
+<p>The specifications <samp>PC_AT_START=</samp> and <samp>PC_AT_END=</samp>
+can be used to set the printing mode at the start of processing a command
+and at the end, respectively. The keywords that can be used in these
+specifications are:
+<dl>
+<dt><samp>NO_PRINT</samp>
+<dd> Do not print anything.
+<dt><samp>TO_SYSBUF</samp>
+<dd> Print to the LTX2X system buffer.
+<dt><samp>TO_BUFFER num</samp>
+<dd> Print to the LTX2X buffer
+ number <samp>num</samp>.
+<dt><samp>TO_FILE name</samp>
+<dd> Print to the file called <samp>name</samp>.
+<dt><samp>RESET</samp>
+<dd> Reset the print mode back to what it was.
+</dl>
+
+
+<p>Unlike the argument printing controls, the print mode is not
+automatically reset. This has to be explicitly specified.
+
+
+<p>As an example, assume that it is required to remove all <samp>figure</samp>
+environments from a LaTeX source and put them into a file on their own.
+The following command table code could be used to accomplish this.
+<pre>
+TYPE= BEGIN_ENV
+NAME= figure
+ PC_AT_START= TO_FILE allfigs.tex
+ START_TAG= "?n\begin{figure}"
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+ START_TAG= "\end{figure}"
+ PC_AT_END= RESET
+END_TYPE
+</pre>
+When a LaTeX <samp>figure</samp> environment is started, printing is switched
+to go to the file called <tt>allfigs.tex</tt>. At the end of the <samp>figure</samp>
+environment, the print mode is reset back to what it was before the environment
+began. If at the first <samp>figure</samp> environment the <tt>allfigs.tex</tt>
+file did not exist, then LTX2X would create it automatically.
+
+
+<p>
+<h5>Read actions</h5>
+
+
+
+<p>As noted above, one of the actions that can be specified for a
+LaTeX comand's argument is to set the print mode for printing to a buffer
+or a file. Similarly there are actions which will read from a buffer or
+a file and print the contents. Within an argument tag these kinds of actions are
+specified via the keyword <samp>SOURCE:</samp>. This can take one of several
+values:
+<dl>
+<dt><samp>SYSBUF</samp>
+<dd> Print the contents of the LTX2X system buffer.
+<dt><samp>BUFFER num</samp>
+<dd> Print the contents of the LTX2X buffer
+ number <samp>num</samp>.
+<dt><samp>FILE name</samp>
+<dd> Print the contents of the file called
+ <samp>name</samp>.
+</dl>
+
+
+<p>In a previous example, the LaTeX <samp>figure</samp> environments
+were all written to the file <tt>allfig.tex</tt>. This file could be read
+in again just before the end of the document so that all figures will be
+typeset after everything else.
+<pre>
+TYPE= END_DOCUMENT
+ END_TAG= "?n % figures collected here by LTX2X ?n"
+ SOURCE: FILE allfigs.tex
+ STRING: "?n\end{document}?n"
+END_TYPE
+</pre>
+
+<p>As another example of the use of the print actions consider the LaTeX
+<samp>\maketitle</samp> command. This typesets the arguments of the <samp>\title</samp>,
+<samp>\author</samp> and <samp>\date</samp> commands, which must have been previously
+specified but not necessarily in this ordering. Here is one way this can
+be simulated using LTX2X.
+<pre>
+TYPE= COMMAND
+NAME= \title
+ START_TAG=
+ RESET_BUFFER: 1
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \author
+ START_TAG=
+ RESET_BUFFER: 2
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 2
+END_TYPE
+
+TYPE= COMMAND
+NAME= \date
+ START_TAG=
+ RESET_BUFFER: 3
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \maketitle
+ START_TAG= "?n"
+ SOURCE: BUFFER 1
+ STRING: "?n?n"
+ SOURCE: BUFFER 2
+ STRING: "?n?n"
+ SOURCE: BUFFER 3
+ STRING: "?n?n"
+ END_TAG=
+ RESET_BUFFER: 1
+ RESET_BUFFER: 2
+ RESET_BUFFER: 3
+END_TYPE
+</pre>
+For the <samp>\title</samp> command, the print mode for its argument is set
+for printing to the buffer number 1. The single action at the start of
+the command is to make sure that buffer 1 is empty (the line
+<samp>RESET_BUFFER: 1</samp>). The actions for the <samp>\author</samp> and
+<samp>\date</samp> commands are similar, except that they print their argument
+texts to buffers 2 and 3 respectively.
+
+
+<p>The <samp>\maketitle</samp> command takes no arguments, so all actions
+must be placed under <samp>START_TAG=</samp> and/or <samp>END_TAG=</samp>.
+There are a set of actions specified for <samp>START_TAG=</samp>. Firstly
+a newline is printed and this is followed by the contents of buffer 1
+(i.e., the text of the argument of the <samp>\title</samp> command).
+Then two new lines are printed, followed by the contents of buffer 2
+(the author). Finally another two newlines are printed, the contents
+of buffer 3 (the date), and another two newlines. The actions
+for <samp>END_TAG=</samp> are to clear the contents of the three buffers.
+
+
+<p>Just to extend the example, here is a specification for the
+LaTeX <samp>\thanks</samp> command. LTX2X is not designed to do footnoting
+(as it does not do page breaking)
+so instead the thanks text will be placed inside parentheses on a new line.
+<pre>
+TYPE= COMMAND
+NAME= \thanks
+ START_TAG= "?n ("
+ REQPARAMS= 1
+ END_TAG= ") "
+END_TYPE
+</pre>
+
+<p>
+ Given these command table specification and the following portion of a
+LaTeX document
+<pre>
+\date{29 February 2000}
+\title{The Calculation of Leap Days\thanks{Originally published in JIR}}
+\author{A. N. Other}
+...
+\maketitle
+</pre>
+then output from LTX2X will be:
+<pre>
+The Calculation of Leap Days
+ (Originally published in JIR)
+
+A. N. Other
+
+29 February 2000
+</pre>
+Note that as the <samp>\thanks</samp> command appears within the argument of the
+<samp>\title</samp> command, it is written to the same place as the text of
+the argument of <samp>\title</samp>. Thus, it also gets written to the output file
+when <samp>\maketitle</samp> is processed.
+
+
+<p>
+<h4>Print switching</h4>
+
+
+<p>There are individual actions that enable the printing destination
+to be changed at will within the action set for any particular tag.
+<dl>
+<dt><samp>SWITCH_TO_BUFFER: num</samp>
+<dd> Direct any following printing
+ to the LTX2X buffer number <samp>num</samp>.
+<dt><samp>SWITCH_TO_FILE: name</samp>
+<dd> Direct any following printing
+ to the file called <samp>name</samp>.
+<dt><samp>SWITCH_TO_SYSBUF</samp>
+<dd> Direct any following printing
+ to the LTX2X system buffer.
+<dt><samp>SWITCH_BACK:</samp>
+<dd> Undo the effect of the last
+ <samp>SWITCH_TO...</samp> action.
+</dl>
+
+
+<p>As an example of the utility of this type of action, consider
+again the LaTeX <samp>\maketitle</samp> command. When LaTeX processes
+this command, it typesets the date as specified by the <samp>\date</samp>
+command, or if this has not been specified then it prints the current
+date instead. We can arrange for LTX2X to do something similar by
+adding the following to the command table shown earlier for the <samp>\date</samp>
+and <samp>\maketitle</samp> commands.
+<pre>
+TYPE= COMMAND
+NAME= \documentclass
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+ START_TAG=
+ c= Initialise buffer 3 to `Today'
+ RESET_BUFFER: 3
+ SWITCH_TO_BUFFER: 3
+ STRING: "Today"
+ SWITCH_BACK:
+END_TYPE
+</pre>
+At the start of the document, the above actions put the string
+<samp>Today</samp> into <samp>BUFFER 3</samp>, having first ensured that it is
+empty. If the LaTeX source includes a <samp>\date</samp> command, then
+the contents of the buffer will be overwritten, otherwise it will be
+as initialised. In any event, when the <samp>\maketitle</samp> command is
+processed, the value output for the date will be either <samp>Today</samp>
+or whatever the argument was of the <samp>\date</samp> command.
+
+
+<p>
+<h4>Notes on the use of buffers and files</h4>
+
+
+<p>Resetting a buffer or a file always has the effect of emptying it
+of an prior contents.
+
+
+<p>When printing from a buffer or a file, the entire contents are
+printed. There is no limit to the number of times that a buffer
+or a file can be used as a printing source.
+
+
+<p>When printing to a buffer, the new strings are appended at
+the end of the current contents of the buffer, at least until it
+overflows. Unlike the behaviour of files,
+this is independant of any intervening prints from the buffer.
+
+
+<p>When printing to a file, the new strings are appended at the
+end of the current contents of the file. However, if a file is printed
+to after it has been printed from, the prior contents of the file
+are lost, and the new string is added at the start of the file.
+In general, it is safest to treat files as either read-only or write-only.
+
+
+<p>
+
+
+<h4>User specified modes</h4>
+
+
+<p>Consider the LaTeX command <samp>\\</samp>. In normal text this signifies
+that a line break must occur. In a <samp>tabular</samp> environment, though,
+it signifies the end of a row in a table. Suppose that in the LTX2X
+procesing of a tabular environment it is required to start and end each
+row with a vertical bar and to seperate each column also with a vertical
+bar. However, in normal text a <samp>\\</samp> command should just translate
+into a newline. Just to complicate matters further, assume that in
+an <samp>eqnarray</samp> environment, the <samp>&</samp> column seperator is to
+be translated to some spaces, and that the string `(X)' is to be
+put at the end of every row.
+
+
+<p>In other words, we need to process some commands differently
+according to where they appear in the LaTeX source. An LTX2X command table
+provides this capability through mode setting and mode-dependent actions.
+Here is an example of using this facility to solve the requirements
+outlined above.
+<pre>
+TYPE= BEGIN_ENV
+NAME= tabular
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: tabular
+END_TYPE
+
+TYPE= END_ENV
+NAME= tabular
+ START_TAG=
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarry
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: eqn
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray
+ START_TAG= " (X)?n"
+ RESET_MODE:
+END_TYPE
+
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " | "
+IN_MODE= eqn
+ START_TAG= " "
+END_MODE
+END_TYPE
+
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+IN_MODE= tabular
+ START_TAG= " |?n"
+ STRING: " | "
+END_MODE
+IN_MODE= eqn
+ START_TAG= " (X)?n"
+END_MODE
+END_TYPE
+</pre>
+
+<p>Let us look at the specification for the <samp>\tabular</samp> environment first.
+The <samp>END_TAG=</samp> action is specified by the single command line
+<samp>SET_MODE:</samp> <samp>tabular</samp>, where <samp>tabular</samp> is any convenient
+name for identifying a mode. Thus, this will set the mode to be <samp>tabular</samp>.
+The action at the end of the environment is to reset the mode
+(<samp>RESET_MODE:</samp>)
+to whatever its previous value was. It is assumed that the last row in any
+<samp>tabular</samp> environment is finished by <samp>\\</samp>. Similar actions are
+performed for the <samp>eqnarray</samp> environment, except that the mode is called
+<samp>eqn</samp> instead of <samp>tabular</samp>. The other difference is that it
+is assumed that the last row is not ended by <samp>\\</samp>, so the end of
+the <samp>eqnarray</samp> environment has to also act like the <samp>\\</samp>.
+
+
+<p>Turning now to the specification for the <samp>&</samp> command, the first part
+of the specification identifies the type and name of the LaTeX command.
+This is then followed by the mode-independent set of actions,
+which in this case
+consists of printing a vertical bar with some spaces on either side of it.
+Following these are any mode-dependent actions, bracketed between
+<samp>IN_MODE=</samp> and <samp>END_MODE</samp>. The value for <samp>IN_MODE=</samp>
+is the name of the relevent mode. In this case the only mode-dependent
+action occurs when <samp>MODE eqn</samp> is in effect and it is to print
+some spaces instead of the default spaces and vertical bar.
+
+
+<p>The specification for the <samp>\\</samp> command has its set of
+mode-independent default actions,
+namely just to print a newline, and two sets of mode-dependent actions.
+When the <samp>tabular</samp> mode is in effect, it prints some spaces, a vertical
+bar, a newline, more spaces, a vertical bar, and finally some more spaces.
+On the other hand, when the <samp>eqn</samp> mode is in effect, it prints some
+spaces, the string `(X)' and a newline. If a mode is in effect
+that is not defined within the specification (e.g., mode <samp>anon</samp>)
+it performs the default mode-independent actions.
+
+
+<p>As a perhaps more practical example, the following command table code will
+convert simple LaTeX <samp>tabular</samp>
+ environments to appropriate mark-up for HTML tables. It is assumed that
+the <samp>tabular</samp> environment is always within a <samp>table</samp> environment.
+
+
+<p>To set the perspective a little, here is the code for a simple table
+in LaTeX:
+<pre>
+\begin{table}[tbp]
+\centering
+\caption{A simple table typeset by \LaTeX.} \label{tab:lxtab}
+\begin{tabular}{|l||r|r||r|r|} \hline
+Stock & \multicolumn{2}{c||}{1994} & \multicolumn{2}{c|}{1995} \\ \cline{2-5}
+ & low & high & low & high \\ \hline
+ABC & 27 & 36 & 23 & 45 \\
+DEF & 53 & 72 & 19 & 54 \\
+GHI & 28 & 49 & 17 & 79 \\ \hline
+\end{tabular}
+\end{table}
+</pre>
+This will be typeset as shown in table <a href="#tab:lxtab">tab:lxtab</a>.
+<center><table border>
+
+<caption>A simple table typeset by LaTeX.</caption> <a name="tab:lxtab">(Table tab:lxtab)</a>
+
+<tr><td> Stock </td><td colspan=2> 1994 </td><td colspan=2> 1995 </tr>
+<tr><td > </td><td > low </td><td > high </td><td > low </td><td > high </tr>
+<tr><td > ABC </td><td > 27 </td><td > 36 </td><td > 23 </td><td > 45 </tr>
+<tr><td >
+DEF </td><td > 53 </td><td > 72 </td><td > 19 </td><td > 54 </tr>
+<tr><td >
+GHI </td><td > 28 </td><td > 49 </td><td > 17 </td><td > 79 </tr>
+<tr><td >
+</table></center>
+
+
+<p>The corresponding HTML code for the table after translation is:
+
+
+
+<p>
+<pre>
+&lt;p&gt;&lt;center&gt;&lt;table border&gt;
+&lt;caption&gt;A simple table typeset by LaTeX.&lt;/caption&gt; &lt;a name="tab:lxtab"&gt;&lt;/a&gt;
+
+
+<p>&lt;tr&gt;&lt;td&gt; Stock &lt;/td&gt;&lt;td colspan=2&gt; 1994 &lt;/td&gt;&lt;td colspan=2&gt; 1995 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+ &lt;/td&gt;&lt;td&gt; low &lt;/td&gt;&lt;td&gt; high &lt;/td&gt;&lt;td&gt; low &lt;/td&gt;&lt;td&gt; high &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt; ABC &lt;/td&gt;&lt;td&gt; 27 &lt;/td&gt;&lt;td&gt; 36 &lt;/td&gt;&lt;td&gt; 23 &lt;/td&gt;&lt;td&gt; 45 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+DEF &lt;/td&gt;&lt;td&gt; 53 &lt;/td&gt;&lt;td&gt; 72 &lt;/td&gt;&lt;td&gt; 19 &lt;/td&gt;&lt;td&gt; 54 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+GHI &lt;/td&gt;&lt;td&gt; 28 &lt;/td&gt;&lt;td&gt; 49 &lt;/td&gt;&lt;td&gt; 17 &lt;/td&gt;&lt;td&gt; 79 &lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;
+&lt;/table&gt;&lt;/center&gt;
+</pre>
+
+
+<p>In the HTML browser that I use this is displayed
+approximately as shown for table <a href="#tab:httab">tab:httab</a>.
+
+
+<p><center><table border>
+
+<caption>A simple table typeset after translation to HTML.</caption> <a name="tab:httab">(Table tab:httab)</a>
+
+<tr><td> Stock </td><td colspan=2> 1994 </td><td colspan=2> 1995 </tr>
+<tr><td > </td><td > low </td><td > high </td><td > low </td><td > high </tr>
+<tr><td > ABC </td><td > 27 </td><td > 36 </td><td > 23 </td><td > 45 </tr>
+<tr><td >
+DEF </td><td > 53 </td><td > 72 </td><td > 19 </td><td > 54 </tr>
+<tr><td >
+GHI </td><td > 28 </td><td > 49 </td><td > 17 </td><td > 79 </tr>
+<tr><td >
+</table></center>
+
+
+<p>In HTML a table is enclosed between
+<samp>&lt;table&gt;</samp> and <samp>&lt;/table&gt;</samp> tags.
+Each row of the table is enclosed between
+<samp>&lt;tr&gt;</samp> and <samp>&lt;/tr&gt;</samp> tags,
+and each element in a row is enclosed between
+<samp>&lt;td&gt;</samp> and <samp>&lt;/td&gt;</samp> tags.
+Under certain circumstances the closing tags (i.e.,
+those like <samp>&lt;/...&gt;</samp>)
+can be inferred by the HTML procesors and need
+not be explicitly put into the source text. The equivalent HTML tags to a
+LaTeX <samp>\multicolumn{num}{col}{text}</samp> command are<br>
+<samp>&lt;td colspan=num&gt; text &lt;/td&gt;</samp>.
+
+
+<p>The general actions that LTX2X has to perform in doing the LaTeX to
+HTML translation are:
+<ul>
+
+
+ <li> The start and end of a <samp>table</samp> environment has to translate to
+ the HTML start and end table tags <samp>&lt;table&gt;</samp> and
+ <samp>&lt;/table&gt;</samp>.
+ (Actually this also needs to handle the
+ centering of the HTML table and drawing a border round it as well.)
+
+
+<p>
+ <li> The start and end of the <samp>tabular</samp> environment has to translate
+ into a row start
+ <samp>&lt;tr&gt;&lt;td&gt;</samp> and end <samp>&lt;/tr&gt;</samp>
+ in the HTML table (and set the mode for the
+ LaTeX <samp>\\</samp> command).
+
+
+<p>
+ <li> The <samp>\\</samp> command must end one row of the HTML table and start the
+ next row
+ (<samp>&lt;/tr&gt;?n&lt;tr&gt;&lt;td&gt;</samp>).
+ It need not end a data element as
+ this is automatically closed by the end of the row.
+
+
+<p>
+ <li> The <samp>&</samp> column delimeter must end one HTML data element and start
+ another one (i.e., <samp>&lt;/td&gt;&lt;td&gt;</samp>).
+
+
+<p>
+ <li> The difficulty is in handling the <samp>\multicolumn</samp> command. In the easy
+ case the LaTeX to HTML translation is: <br>
+ <samp>... &amp; text &amp; ...</samp> maps to <br>
+ <samp>... &lt;/td&gt;&lt;td&gt; text &lt;/td&gt;&lt;td&gt; ...</samp>. <br>
+ However, when a multicolumn is involved the translation is <br>
+<samp>... & \multicolumn{N}{P}{text} & ...</samp> maps to <br>
+<samp>... &lt;/td&gt;&lt;td colspan=N&gt; text &lt;/td&gt;&lt;td&gt; ...</samp>. <br>
+As there is no look-ahead in LTX2X we have to be careful about starting a
+data element after a <samp>&</samp> because at that point LTX2X cannot know
+whether or not a <samp>\multicolumn</samp> command comes next, or just an ordinary
+data element.
+
+
+<p></ul>
+
+
+
+<p>We solve this last problem partly by using buffers
+(numbers <samp>8</samp> and <samp>9</samp> in the specification below)
+as temporary storage, and partly by a subtle specification for the
+<samp>\multicolumn</samp> command.
+
+
+<p>
+
+
+<p>
+<pre>
+C= start of a table
+TYPE= BEGIN_ENV
+NAME= table
+ START_TAG= "&lt;center&gt;&lt;table border&gt;"
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+END_TYPE
+
+
+<p>C= end a table
+TYPE= END_ENV
+NAME= table
+ START_TAG= "&lt;/table&gt;&lt;/center&gt;"
+END_TYPE
+
+
+<p>C= start a tabular
+TYPE= BEGIN_ENV
+NAME= tabular
+ START_TAG= "?n&lt;tr&gt;&lt;td"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ C= ignore the column specification
+ PRINT_P1= NO_OP
+ END_TAG=
+ SET_MODE: tabular
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+
+
+<p>C= end a tabular
+TYPE= END_ENV
+NAME= tabular
+ PC_AT_START= RESET
+ START_TAG= "&gt;"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ RESET_MODE:
+END_TYPE
+
+
+<p>C= we can do some processing of the <samp>\multicolumn</samp> command
+TYPE= COMMAND
+NAME= <samp>\multicolumn</samp>
+ PC_AT_START= TO_BUFFER 8
+ REQPARAMS= 2
+ START_TAG_1= " colspan="
+ PRINT_P2= NO_PRINT
+ PC_AT_END= RESET
+END_TYPE
+
+
+<p>C= now for the end/start of a row
+TYPE= CHAR_COMMAND
+NAME= <samp>\\</samp>
+ START_TAG= "&lt;br&gt;"
+IN_MODE= tabular
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "&gt; "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= "&lt;/tr&gt;?n&lt;tr&gt;&lt;td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_MODE
+END_TYPE
+
+
+<p>C= and the column seperator
+TYPE= TEX_CHAR
+NAME= &amp;
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "&gt; "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= " &lt;/td&gt;&lt;td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+</pre>
+
+
+
+<p>Regarding the <samp>\multicolumn</samp> specification, we state that as far as
+LTX2X is concerned, it only has two required parameters, and that the action
+for the second one is <samp>NO_PRINT</samp>. The first argument is written to
+buffer <samp>8</samp> after `colspan=' has first been put into it. LTX2X will treat
+the actual third argument to the <samp>\multicolumn</samp> as ordinary text, just
+as if there was no <samp>\multicolumn</samp> in the LaTeX source. We use buffer
+<samp>9</samp> for storing the text of a data element. When LTX2X processes
+a <samp>&amp;</samp> column delimeter it first outputs the contents of
+buffer <samp>8</samp> (the number of columns specification) and then appropriate
+HTML characters. It then outputs the contents of buffer <samp>9</samp> (the
+element text), finishes off the element and partially starts the next element.
+Similar actions are performed at the start of the <samp>tabular</samp> environment
+and at the end of each row in the table.
+
+
+<p>
+<h3>Sectioning command types</h3>
+
+
+
+<p>LTX2X does some particular processing for sectioning command types. Although
+LaTeX can determine where any section of a document ends, other tagging systems
+cannot always do this. They require both a `begin section' and an `end section'
+tag. LTX2X can take account of the nesting depth of document sections and,
+given appropriate specifications, can supply both `begin section' and `end section'
+tags appropriately. This requires a little bit more in the way of specifications
+than we have met so far.
+
+
+<p>For a <samp>SECTIONING</samp> command type, the command line
+<samp>SECTIONING_LEVEL=</samp>
+must be included within the specification. The value of this command is a keyword
+from the following list.
+<dl>
+<dt><samp>PART</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\part</samp> command.
+<dt><samp>CHAPTER</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\chapter</samp> command.
+<dt><samp>SECT</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\section</samp> command.
+<dt><samp>SUBSECT</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\subsection</samp> command.
+<dt><samp>SUBSUBSECT</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\subsubsection</samp> command.
+<dt><samp>PARA</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\paragraph</samp> command.
+<dt><samp>SUBPARA</samp>
+<dd> For a sectioning command equivalent to the
+ LaTeX <samp>\subparagraph</samp> command.
+</dl>
+
+
+<p>When a sectioning command is read from the LaTeX source, LTX2X firstly
+performs the <samp>END_TAG=</samp> actions for any `lower level' sections
+that this one is closing off. It then performs the <samp>START_TAG=</samp>
+actions for the current command, and stores its own <samp>END_TAG=</samp> actions for
+later use. It then goes on and process any arguments as usual.
+ The <samp>END_DOCUMENT</samp> command automatically closes off any opened
+sections.
+
+
+<p>As an example, assume that some kind soul has supplied a LaTeX style
+file that makes the commands <samp>\clause</samp> synonymous with <samp>\subsection</samp>,
+and <samp>\sclause</samp> synonymous with <samp>\subsubsection</samp>, etc. Also assume
+that it is required to output start and end tags of the form
+<samp>&lt;div.1&gt;</samp> and <samp>&lt;/div.1&gt;</samp>
+for sections, <samp>&lt;div.2&gt;</samp> for clauses, etc., and surround the
+headings with tags <samp>&lt;heading&gt;</samp> and <samp>&lt;/heading&gt;</samp>.
+Further, the first
+optional argument is of no interest as the output is going to be
+used by a processing system unable to automatically handle tables of contents.
+Part of an appropriate command table for doing this is:
+
+
+<p>
+
+<pre>
+TYPE= SECTIONING
+NAME= <samp>\section</samp>
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "&lt;heading&gt;"
+ END_TAG_1= "&lt;/heading&gt;?n"
+END_TYPE
+
+
+<p>TYPE= SECTIONING
+NAME= <samp>\clause</samp>
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "?n?n&lt;div.2&gt;?n"
+ END_TAG= "?n&lt;/div.2&gt;"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "&lt;heading&gt;"
+ END_TAG_1= "&lt;/heading&gt;?n"
+END_TYPE
+</pre>
+
+
+
+<p>An example output resulting from this command table (if it had been applied to this
+document) is:
+
+
+<pre>
+...
+&lt;/div.2&gt;
+&lt;/div.1&gt;
+
+
+<p>&lt;div.1&gt;
+&lt;heading&gt;The command table file&lt;/heading&gt;
+
+
+<p>By default, ...
+</pre>
+
+
+
+<p>
+<h3>List environment types</h3>
+
+
+
+<p>In LaTeX the use of the <samp>\item</samp> command is restricted to within a
+list environment. The typeset appearance of an <samp>\item</samp> typically depends
+on the particular environment in which it is used. LTX2X has a limited capability
+of modifying its <samp>\item</samp> tagging output. It can also provide an `end item'
+tag for those tagging systems that require such a thing.
+
+
+<p>For such list environments, identified by the command type keyword
+<samp>BEGIN_LIST_ENV</samp>,
+the following command lines should be included within the type specification.
+<dl>
+<dt><samp>START_ITEM=</samp>
+<dd> Actions to be performed at the start
+ of each <samp>\item</samp> command in the list.
+<dt><samp>END_ITEM=</samp>
+<dd> Actions to be performed after processing all
+ the <samp>\item</samp>'s text.
+<dt><samp>START_ITEM_PARAM=</samp>
+<dd> Actions to be performed at the start of an
+ <samp>\item</samp>'s optional argument text.
+<dt><samp>END_ITEM_PARAM=</samp>
+<dd> Actions to be performed at the end of an
+ <samp>\item</samp>'s optional argument text.
+</dl>
+As usual, an unspecified tag defaults to no actions.
+
+
+<p>For example, assume that we are not interested in tagging the end of an item,
+but we do want to mark each item in an <samp>itemize</samp> environment with the lowercase
+letter `o', each <samp>enumerate</samp> item with `(N)' and put a colon after the
+optional argument in a description environment. Also, each item should have some
+indentation from the left hand margin.
+
+
+<p><pre>
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_ITEM= "?n (N) "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+END_TYPE
+</pre>
+
+<p>With the above commands, this LaTeX text:
+<pre>
+\begin{description}
+\item[An example]
+ \begin{itemize}
+ \item the first item;
+ \item the second item.
+ \end{itemize}
+\end{description}
+</pre>
+will be transformed into:
+<pre>
+ An example :
+ o the first item;
+ o the second item.
+</pre>
+
+
+<p>
+<h3>Character types</h3>
+
+
+
+<p>LaTeX treats some characters specially. These special characters are:
+<samp>#</samp>,
+<samp>$</samp>,
+<samp>%</samp>,
+<samp>&</samp>,
+<samp>~</samp>,
+<samp>_</samp>,
+<samp>^</samp>,
+<samp>\</samp>,
+<samp>{</samp>,
+<samp>}</samp>,
+and, under some circumstances, also the
+character <samp>@</samp>.
+ LTX2X recognizes these special characters and, if directed, will
+perform specified actions; otherwise it treats them as it treats any alphanumeric
+character, which is just to print it.
+
+
+<p>It has already been stated that commands for the left and right braces
+(i.e. <samp>{</samp> and <samp>}</samp>) must be given
+within the command table as command types
+<samp>LBRACE</samp>, <samp>RBRACE</samp> respectively.
+The dollar symbol ($) must also be specified via the two command types
+<samp>BEGIN_DOLLAR</samp> and <samp>END_DOLLAR</samp>. Here is an
+example of replacing the dollar signs by tags intended to indicate
+the start and end of a mathematical phrase.
+
+
+<pre>
+TYPE= BEGIN_DOLLAR
+ START_TAG= "&lt;math&gt;"
+END_TYPE
+
+
+<p>TYPE= END_DOLLAR
+ START_TAG= "&lt;/math&gt;"
+END_TYPE
+</pre>
+
+
+
+<p>Commands for the other special LaTeX characters are specified with the
+<samp>TEX_CHAR</samp> command type keyword.
+
+
+<p>The characters <samp>_</samp> (underscore) and <samp>^</samp> (caret) are used in
+LaTeX math mode to indicate subscripting and superscripting respectively. The
+following will replace <samp>^</samp> by <samp>&lt;sup&gt;</samp>, print the superscript
+text (which must be enclosed in braces (Footnote: It is good practice to
+always enclose superscript and subscript text in braces, even though
+TeX does not always require this.) ) and at the end close with
+<samp>&lt;/sup&gt;</samp>.
+
+
+
+<p>
+<pre>
+TYPE= TEX_CHAR
+NAME= <samp>^</samp>
+ START_TAG= "&lt;sup&gt;"
+ REQPARAMS= 1
+ END_TAG= "&lt;/sup&gt;"
+END_TYPE
+</pre>
+
+
+
+<p>Given the above specifications, then <samp>$(2^{15} - 1)$</samp> will be transformed
+into <br>
+<samp>&lt;math&gt;(2&lt;sup&gt;15&lt;/sup&gt; - 1)&lt;/math&gt;</samp>.
+
+
+<p>
+<h3>Verbatim like types</h3>
+
+
+
+<p>The command type <samp>VCOMMAND</samp> is for the procesing of LaTeX
+<samp>\verb</samp>-like commands where the argument of the command is to be
+typeset as-is. For example, there might be a command called <samp>\url</samp>
+which takes one argument which is meant to be an Internet URL. If the
+application was the conversion of a LaTeX document to HTML, then the
+following specification could be useful.
+
+
+<pre>
+TYPE= VCOMMAND
+NAME= <samp>\url</samp>
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 7
+ START_TAG=
+ RESET_BUFFER: 7
+ END_TAG= "&lt;a href=""
+ SOURCE: BUFFER 7
+ STRING: ""&gt;"
+ SOURCE: BUFFER 7
+ STRING: "&lt;/a&gt;"
+ RESET_BUFFER: 7
+END_TYPE
+</pre>
+
+
+
+<p>If the LaTeX source included:
+<pre>
+... obtainable from
+\url{http://www.cdrom.com/pub/tex}
+</pre>
+then the resulting LTX2X output would be:
+
+
+<pre>
+... obtainable from
+&lt;a href="http://www.cdrom.com/pub/tex"&gt;http://www.cdrom.com/pub/tex&lt;/a&gt;
+</pre>
+
+which, if this was then read via an appropriate browser, a link to the URL
+
+<a href="http://www.cdrom.com/pub/tex">http://www.cdrom.com/pub/tex</a>
+
+would be automatically established.
+
+
+<p>Similarly <samp>verbatim</samp>-like environments can also be specified with
+the types <samp>BEGIN_VENV</samp> and <samp>END_VENV</samp>.
+For example, the <tt>html.sty</tt> package defines three LaTeX
+environments for documents that might be converted from LaTeX tagging
+to HTML tagging. One of these, <samp>latexonly</samp> is for LaTeX code
+that is not to occur in the HTMLed document and another is <samp>htmlonly</samp>
+which contains HTML code that is required for an HTML version
+of the document but which is not to appear in the LaTeX ed document.
+The third one is <samp>rawhtml</samp> which is for HTML code to be output
+verbatim to the HTML document source.
+These could be simulated by:
+<pre>
+TYPE= BEGIN_VENV
+NAME= latexonly
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= latexonly
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= END_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= rawhtml
+END_TYPE
+
+TYPE= END_VENV
+NAME= rawhtml
+END_TYPE
+</pre>
+
+<p>
+
+<h3>Odd command types</h3>
+
+
+
+<p>The majority of commands in LaTeX that take optional arguments
+have only a single optional argument that is either immediately after
+the command or after all the required arguments. There are, however, some
+commands that do not fit this pattern. This set of command types enables
+at least some of these `odd' commands to be handled.
+
+
+<p>The command type keyword is of the form <samp>COMMAND_code</samp>, where
+<samp>code</samp> indicates the type and ordering of the arguments. The
+<samp>code</samp> is composed from combinations of the letters <samp>O</samp>
+(for an optional argument) and <samp>P</samp> (for a required parameter (i.e.,
+argument)). The ordering of these letters in the <samp>code</samp> specifies
+the type and ordering of the command's arguments.
+
+
+<p>The `odd' command types are:
+<dl>
+<dt><samp>COMMAND_OOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com[OptParam][OptParam]{ReqParam}</samp>.
+For example, the <samp>\makebox</samp>
+command falls into this category.
+
+
+<p><dt><samp>COMMAND_OOOPP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com[OptParam][OptParam][OptParam]{ReqParam}{ReqParam}</samp>.
+For example, the <samp>\parbox</samp>
+command falls into this category.
+
+
+<p><dt><samp>COMMAND_OPO</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com[OptParam]{ReqParam}[OptParam]</samp>.
+For example, the <samp>\RequirePackage</samp> and <samp>\LoadClass</samp>
+commands fall into this category.
+
+
+<p><dt><samp>COMMAND_POOOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com{ReqParam}[OptParam][OptParam][OptParam]{ReqParam}</samp>.
+
+
+<p><dt><samp>COMMAND_POOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com{ReqParam}[OptParam][OptParam]{ReqParam}</samp>.
+For example, the <samp>\newcommand</samp> and its companion commands
+fall into this category.
+
+
+<p><dt><samp>COMMAND_POOPP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+<samp>\com{ReqParam}[OptParam][OptParam]{ReqParam}{ReqParam}</samp>.
+For example, the <samp>\newenvironment</samp> and its companion command
+fall into this category.
+</dl>
+
+
+<p>As usual, the command name is required, as are any actions. However,
+it is not necessary to specify the number of required arguments (i.e.
+<samp>REQPARAMS=</samp>) nor the position of the optional argument (i.e.
+<samp>OPT_PARAM=</samp>), as LTX2X already has this information. The tag actions
+are according to the argument ordering given in the <samp>code</samp> and are
+specified by the required argument tags (e.g. <samp>START_TAG_n=</samp> and
+<samp>END_TAG_n=</samp>).
+Do not use any of the command lines for optional arguments. Argument
+actions are controlled in the usual manner.
+
+
+<p>A typical example of the use of these commands is to supress any processing
+of the LaTeX <samp>\newcommand</samp> and its ilk. For example:
+<pre>
+TYPE= COMMAND_POOP
+NAME= \providecommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \renewenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+</pre>
+
+<p>
+
+<h3>Other command types</h3>
+
+
+
+<p>The <samp>OTHER_</samp> command types (<samp>OTHER_COMMAND</samp>,
+<samp>OTHER_BEGIN</samp>
+and <samp>OTHER_END</samp>)
+are very limited in what can be affected. Basically, these provide for
+default printing actions if the corresponding LaTeX command has not been
+identified elsewhere in the command table.
+
+
+<p>If there are no commands within the specification, the name of the command and
+all its arguments will be printed verbatim.
+
+
+<p>The command lines <samp>START_TAG=</samp> and <samp>END_TAG=</samp>
+cause the corresponding
+actions to be performed before and after the name of the command is printed. Any
+arguments are printed verbatim.
+
+
+<p>The command line <samp>PRINT_CONTROL=</samp> with a value of <samp>NO_PRINT</samp>
+causes the command name not to be printed, nor any arguments that LTX2X may
+find associated with the command.
+
+
+<p>
+<h3>Picture types</h3>
+
+
+
+<p>The <samp>_PICTURE_</samp> command types differ from all the other types in
+LTX2X, just as they do in LaTeX. In LaTeX some of the picture drawing commands
+take arguments of the form <samp>(number, number)</samp>, representing a coordinate
+pair, as well as the usual
+required arguments enclosed in curly braces and possibly an optional
+argument enclosed in square brackets. Within LTX2X, commands that take coordinate
+arguments are treated specially in the command table.
+
+
+<p>Generally speaking, the LTX2X command types are of the form
+<samp>PICTURE_code</samp>,
+where <samp>code</samp> indicates the type and ordering of the arguments. The
+<samp>code</samp> is composed from combinations of the letters <samp>C</samp> (for a
+coordinate argument), <samp>O</samp> (for an optional argument) and <samp>P</samp> (for
+a required argument). For example, <samp>PICTURE_PCOP</samp> indicates a picture
+command that has a required argument, followed by a coordinate argument,
+followed by an optional argument and finally another required argument.
+
+
+<p>The provided picture types are:
+<dl>
+<dt><samp>BEGIN_PICTURE_CC</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\begin{PictureEnv}(coords)(coords)</samp>, where the final coordinate argument
+ is optional.
+<dt><samp>PICTURE_CCPP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords)(coords){ReqParam}{ReqParam}</samp>.
+ For example, the <samp>\multiput</samp> command falls into this category.
+<dt><samp>PICTURE_CO</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords)[OptParam]</samp>.
+ For example, the standard LaTeX <samp>\oval</samp> command falls into
+ this category.
+<dt><samp>PICTURE_COP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords)[OptParam]{ReqParam}</samp>.
+ For example, the <samp>\makebox</samp> and <samp>\framebox</samp> commands fall
+ into this category.
+<dt><samp>PICTURE_CP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com(coords){ReqParam}</samp>.
+ For example, the <samp>\put</samp>, <samp>\line</samp> and <samp>\vector</samp> commands
+ fall into this category.
+<dt><samp>PICTURE_OCC</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com[OptParam](coords)(coords)</samp>.
+ For example, the <samp>\graphpaper</samp> command from the <samp>graphpap</samp>
+ package falls into this category.
+<dt><samp>PICTURE_OCCC</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com[OptParam](coords)(coords)(coords)</samp>.
+ For example, the <samp>\qbezier</samp> command falls into this category.
+<dt><samp>PICTURE_OCO</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com[OptParam](coords)[OptParam]</samp>.
+ For example, the <samp>\oval</samp> command from the <samp>pict2e</samp> package
+ falls into this category.
+<dt><samp>PICTURE_PCOP</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\com{ReqParam}(coords)[OptParam]{ReqParam}</samp>.
+ For example, the <samp>\dashbox</samp> and <samp>\savebox</samp> commands fall
+ into this category.
+<dt><samp>END_PICTURE</samp>
+<dd> Corresponding to a LaTeX command of the form <br>
+ <samp>\end{PictureEnv}</samp>.
+</dl>
+
+
+<p>As usual, the command name is required, as are any actions. However,
+it is not necessary to specify the number of required arguments (i.e.
+<samp>REQPARAMS=</samp>) nor the position of the optional argument (i.e.
+<samp>OPT_PARAM=</samp>), as LTX2X already has this information. The tag actions
+are according to the argument ordering given in the <samp>code</samp> and are
+specified by the required argument tags (e.g. <samp>START_TAG_n=</samp> and
+<samp>END_TAG_n=</samp>).
+Do not use any of the command lines for optional arguments. Argument
+actions controlled in the usual manner.
+
+
+<p>As an example, the following specifications within a command table should be
+sufficient to ensure that any picture commands in a source file are
+not passed through to the output file.
+
+
+<p><pre>
+TYPE= BEGIN_PICTURE_CC
+NAME= picture
+PRINT_P1= NO_PRINT
+PRINT_P2 = NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CP
+NAME= \put
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_OP
+END_TYPE
+
+TYPE= PICTURE_CCPP
+NAME= \multiput
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_PCOP
+NAME= \savebox
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_OCC
+NAME= \graphpaper
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCCC
+NAME= \qbezier
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= END_PICTURE
+NAME= picture
+END_TYPE
+</pre>
+
+<p><dl>
+<dt>NOTE 1:
+<dd> The action <samp>NO_OP</samp> cannot be applied to an
+ argument that is a coordinate pair.
+
+
+<p><dt>NOTE 2:
+<dd> As LTX2X is essentially limited to printing actions,
+and cannot actually process any
+LaTeX picture drawing commands, the suppression of picture printing is
+probably the most usual use of the picture commands.
+</dl>
+
+
+<p>
+<h3>Special command types</h3>
+
+
+
+<p>The <samp>SPECIAL_</samp> commands, namely <samp>SPECIAL_COMMAND</samp>,
+<samp>SPECIAL_BEGIN_ENV</samp>,
+ <samp>SPECIAL_BEGIN_LIST</samp>,
+<samp>SPECIAL_END_ENV</samp>,
+<samp>SPECIAL_END_LIST</samp> and
+<samp>SPECIAL_SECTIONING</samp>, are provided for cases where some special kind of
+output processing is required that is not built into LTX2X. In order to implement
+any commands of these types, it is necessary to modify the internals of LTX2X
+and recompile the source code. This is not recommended.
+
+
+<p>
+<h3>File inclusion</h3>
+
+
+
+<p>A command table file can include other command table files. In turn an included
+file can recursively include other command table files. The file inclusion command
+line is
+<pre>
+INCLUDE= FileName
+</pre>
+where <samp>FileName</samp> is the name of the command table file to be included. The effect
+is that the above line is replaced by the contents of <samp>FileName</samp>.
+
+
+<p>For example, assume that there are three command table files called respectively
+<tt>detex.ct</tt>, <tt>detex.l2x</tt> and <tt>detex.fl</tt>. The contents of these
+files are:
+<pre>
+C= ----------file detex.ct
+...
+INCLUDE= detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+</pre>
+and for <tt>detex.l2x</tt> as:
+<pre>
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+INCLUDE= detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+END_CTFILE= end of file detex.l2x
+</pre>
+and lastly <tt>detex.fl</tt> is:
+<pre>
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+END_CTFILE= end file detex.fl
+</pre>
+Then, as far as LTX2X is concerned, the original <tt>detex.ct</tt> file is
+treated as though it had been written as:
+<pre>
+C= ----------file detex.ct
+...
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+</pre>
+
+<p>Note that nasty things will happen if you have a cycle of inclusions. That is,
+you must not have anything similar to file <tt>A</tt> including file <tt>B</tt> which
+includes file <tt>C</tt> which in turn includes either file <tt>A</tt> or <tt>B</tt>.
+
+
+<p>
+<h3>Interpreter commands</h3>
+ <a name="sec:intcom"></a>
+
+
+<p>LTX2X includes an interpreter for a procedural programming language
+that is based on the ISO international standard EXPRESS information
+modeling language [<a href="#EBOOK, EXPRESSIS">EBOOK, EXPRESSIS</a>]. At the moment the
+programming language within LTX2X is anonymous, but for ease
+of reference I will call it EXPRESS-A
+(EXPRESS -Almost? -Approximate? -Anonymous?).
+The EXPRESS-A language is described later in section <a href="#sec:expressa">sec:expressa</a>,
+but for now it is sufficient to know the commands that signify
+the start and end of this code.
+
+
+<p>The command <samp>CODE_SETUP=</samp> indicates the commencement of
+code to be run before any document processing occurs. The
+<samp>END_CODE</samp> command signifies the end of this code block.
+This block should be placed in the command table before any other commands
+except for the <samp>ESCAPE...</samp> commands, if any. This block
+can contain variable declarations, function and procedure declarations,
+and statements.
+
+
+<p>Code consisting purely of statements can be placed anywhere that
+a tagging action may be specified. These statements are enclosed
+between a <samp>CODE:</samp> and <samp>END_CODE</samp> pair of commands.
+
+
+<p>The EXPRESS-A language is described in detail in <a href="#sec:expressa">sec:expressa</a>,
+but to give a flavour of it here
+is a simple possible application. It has been noted that LTX2X will find
+difficulty in processing the contents of the LaTeX <samp>picture</samp>
+environment. The following portions of a command table write the contents
+of a <samp>figure</samp> environment to an external file and uses the programming
+language to keep a count of the number of figures so processed.
+
+
+<p><pre>
+c= declare and initialise a variable
+CODE_SETUP=
+ LOCAL
+ fignum : INTEGER;
+ END_LOCAL;
+ fignum := 0;
+END_CODE
+
+c= write figure contents to an external file
+TYPE= BEGIN_ENV
+NAME= figure
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ PC_AT_START= TO_FILE figs.tmp
+ START_TAG=
+ CODE:
+ fignum := fignum + 1; -- increment figure counter
+ println; -- print a blank line
+ println('%%% FIGURE ', fignum); -- write counter as a LaTeX comment
+ END_CODE
+ STRING: "\begin{figure}"
+END_TYPE
+
+c= close figure environment, back to normal output, and output
+c= text indicating that a figure should be here
+TYPE= END_ENV
+NAME= figure
+ PC_AT_START= RESET
+ START_TAG=
+ SWITCH_TO_FILE: figs.tmp
+ STRING: "\end{figure}?n?n"
+ SWITCH_BACK:
+ CODE:
+ println;
+ println('PLACE FOR FIGURE ', fignum);
+ println;
+ END_CODE
+END_TYPE
+</pre>
+
+<p>
+<h2>The LTX2X program</h2>
+ <a name="sec:program"></a>
+
+
+<p>LTX2X is written using flex and bison. The resulting C code should
+compile on any system. More details are given later, but for the end-user
+the next section describes how to run the program, assuming that is available
+on your system.
+
+
+<p>
+<h3>Running LTX2X</h3>
+
+
+
+<p>The syntax for running the compiled version of LTX2X is:
+<pre>
+ltx2x [-c] [-f table-file] [-p number] [-w] [-D dir_cat_char]
+ [-P path_seperators] [-S]
+ [-i number] [-l number] [-t] [-y number] [-C] [-E]
+ input-file output-file
+</pre>
+where elements in square brackets are options. The options fall into
+two groups, one for the casual user and the other for those who may be
+interested in the internals of LTX2X. The first group of options includes:
+<dl>
+<dt>-c
+<dd> By default, LTX2X ignores all LaTeX comments in the input
+ file. This option causes LTX2X to write the comments to the output file.
+
+
+<p><dt>-f
+<dd> By default, LTX2X reads the command table from a file called
+ <samp>ltx2x.ct</samp>. If the required command table is in a file with another name this
+ option is used to change from the default file. For example,
+<pre>
+> ltx2x in.tex out.l2x
+</pre>
+reads a command table from <samp>ltx2x.ct</samp>, while
+<pre>
+> ltx2x -f detex.ct in.tex out.l2x
+</pre>
+reads a command table from file <samp>detex.ct</samp>.
+
+
+<p><dt>-p
+<dd> This option causes LTX2X to `pretty print' the output file
+ (as far as it is able to). The <samp>number</samp> is required and it indicates
+ the desired maximum number
+ of characters per output line. If this is considered to be too small,
+ then LTX2X chooses a value. Note that pretty printing is only applied
+ to the source file --- not to any replacement tags. That is, it
+ only tries to format the running text from the source file.
+
+
+<p><dt>-w
+<dd> By default, LTX2X outputs source white space just at it reads it.
+ This option causes LTX2X to collapse any amount of contiguous white space
+ to a single space. The <samp>-p</samp> option includes the <samp>-w</samp> option.
+
+
+<p><dt>-D
+<dd> The value of this option is the character that the operating system
+ uses to catenate directory names to form a path (see <a href="#sec:search">sec:search</a>).
+ The default value is a
+ slash (i.e. <samp>/</samp>). The default could be changed to a backslash, for example,
+ by <samp>-D \</samp>.
+
+
+<p><dt>-P
+<dd> The environment variable (see <a href="#sec:search">sec:search</a>)
+ contains a list of directories (also known
+ as path names). In the operating system that I use, these are separated by
+ the colon (<samp>:</samp>) character which, together with the semi-colon
+ and space characters, form
+ the LTX2X default separators. The path separator characters can be changed
+ with this option.
+ For example, <samp>-P :</samp> will make the separators be a colon
+ or a space (space is automatically included in the separator list).
+
+
+<p><dt>-S
+<dd> This option enables the source level debugger
+ (see <a href="#sec:sld">sec:sld</a>) for any embedded EXPRESS-A code.
+</dl>
+
+
+<p>The second group of options are principally for those who might be
+extending the LTX2X system.
+
+
+<p><dl>
+<dt>-i
+<dd> This produces information that may be useful for debugging
+ the EXPRESS-A interpreter. <samp>number</samp> is an integer
+ between 1 and 9 inclusive.
+ The greater the number, the more diagnostics are generated.
+
+
+<p><dt>-l
+<dd> This produces information that may be useful for debugging
+ the LTX2X program. <samp>number</samp> is an integer between 1 and 9 inclusive.
+ The greater the number, the more diagnostics are generated.
+
+
+<p><dt>-t
+<dd> This generates diagnostics related to the processing of
+ the command table file.
+
+
+<p><dt>-y
+<dd> Like the <samp>l</samp> option, but produces diagnostic information
+ from the parser (this is actually a null option, but may be useful
+ in the future).
+
+
+<p><dt>-C
+<dd> Disable any interpreter debugging information during
+ the code generation pass. This is not necessary unless the -i
+ option is used.
+
+
+<p><dt>-E
+<dd> Disable any interpreter debugging information during
+ the code execution processing.This is not necessary unless the -i
+ option is used.
+
+
+<p></dl>
+
+
+<p>
+
+
+ LTX2X first reads the specified command table file, together with any included files,
+looking first in the current directory, then in the directories specified by
+the environment variable (if it exists).
+ It then reads the <samp>input-file</samp> from the current directory,
+performs the actions specified in the command table and outputs the results to
+the <samp>output-file</samp>.
+
+
+<p>Three other files are also generated.
+<ul>
+
+
+ <li> <samp>ltx2xct.lis</samp> --- This contains a human-readable form of the internal
+ representation of the command table. It may be useful if there are any errors
+ in the original command table.
+
+ <li> <samp>ltx2x.err</samp> --- This contains any error or warning messages generated
+ by LTX2X. It also contains any diagnostic information that may have been
+ requested via a command line option.
+
+ <li> <samp>interp.csg</samp> --- This contains a human readable listing of the
+ internal byte code generated by the EXPRESS-A interpreter.
+</ul>
+
+
+
+<p>When LTX2X is running normally it prints out a counter to the terminal
+indicating how many hundreds of input source file lines it has processed.
+Lack of such output is an indication that the program may be in a loop and
+chewing up CPU cycles to no avail. In this case, stop the program and examine
+the output for indications of where the trouble is occurring.
+
+
+<p>A limited number of errors are allowed when processing the command table
+and the input LaTeX file before LTX2X gives up and quits. In
+particular, if it is reading a command table file that includes another file, say one
+called <tt>zilch</tt>,
+that it cannot read, it prints the following message to the user's terminal.
+<pre>
+Can't open file zilch
+Enter new file name, or I to ignore, or Q to quit
+:
+</pre>
+A Q (or q) response stops LTX2X from any further processing. An
+I (or i) response causes LTX2X to stop looking for the included file
+and continue processing the current file. Any other response is taken to be
+the name of an included file, which LTX2X then tries to read. If it fails, then
+the above message is repeated. The user is given a limited number of opportunities
+to identify a readable file before LTX2X quits altogether with this message:
+<pre>
+Last attempt. Can't open file zilch. I'm giving up.
+</pre>
+
+
+<p>
+ Regarding performance, the time taken by LTX2X to process a document does
+not appear to be significantly different from the time to LaTeX the
+same document.
+
+
+<p>
+<h4>Directory searching</h4> <a name="sec:search"></a>
+
+
+<p>The program employs a search algorithm to find files that are not
+in the current directory. It first looks in the current directory and
+if a file of the given name is found, then that is used. If the file
+is not found, then it searches for it among directories that are
+specified in a system environment variable. This variable specifies
+a list of pathnames, where the directories forming the path are
+combined using a catenation character. For example, <samp>dir1/dir2/dir3</samp>
+could be a pathname, where the slash (<samp>/</samp>) is the catenation character.
+If it is looking for file <samp>afile.txt</samp> it will catenate the file name
+to the path name (e.g. <samp>dir1/dir2/dir3/afile.txt</samp>) and look for
+that. The pathnames in the list are separated by another character
+(in fact it can be one from a list of characters). For example here
+is a list of two pathnames; <samp>dir1/dir2;dir1/dir4</samp>, where the semi-colon
+(<samp>;</samp>) is the pathname separator.
+
+
+<p>By default, the program uses a slash (<samp>/</samp>) as the directory
+catenation character and the pathname separators can be a space, or
+a colon or a semi-colon (i.e., any of <samp> :;</samp>). All these characters
+can be altered via the program command line options, and should be set to
+match the conventions of your operating system.
+
+
+<p>The environment variable used by the program is LTX2XTABLES.
+On the operating system that I use, I set this in my login file like:
+<pre>
+setenv LTX2XTABLES .:/dir1/dir2:/dir3/dir4
+</pre>
+Your system may have different conventions. Note that if the environment
+variable is not set, only files in the current directory are considered.
+
+
+<p>
+
+<h3>System components</h3>
+
+
+
+<p>The system consists of five main components --- a lexer, a parser, a
+library of support functions and command table parsing code, a
+user-defined library of functions, and an interpreter for the EXPRESS-A
+language.
+
+
+<p>
+<h4>The lexer</h4>
+
+
+<p>The lexer is generated by flex [<a href="#LEVINE92">LEVINE92</a>]
+(a more functional version of lex [<a href="#LESK75">LESK75</a>]).
+The source for the lexer is in file <tt>l2x.l</tt>.
+Its principal function is to read a LaTeX
+source file and recognize LaTeX commands. In general, it passes off the
+relevant command tokens to the parser for performing appropriate actions.
+
+
+<p>However, the lexer does do some processing of the source itself.
+<ul>
+
+
+ <li> It recognizes LaTeX comments (i.e. any text starting with a percent
+ sign and ending with a newline). It silently ignores these comments, unless
+ run with the <samp>-c</samp> option.
+
+ <li> It recognizes the `standard' LaTeX verbatims. It will write out the
+ appropriate tags at the start and end of the verbatim text, while writing
+ the verbatim text directly to the output file, bypassing the parser.
+ It does not distinguish between the unstarred and starred
+ versions of the verbatims.
+
+ <li> Newlines and whitespace are directly written to the output file, again
+ bypassing the parser. The <samp>-p</samp> and <samp>-w</samp> options control the
+ final appearance of whitespace, newlines and paragraphing.
+
+ <li> It recognizes the command <samp>\ </samp> i.e. a backslash followed by a
+ space, and writes the tags defined in the <samp>SLASH_SPACE</samp> specification
+ directly to the output file.
+</ul>
+
+
+
+<p>The lexer is designed to recognize four kinds of LaTeX commands.
+<ul>
+
+
+ <li> Commands of the form <samp>\begin{environment}</samp>
+
+ <li> Commands of the form <samp>\end{environment}</samp>
+
+ <li> Any other command of the form <samp>\command</samp>
+
+ <li> As special cases, commands that are 'verbatim-like' or `verb-like'.
+</ul>
+
+When it finds a command, it looks up the command or environment name in the
+command table and sends the appropriate token and its command table location to the
+parser. As a special case the contents of verbatim-like environments and
+the argument of verb-like coommands are processesd within
+the lexer and not sent to the parser.
+
+
+<p>
+
+<h4>The parser</h4>
+
+
+<p>The parser is generated by bison [<a href="#LEVINE92">LEVINE92</a>]
+(a more powerful version of YACC [<a href="#JOHNSON75">JOHNSON75</a>]).
+The source for the parser is in file <tt>l2x.y</tt>.
+Essentially it defines a very simple
+grammar for a LaTeX document. That is, the grammar is limited to
+generic kinds of commands and command arguments. It does not understand
+the `meaning' of any of the commands or arguments.
+
+
+<p>When the parser receives a token from the lexer it tries to match it with
+one of the grammar rules, performing the actions specified by the command table.
+Here is an extract from the parser grammar file, <tt>l2x.y</tt>,
+for a LaTeX command that has
+two required arguments followed by an optional argument.
+
+
+<p><pre>
+l2xComm2Opt: COMMAND_2_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_opt($1,2);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+</pre>
+
+<p>The actions are enclosed in braces, and are interspersed with the elements
+of the grammar.
+
+
+<p>The token <samp>COMMAND_2_OPT</samp> indicates that the lexer has found a command
+that takes two required arguments followed by an optional argument.
+The parser then performs some
+actions. The <samp>start_with_req</samp> function is the standard LTX2X function
+for the first action in a command production where the final argument
+is optional. The <samp>$1</samp> refers to the
+location of the particular command in the command table, and its value is passed to the
+parser by the lexer.
+
+
+<p>The parser then expects a required argument (i.e. <samp>{</samp>, token <samp>LBRACE</samp>)
+as the start of the required argument, followed by the text of the argument and
+finished off by a right brace (i.e. <samp>}</samp>, token <samp>RBRACE</samp>); the grammar
+for all of this is specified in the production called <samp>ReqParam</samp>). If it
+finds these it performs some further actions, otherwise it reports an
+error.
+In this case the action is defined by the function <samp>action_p_p1</samp>,
+which is the standard action performed between two required arguments
+(the second argument in the function call specifies the Pth argument that
+has been recognized). Another required argument is then expected.
+In this case the action is defined by the function <samp>action_p_opt</samp>,
+which is the standard action performed between the end of the Pth required argument
+and the start of an optional argument. It then looks for an optional
+argument, the grammar for which is specified in the production called
+<samp>OptParam</samp>. The final action is specified by the standard function
+<samp>action_last_opt</samp> for finishing off a command that ends with an
+optional argument.
+
+
+<p>The grammar for a command that that has two required arguments,
+and possibly an
+initial optional argument is similar:
+
+
+<p><pre>
+l2xComm2: COMMAND_2
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_last_p($1,2);
+ }
+ ;
+</pre>
+
+<p>
+<h4>The support libraries</h4>
+
+
+<p>Source code for the C main program and support functions is in file
+<tt>l2xlib.c</tt>.
+ The main program is responsible for reading in the command table and calling the
+lexer and parser to do the appropriate processing.
+ The file also contains a variety of support functions that are, or could
+be, used in the lexer, parser, action library, or user-defined library.
+
+
+<p>The standard actions for the grammar are contained in file <tt>l2xacts.c</tt>.
+
+
+<p>
+<h4>The user-defined library</h4>
+
+
+<p>The intent of this library is that masochistic users can define their
+own functions for use within LTX2X when processing their <samp>SPECIAL_</samp>
+commands, without having to modify the LTX2X support or action libraries.
+
+
+<p>Source code for the user-defined library should be maintained in a file
+called <tt>l2xusrlb.c</tt> and a corresponding header file called <tt>l2xusrlb.h</tt>.
+
+
+<p>
+<h4>The EXPRESS-A interpreter</h4>
+
+
+<p>The EXPRESS-A interpreter is based on algorithms originally developed
+by Ronald Mak [<a href="#MAKR91">MAKR91</a>] for interpreting Pascal. His original
+algorithms have been modified and extended to cater for EXPRESS-A.
+The interpreter module has a minimal interface with the rest of the
+LTX2X system, and could easily be modified to be a stand-alone program
+(in fact it started that way in the first place). The interface
+between LTX2X and the interpreter is confined to the small
+<tt>l2xistup.c</tt> file.
+
+
+<p>
+
+<h2>The EXPRESS-A programming language</h2>
+ <a name="sec:expressa"></a>
+
+
+<p>EXPRESS is a language for information modeling and includes both
+declarative and procedural aspects [<a href="#EBOOK">EBOOK</a>]. There are also two other
+companion languages called respectively EXPRESS-G and EXPRESS-I. The former
+of these is a graphical form of the declaritive aspects of EXPRESS, and the
+later is an instiation and test case specification language. These languages
+are either ISO international standards [<a href="#EXPRESSIS">EXPRESSIS</a>] or on the way
+to becoming so [<a href="#EXPRESSITR">EXPRESSITR</a>].
+
+
+<p>Certain of the procedural aspects of EXPRESS and EXPRESS-I are relevent
+to the LTX2X concepts and so, together with some other reasons,
+it seemed appropriate to provide an interpreter for a similar language for
+use within LTX2X. EXPRESS-A provides a major subset of the EXPRESS procedural
+language, together with some Pascal-like additions for input and output.
+Of particular note, strings are a built-in type in EXPRESS-A. The language
+also supports three-valued logic and the concept of an `indeterminate'
+value of any type.
+
+
+<p>Earlier I gave an example command table to replace the text of a
+LaTeX document with the words `Goodbye document'. Here is
+an EXPRESS-A program that outputs `Goodbye document'.
+<pre>
+println('Goodbye document');
+END_CODE
+</pre>
+
+<p>The following gives a brief overview of EXPRESS-A. For more details
+consult Schenck &amp; Wilson [<a href="#EBOOK">EBOOK</a>].
+
+
+<p>
+<h3>Basic elements</h3>
+
+
+
+<p>EXPRESS-A is a case-insensitive language and uses the ASCII character
+set. Two kinds of comments are supported --- an end of line comment,
+which starts with a <samp>--</samp> pair and continues until the end of the current
+line --- and an extended comment. An extended comment starts with a
+<samp>(*</samp> pair and is ended by a matching <samp>*)</samp> pair; extended comments
+may be nested.
+
+
+<p>The language contains many reserved words, some of which are only
+applicable to the EXPRESS and EXPRESS-I languages.
+
+
+<p>Identifiers are composed of an initial letter, possibly followed by
+any number of letters, digits, and the underscore character.
+
+
+<p>Literals are self defining constant values. An integer literal consists
+of one or more digits, the first of which shall not be zero. Real numbers
+start with one or more digits, followed by a decimal point. Further
+digits may occur after the point, and finaly there may be an exponent
+in the `e' notation format (e.g., <samp>123.456e-78</samp>).
+
+
+<p>A string literal is any sequence of characters enclosed by single
+quote marks. If a single quote mark is meant to form part of the string,
+two quote marks must be used at that point.
+
+
+<p>Logical literals consists of one of these keywords: <samp>FALSE</samp>,
+<samp>UNKNOWN</samp> or <samp>TRUE</samp>.
+
+
+<p>EXPRESS-A also includes some other constants. <samp>PI</samp> stands
+for the value of the mathematical constant (3.1415...),
+and <samp>CONST_E</samp>
+stands for the value of the mathematical constant e (2.7182...),
+the base of natural logarithms. The special token <samp>?</samp> stands for
+an indeterminate value of any type. The three constants
+<samp>THE_DAY</samp>, <samp>THE_MONTH</samp> and <samp>THE_YEAR</samp> are integer
+values for the current date holding the day of the month (1--31), the
+month of the year (1--12) and the year (four digits), respectively.
+
+
+<p>
+
+<h3>Data types</h3>
+
+
+
+<p>EXPRESS-A is a typed language. The simple data types are: <samp>INTEGER</samp>,
+<samp>REAL</samp>, <samp>STRING</samp> and <samp>LOGICAL</samp>.
+
+
+<p>The aggregation data types are <samp>ARRAY</samp>, <samp>BAG</samp>, <samp>LIST</samp>,
+and <samp>SET</samp>. The array data type is of a fixed size and must have
+declared lower and upper bounds (index range), such as <samp>ARRAY [-7:10] OF</samp>.
+The other aggregate data types are dynamic in size, but may have lower and
+upper bounds specified for the number of elements, such as <samp>SET [2:5] OF</samp>,
+meaning a set that should have between two and five members. For the
+dynamic aggregates the upper bound may be given as <samp>?</samp>, which means
+an unlimited upper bound, such as <samp>LIST [2:?] OF</samp>. If a bound
+specification is absent, then the dynamic aggregate can hold from zero
+to any number of elements. (Footnote: The dynamic aggregates may not
+be fully implemented due to lack of time.)
+
+
+<p>Aggregates are one dimensional, but can be chained together for
+multi-dimensional aggregates, like
+<pre>
+ARRAY [1:4] OF LIST OF INTEGER;
+</pre>
+
+<p>The enumeration data type is a parenthesised comma seperated list of
+identifiers. These identifiers represent the values of the enumerated type;
+for instance
+<pre>
+ENUMERATION OF (red, green, blue)
+</pre>
+
+<p>A defined data type is one declared and named by the user using the
+<samp>TYPE</samp> and <samp>END_TYPE</samp> construct. For example
+<pre>
+TYPE length = REAL; END_TYPE;
+TYPE crowd_size = INTEGER; END_TYPE;
+TYPE signal_colour = ENUMERATION OF (red, amber, green); END_TYPE;
+</pre>
+
+<p>An entity data type consists of a list of attributes and their types, enclosed
+in a <samp>ENTITY</samp> and <samp>END_ENTITY</samp> pair. An entity type
+is named.
+<pre>
+ENTITY an_ent;
+ auditorium_width : length;
+ audience : crowd_size;
+ title : STRING;
+ profit : REAL;
+END_ENTITY;
+</pre>
+
+<p>EXPRESS-A provides for algorithms in the form of functions and procedures.
+
+
+<p>A <samp>FUNCTION</samp> is an algorithm that operates on parameters and returns
+a single resultant value of a specified data type. An invocation of a function
+in an expression evaluates to the resultant value at the point of invocation.
+For example:
+<pre>
+FUNCTION func (par1 : INTEGER; par2 : STRING) : STRING;
+ LOCAL
+ str : STRING;
+ -- other variable declarations
+ END_LOCAL;
+ -- the algorithm statements are here
+ RETURN(str);
+END_FUNCTION;
+</pre>
+Note that the parameters are typed.
+
+
+<p>A <samp>PROCEDURE</samp> is an algorithm that receives parameters from the
+point of invocation and operates on them in some manner. Changes to the parameters
+within the procedure are only reflected to the point of invocation
+when the formal parameter is preceded by the keyword <samp>VAR</samp>.
+For example:
+<pre>
+PROCEDURE proc (par1 : INTEGER; VAR par2 : STRING);
+ -- local declarations and the algorithm statements
+END_PROCEDURE;
+</pre>
+Note that the parameters are typed. In this case the value of <samp>par2</samp>
+may be changed.
+
+
+<p>Variables are declared in a local block, enclosed by the keywords
+<samp>LOCAL</samp> and <samp>END_LOCAL</samp>. A variable declaration consists
+of an identifer and its type, such as:
+<pre>
+LOCAL
+ str : STRING;
+ e1, e2 : an_ent; -- e1 and e2 are both of type an_ent
+ e3 : an_ent; -- so is e3
+ num : INTEGER;
+ col : signal_colour;
+ matrix : ARRAY [1:15] OF ARRAY [1:15] OF REAL;
+END_LOCAL;
+</pre>
+
+<p>The above declarations must be in the following order:
+<ol>
+
+
+ <li> <samp>ENTITY</samp> and/or <samp>TYPE</samp> declarations
+
+ <li> <samp>FUNCTION</samp> and/or <samp>PROCEDURE</samp> declarations
+
+ <li> a <samp>LOCAL</samp> declaration block
+</ol>
+
+
+
+<p>After the above can come any number of statements.
+
+
+<p>
+<h3>Statements</h3>
+
+
+
+<p>EXPRESS-A supports the following statements:
+<ul>
+
+
+ <li> Null statement
+
+ <li> Assignment statement
+
+ <li> Call statement
+
+ <li> <samp>BEGIN</samp> ... <samp>END</samp> compound statement
+
+ <li> <samp>CASE</samp> ... <samp>END_CASE</samp> statement
+
+ <li> <samp>IF</samp> ... <samp>THEN</samp> ... <samp>ELSE</samp>
+ ... <samp>END_IF</samp> statement
+
+ <li> <samp>REPEAT</samp> ... <samp>WHILE</samp> ... <samp>UNTIL</samp> ...
+ <samp>END_REPEAT</samp> statement. This also includes the
+ <samp>ESCAPE</samp> and <samp>SKIP</samp> statements
+
+ <li> <samp>RETURN</samp> statement
+</ul>
+
+
+
+<p>All the above statements are completed by a <samp>;</samp> (semicolon).
+The <em>null</em> statement just consists of a semicolon.
+
+
+<p>The <em>assignment</em> statement is used to assign an instance to a local
+variable or parameter. The data types must be compatible.
+<pre>
+LOCAL
+ a, b, c : REAL;
+END_LOCAL;
+...
+ a := 2.3E-6;
+ b := a;
+ a := -27.0;
+ c := 33.3*b;
+</pre>
+
+<p>The <em>call</em> statement invokes a procedure or a function. The actual
+parameters provided with the call must agree in number, order and type
+with the formal parameters specified in the procedure or function
+declaration. The supplied parameter values must be assignment compatible
+with the formal parameters. This is an example of calling the EXPRESS-A
+defined <samp>INSERT</samp> procedure which takes three parameters:
+<pre>
+INSERT(my_list, list_element, 0);
+</pre>
+
+<p>The <em>compound</em> statement consists of one or more statements enclosed
+between a <samp>BEGIN</samp> and <samp>END</samp> pair. The enclosed statements
+are treated as a single statement.
+<pre>
+...
+ BEGIN
+ a := 2.3e-7;
+ b := a;
+ c := b*33.3;
+ END;
+</pre>
+
+<p>The <em>case</em> statement is a means of selectively executing statements
+based on the value of an expresion.
+<pre>
+LOCAL
+ a : INTEGER;
+ x, y : REAL;
+END_LOCAL;
+...
+ a := 2;
+ x := 21.9;
+ CASE 2*a OF
+ 1 : x := SIN{x};
+ 2 : x := SQRT(x);
+ 3 : x := LOG(x);
+ 4 : x := COS(x); -- this is executed
+ 5, 6 : y := y**x;
+ OTHERWISE : x := 0.0;
+ END_CASE;
+</pre>
+The integer expression following the <samp>CASE</samp> keyword is evaluated.
+The result is compared to the values of the case labels and the
+statement following the first matching label is executed. Execution then
+continues at the statement following the <samp>END_CASE;</samp>. If no
+label matches, then no statements within the case block are executed,
+except if an <samp>OTHERWISE</samp> label is included, which will match
+anything. All other labels are examined before looking for the
+<samp>OTHERWISE</samp>.
+
+
+<p>The <em>if ... then ... else</em> statement allows the conditional
+execution of statements depending on the value of a <samp>LOGICAL</samp>
+expression. When the expression evaluates to <samp>TRUE</samp> the statement(s)
+following the <samp>THEN</samp> are executed, after which control passes
+to the statement following the closing <samp>END_IF</samp>. When the logical
+expression evaluates to <samp>FALSE</samp> or <samp>UNKNOWN</samp> the <samp>THEN</samp>
+statements are jumped over and execution starts at the statement(s) following
+the <samp>ELSE</samp> keyword if present, or at the statement following
+the <samp>END_IF</samp> keyword.
+<pre>
+IF a > 20 THEN
+ b := a + 2;
+ c := c - 1;
+ELSE
+ IF a > 10 THEN
+ b := a + 1;
+ ELSE
+ c := c + 1;
+ END_IF;
+END_IF;
+</pre>
+
+<p>The <em>repeat</em> statement is used to control the conditional repetition
+of a series of statements. The control conditions are:
+<ul>
+
+
+ <li> finite iteration until an integer expression reaches a specified
+ value;
+
+ <li> <samp>WHILE</samp> a logical condition is <samp>TRUE</samp>;
+
+ <li> <samp>UNTIL</samp> a logical condition is <samp>TRUE</samp>.
+</ul>
+
+<pre>
+REPEAT i := 100 TO 0 BY -7 WHILE r >= 0.0 UNTIL err < 1.0e-8;
+ ...
+ r := ...;
+ err := ...;
+END_REPEAT;
+</pre>
+At entry to the <samp>REPEAT</samp> statement the iteration variable is
+initialized to the first bound. If the variable less than or equal to the
+<samp>TO</samp> bound and the increment is positive, or the variable is less
+than the <samp>TO</samp> bound and the increment is negative, processing
+jumps to after the <samp>END_REPEAT</samp>, otherwise processing continues.
+The <samp>WHILE</samp> condition is checked and if
+<samp>TRUE</samp> then the statements in the body are executed. After
+these have been executed the <samp>UNTIL</samp> condition is checked. If this
+is not <samp>TRUE</samp> then processing continues by incrementing the iteration
+variable by either unity or by the <samp>BY</samp> value if present. The whole
+process then starts again with the checking of the iteration variable
+against the <samp>TO</samp> bound.
+
+
+<p>All three types of controls are optional. If none are given then the
+<samp>REPEAT</samp> statement will loop for ever. The <em>escape</em> statement
+causes an immediate transfer out of the <samp>REPEAT</samp> statement
+in which it occurs. The <em>skip</em> statement causes a jump to the
+end of the <samp>REPEAT</samp> statement in which it occurs (i.e., to the point
+where the <samp>UNTIL</samp> expression is tested).
+<pre>
+REPEAT UNTIL (a = 1);
+ ...
+ IF a = 0 THEN
+ ESCAPE;
+ END_IF;
+ ...
+ IF a > 10 THEN
+ SKIP;
+ END_IF;
+ ...
+ ...
+-- SKIP transfers control to here
+END_REPEAT;
+ -- ESCAPE transfers control to here
+</pre>
+
+<p>The <em>return</em> statement terminates the execution of a <samp>FUNCTION</samp>
+or <samp>PROCEDURE</samp>. The <samp>RETURN</samp> statement within a function
+must specify an expression, the value of which is the value returned
+by the function. A <samp>RETURN</samp> in a procedure must not specify an
+expression.
+<pre>
+RETURN(a <> b); -- example for within a function
+RETURN; -- example for within a procedure
+</pre>
+
+<p>
+<h3>Expressions</h3>
+
+
+
+<p>Expressions are combinations of operators, operands and function calls
+which are evaluated to produce a value. The simplest expression is
+either a literal value or the name of a variable.
+
+
+<p>
+<h4>Arithmetic operators</h4>
+
+
+<p>The arithmetic operators act on number values and produce a number
+result. If any operand
+is indeterminate (i.e., <samp>?</samp>) then the result is also
+indeterminate. The operators are:
+<dl>
+<dt>Unary
+<dd> The operators <samp>+</samp> and <samp>-</samp>, the latter of which
+negates its following operand.
+<dt>Binary
+<dd> Addition (<samp>+</samp>),
+ subtraction (<samp>-</samp>),
+ multiplication (<samp>*</samp>),
+ real division (<samp>/</samp>),
+ exponentiation (<samp>**</samp>),
+ integer division (<samp>DIV</samp>),
+ and modulo (<samp>MOD</samp>).
+</dl>
+
+
+<p>
+<h4>Relational operators</h4>
+
+
+<p>The result of a relational expression is a <samp>LOGICAL</samp> value.
+If either operand is indeterminate, the expression evaluates to
+<samp>UNKNOWN</samp>.
+
+
+<p><dl>
+<dt>Value comparison
+<dd> Equal (<samp>=</samp>),
+ not equal (<samp><></samp>),
+ greater than (<samp>></samp>),
+ less than (<samp><</samp>),
+ greater than or equal (<samp>>=</samp>), and
+ less than or equal (<samp><=</samp>).
+
+
+<p><dt>Membership
+<dd> The <samp>IN</samp> operator tests an item for membership
+in a dynamic aggregate (e.g., <samp>IF fred IN mylist THEN ...</samp>).
+
+
+<p><dt>Matching
+<dd> The <samp>LIKE</samp> operator compares a string against a pattern,
+evaluating to <samp>TRUE</samp> if they match. The pattern characters are:
+ <ul>
+
+
+ <li> <samp>@</samp> Matches any letter.
+
+ <li> <samp>^</samp> Matches any upper-case letter.
+
+ <li> <samp>?</samp> Matches any character.
+
+ <li> <samp>&</samp> Matches remainder of string.
+
+ <li> <samp>#</samp> Matches any digit.
+
+ <li> <samp>$</samp> Matches a substring terminated by a space character
+ or end-of-string.
+
+ <li> <samp>*</samp> Matches any number of characters.
+
+ <li> <samp>\</samp> Begins a pattern escape sequence.
+
+ <li> <samp>!</samp> Negation character (used with the other characters).
+
+ <li> Any other character matches itself.
+ </ul>
+
+
+
+<p>Some examples:
+ <ul>
+
+
+ <li> <samp>'The quick red fox' LIKE '$$$$'</samp> is <samp>TRUE</samp>.
+
+ <li> <samp>'Page 231' LIKE '$ ###'</samp> is <samp>TRUE</samp>.
+
+ <li> <samp>'Page 27' LIKE 'Page ###'</samp> is <samp>FALSE</samp>.
+
+ <li> <samp>'\aaaa' LIKE '\\aaaa'</samp> is <samp>TRUE</samp>.
+
+ <li> <samp>'\aaaa' LIKE '\aaaa'</samp> is <samp>FALSE</samp>.
+
+ <li> <samp>'aaaa' LIKE 'a@@a'</samp> is <samp>TRUE</samp>.
+ </ul>
+
+
+
+<p></dl>
+
+
+<p>
+<h4>Logical operators</h4>
+
+
+<p>The logical operators produce a logical result. Except for the
+<samp>NOT</samp> operator which takes one logical operand (e.g., <samp>NOT op</samp>),
+they take two logical operands (e.g., <samp>op1 XOR op2</samp>).
+
+
+<p>The evaluation of the <samp>NOT</samp> operator is given in table <a href="#tab:not">tab:not</a>.
+
+
+<p><center><table border>
+<caption>The NOT logical operator</caption> <a name="tab:not">(Table tab:not)</a>
+
+<tr><td> Operand value </td><td > Result value </tr>
+<tr><td > <samp>TRUE</samp> </td><td > <samp>FALSE</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>TRUE</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>The evaluation of the <samp>AND</samp>, <samp>OR</samp> and <samp>XOR</samp> operators
+is given in table <a href="#tab:andorxor">tab:andorxor</a>.
+
+
+<p><center><table border>
+<caption>The AND, OR and XOR logical operators</caption>
+<a name="tab:andorxor">(Table tab:andorxor)</a>
+
+<tr><td> Op1 </td><td > Op2 </td><td > Op1 <samp>AND</samp> Op2 </td><td > Op1 <samp>OR</samp> Op2 </td><td > Op1 <samp>XOR</samp> Op2 </tr>
+<tr><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>FALSE</samp> </tr>
+<tr><td >
+<samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>TRUE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>UNKNOWN</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>TRUE</samp> </td><td > <samp>TRUE</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>UNKNOWN</samp> </td><td > <samp>UNKNOWN</samp> </tr>
+<tr><td >
+<samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </td><td > <samp>FALSE</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>
+<h4>Miscellaneous</h4>
+
+
+<p><dl>
+
+
+<p><dt>Function call
+<dd> A function may be called without the result necessarily
+being assigned to a variable. If <samp>fun</samp> is a function with two
+arguments (for simplicitly integer arguments) and returning a logical
+value, then
+<pre>
+log := fun(i1, i2);
+fun(i3, 24*i4);
+</pre>
+are both legitimate calls.
+
+
+<p>
+<dt>Dot operator
+<dd> The dot operator is used to access an attribute from an
+entity. If <samp>ent</samp> is an <samp>ENTITY</samp> type with an attribute
+<samp>att</samp>, then <samp>ent.attr</samp> evaluates to the value of the
+<samp>attr</samp> attribute within the <samp>ent</samp>.
+
+
+<p><dt>String operators
+<dd> <br>
+ The <samp>+</samp> operator takes two strings as
+its operands and evaluates to the string that is the concatenation of its
+operands. For example:
+<pre>
+str1 := 'string1';
+str2 := 'string2';
+str1 := str1 + str2;
+-- str1 = 'string1string2' is TRUE
+</pre>
+
+<p>The substring operator <samp>[i1:i2]</samp> is a postfix operator that when
+applied to a string, evalutes to the string whose characters are composed
+of the <samp>i1</samp>'th through the <samp>i2</samp>'th characters, inclusively,
+of its operand. Note that <samp>i2</samp> must be greater than or equal to
+<samp>i1</samp>, and both must be within the limits of the number of characters
+in the string. For example:
+<pre>
+str1 := 'string';
+str2 := str1[2:4];
+str1 := str1 + str2;
+-- str1 = 'tristring' is TRUE
+</pre>
+
+<p><dt>Aggregate operators
+<dd> <br>
+ The index operator <samp>[i]</samp> is a postfix operator that can be applied
+to an aggregate operand; the expression evaluates to the value of the
+aggregate at the index position. For example, if <samp>lagg</samp> is a
+list of integers:
+<pre>
+insert(lagg, 20, 0);
+insert(lagg, 40, 0);
+insert(lagg, 60, 0);
+insert(lagg, 80, 0);
+-- lagg[2] = 60 is TRUE
+</pre>
+
+<p><dt>Interval expression
+<dd> <br>
+ An <em>interval expression</em> is a <samp>LOGICAL</samp> expression
+consisting of three operands and two operators. It has the form:
+<pre>
+{ low op1 test op2 high }
+</pre>
+where <samp>op1</samp> and <samp>op2</samp> are either of the two relational
+operators <samp><</samp> or <samp><=</samp>, and <samp>low</samp>, <samp>test</samp> and
+<samp>high</samp> are expressions of the same type. The interval expression
+is equivalent to:
+<pre>
+((low op1 test) AND (test op2 high))
+</pre>
+The value of the interval expression is given by
+<ol>
+
+
+ <li> If any operand is indeterminate, then it evauates to <samp>UNKNOWN</samp>.
+
+ <li> If either of the logical relationships evaluates to <samp>FALSE</samp>,
+ then it evauates to <samp>FALSE</samp>.
+
+ <li> If both logical relationships evalute to <samp>TRUE</samp>,
+ then it evauates to <samp>TRUE</samp>.
+
+ <li> Otherwise it evaluates to <samp>UNKNOWN</samp>.
+</ol>
+
+For example:
+<pre>
+i := 10;
+{1 <= i < 20} -- is TRUE
+{1 <= i < 10} -- is FALSE
+i := ?;
+{1 <= i < 10} -- is UNKNOWN
+</pre>
+
+<p>
+</dl>
+
+
+<p>
+
+<h3>Built in procedures and functions</h3>
+
+
+
+<p>
+<h4>Procedures</h4>
+
+
+<p>The following procedures are an integral part of EXPRESS-A. They are
+shown as signatures to inidicate the data types of the formal parameters.
+For convenience, <samp>GENERIC</samp> is used to indicate any type.
+
+
+<p><ul>
+
+
+ <li> <samp>INSERT (VAR L:LIST OF GENERIC; E:GENERIC; P:INTEGER)</samp> <br>
+ <samp>INSERT</samp> inserts the element <samp>E</samp> into a list
+<samp>L</samp> at position <samp>P</samp>. The insertion follows the existing
+element at <samp>P</samp>, so that if <samp>P=0</samp>, <samp>E</samp> will
+become the first element.
+
+
+<p>
+ <li> <samp>REMOVE (VAR L:LIST OF GENERIC; P:INTEGER)</samp> <br>
+ <samp>REMOVE</samp> modifies the list <samp>L</samp> by deleting the
+element at position <samp>P</samp>.
+
+
+<p>
+ <li> <samp>SYSTEM (V:STRING)</samp> <br>
+ <samp>SYSTEM</samp> passes the string <samp>V</samp> to the operating system.
+This is typically used to get the operating system to perform some action.
+
+
+<p>
+ <li> <samp> READ(VAR V1, V2,...:GENERIC)</samp>, <samp>READLN(VAR V1, V2,...:GENERIC)</samp> <br>
+ These two procedures are similar to the Pascal procedures of the same
+ name and put data from standard input into the variable(s)
+ <samp>V1</samp>, etc.
+
+
+<p>The argument is a comma-seperated list of variables. The variables may be
+ of different types, but the types are limited to
+ <samp>INTEGER</samp>,
+ <samp>REAL</samp>,
+ <samp>LOGICAL</samp>, and
+ <samp>STRING</samp>.
+ The procedure gets the next value of the variable's type from standard input
+ and assigns it to the variable. An integer is recognised as a set of digits,
+ optinally preceeded by a sign. A real is in either decimal or scientific
+ notation (e.g., <samp>12.34</samp> or <samp>1.234e1</samp>). A logical is <samp>TRUE</samp>,
+ <samp>FALSE</samp> or <samp>UNKNOWN</samp> (case independent, so <samp>TRUE</samp> could also
+ be <samp>tRuE</samp>). A string is
+ any non-empty set of characters ended by white space (e.g., <samp>string </samp>
+ is one string but <samp>ball of str8 string </samp> is four strings). The difference
+ between <samp>READ</samp> and <samp>READLN</samp> is that the former performs the
+ actions described above, while the latter will discard any remaining characters
+ in the input line after processing its arguments.
+
+
+<p>
+
+ <li> <samp> WRITE(format)</samp>, <samp>WRITELN(format)</samp> <br>
+ These two procedures are similar to the Pascal procedures of the same name.
+ They write data to standard output.
+
+
+<p>The <samp>format</samp> consists of a comma-seperated list of variables with
+ optional spacing specifications. The variable types may be
+ <samp>INTEGER</samp>,
+ <samp>REAL</samp>,
+ <samp>LOGICAL</samp>, or
+ <samp>STRING</samp>.
+ The <samp>LOGICAL</samp> and <samp>STRING</samp> types take no spacing declarations.
+ An <samp>INTEGER</samp> variable can take one optional space specification which
+ is an integer number specifying the minimum field width for printing the value
+ (e.g., <samp>int:6</samp> to specify a minimum field width of 6 characters).
+ A <samp>REAL</samp> variable can take two optional space specifications. The
+ first is the field width and the second is the number of digits to be printed
+ (e.g., <samp>r:10:5</samp> for printing with a field width of 10 characters
+ and to a pecision of 5 digits). For example:
+<pre>
+BEGIN_LOCAL
+ int : INTEGER;
+ r : REAL;
+ log : LOGICAL;
+ str : STRING;
+END_LOCAL;
+ int := 23;
+ r := 23.0;
+ log := true;
+ str := 'This is a string.';
+WRITE('Example', int, r:10:5, ' ', log, ' ', str);
+</pre>
+will produce:
+<pre>
+Example 23 23.000 TRUE This is a string.
+</pre>
+
+<p>The difference between <samp>WRITE</samp> and <samp>WRITELN</samp> is that the latter
+ will end the output line after it has output the values of its arguments.
+ (<samp>WRITELN</samp> need take no arguments, in which case it justs ends the current
+ output line).
+
+
+<p>
+ <li> <samp> PRINT(format)</samp>, <samp>PRINTLN(format)</samp> <br>
+ These <samp>PRINT</samp> procedures are the same as the
+ <samp>WRITE</samp> procedures, except that they send the data
+ to the current LTX2X output destination.
+
+
+<p></ul>
+
+
+
+<p>
+<h4>Functions</h4>
+
+
+<p>The following functions are supplied as part of EXPRESS-A. They are
+exhibited as signatures to show the formal parameters. For convenience,
+<samp>NUMBER</samp> is being used to denote either an <samp>INTEGER</samp> or a
+<samp>REAL</samp> number.
+
+
+<p><ul>
+
+
+ <li> <samp>ABS (V:NUMBER) : NUMBER;</samp> <br>
+ <samp>ABS</samp> returns the absolute value of its argument.
+
+ <li> <samp>COS (V:NUMBER) : REAL;</samp> <br>
+ Returns the cosine of an an angle specified in radians.
+
+ <li> <samp>EOF () : LOGICAL;</samp> <br>
+ Returns <samp>TRUE</samp> if the next character from standard input
+ is `end-of-file', otherwise it returns <samp>FALSE</samp>.
+
+ <li> <samp>EOLN () : LOGICAL;</samp> <br>
+ Returns <samp>TRUE</samp> if the next character from standard input
+ is `end-of-line', otherwise it returns <samp>FALSE</samp>.
+
+ <li> <samp>EXISTS (V:GENERIC) : LOGICAL;</samp> <br>
+ The function <samp>EXISTS</samp> returns <samp>FALSE</samp> if its
+ argument is indeterminate or does not exist, otherwise it returns
+ <samp>TRUE</samp>.
+
+ <li> <samp>EXP (V:NUMBER) : REAL;</samp> <br>
+ Returns e (the base of natural logarithms (<samp>CONST_E</samp>))
+ raised to the power of <samp>V</samp>.
+
+ <li> <samp>HIBOUND (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>HIBOUND</samp> returns the declared upper index of an <samp>ARRAY</samp>
+ or the declared upper bound of a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+ <li> <samp>HIINDEX (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>HIINDEX</samp> returns the declared upper index of an <samp>ARRAY</samp>
+ or the number of elements in a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+ <li> <samp>LENGTH (V:STRING) : INTEGER;</samp> <br>
+ Returns the number of characters in its argument.
+
+ <li> <samp>LOBOUND (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>LOBOUND</samp> returns the declared lower index of an <samp>ARRAY</samp>
+ or the declared lower bound of a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+ <li> <samp>LOG (V:NUMBER) : REAL;</samp> <br>
+ Returns the natural logarithm of its argument.
+
+ <li> <samp>LOG2 (V:NUMBER) : REAL;</samp> <br>
+ Returns the base 2 logarithm of its argument.
+
+ <li> <samp>LOG10 (V:NUMBER) : REAL;</samp> <br>
+ Returns the base 10 logarithm of its argument.
+
+ <li> <samp>LOINDEX (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>LOINDEX</samp> returns the declared lower index of an <samp>ARRAY</samp>
+ or the value 1 for a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp>.
+
+
+<p>The <samp>..INDEX</samp> functions are useful for iterating over
+ aggregates. For example, if <samp>lagg</samp> is a list of integer,
+ then all the elements can be printed out as a comma-seperated
+ list enclosed in parentheses by:
+<pre>
+writeln;
+write('lagg = (');
+REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ IF (i = HIINDEX(lagg)) THEN write(lagg[i]:1);
+ ELSE write(lagg[i]:1, ', ');
+ END_IF;
+END_REPEAT;
+writeln(')');
+</pre>
+
+ <li> <samp>NVL (V:GENERIC; SUBS:GENERIC) : GENERIC;</samp> <br>
+ If the argument <samp>V</samp> exists then it is returned, otherwise
+ the argument <samp>SUBS</samp> is returned. Both arguments must be
+ of the same type.
+
+ <li> <samp>ODD (V:INTEGER) : LOGICAL;</samp> <br>
+ Returns <samp>TRUE</samp> or <samp>FALSE</samp> depending on whether or not
+ its argument is odd or even.
+
+ <li> <samp>REXPR (V:STRING; E:STRING) : LOGICAL;</samp> <br>
+ This function tests whether the <samp>V</samp> string parameter
+ matches a regular expression <samp>E</samp>. <samp>REXPR</samp>
+ returns <samp>TRUE</samp> if there is a match, <samp>FALSE</samp>
+ if there is not a match, or <samp>UNKNOWN</samp> if the regular
+ expression is ill-formed.
+
+
+<p>In the regular expression, most characters stand for themselves,
+ but <samp>\</samp> can be used to escape any of the meta-characters.
+ <ul>
+
+
+ <li> The meta-characters <samp>(</samp> and <samp>)</samp> are used for
+ grouping sub-expressions.
+
+ <li> <samp>|</samp> between expressions means one or the other.
+
+ <li> <samp>+</samp> following an expression means match one or more times.
+
+ <li> <samp>*</samp> following an expression means match zero or more times.
+
+ <li> <samp>?</samp> following an expression means match zero or one times.
+
+ <li> <samp>[...]</samp> is an expression indicating that any of the enclosed
+ characters are acceptable.
+
+ <li> <samp>[^...]</samp> is an expression indicating that any characters
+ except those enclosed are acceptable.
+
+ <li> Within a bracket expression a range of characters can be
+ specified by providing the first and last with a seperating hyphen.
+ For instance, <samp>[a-zA-Z]</samp> will match any alphabetic character.
+ </ul>
+
+
+
+<p>Some examples:
+ <ul>
+
+
+ <li> <samp>[a-zA-Z]+</samp> match one or more letters.
+
+ <li> <samp>[0-9]+.[0-9]+([eE][\-\+]?[0-9]+)?</samp> match a floating
+ point number <br>
+ (e.g., <samp>1.23e-27</samp> or <samp>0.987</samp>)
+
+ <li> <samp>[a-zA-Z][0-9a-zA-Z_]*</samp> match an EXPRESS-A variable.
+
+ <li> <samp>[^0-9a-zA-Z]</samp> match anything except letters or digits.
+
+ <li> <samp>(I|i)(F|f)</samp> case insensitive match for the word <samp>IF</samp>.
+ </ul>
+
+
+
+<p>
+ <li> <samp>ROUND (V:NUMBER) : INTEGER;</samp> <br>
+ Returns the nearest integer to its argument value.
+
+ <li> <samp>SIN (V:NUMBER) : REAL;</samp> <br>
+ Returns the sine of an an angle specified in radians.
+
+ <li> <samp>SIZEOF (V:AGGREGATE OF GENERIC) : INTEGER;</samp> <br>
+ <samp>SIZEOF</samp> returns the number of elements in its argument.
+ When <samp>V</samp> is an <samp>ARRAY</samp> this is the declared number
+ of elements. When <samp>V</samp> is a
+ <samp>BAG</samp>, <samp>LIST</samp> or <samp>SET</samp> this is the actual
+ number of elements.
+
+ <li> <samp>SQRT (V:NUMBER) : REAL;</samp> <br>
+ Returns the square root of its argument.
+
+ <li> <samp>TAN (V:NUMBER) : REAL;</samp> <br>
+ Returns the tangent of an an angle specified in radians.
+
+ <li> <samp>TRUNC (V:NUMBER) : INTEGER;</samp> <br>
+ Chops off any decimal part of its argument, returning the corresponding
+ integer value.
+
+
+<p></ul>
+
+
+
+<p>
+
+<h3>Source level debugger</h3>
+ <a name="sec:sld"></a>
+
+
+<p>The EXPRESS-A interpreter includes a source level debugger for
+use when your code appears to be misbehaving. When in operation the
+debugger will prompt for a command to be entered. It understands
+the following commands.
+
+
+<p><ul>
+
+
+ <li> <samp>&lt;return&gt;</samp> Continue processing.
+
+ <li> <samp>break</samp> <samp>&lt;number&gt;</samp> Place a breakpoint at the statement
+ on line <samp>&lt;number&gt;</samp>.
+
+ <li> <samp>break</samp> Print the line numbers of all the breakpoints.
+
+ <li> <samp>unbreak</samp> <samp>&lt;number&gt;</samp> Remove the breakpoint from line
+ <samp>&lt;number&gt;</samp>.
+
+ <li> <samp>unbreak</samp> Remove all breakpoints.
+
+ <li> <samp>trace</samp> Turn on statement tracing.
+
+ <li> <samp>untrace</samp> Turn off statement tracing.
+
+ <li> <samp>entry</samp> Turn on tracing of entry to procedures and functions.
+
+ <li> <samp>unentry</samp> Turn off entry tracing.
+
+ <li> <samp>exit</samp> Turn on tracing of exits from procedures and functions.
+
+ <li> <samp>unexit</samp> Turn off exit tracing.
+
+ <li> <samp>traceall</samp> Turn on all tracing.
+
+ <li> <samp>untraceall</samp> Turn off all tracing.
+
+ <li> <samp>stack</samp> Turn on display of the runtime stack accesses.
+
+ <li> <samp>unstack</samp> Turn off stack display.
+
+ <li> <samp>step</samp> Turn on single-stepping.
+
+ <li> <samp>unstep</samp> Turn off single stepping.
+
+ <li> <samp>fetch</samp> <samp>&lt;variable&gt;</samp> Print data fetches for
+ <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>store</samp> <samp>&lt;variable&gt;</samp> Print data stores for
+ <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>watch</samp> <samp>&lt;variable&gt;</samp> Print both data fetches and
+ stores for <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>watch</samp> Print the names of all variables being watched.
+
+ <li> <samp>unwatch</samp> <samp>&lt;variable&gt;</samp> Remove the watch from
+ <samp>&lt;variable&gt;</samp>.
+
+ <li> <samp>unwatch</samp> Remove all watches.
+
+ <li> <samp>show</samp> <samp>&lt;expression&gt;</samp> Print the value of
+ the EXPRESS-A expresion <samp>&lt;expression&gt;</samp>. The variables
+ in the expression must have been declared in the EXPRESS-A code.
+ For example:
+<pre>
+show (23.0 + LOG(num))/(PI*r**2)
+</pre>
+
+ <li> <samp>assign</samp> <samp>&lt;variable := expression&gt;</samp> Assign the value
+ of <samp>&lt;expression&gt;</samp> to the EXPRESS-A variable <samp>&lt;variable&gt;</samp>.
+ For example:
+<pre>
+assign num := SIN(theta/300.0)
+</pre>
+
+ <li> <samp>where</samp> Print the current line number and the text of the
+ next statement to be executed.
+
+ <li> <samp>kill</samp> Terminate the execution of the LTX2X program.
+</ul>
+
+
+
+<p>
+<h3>Example EXPRESS-A code</h3>
+
+
+
+<p>The following demonstrates most of the functionality of EXPRESS-A.
+Most of this is not particularly interesting, except possibly for the
+algorithms for calculating the date of Easter and for generating
+magic squares.
+
+
+<p><pre>
+ c= fun.ct Test of CODE ltx2x
+
+CODE_SETUP=
+ ENTITY ent;
+ attr1, attr3 : INTEGER;
+ attr2 : STRING;
+ END_ENTITY;
+
+ TYPE joe = INTEGER;
+ END_TYPE;
+
+ TYPE colour = ENUMERATION OF (red, blue, green);
+ END_TYPE;
+
+
+PROCEDURE easter;
+(* calculates the date of Easter for the present year
+ The algorithm can be applied to any year between
+ 1900 and 2099 inclusive, but if so, then the year
+ should be checked to ensure that it is within this range. *)
+ LOCAL
+ n, a, b, m, q, w : INTEGER;
+ day : INTEGER;
+ month : STRING;
+ END_LOCAL;
+
+ n := THE_YEAR - 1900;
+ a := n MOD 19;
+ b := (7*a + 1) DIV 19;
+ m := (11*a + 4 - b) MOD 29;
+ q := n DIV 4;
+ w := (n + q + 31 - m) MOD 7;
+ day := 25 - m - w;
+ month := 'April';
+ IF (day < 1) THEN
+ month := 'March';
+ day := day + 31;
+ END_IF;
+ writeln('In ', THE_YEAR:1, ' Easter is on ', month, day:3);
+END_PROCEDURE;
+
+
+FUNCTION magic_square(order:INTEGER): LOGICAL;
+(* calculates magic squares from order 1 through 15.
+ The order must be an odd number. *)
+ LOCAL
+ row, col, num : INTEGER;
+ sqr_order : INTEGER;
+ magic : ARRAY[1:15] OF ARRAY[1:15] OF INTEGER;
+ END_LOCAL;
+
+ IF (order > 15) THEN -- only squares up to order 15
+ RETURN(FALSE);
+ ELSE
+ IF (order < 1) THEN -- squares have at least one entry
+ RETURN(FALSE);
+ ELSE
+ IF (NOT ODD(order)) THEN -- squares are odd
+ RETURN(FALSE);
+ END_IF;
+ END_IF;
+ END_IF;
+
+ sqr_order := order**2;
+ row := 1;
+ col := (order + 1) DIV 2;
+ REPEAT num := 1 TO sqr_order;
+ magic[row][col] := num;
+ IF ((num MOD order) <> 0) THEN
+ IF (row = 1) THEN row := order; ELSE row := row - 1; END_IF;
+ IF (col = order) THEN col := 1; ELSE col := col + 1; END_IF;
+ ELSE
+ IF (num <> sqr_order) THEN row := row + 1; END_IF;
+ END_IF;
+ END_REPEAT;
+
+ writeln(Magic square of order ',order:2);
+ REPEAT row := 1 TO order;
+ REPEAT col := 1 TO order;
+ write(magic[row][col]:4);
+ END_REPEAT;
+ writeln;
+ END_REPEAT;
+ writeln;
+
+ RETURN(TRUE);
+END_FUNCTION;
+
+FUNCTION month(mnum:INTEGER) : STRING;
+(* Given an integer representing the month in a year,
+ returns the name of the month. *)
+LOCAL
+ str : STRING;
+END_LOCAL;
+
+ CASE mnum OF
+ 1 : str := 'January';
+ 2 : str := 'February';
+ 3 : str := 'March';
+ 4 : str := 'April';
+ 5 : str := 'May';
+ 6 : str := 'June';
+ 7 : str := 'July';
+ 8 : str := 'August';
+ 9 : str := 'September';
+ 10 : str := 'October';
+ 11 : str := 'November';
+ 12 : str := 'December';
+ OTHERWISE : str := '';
+ END_CASE;
+RETURN(str);
+END_FUNCTION;
+
+ LOCAL
+ a : array[1:3] of integer;
+ lagg : list [0:5] of integer;
+ a23 : array[1:2] of array[1:3] of integer;
+ i, n : integer;
+ s1, s2 : string;
+ b : logical;
+ r1, r2 : real;
+ nega : array[-3:-1] of integer;
+ posa : array[3:5] of integer;
+ j : joe;
+ ex : ent;
+ END_LOCAL;
+
+ -- start with a massive compound statement
+ BEGIN
+
+ writeln;
+ println;
+
+ (* write today's date *)
+ writeln('Today is ', THE_DAY:1, ' ', month(THE_MONTH), ' ', THE_YEAR:1);
+ writeln;
+
+ (* The user might be interested in Easter *)
+ easter;
+ writeln;
+
+ (* Call some math functions *)
+ r1 := PI/4;
+ writeln('r1 = PI/4 (0.78539...)', r1);
+ writeln('cos(r1) (0.70710...)', cos(r1));
+ writeln('sin(r1) (0.70710...)', sin(r1));
+ writeln('tan(r1) (1.0)', tan(r1));
+
+ r1 := CONST_E;
+ writeln('r1 = CONST_E (2.7182...)', r1);
+ writeln('log(4.5) (1.50407...)', log(4.5));
+ writeln('log2(8) (3.0)', log2(8));
+ writeln('log10(10) (1.0)', log10(10));
+
+ r2 := exp(10);
+ writeln('exp(10) (2.203...e4)', r2);
+
+ r2 := sqrt(121);
+ writeln('sqrt(121) (11.0)', r2);
+
+ (* populate and print some arrays *)
+ writeln;
+ posa[3] := 10;
+ posa[4] := 20;
+ posa[5] := 30;
+ REPEAT i := LOINDEX(posa) TO HIINDEX(posa);
+ writeln('posa[', i:1, '] = ', posa[i]);
+ END_REPEAT;
+
+ writeln;
+ nega[-3] := 1;
+ nega[-2] := 2;
+ nega[-1] := 3;
+ REPEAT i := LOINDEX(nega) TO HIINDEX(nega);
+ writeln('nega[', i:1, '] = ', nega[i]);
+ END_REPEAT;
+
+ (* Do some things with a list *)
+
+ -- check the initial size (should be empty)
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+
+ -- insert elements at the front
+ INSERT(lagg, 10, 0);
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+ INSERT(lagg, 20, 0);
+ writeln('no. of els in lagg = ', SIZEOF(lagg));
+
+ -- print some of the elements
+ i := lagg[1];
+ writeln('first in lagg = ', i);
+ writeln('lagg[2] = ', lagg[2]);
+
+ -- check if a value in in the list
+ b := 10 IN lagg;
+ writeln(b); -- should be TRUE
+ b := 30 IN lagg;
+ writeln(b); -- should be FALSE
+
+ -- write all the elements
+ REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ writeln('lagg[', i:1, '] = ', lagg[i]);
+ println('lagg[', i:1, '] = ', lagg[i]);
+ END_REPEAT;
+
+ (* see what happens with an indeterminate value *)
+ b := FALSE;
+ b := ?;
+ writeln(b);
+ println(b);
+ (* Some more attempts with indeterminate *)
+ i := 2;
+ n := 3*i;
+ writeln(i, n); -- should be 2 6
+ n := 3*?;
+ writeln(i, n); -- should be 2 ?
+ i := ?;
+ n := 3*i;
+ writeln(i, n); -- should be ? ?
+
+END; -- end of compound statement
+ -- but we can have individual statements
+
+
+ (* Try to provide some excitement by making a magic square *)
+ writeln;
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ IF NOT magic_square(n) THEN
+ writeln('I did not like your number which was ', n:1);
+ writeln('If you get it right next time, something magic will happen.');
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ magic_square(n);
+ END_IF;
+
+
+ (* Try a couple of REPEAT statements *)
+ writeln('Test REPEAT (should print -2)');
+ i := -2;
+ REPEAT UNTIL i = 0;
+ writeln(i);
+ println(i);
+ ESCAPE;
+ i := i + 1;
+ END_REPEAT;
+
+ writeln('Test REPEAT (should print 3, 2, 1)');
+ REPEAT i := 3 TO 1 BY -1;
+ writeln(i);
+ END_REPEAT;
+
+
+ (* Try the LIKE operator *)
+ writeln('Test LIKE');
+ writeln(('A' LIKE 'A')); -- should be TRUE
+ writeln(('A' LIKE 'b')); -- should be FALSE
+ writeln(('Page 407' LIKE '$###')); -- should be TRUE
+ writeln(('Page 23' LIKE '$###')); -- should be FALSE
+
+
+ (* Try the REXPR function *)
+ writeln('Test rexpr');
+ writeln(rexpr('A', 'A')); -- should be TRUE
+ writeln(rexpr('A', 'b')); -- should be FALSE
+ writeln(rexpr('Page 407', '[a-zA-Z]+\ [0-9]+')); -- should be TRUE
+ writeln(rexpr('Page 23', '[a-zA-Z]+\ [0-9]')); -- should be FALSE
+
+
+ (* Try an ARRAY OF ARRAY *)
+ a23[1][1] := 11;
+ a23[1][2] := 12;
+ a23[1][3] := 13;
+ a23[2][1] := 21;
+ a23[2][2] := 22;
+ a23[2][3] := 23;
+
+ writeln('Test REPEAT (should be 1 1 11, 1 2 12, 1 3 13, 2 1 21, 2 2 22 etc)');
+ REPEAT n := 1 TO 2;
+ REPEAT i := 1 TO 3;
+ writeln(n, i, a23[n][i]);
+ END_REPEAT;
+ END_REPEAT;
+
+
+ (* do some simple string operations *)
+ s1 := 'string';
+ writeln(s1); -- should be string
+ s2 := s1[2:4];
+ writeln(s2); -- should be tri
+ b := s1 <> s2;
+ writeln(b); -- should be TRUE
+ writeln(s2 + s1); -- should be tristring
+
+
+ (* Assign and print to a user-defined type *)
+ j := 33;
+ writeln(j*3); -- should be 99
+
+ (* Do something with a variable of type ENTITY */
+ ex.attr1 := 33;
+ ex.attr2 := 'The attribute named attr2';
+ ex.attr3 := ex.attr1/3;
+ writeln('ex.attr1 should be 33 and is: ', ex.attr1);
+ writeln('ex.attr2 is: ', ex.attr2);
+ writeln('ex.attr3 should be 11 and is: ', ex.attr3);
+
+END_CODE
+</pre>
+
+<p>
+<h2>Specifying a SPECIAL_ command</h2>
+ <a name="sec:special"></a>
+
+
+<p>This section gives some hints on how to specify a LaTeX command that
+requires some special processing. The faint-hearted should skip this. It is
+assumed that the implementor will have knowledge of LaTeX, C programming,
+and lex and
+YACC style lexer and parser generator systems.
+
+
+<p>There are two ways of defining <samp>SPECIAL_</samp> kinds of commands though
+neither is particularly simple. The easiest is by what is termed the
+coding method. This involves modifying the standard actions. The
+more complicated means is by the grammar method, which involves extending
+the production grammar and, typically, also coding new kinds of actions.
+
+
+<p>The process of specifying one of the <samp>SPECIAL_</samp> kinds of command
+actions is:
+<ul>
+
+
+ <li> Seriously question the need for the special command. One is only required if
+ the standard actions cannot be coerced into serving the needs of the command
+ processing and/or the command grammar is not supported by the LTX2X system.
+
+ <li> Design the required entry for the command table.
+
+ <li> Decide whether the coding or the grammar method is to be used for
+ extending LTX2X.
+ <dl>
+ <dt>Coding method
+<dd> Modify the actions in <tt>l2xusrlb.c</tt>,
+ and possibly
+ add new functions in <tt>l2xusrlb.c</tt> and <tt>l2xusrlb.h</tt>.
+
+
+<p><dt>Grammar method
+<dd> Extend the grammar in <tt>l2x.y</tt>. Typically it
+ be necessary to add new functions to the user-defined
+ library <tt>l2xusrlb</tt> as well.
+ </dl>
+
+ <li> Compile the modified LTX2X system. A <samp>make</samp> file for this is given
+ in Appendix <a href="#sec:install">sec:install</a>.
+
+ <li> Test the extensions and debug the program.
+</ul>
+
+
+
+<p>The <samp>l2xlib</samp> has many functions that may be of use in this process.
+ Some of these are indicated below.
+
+
+<p><ul>
+
+
+ <li> <samp>char *strsave(char s[])</samp> saves a string somewhere
+
+ <li> <samp>void myprint(char s[])</samp> writes a string to the output medium. Its
+ particular action is controlled by the <samp>set_print</samp> and
+ <samp>reset_print</samp> functions, as well as the <samp>-p</samp> option.
+
+ <li> <samp>void verbatim_print(char s[])</samp> like <samp>myprint</samp>,
+ writes a string to the output medium. Its actions are controlled
+ by the current print mode, and newlines are obeyed (i.e., it ignores
+ any pretty-printing option).
+
+ <li> <samp>void yyerror(char s[])</samp> used by the lexer and parser to print
+ an error message string.
+
+ <li> <samp>void warning(char s[])</samp> writes a warning message string.
+
+ <li> <samp>void do_newline()</samp> used within the lexer to set internal variables
+ whenever a newline is encountered in the input.
+
+ <li> <samp>void initialise_sysbuf()</samp> initialises the system supplied string
+ buffer.
+
+ <li> <samp>void print_sysbuf()</samp> writes the content of the system string buffer
+ to the output file.
+
+ <li> <samp>void copy_sysbuf(char s[])</samp> copies the contents of the system
+ string buffer to the user-supplied string. It is the user's responsibility
+ to ensure that the string is big enough.
+
+ <li> <samp>void set_print(PSTRWC pswitch)</samp> controls the action of <samp>myprint</samp>,
+ <samp>print_newline</samp> and <samp>verbatim_print</samp>. If the input argument is
+ <samp>p_default_print</samp>
+ then the print functions should write to the output file; this is the
+ default behavior. If the
+ argument is <samp>p_no_print</samp>, then no writing occurs. If the argument
+ is <samp>p_print_to_sysbuf</samp>, then the print functions write to the system
+ string buffer.
+
+ <li> <samp>void reset_print()</samp> resets the behavior of the print functions. This
+ function should always be used after a call to <samp>set_print</samp>.
+
+ <li> <samp>int lookup_entry(char s[], int kind)</samp> returns the location
+ within the command table of the
+ command name given in <samp>s</samp> of the command type given in <samp>kind</samp>.
+ If <samp>kind</samp> is <samp>DONT_CARE</samp> then the position of the first occurrence
+ of <samp>s</samp> is returned.
+
+ <li> <samp>void get_env_name(char s[])</samp> extracts the name of a LaTeX
+ environment from <samp>s</samp>, which is assumed to have the form
+ <samp>\something { environment }</samp>. The name of the environment is put
+ into the global string <samp>env_name</samp>.
+
+ <li> <samp>PSENTRY get_mode_sym(int loc)</samp> returns a pointer to the
+ symbol table entry at position <samp>loc</samp> in the command table
+ for the current mode.
+
+ <li> <samp>int command_type(int loc)</samp> returns the system defined
+ kind of command at location
+ <samp>loc</samp> in the command table.
+
+ <li> <samp>int get_user_type(int loc)</samp> returns the user input (<samp>TYPE=</samp>)
+ kind of command at location
+ <samp>loc</samp> in the command table.
+
+ <li> <samp>PSTRWC get_t(PSENTRY loc)</samp> returns a pointer to the
+ <samp>START_TAG=</samp> specification for symbol entry <samp>loc</samp>.
+ There are similar functions for other tagging specifications.
+
+ <li> <samp>PSTRWC get_tag_t(PSENTRY loc, int n)</samp> returns a pointer
+ to the <samp>START_TAG_n</samp> specification for the <samp>n</samp>'th
+ argument for symbol entry <samp>loc</samp>. There are similar
+ functions for other argument tagging specifications.
+
+ <li> <samp>PSTRWC get_param_print(PSENTRY loc, int n)</samp> returns a
+ pointer to the print control specification for the
+ <samp>n</samp>'th required argument for symbol entry <samp>loc</samp>.
+ There are similar functions for other print controls.
+
+ <li> <samp>int get_level(PSENTRY loc)</samp> returns the <samp>SECTIONING_LEVEL=</samp>
+ value for symbol entry <samp>loc</samp>.
+</ul>
+
+
+
+<p>The process of specifying a <samp>SPECIAL_</samp> is best described via
+an example.
+
+
+<p>
+<h3>Example</h3>
+
+
+
+<p>Assume that there is a `non-standard' LaTeX command
+which has one required argument. When this command is processed by LaTeX its
+effect is to start a new section in a document entitled
+Normative References. Some boilerplate text is then typeset (specified
+within the definition of the command). This boilerplate includes two
+instances of the text from the argument of the command. Finally, a
+description
+list environment is started.
+
+
+<p>In LaTeX terms, this command could have been defined as:
+<pre>
+\newcommand{\XXspecial}[1]{\section{Normative References}
+ Some boilerplate text with #1
+ in the middle. Now there is
+ some more boilerplate with #1
+ in the middle of it.
+ \begin{description} }
+</pre>
+
+<p>For the purposes of the example, it is desired to replace the occurrence
+of the <samp>\XXspecial</samp> command by the `normal' section heading for the
+output tagged style, and also print out the boilerplate text including
+the argument text in the right places. The start of the list environment has
+also to be taken into account. The <samp>\item</samp> optional argument text is
+to be enclosed in parentheses, with a dash before the main text.
+These requirements are not something that can
+be currently accomplished with the standard LTX2X system.
+
+
+<p>To make the requirements more concrete, if the input LaTeX source
+includes:
+<pre>
+....
+\XXspecial{REQ PARAM TEXT}
+
+\item[Ref 1] Text 1.
+\item[Ref 2] Text 2.
+\end{description}
+....
+</pre>
+then the desired output is to look like:
+<pre>
+....
+
+</div.1>
+
+<div.1>
+<heading>Normative References</heading>
+
+Some boilerplate text with REQ PARAM TEXT
+in the middle. Now there is
+some more boilerplate with REQ PARAM TEXT
+in the middle of it.
+
+ (Ref 1) -- Text 1.
+ (Ref 2) -- Text 2.
+....
+</pre>
+
+<p>
+ Now, let's write a specification for the command table, which we will do in pieces,
+starting with the sectioning tags. In this tagging style, end tags for sections
+take the form <samp>&lt;/div.1&gt;</samp>, and start tags the form <samp>&lt;div.1&gt;</samp>.
+The titles of sections are enclosed between <samp>&lt;heading&gt;</samp> and
+<samp>&lt;/heading&gt;</samp> tags. We also
+want some newlines in the output to set things off. If <samp>?</samp> is used as the
+escape character, then we can specify for the sectioning tagging:
+
+
+<pre>
+SECTIONING_LEVEL= SECT
+START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+END_TAG= "?n&lt;/div.1&gt;"
+</pre>
+
+
+
+<p>There is one required argument and no optional arguments, so we need:
+<pre>
+REQPARAMS= 1
+</pre>
+
+<p>The LaTeX command also starts off a <samp>description</samp> environment, so we have
+to set the tags for the <samp>\item</samp> commands that will follow. This is done by:
+<pre>
+START_ITEM= "?n"
+START_ITEM_PARAM= " ("
+END_ITEM_PARAM= ") -- "
+</pre>
+
+<p>Most of the work is now completed though we still have to give the command name,
+decide what sort of <samp>SPECIAL_</samp> it will be and set the <samp>SPECIAL_TOKEN</samp>
+value. None of the provided <samp>SPECIAL_</samp> types exactly fit this entry as it is
+a mixture of sectioning and list environment, so we will just call it a
+<samp>SPECIAL_COMMAND</samp> type.
+To summarize, the effective state of the command table entry is:
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+C= NAME= to be specified
+C= SPECIAL_TOKEN= to be specified
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+
+
+<p>For pedagogical purposes, this special will be implemented using both the
+grammar and code methods, and the command names used will be <samp>\GRAMMspecial</samp>
+and <samp>\CODEspecial</samp> respectively.
+
+
+<p>
+<h4>Grammar method implementation</h4>
+
+
+<p>The command name for this implementation will be <samp>\GRAMMspecial</samp>.
+
+
+<p>The grammar method requires changes to the grammar specified in <tt>l2x.y</tt>.
+
+
+<p><ol>
+
+
+ <li> A new token has to be defined, call it <samp>GRAMMSPECIAL</samp>, in the first
+part of the file. There is a slot for this under the comment <samp>/* specials */</samp>.
+An integer number, greater than or equal to 10,000 (ten thousand) and less than
+32,768 (2<sup>15</sup>), has to be
+associated with this token. (Footnote: The upper limit of (2<sup>15</sup>-1) is
+set by the bison processor.)
+ Further, this number must not be the same as any other
+number associated with any other token. Let us use
+the maximum number 32,767. The relevant portion of <tt>l2x.y</tt> will look like
+
+
+<pre>
+ /* specials */
+%token &lt;pos&gt; /* other specials here */
+%token &lt;pos&gt; GRAMMSPECIAL 32767
+ /* precedences */
+</pre>
+
+This number is used for communication within the LTX2X system, and is the number
+set as the value of the <samp>SPECIAL_TOKEN</samp> in the command table. We can now finalize
+the command table entry as:
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+NAME= <samp>\GRAMMspecial</samp>
+SPECIAL_TOKEN= 32767
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+
+
+<p>
+ <li> A new production, or productions, has to be added to the grammar. There is
+a place for this at the end of the rules section in the file, under the predefined
+production <samp>l2xSpecials</samp>. Let us call our new production <samp>GrammSpecial</samp>,
+and add it as:
+<pre>
+l2xSpecials: ASpecial
+ | AnotherSpecial
+ | GrammSpecial
+ ;
+</pre>
+where the <samp>ASpecial</samp> and <samp>AnotherSpecial</samp> are pre-existing specials.
+
+
+<p>
+ <li> The production now has to be defined, specifying the expected syntax
+and required actions. This looks like:
+<pre>
+GrammSpecial: GRAMMSPECIAL
+ {
+ start_section($1);
+ myprint(get_t($1));
+ myprint(get_tag_t($1,1));
+ initialise_sysbuf();
+ set_print(p_print_to_sysbuf);
+ }
+ ReqParam
+ {
+ initialise_string(grammbuf);
+ copy_sysbuf(grammbuf);
+ reset_print();
+ prwboiler1();
+ print_sysbuf();
+ prwboiler2();
+ myprint(grammbuf);
+ prwboiler3();
+ start_list($1);
+ }
+ ;
+</pre>
+The actions are enclosed in braces and are defined in terms of
+C code.
+
+
+<p>Once the parser has been given the <samp>GRAMMSPECIAL</samp> token from the lexer,
+it will attempt to
+perform the actions within the first set of braces. The first of these,
+<samp>start_section($1)</samp>, is the LTX2X action for starting a sectioning command.
+Basically, this deals with any closing of prior sections of the document and
+remembering the closing tag for this section.
+The next two actions
+print the start tags for the command and its required argument,
+taking the strings from the command table.
+<samp>initialise_sysbuf()</samp> initializes the
+system string buffer ready for new input. Then the print control is set so
+that any output will be directed into the system string buffer rather
+than the output
+file. This finishes the first set of actions.
+
+
+<p>The production grammar for the required argument comes next. If this
+is incorrect, the parser automatically gives an (uninformative) error message.
+Otherwise, the last set of actions are done. At this point, the text
+of the required argument will be contained in the system string buffer.
+This is then copied to a temporary buffer <samp>grammbuf</samp>, that we have yet
+to define, by calling
+<samp>copy_sysbuf(grammbuf)</samp> having first made sure that this buffer has
+been cleared of any previous contents (the <samp>initialise_string(grammbuf)</samp>
+action). The printing control must now be reset (<samp>reset_print()</samp>), or
+things might get corrupted later. A function <samp>prwboiler1()</samp> is called to
+print the first part of the boilerplate text, followed by printing the contents
+of the system buffer by the action <samp>print_sysbuf()</samp> (remember that this should
+contain the text of the required argument). The second part of the boilerplate
+is written by the function <samp>prwboiler2()</samp>. Just for pedagogical purposes,
+the required argument text is written out using the text stored in the temporary
+buffer (<samp>myprint(grammbuf)</samp>) rather than from the system buffer. The penultimate
+action is the printing of the last piece of boilerplate.
+
+
+<p>The final action --- <samp>start_list($1)</samp> --- is the standard LTX2X action
+at the start of a list environment. This remembers the various tags for the list
+items to follow.
+
+
+<p>A character buffer, <samp>grammbuf</samp>, is now defined in the initial
+section of the <tt>l2x.y</tt> file, as:
+<pre>
+char grammbuf[80];
+</pre>
+which is intended to be large enough to hold the text of the required
+argument of the command.
+
+
+<p>This completes the changes to the grammar file.
+
+
+<p>
+ <li> The three functions called out in the above actions for printing
+the boilerplate are coded and placed in the user library file
+<tt>l2xusrlb.c</tt> and are also added to <tt>l2xusrlb.h</tt>. Here is
+the relevant code as it would appear in <tt>l2xusrlb.c</tt>.
+<pre>
+ /* demonstration string definition */
+
+STRING boiler_string_3 = "\nin the middle of it.\n\n";
+
+ /* demonstration functions */
+
+/* PRWBOILER1 print some demonstration boilerplate */
+void prwboiler1()
+{
+ myprint("\nSome boilerplate text with ");
+} /* end PRWBOILER1 */
+
+/* PRWBOILER2 print some demonstration boilerplate */
+void prwboiler2()
+{
+ myprint("\nin the middle. Now there is\n");
+ myprint("some more boilerplate with ");
+} /* end PRWBOILER2 */
+
+/* PRWBOILER3 yet more demonstration boilerplate */
+void prwboiler3()
+{
+ myprint(boiler_string_3);
+} /* end PRWBOILER1 */
+</pre>
+
+<p>
+ <li> The system is recompiled, using <samp>make</samp>, and tested on some example
+LaTeX files.
+
+
+<p></ol>
+
+
+
+<p>
+
+
+<h4>Code method implementation</h4>
+
+
+<p>This method `merely' requires extending the standard actions to
+account for the new requirements. First, however, we must complete
+the definition of the command table entry. We will call the new
+command <samp>\CODEspecial</samp>. Also a unique value has to be assigned
+to the <samp>SPECIAL_TOKEN</samp>. This must have a value greater than or
+equal to 50,000 (fifty thousand). We will use a value 59,999. Later this
+value is used within the action code to identify the special.
+The command table entry is thus:
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+NAME= <samp>\CODEspecial</samp>
+SPECIAL_TOKEN= 59999
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+which only differs from that for the grammar implemented special in the
+<samp>SPECIAL_TOKEN=</samp> and the <samp>NAME=</samp> values.
+
+
+<p>Before proceeding further, some explanation of the internals of
+the LTX2X system is in order.
+
+
+<p><dl>
+<dt>Command table entry
+<dd> Internally, an array of C structs
+is used for storing the data corresponding to the command table. The struct
+is fully
+defined in file <tt>l2xcom.h</tt>, and type PSENTRY is a
+pointer to an instance of the struct. There is an entry in
+the internal command table for each command. Where a command specification
+is mode-dependent, then the entries for this are stored as a list (the
+command table array is actually an array of lists of command specifications,
+one list per command).
+
+
+<p>For the purposes at hand, only a few
+of the elements are of concern; these are <samp>kind</samp>, <samp>parse_kind</samp>
+and <samp>special_token</samp>. The element <samp>kind</samp> contains an identifier
+of the <samp>TYPE=</samp> value; that is, the type of the command as specified
+by the user. The element <samp>special_token</samp> contains the
+<samp>SPECIAL_TOKEN=</samp> value. The <samp>parse_kind</samp> element contains
+an identifier of the type of command as assigned internally by LTX2X.
+This last identifier is generated by the table processing code
+in <samp>l2xlib.c</samp> and corresponds to one of the token values
+acceptable to the parser.
+
+
+<p><dt>The lexer
+<dd> The lexer reads the source LaTeX file, looking for
+LaTeX commands (essentially anything starting with a backslash). Each
+time it finds a command it looks it up in the command table array, and
+sends its parser token value (the <samp>parse_kind</samp> value) and the command
+table array position to the parser.
+
+
+<p><dt>The parser
+<dd> Given a token from the lexer, the parser finds the
+appropriate grammar production and performs the specified actions. It
+is able to access command information through having the command table
+position.
+
+
+<p><dt>The grammar
+<dd> The grammar used for the LaTeX general commands (and
+environments) is actually very simple --- the complexity is reserved for the
+lexer and the actions. At the grammar level, no distinction is made
+between a command and an environment. There are a total of 19 different
+command types (tokens), which fall into a smaller number of groups.
+<ol>
+
+
+ <li> A command with no arguments.
+
+ <li> A command with just a single optional argument.
+
+ <li> Commands with a final optional argument and between 1 and 8 required
+ arguments.
+
+ <li> Commands with between 1 and 8 required arguments. In this case
+ it is always assumed that there might be an initial optional
+ argument.
+
+ <li> A command with 9 required arguments.
+</ol>
+
+Note that this partitioning is based solely on the number of required
+arguments and the position (if any is declared) of an optional
+argument.
+
+
+<p>For example, if a command/environment is specified in the command table as
+having one required argument and no optional arguments, then this will
+be treated as a command with possibly an initial optional argument and
+one required argument. The grammar for this is:
+<pre>
+l2xComm1: COMMAND_1
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_last_p($1,1);
+ }
+ ;
+</pre>
+where the words in all upper case are grammar tokens, and words in mixed
+case are other grammar productions. The actions are enclosed between braces.
+The <samp>$1</samp> is the position of the command in the command table array.
+
+
+<p><dt>Actions
+<dd> The standard actions are contained in file <tt>l2xacts.c</tt>.
+Within the code for each standard action, provision is made for
+calling
+action code for specials. All the functions have the same
+general structure. Here, for instance, is the code for the standard
+action that is called between the start of a command and a first optional
+argument.
+<pre>
+/* START_WITH_OPT start action for command with optional param */
+void start_with_opt(pos)
+int pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ start_it(pos); /* command start action */
+ default_start_with_opt(pos); /* start optional param */
+ break;
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING:
+ special_start_with_opt(pos);
+ break;
+ default: /* should not be here! */
+ warning("(start_with_opt) Unrecognized command type");
+ break;
+ } /* end switch on user_kind */
+} /* end START_WITH_OPT */
+</pre>
+
+<p>The special actions code is in file <samp>l2xusrlib.c</samp>. The code
+for these all follow the same general pattern. For example, here is
+the code implementing the special action between the start of a
+command and a first optional argument.
+<pre>
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+</pre>
+Note that the code as provided just issues a warning message.
+
+
+<p>
+</dl>
+
+
+<p>
+ With this background, we will now go on with the example.
+
+
+<p><ol>
+
+
+ <li> Decide on how the LTX2X system will translate your command/environment
+description into its internal grammar command type. In this case it
+will translate into a command with possibly an initial optional argument
+and one required argument.
+
+
+<p>
+ <li> Examine the grammar for the command and hence determine which standard
+actions will be called. In this case there are three of these, namely
+<samp>start_with_opt</samp>, <samp>action_opt_first</samp> and <samp>action_last_p</samp>.
+These are the actions that might require modification.
+
+
+<p>
+ <li> Determine what actions are required for your special. Conceptually
+replace the standard actions in the grammar by your actions. Then determine
+how these should be incorporated into the special action code in
+<samp>l2xusrlb</samp>. In plain
+language, the grammar and conceptual actions for the example are:
+<pre>
+l2xComm1: COMMAND_1
+ {
+ start of as a sectioning command
+ ignore the optional argument as there isn't one
+ }
+ OptParam
+ {
+ finish processing the non-existent optional
+ get ready to store the argument text in a buffer
+ }
+ ReqParam
+ {
+ print the boilerplate and argument text
+ start the description list
+ }
+ ;
+</pre>
+Note that this is essentially the same as we did for the grammar
+implementation for <samp>\GRAMMspecial</samp>, except that there is the additional
+optional argument to be dealt with.
+
+
+<p>
+ <li> Modify the requisite special action code.
+
+
+<p>In the example, three standard actions have to be modified. Here is
+the modification to <samp>special_start_with_opt</samp>:
+<pre>
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ codespecial_start(pos);
+ default_start_with_opt(pos);
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+</pre>
+The addition is done by adding a new <samp>case 59999:</samp> together with
+appropriate code. The number 59999 is that corresponding to the
+value for <samp>SPECIAL_TOKEN=</samp> in the command table specification
+of <samp>\CODEspecial</samp>. The function <samp>codespecial_start</samp> is to
+be written, while <samp>default_start_with_opt</samp> is an LTX2X defined
+function which initiates processing of an initial optional argument.
+
+
+<p>Similarly, here is the modification to <samp>special_action_opt_first</samp>:
+<pre>
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ default_end_start_opt(pos);
+ codespecial_p1(pos);
+ break;
+
+ /* end of cases for specials */
+</pre>
+where <samp>codespecial_p1</samp> is to be written and <samp>default_end_start_opt</samp>
+is the standard LTX2X action at the end of an initial optional argument.
+
+
+<p>Finally, here is the modification to <samp>special_action_last_p</samp>:
+<pre>
+/* SPECIAL_ACTION_LAST_P action after last req argument */
+void special_action_last_p(pos,p)
+int pos; /* position of command in table */
+int p; /* number of last argument */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ if (p == 1) { /* has only one req param */
+ codespecial_end(pos);
+ }
+ break;
+
+ /* end of cases for specials */
+ /* stuff deleted to save space */
+</pre>
+
+<p>
+ <li> Code the functions for the new actions.
+
+
+<p>Code for these functions should be put into file <samp>l2xusrlb.c</samp>
+and file <samp>l2xusrlb.h</samp> modified accordingly.
+
+
+<p>Here is the code for the three <samp>codespecial_</samp> functions.
+<pre>
+char codebuf[80]; /* a string buffer */
+
+/* CODESPECIAL_START actions for start of CODEspecial command */
+void codespecial_start(pos)
+int pos; /* command table position */
+{
+ start_section(pos); /* do start of sectioning */
+ myprint(get_t(pos)); /* print start tag */
+} /* end CODESPECIAL_START */
+
+/* CODESPECIAL_P1 actions at start of CODEspecial param 1 */
+void codespecial_p1(pos)
+int pos; /* command table position */
+{
+ myprint(get_tag_t(pos,1)); /* print 1st param start tag */
+ initialise_sysbuf(); /* clear system string buffer */
+ set_print(p_print_to_sysbuf); /* put arg text into sys buffer */
+} /* end CODESPECIAL_P1 */
+
+/* CODESPECIAL_END actions at end of CODEspecial command */
+void codespecial_end(pos)
+int pos; /* command table position */
+{
+ initialise_string(codebuf); /* clear this string buffer */
+ copy_sysbuf(codebuf); /* copy sys buffer into codebuf */
+ reset_print(); /* normal printing */
+ prwboiler1(); /* print some boilerplate */
+ print_sysbuf(); /* print system buffer */
+ prwboiler2(); /* print more boilerplate */
+ myprint(codebuf); /* print codebuff */
+ prwboiler3(); /* print yet more boilerplate */
+ start_list(pos); /* start a list environment */
+} /* end CODESPECIAL_END */
+</pre>
+Note that these actions are almost identical to those that were used
+within the grammar when implementing the <samp>\GRAMMspecial</samp> command.
+
+
+<p>
+ <li> Compile the modified system and test it on example LaTeX files.
+
+
+<p></ol>
+
+
+
+<p>
+<h3>Notes</h3>
+
+
+
+<p><ol>
+
+
+ <li> Installation of a <samp>SPECIAL_</samp> can be limited to making changes
+ to the parser (file <samp>l2x.y</samp>) and/or the user library
+ (files <samp>l2xusrlb.c</samp> and <samp>l2xusrlb.h</samp>).
+ It should not be necessary to touch any other part of the system.
+
+
+<p>
+ <li> Changes to <tt>l2x.y</tt> will necessitate executing the parser generator
+ on this file and
+ system compilation. Changes to the other files will only necessitate
+ compilation.
+
+
+<p>
+ <li> Always use the <samp>myprint</samp>, <samp>verbatim_print</samp>
+ or <samp>print_sysbuf</samp> functions for
+ printing because they incorporate the print control
+ capability.
+
+
+<p>
+ <li> The printing in the above example is trivial. However, it is good practice
+ to define printed output separately from the parser. It makes for easier
+ maintenance. If, for example the boilerplate above was several thousand
+ characters, it might have been an idea to store the text in a file, or
+ files, and then have the boilerplate printing functions read from
+ the file(s).
+ If the text is in a state of flux this could be a good design decision
+ in any case, as changing the text would only involve modifying the
+ text file(s) and avoid recompilation of LTX2X.
+</ol>
+
+
+
+<p>
+<h4>An updated method</h4>
+
+
+<p>The above descriptions of installing a <samp>SPECIAL_</samp> command were
+written for the original release of the LTX2X system, which did not
+have the input and output specification facilities currently available
+within a command table. Below is given a possible command table entry using these
+facilities.
+
+
+<pre>
+TYPE= SPECIAL_COMMAND
+NAME= C= SPECIAL_TOKEN= set the appropriate number
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n&lt;div.1&gt;?n"
+ STRING: "&lt;heading&gt;Normative References&lt;/heading&gt;?n"
+ RESET_SYSBUF:
+ END_TAG= "?n&lt;/div.1&gt;"
+ REQPARAMS= 1
+ PRINT_P1= TO_SYSBUF
+ END_TAG_1=
+ STRING: "?nSome boilerplate text with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle. Now there is?n"
+ STRING: "some more boilerplate with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle of it.?n"
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+</pre>
+
+The actual implementation of this as either a grammar special or a code
+special is left as an exercise for the reader. Basically it involves
+the deletion of the specific print action and buffer code because this is now
+handled automatically via the command table specification.
+
+
+<p>
+
+
+<h2>APPENDICES</h2>
+
+
+<h2>Example command table file for de-TeX ing</h2>
+ <a name="sec:detexing"></a>
+
+
+<p>This appendix provides the skeleton of a command table file that could be used for
+de-TeX ing a LaTeX document.
+
+
+<p><pre>
+C= detex.ct command table file for ltx2x to deTeX source
+
+C= -----------------------------------escape sequences
+
+C= don't use default here as it may clash with command name output
+ESCAPE_CHAR= ?
+C= keep tye default vaues for the rest
+
+C= ----------------------------------- the built in commands
+TYPE= BEGIN_DOCUMENT
+END_TYPE
+
+TYPE= END_DOCUMENT
+END_TYPE
+
+TYPE= BEGIN_VERB
+END_TYPE
+
+TYPE= END_VERB
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+END_TYPE
+
+TYPE= END_DOLLAR
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= " "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+C= throw away naked braces
+TYPE= LBRACE
+END_TYPE
+
+TYPE= RBRACE
+END_TYPE
+
+C= Pretty printing will probably be applied. Indent start of paragraphs
+TYPE= PARAGRAPH
+ START_TAG= "?n?n "
+END_TYPE
+
+C= -------------------------------------(La)TeX special characters
+
+C= hash (for use in \def s )
+TYPE= TEX_CHAR
+NAME= #
+END_TYPE
+
+C= ampersand (tabular column delimiter, replace by some spaces)
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " "
+END_TYPE
+
+C= twiddle (unbreakable space)
+TYPE= TEX_CHAR
+NAME= ~
+ START_TAG= " "
+END_TYPE
+
+C= underscore (math subscript)
+TYPE= TEX_CHAR
+NAME= _
+ START_TAG= "_"
+END_TYPE
+
+C= caret (math superscript)
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "^"
+END_TYPE
+
+C= at
+TYPE= TEX_CHAR
+NAME= @
+ START_TAG= "@"
+END_TYPE
+
+C= ------------------------- default single character commands
+C= (replace by appropriate character)
+
+C= LaTeX start a new line
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+END_TYPE
+
+C= small space
+TYPE= CHAR_COMMAND
+ NAME= \,
+START_TAG= " "
+END_TYPE
+
+C= end of sentence space
+TYPE= CHAR_COMMAND
+NAME= \@
+ START_TAG= " "
+END_TYPE
+
+C= hash
+TYPE= CHAR_COMMAND
+NAME= \#
+ START_TAG= "#"
+END_TYPE
+
+C= dollar
+TYPE= CHAR_COMMAND
+NAME= \$
+ START_TAG= "$"
+END_TYPE
+
+C= ampersand
+TYPE= CHAR_COMMAND
+NAME= \&
+ START_TAG= "&"
+END_TYPE
+
+C= underscore
+TYPE= CHAR_COMMAND
+NAME= \_
+ START_TAG= "_"
+END_TYPE
+
+C= percent
+TYPE= CHAR_COMMAND
+NAME= \%
+ START_TAG= "%"
+END_TYPE
+
+C= left brace
+TYPE= CHAR_COMMAND
+NAME= \{
+ START_TAG= "{"
+END_TYPE
+
+C= right brace
+TYPE= CHAR_COMMAND
+NAME= \}
+ START_TAG= "}"
+END_TYPE
+
+C= optional hyphenation
+TYPE= CHAR_COMMAND
+NAME= \-
+ START_TAG= ""
+END_TYPE
+
+C= ----------------------------- General LaTeX
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+ START_ITEM= "?n -- "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "?n"
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+START_TAG= "?n"
+END_TYPE
+
+C= replace \footnote with parenthesized text
+TYPE= COMMAND
+NAME= \footnote
+ START_TAG= " ("
+ END_TAG= ") "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+C= ----------------------- sectioning (keep headers only)
+
+C= repeat for all the other sectioning commands
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= repeat for all the other starred sectioning commands
+TYPE= SECTIONING
+NAME= \section*
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= and whatever else is interesting
+END_CTFILE=
+</pre>
+
+<p>
+<h2>LaTeX to HTML translation</h2>
+ <a name="sec:htmling"></a>
+
+
+<p>The command table file <tt>l2h.ct</tt> contains a set of commands that
+enable simple LaTeX documents to be translated into HTML tagged
+documents for display using a World Wide Web browser. At a minumum
+this command table can be used for conversion of the LaTeX source of
+this manual. It can also handle some very simple mathematics but not
+pictures. (Footnote: HTML itself cannot handle pictures directly (i.e.,
+there is no equivalent to the LaTeX <samp>picture</samp> environment),
+and can only handle simple mathematics.) The specification
+for the HTML tags was taken from Musciano and Kennedy [<a href="#MUSCIANO96">MUSCIANO96</a>].
+
+
+<p>Generally speaking and subject to the above limitations,
+a LaTeX document can be translated
+to HTML without the document having been planned for this purpose,
+with one exception.
+The exception is that a new LaTeX command should be used in the
+document preamble.
+I have called this <samp>\mltitle</samp> and its purpose to to define
+the contents of the header for the HTML text. The definition of this command
+is:
+<pre>
+\newcommand{\mltitle}[1]{}
+</pre>
+That is, as far as LaTeX is concerned, the argument to the command is
+thrown away and is a non-event. As far as the <tt>l2h.ct</tt> command table is concerned
+the argument is the header title. As an example, this manual starts with:
+<pre>
+...
+\mltitle{LaTeX to X translator}
+\begin{document}
+\title{\lx: A \LaTeX{} to X Auto-tagger}
+...
+</pre>
+which gets converted into:
+
+
+<pre>
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;LaTeX to X translator&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+
+<p>&lt;h1 align=center&gt;
+ LTX2X: A LaTeX to X Auto-tagger
+&lt;/h1&gt;
+...
+</pre>
+
+If the <samp>\mltitle</samp> command is not used, then the effect is to have
+an empty &lt;title&gt; in the &lt;head&gt; of the HTML document.
+
+
+<p>
+ Several aspects of the design of <tt>l2h.ct</tt> in the context of
+the conversion of typical LaTeX documents have been discussed
+as examples in the body of the manual. However, there are some aspects
+specific to the translation of this document should be mentioned.
+These stem from the fact that HTML has no tags corresponding to
+to the LaTeX <samp>\verb</samp> command or <samp>verbatim</samp> environment which
+switch off the meanings of special characters.
+
+
+<p>HTML treats the characters &lt;, &gt;, &amp; and &#035; specially.
+Within a &lt;pre&gt;...&lt;/pre&gt; the browser honours the line breaks
+but does not switch off the meanings of the special characters. In LaTeX,
+the <samp>\verb</samp> command switches off all special characters but prohibits
+any line breaking. The <samp>verbatim</samp> environment both honours line breaks
+and switches off all special characters. The difficulty with this particular
+document is that I want to show author-formatted HTML source, and that is not
+easly possible, unlike using the LaTeX <samp>verbatim</samp> environment for
+showing user-formatted LaTeX source.
+
+
+<p>The problem was solved through the use of two LaTeX environments.
+The first of these is <samp>latexonly</samp> which is used for input that is
+to be processed normally by LaTeX but which is to be totally ignored
+by LTX2X. The other environment is <samp>htmlverbatim</samp> which is used
+for input that is to be totally ignored by LaTeX but which is to be
+processed by LTX2X into an HTML &lt;pre&gt; environment.
+
+
+<p>A package file has been written which provides some addtional
+commands and environments.
+
+
+
+<p>
+<pre>
+<samp>\ProvidesPackage{ltx2html}[1996/08/29 ltx2x HTMLing]</samp>
+<samp>\RequirePackage{html} % the package file for the Perl program</samp>
+ % latex2html
+
+
+<p>% The document title for the WWW browser.
+% If used, must be placed in the preamble.
+<samp>\newcommand{\mltitle}[1]{}</samp>
+
+
+<p>% argument is for processing by LaTeX only
+<samp>\providecommand{\latex}[1]</samp>{&#035;1}
+
+
+<p>% argument is for HTML processing only
+<samp>\providecommand{\html}[1]{}</samp>
+
+
+<p>% print argument as an SGML/HTML start tag
+<samp>\newcommand{\ST}</samp>[1]{&lt;&#035;1&gt;}
+
+
+<p>% print argument as an SGML/HTML end tag
+<samp>\newcommand{\ET}</samp>[1]{&lt;/&#035;1&gt;}
+
+
+<p>% print HTML special characters
+<samp>\newcommand{\Amp}</samp>{&amp;}
+<samp>\newcommand{\GT}</samp>{&gt;}
+<samp>\newcommand{\LT}</samp>{&lt;}
+<samp>\newcommand{\HASH}</samp>{&#035;}
+
+
+<p>% treat contents as a LaTeX comment but
+% translate contents into an HTML "verbatim" environment
+<samp>% Use as: \begin{htmlverbatim} ... \end{htmlverbatim}</samp>
+<samp>\excludecomment{htmlverbatim}</samp>
+
+
+<p><samp>\endinput</samp>
+</pre>
+
+
+
+<p>The command table entries for some of these are:
+
+
+<pre>
+TYPE= COMMAND
+NAME= &amp;
+ START_TAG= "&amp;amp;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= &gt;
+ START_TAG= "&amp;gt;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= &lt;
+ START_TAG= "&amp;lt;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= &#035;
+ START_TAG= "&amp;&#035;035;"
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= <samp>\ST</samp>
+ START_TAG= "&amp;lt;"
+ END_TAG= "&amp;gt;"
+ REQPARAMS= 1
+END_TYPE
+
+
+<p>TYPE= COMMAND
+NAME= <samp>\ET</samp>
+ START_TAG= "&amp;lt;/"
+ END_TAG= "&amp;gt;"
+ REQPARAMS= 1
+END_TYPE
+</pre>
+
+
+
+<p>Finally, as an example, this is how some of the prior example text
+could be
+written in the source of this document.
+.
+
+
+
+<p>
+<pre>
+<samp>\begin{latexonly}</samp>
+<samp>\begin{verbatim}</samp>
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;LaTeX to X translator&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+
+<p>&lt;h1 align=center&gt;
+ LTX2X: A LaTeX to X Auto-tagger
+&lt;/h1&gt;
+...
+<samp>\end{verbatim}</samp>
+<samp>\end{latexonly}</samp>
+
+
+<p><samp>\begin{htmlverbatim}</samp>
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;LaTeX to X translator<samp>\ET{title}</samp>
+<samp>\ET{head}</samp>
+&lt;body&gt;
+
+
+<p>&lt;h1 align=center&gt;
+&lt;title&gt;LaTeX to X translator<samp>\ET{title}</samp>
+<samp>\ET{head}</samp>
+<samp>...</samp>
+<samp>\end{htmlverbatim}</samp>
+</pre>
+
+
+
+<p>Reading the LaTeX source of this document will reveal some
+other details. Admittedly the problem was compounded by the fact
+that this document contains demonstrations of both LaTeX and
+HTML commands which will be processed through both LaTeX and HTML
+browsers, thus a modicum of care is required to appropriately
+process both sets of special characters.
+
+
+<p>
+
+<h2>Known limitations</h2>
+ <a name="sec:limitations"></a>
+
+
+<p>LTX2X does not do everything that it might (and probably never will).
+The following are some of the things that it does not do.
+
+
+<p><ul>
+
+
+ <li> It does not understand the LaTeX <samp>\input</samp> or <samp>\include</samp>
+ commands ---
+ it just reads the source file as given. It may be useful to pre-process the
+ source file through a program that will automatically incorporate included
+ files into a LaTeX root file [<a href="#PRW94b">PRW94b</a>].
+
+
+<p>
+ <li> The <samp>\newcommand</samp> and friends do not readily
+ fit into the command patterns that
+ LTX2X can deal with. In particular, if it comes across a <samp>\newcommand</samp>
+ specification for a command that is specified in the command table, interesting
+ results might occur (for example, all the following output could be thrown
+ away if the command takes any arguments).
+
+
+<p>For instance, if the document and the command table contain:
+<pre>
+\newcommand{\lx}{LTX2X}
+....
+The \lx\ program ...
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+</pre>
+then there is usually no problem. On the other hand, if the document and
+ the command table contain:
+<pre>
+\newcommand{\fd}[1]{\texttt{#1}}
+....
+where \fd{InputFile} is the name ...
+
+TYPE= COMMAND
+NAME= \fd
+ REQPARAMS= 1
+END_TYPE
+</pre>
+then there may be a problem, which might be as `minor' as LTX2X reporting
+ a parse error when it has reached <samp>\newcommand{\fd}</samp> in the input
+ file and then carrying on, or it may be more serious.
+
+
+<p>
+ <li> There is a slight problem with optional arguments. LTX2X always takes the
+ first close bracket (<samp>]</samp>) after the opening bracket as signalling
+ the end of the argument text. This occurs even if the close bracket
+ is enclosed in braces (i.e. <samp>{]}</samp>). Opening brackets within optional
+ argument text are handled correctly.
+
+
+<p>
+ <li> It cannot sensibly handle LaTeX
+ constructs of the form <samp>{\em emph text}</samp>.
+ That is, except for command arguments, it does not recognize
+ <samp>{...}</samp> as a grouping construct, so cannot successfully
+ tag the end of the <samp>emph text</samp> in the example. On the other
+ hand, if constructs like <samp>\emph{emph text}</samp> or
+ <samp>\begin{em}emph text\end{em}</samp> are used instead, start and end
+ tags can be generated, given appropriate specifications in the
+ command table.
+
+
+<p>
+ <li> It assumes that all commands that take arguments are written so
+ that each argument is enclosed in braces. For example, the
+ superscripting command should be written as <samp>^{2}</samp> and not
+ as <samp>^2</samp>. Similarly, accent commands should be written as
+ <samp>\={o}</samp> rather than <samp>\=o</samp>, and so on.
+
+
+<p>
+ <li> There has not been time to test all aspects of the EXPRESS-A
+ interpreter. It is possible that this may not perform quite
+ as advertised. In particular dynamic aggregates have not been fully
+ implemented. For example:
+<pre>
+LIST OF INTEGER;
+</pre>
+appears to be handled correctly. More complicated constructs involving
+ dynamic aggregates, such as
+<pre>
+ARRAY [1:7] OF LIST OF ARRAY [-21:21] OF INTEGER;
+</pre>
+have not been tested. It is improbable that <samp>BAG</samp> will
+ work; the status of <samp>SET</samp> is similar and additionally
+ the uniqueness test for set membership has not been implemented.
+
+ <li> No doubt other limitations will come to light as LTX2X gets more use.
+ On the other
+ hand, LTX2X has been able to handle a broader range of cases than
+ it was designed to address.
+
+
+<p>
+</ul>
+
+
+
+<p>
+
+<h2>Command table summary</h2>
+ <a name="sec:summary"></a>
+
+
+<p>This section summarizes the commands and specifications available
+for defining a command table.
+
+
+<p>
+<h3>Special print characters</h3>
+
+
+
+<p>The combination of an escape character and another character can be used to
+specify certain non-visible characters within a tag string. The commands are
+given in Table <a href="#tab:spc">tab:spc</a>.
+
+
+<p><center><table border>
+
+<caption>Special print character commands.</caption> <a name="tab:spc">(Table tab:spc)</a>
+
+<tr><td> Command </td><td > Default </tr>
+<tr><td > <samp>AUDIBLE_ALERT_CHAR=</samp> </td><td > <samp>a</samp> </tr>
+<tr><td >
+<samp>BACKSPACE_CHAR=</samp> </td><td > <samp>b</samp> </tr>
+<tr><td >
+<samp>CARRIAGE_RETURN_CHAR=</samp> </td><td > <samp>r</samp> </tr>
+<tr><td >
+<samp>ESCAPE_CHAR=</samp> </td><td > <samp>\</samp> </tr>
+<tr><td >
+<samp>FORMFEED_CHAR=</samp> </td><td > <samp>f</samp> </tr>
+<tr><td >
+<samp>HEX_CHAR=</samp> </td><td > <samp>x</samp> </tr>
+<tr><td >
+<samp>HORIZONTAL_TAB_CHAR=</samp> </td><td > <samp>t</samp> </tr>
+<tr><td >
+<samp>NEWLINE_CHAR=</samp> </td><td > <samp>n</samp> </tr>
+<tr><td >
+<samp>VERTICAL_TAB_CHAR=</samp> </td><td > <samp>v</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>These commands take one character as their value. If any commands are not
+specified, then the default value is used. These commands, if used, must be
+at the beginning of the command table before any <samp>TYPE=</samp> commands,
+although their ordering is not significant among themselves.
+
+
+<p>
+<h3>EXPRESS-A code initialization</h3>
+
+
+
+<p>The keyword <samp>CODE_SETUP=</samp> indicates that the following part
+of the command table, up until the <samp>END_CODE</samp> keyword, contains
+EXPRESS-A code declarations and/or statements. If used, this block
+must come before any of the <samp>TYPE=</samp> commands.
+
+
+<p>
+<h3>Comments and file inclusion</h3>
+
+
+
+<p>A comment within a command table file is any line starting with <samp>C= </samp>.
+
+
+<p>A file can be included within another command table file with the command line
+<pre>
+INCLUDE= FileName
+</pre>
+where <samp>FileName</samp> is the name of the file to be included. The
+<samp>INCLUDE=</samp>
+command cannot appear between the command pair <samp>TYPE=</samp> and its following
+<samp>END_TYPE</samp>.
+
+
+<p>The end of a command table file is either the physical end of the file or
+the command <samp>END_CTFILE=</samp>, whichever occurs first.
+
+
+<p>
+<h3>Command types</h3>
+
+
+
+<p>All command type specifications have the general form:
+<pre>
+TYPE= CommandType
+NAME= CommandName
+ C= a possibly empty list of mode-independent commands
+ C= possibly sets of mode-dependent commands
+END_TYPE
+</pre>
+where <samp>CommandType</samp> is a keyword identifying the kind of command being
+specified and <samp>CommandName</samp> is the identifier of a LaTeX command
+or environment. The potential set of commands that can be used between the
+<samp>TYPE=</samp>
+and <samp>END_TYPE</samp> commands depends on the kind of command being specified,
+but the special print character commands, Table <a href="#tab:spc">tab:spc</a>,
+and the <samp>INCLUDE=</samp> command cannot
+appear within a type specification. All command specifications, except
+for the built in command types (see Table <a href="#tab:rct">tab:rct</a>),
+must include at least a <samp>NAME=</samp> command.
+The ordering of commands within a type
+specification is not significant. The ordering of type specifications within
+a command table file is not significant.
+
+
+<p>The <samp>NAME=</samp> command takes as its value the name of a LaTeX command or
+environment. The name must be written exactly as it would appear in a LaTeX
+source file. That is, <samp>\command</samp> for any command except <samp>\begin{}</samp>
+or <samp>\end{}</samp>, and as <samp>env</samp> for an
+environment begun as <samp>\begin{env}</samp> or ended by <samp>\end{env}</samp>.
+
+
+<p>
+<h4>Built in command types</h4>
+
+
+<p>Table <a href="#tab:rct">tab:rct</a> lists the keywords for the built in command types.
+
+
+<p><center><table border>
+
+<caption>Built in command type keywords.</caption> <a name="tab:rct">(Table tab:rct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command </tr>
+<tr><td > <samp>BEGIN_DOCUMENT</samp> </td><td > <samp>\begin{document}</samp> </tr>
+<tr><td >
+<samp>BEGIN_DOLLAR</samp> </td><td > <samp>$</samp> at start of in-text math </tr>
+<tr><td >
+<samp>BEGIN_VERB</samp> </td><td > <samp>\verb</samp> or <samp>\verb*</samp> and its following character </tr>
+<tr><td >
+<samp>BEGIN_VERBATIM</samp> </td><td > <samp>\begin{verbatim}</samp> or <samp>\begin{verbatim*}</samp> </tr>
+<tr><td >
+<samp>END_DOCUMENT</samp> </td><td > <samp>\end{document}</samp> </tr>
+<tr><td >
+<samp>END_DOLLAR</samp> </td><td > <samp>$</samp> at end of in-text math </tr>
+<tr><td >
+<samp>END_VERB</samp> </td><td > the ending character for <samp>\verb</samp> or <samp>\verb*</samp> </tr>
+<tr><td >
+<samp>END_VERBATIM</samp> </td><td > <samp>\end{verbatim}</samp> or <samp>\end{verbatim*}</samp> </tr>
+<tr><td >
+<samp>LBRACE</samp> </td><td > <samp>{</samp> </tr>
+<tr><td >
+<samp>OTHER_BEGIN</samp> </td><td > of the form <samp>\begin{env}</samp> not specified elsewhere </tr>
+<tr><td >
+<samp>OTHER_COMMAND</samp> </td><td > of the form <samp>\comm</samp> not specified elsewhere </tr>
+<tr><td >
+<samp>OTHER_END</samp> </td><td > of the form <samp>\end{env}</samp> not specified elsewhere </tr>
+<tr><td >
+<samp>PARAGRAPH</samp> </td><td > blank source line </tr>
+<tr><td >
+<samp>RBRACE</samp> </td><td > <samp>}</samp> </tr>
+<tr><td >
+<samp>SLASH_SPACE</samp> </td><td > <samp>\ </samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>The built in command type specifications can only sensibly use two kinds
+of actions ---
+those specified at the start of the command (e.g., <samp>PC_AT_START=</samp>
+and <samp>START_TAG=</samp>) and/or actions at the end of the command
+(e.g., <samp>PC_AT_END</samp> and <samp>END_TAG=</samp>).
+The <samp>NAME=</samp> command must not be used.
+
+
+<p>The <samp>OTHER_</samp> types are an exception to the above, in that they can include
+the command line <samp>PRINT_CONTROL= NO_PRINT</samp>.
+
+
+<p>LTX2X checks the command table for the presence of these required types. If one
+or more have not been specified, then they are automatically added to the command table
+with default values (e.g. empty strings) for the tags, and a warning message is
+printed giving the default value(s).
+
+
+<p>
+<h4>Optional command types</h4>
+
+
+<p>For discussion purposes, the optional command types have been tabulated
+in different categories. The basic distinction between these categories is
+the sets of commands that are permissible within the command specification.
+
+
+<p>At a minimum, all the specifications must include a <samp>NAME=</samp> command
+and must not contain any <samp>PRINT_CONTROL=</samp> or <samp>INCLUDE=</samp> commands
+or the special
+print character commands listed in Table <a href="#tab:spc">tab:spc</a>.
+
+
+<p>
+ The keywords for the general command types are given Table <a href="#tab:gct">tab:gct</a>.
+
+
+<p><center><table border>
+
+<caption>General command type keywords.</caption> <a name="tab:gct">(Table tab:gct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command form </tr>
+<tr><td > <samp>TEX_CHAR</samp> </td><td > LaTeX special characters (except <samp>{ } $</samp>) </tr>
+<tr><td >
+<samp>CHAR_COMMAND</samp> </td><td > <samp>\c</samp>, where <samp>c</samp> is non-alphabetic </tr>
+<tr><td >
+<samp>COMMAND</samp> </td><td > <samp>\command</samp> except for sectioning or picture commands </tr>
+<tr><td >
+<samp>BEGIN_ENV</samp> </td><td > <samp>\begin{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>END_ENV</samp> </td><td > <samp>\end{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>VCOMMAND</samp> </td><td > a <samp>\verb</samp>-like command </tr>
+<tr><td >
+<samp>BEGIN_VENV</samp> </td><td > start of a <samp>verbatim</samp>-like environment </tr>
+<tr><td >
+<samp>END_VENV</samp> </td><td > end of a <samp>verbatim</samp>-like environment </tr>
+<tr><td >
+</table></center>
+
+
+<p>A general command type specification can include any of the tagging and print
+option commands. They cannot contain a <samp>SECTION_LEVEL=</samp> command, nor can
+they contain any of the <samp>_ITEM_</samp> commands.
+
+
+<p>The keywords for the specific command types are given in Table <a href="#tab:sct">tab:sct</a>.
+
+
+<p><center><table border>
+
+<caption>Specific command type keywords.</caption> <a name="tab:sct">(Table tab:sct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command form </tr>
+<tr><td > <samp>BEGIN_LIST_ENV</samp> </td><td > <samp>\begin{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>BEGIN_PICTURE_CC</samp> </td><td > <samp>\begin{pic}()()</samp> </tr>
+<tr><td >
+<samp>END_LIST_ENV</samp> </td><td > <samp>\end{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>END_PICTURE</samp> </td><td > <samp>\end{pic}</samp> </tr>
+<tr><td >
+<samp>PICTURE_CCPP</samp> </td><td > <samp>\pic()(){}{}</samp> </tr>
+<tr><td >
+<samp>PICTURE_CO</samp> </td><td > <samp>\pic()[]</samp> </tr>
+<tr><td >
+<samp>PICTURE_COP</samp> </td><td > <samp>\pic()[]{}</samp> </tr>
+<tr><td >
+<samp>PICTURE_CP</samp> </td><td > <samp>\pic(){}</samp> </tr>
+<tr><td >
+<samp>PICTURE_OCC</samp> </td><td > <samp>\pic[]()()</samp> </tr>
+<tr><td >
+<samp>PICTURE_OCCC</samp> </td><td > <samp>\pic[]()()()</samp> </tr>
+<tr><td >
+<samp>PICTURE_OCO</samp> </td><td > <samp>\pic[]()[]</samp> </tr>
+<tr><td >
+<samp>PICTURE_PCOP</samp> </td><td > <samp>\pic{}()[]{}</samp> </tr>
+<tr><td >
+<samp>SECTIONING</samp> </td><td > <samp>\command</samp> for a document section </tr>
+<tr><td >
+<samp>COMMAND_OOP</samp> </td><td > <samp>\com[][]{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_OOOPP</samp> </td><td > <samp>\com[][][]{}{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_OPO</samp> </td><td > <samp>\com[]{}[]</samp> </tr>
+<tr><td >
+<samp>COMMAND_POOOP</samp> </td><td > <samp>\com{}[][][]{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_POOP</samp> </td><td > <samp>\com{}[][]{}</samp> </tr>
+<tr><td >
+<samp>COMMAND_POOPP</samp> </td><td > <samp>\com{}[][]{}{}</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>A <samp>BEGIN_LIST_ENV</samp> specification should include at least a
+<samp>START_ITEM=</samp> command. The other <samp>_ITEM_</samp> commands
+are optional.
+Other commands follow the rules for the general command types.
+
+
+<p>The potential commands for the <samp>_PICTURE_</samp> commands are the same as
+for the general commands, with the exception that commands related to optional
+argument processing are not available for use.
+
+
+<p>A <samp>SECTIONING</samp> command specification must include a
+<samp>SECTIONING_LEVEL=</samp>
+command. Other commands follow the rules for the general command types.
+
+
+<p>The keywords for the special command types are given in
+Table <a href="#tab:specct">tab:specct</a>.
+
+
+<p><center><table border>
+
+<caption>Special command type keywords.</caption> <a name="tab:specct">(Table tab:specct)</a>
+
+<tr><td> Keyword </td><td > LaTeX command form </tr>
+<tr><td > <samp>SPECIAL</samp> </td><td > reserved for possible future use </tr>
+<tr><td >
+<samp>SPECIAL_BEGIN_ENV</samp> </td><td > <samp>\begin{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_BEGIN_LIST</samp> </td><td > <samp>\begin{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_COMMAND</samp> </td><td > <samp>\command</samp> </tr>
+<tr><td >
+<samp>SPECIAL_END_ENV</samp> </td><td > <samp>\end{env}</samp> except for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_END_LIST</samp> </td><td > <samp>\end{env}</samp> for <samp>\item</samp> lists </tr>
+<tr><td >
+<samp>SPECIAL_SECTIONING</samp> </td><td > <samp>\command</samp> for a document section </tr>
+<tr><td >
+</table></center>
+
+
+<p>Apart from the general restrictions on the allowed commands within
+a specification, there are no restrictions on the commands that can be
+included within the specification of a <samp>SPECIAL_</samp> command. It is up
+to the creator of the special to decide what is appropriate. However,
+each <samp>SPECIAL_</samp> specification must include the command
+<pre>
+SPECIAL_TOKEN= N
+</pre>
+where <samp>N</samp> is an integer number (with 10000 &lt;= N &lt;= 32767 for a
+grammar special, or N &gt; 50000 for a code special) that has been specified
+within LTX2X as being identified with the grammar and actions corresponding to the
+value of the <samp>NAME=</samp> command for the <samp>SPECIAL_</samp>.
+
+
+<p>
+<h3>Tag specification commands</h3>
+
+
+
+<p>
+<h4>Arguments</h4>
+
+
+<p>The commands relating to the specification of LaTeX command arguments
+are given in Table <a href="#tab:param">tab:param</a>.
+
+
+<p><center><table border>
+
+<caption>Argument commands.</caption> <a name="tab:param">(Table tab:param)</a>
+
+<tr><td> Command </td><td > Value </tr>
+<tr><td > <samp>OPT_PARAM=</samp> </td><td > <samp>FIRST</samp> or <samp>LAST</samp> </tr>
+<tr><td >
+<samp>REQPARAMS=</samp> </td><td > Integer. The number of required arguments </tr>
+<tr><td >
+</table></center>
+
+
+<p>The <samp>OPT_PARAM=</samp> command specifies that the LaTeX command takes one
+optional argument and it is the <samp>FIRST</samp> or <samp>LAST</samp> in the argument
+list.
+
+
+<p>The <samp>REQPARAMS=</samp> command specifies that the LaTeX command has
+<samp>Integer</samp> number of required arguments. <samp>Integer</samp> must be between
+one and nine (Footnote: Or eight if <samp>OPT_PARAM=</samp> is specified.) inclusive.
+
+
+<p>Absence of these commands implies that the relevant LaTeX command has
+no arguments of the unspecified kind.
+
+
+<p>
+<h4>Tag actions</h4>
+
+
+<p>The commands for specifying the tag actions are summarized in
+Table <a href="#tab:tag">tab:tag</a>.
+The <samp>_ITEM_</samp> commands can only be used within a
+<samp>BEGIN_LIST_ENV</samp> or a <samp>SPECIAL_</samp> command specification.
+
+
+<p><center><table border>
+
+<caption>Tag commands.</caption> <a name="tab:tag">(Table tab:tag)</a>
+
+<tr><td> Command </td><td > Application </tr>
+<tr><td > <samp>END_ITEM=</samp> </td><td > actions after <samp>\item</samp> text </tr>
+<tr><td >
+<samp>END_ITEM_PARAM=</samp> </td><td > actions after <samp>\item</samp> optional argument </tr>
+<tr><td >
+<samp>END_OPT=</samp> </td><td > actions after optional argument </tr>
+<tr><td >
+<samp>END_TAG=</samp> </td><td > actions after all arguments processed </tr>
+<tr><td >
+<samp>END_TAG_n=</samp> </td><td > actions after n'th required argument </tr>
+<tr><td >
+<samp>START_ITEM=</samp> </td><td > actions before <samp>\item</samp> </tr>
+<tr><td >
+<samp>START_ITEM_PARAM=</samp> </td><td > actions before <samp>\item</samp> optional argument </tr>
+<tr><td >
+<samp>START_OPT=</samp> </td><td > actions before optional argument </tr>
+<tr><td >
+<samp>START_TAG=</samp> </td><td > actions at start of command </tr>
+<tr><td >
+<samp>START_TAG_n=</samp> </td><td > actions before n'th required argument </tr>
+<tr><td >
+</table></center>
+
+
+<p>
+
+ Each of these commands can specify a list of actions to be performed;
+typically this is just to print a text string. A string is any set of
+characters enclosed in double
+quote marks. The string can include any special printing characters. The
+text string starts immediately after the first double quote and ends immediately
+before the last double quote. The string cannot include a physical linebreak
+within the command table file. If the first action is to print a string then the
+string may be placed on the same line as the keyword.
+
+
+<p>The actions are listed one per line and are performed in the order they
+are listed. Table <a href="#tab:tagaction">tab:tagaction</a> lists the action commands.
+
+
+<p><center><table border>
+
+<caption>Tag actions.</caption> <a name="tab:tagaction">(Table tab:tagaction)</a>
+
+<tr><td> Keyword </td><td > Value </td><td > Application </tr>
+<tr><td > <samp>STRING:</samp> </td><td > text string </td><td > Print the string </tr>
+<tr><td >
+<samp>SOURCE:</samp> </td><td > <samp>BUFFER</samp> <samp>num</samp> </td><td > Print the contents of
+ buffer number <samp>num</samp> </tr>
+<tr><td >
+<samp>SOURCE:</samp> </td><td > <samp>FILE</samp> <samp>name</samp> </td><td > Print the contents of file
+<samp>name</samp> </tr>
+<tr><td >
+<samp>SOURCE:</samp> </td><td > <samp>SYSBUF</samp> </td><td > Print the contents of the system buffer </tr>
+<tr><td >
+<samp>RESET_BUFFER:</samp> </td><td > <samp>num</samp> </td><td > Reset the buffer <samp>num</samp> </tr>
+<tr><td >
+<samp>RESET_FILE:</samp> </td><td > <samp>name</samp> </td><td > Reset the file <samp>name</samp> </tr>
+<tr><td >
+<samp>RESET_SYSBUF:</samp> </td><td > </td><td > Reset the system buffer </tr>
+<tr><td >
+<samp>SWITCH_TO_BUFFER:</samp> </td><td > <samp>num</samp> </td><td > Print to buffer number <samp>num</samp> </tr>
+<tr><td >
+<samp>SWITCH_TO_FILE:</samp> </td><td > <samp>name</samp> </td><td > Print to file called <samp>name</samp> </tr>
+<tr><td >
+<samp>SWITCH_TO_SYSBUF:</samp> </td><td > </td><td > Print to the system buffer </tr>
+<tr><td >
+<samp>SWITCH_BACK:</samp> </td><td > </td><td > Reset the print mode </tr>
+<tr><td >
+<samp>SET_MODE:</samp> </td><td > <samp>name</samp> </td><td > Set the mode to <samp>name</samp> </tr>
+<tr><td >
+<samp>RESET_MODE:</samp> </td><td > </td><td > Reset the mode to its prior value </tr>
+<tr><td >
+<samp>CODE:</samp> </td><td > </td><td > Start of a set of EXPRESS-A statements </tr>
+<tr><td >
+</table></center>
+
+
+<p>
+<h4>Print control</h4>
+
+
+<p>The print control commands are summarized in Table <a href="#tab:print">tab:print</a>.
+These are used to set the print mode at the start and end of a command, and for
+each argument. The exception is the <samp>PRINT_CONTROL=</samp> command
+which can only be used within an <samp>OTHER_</samp> command type
+specification, and which is the only print control that can be
+specified for the <samp>OTHER_</samp> commands.
+
+
+<p><center><table border>
+
+<caption>Print control commands.</caption> <a name="tab:print">(Table tab:print)</a>
+
+<tr><td> Command </td><td > Application </tr>
+<tr><td > <samp>PRINT_CONTROL=</samp> </td><td > printing of <samp>OTHER_</samp> commands </tr>
+<tr><td >
+<samp>PC_AT_START=</samp> </td><td > set printing at start of command </tr>
+<tr><td >
+<samp>PC_AT_END=</samp> </td><td > set printing at end of command </tr>
+<tr><td >
+<samp>PRINT_OPT=</samp> </td><td > printing of optional argument </tr>
+<tr><td >
+<samp>PRINT_Pn=</samp> </td><td > printing of n'th required argument </tr>
+<tr><td >
+</table></center>
+
+
+<p>The values that these commands may take are given in Table <a href="#tab:pcvalues">tab:pcvalues</a>.
+These direct where any print output is to be directed. The default is to
+send all output the the file named as the output on the command line when
+starting LTX2X.
+
+
+<p><center><table border>
+
+<caption>Print control values.</caption> <a name="tab:pcvalues">(Table tab:pcvalues)</a>
+
+<tr><td> Value </td><td > Application </tr>
+<tr><td > <samp>NO_PRINT</samp> </td><td > Do not print at all </tr>
+<tr><td >
+<samp>TO_SYSBUF</samp> </td><td > Print to the system buffer </tr>
+<tr><td >
+<samp>TO_BUFFER</samp> <samp>num</samp> </td><td > Print to buffer number <samp>num</samp> </tr>
+<tr><td >
+<samp>TO_FILE</samp> <samp>name</samp> </td><td > Print to file called <samp>name</samp> </tr>
+<tr><td >
+<samp>NO_OP</samp> </td><td > Do not do any processing </tr>
+<tr><td >
+<samp>RESET</samp> </td><td > Reset the print mode </tr>
+<tr><td >
+</table></center>
+
+
+<p><samp>NO_PRINT</samp> and <samp>NO_OP</samp> both produce no printed output.
+However, in the <samp>NO_OP</samp> case the lexer handles all the processing,
+and effectively just ignores the source document text. In the <samp>NO_PRINT</samp>
+case, the source text is processed as normal, but the printing is directed
+to a black hole.
+
+
+<p>
+
+
+<h4>Sectioning</h4>
+
+
+<p>
+ <samp>SECTIONING</samp> command specifications require a
+<samp>SECTIONING_LEVEL=</samp>
+command. The values that this can take are listed in Table <a href="#tab:level">tab:level</a>.
+
+
+<p><center><table border>
+
+<caption>Sectioning level values.</caption> <a name="tab:level">(Table tab:level)</a>
+
+<tr><td> Value </td><td > Application </tr>
+<tr><td > <samp>PART</samp> </td><td > sectioning equivalent to <samp>\part</samp> </tr>
+<tr><td >
+<samp>CHAPTER</samp> </td><td > sectioning equivalent to <samp>\chapter</samp> </tr>
+<tr><td >
+<samp>SECT</samp> </td><td > sectioning equivalent to <samp>\section</samp> </tr>
+<tr><td >
+<samp>SUBSECT</samp> </td><td > sectioning equivalent to <samp>\subsection</samp> </tr>
+<tr><td >
+<samp>SUBSUBSECT</samp> </td><td > sectioning equivalent to <samp>\subsubsection</samp> </tr>
+<tr><td >
+<samp>PARA</samp> </td><td > sectioning equivalent to <samp>\paragraph</samp> </tr>
+<tr><td >
+<samp>SUBPARA</samp> </td><td > sectioning equivalent to <samp>\subprargraph</samp> </tr>
+<tr><td >
+</table></center>
+
+
+<p>A sectioning command specification uses the <samp>END_TAG=</samp> text tag differently
+from its use by any other specification. In this case, the tag is printed at
+the closure of the text forming the body of the section of the document. A
+document section is considered to be closed when it is followed by a higher
+level sectioning command. The values in Table <a href="#tab:level">tab:level</a> are listed
+in decreasing level. That is, a section at level <samp>CHAPTER</samp> is at a higher
+level than a section at level <samp>PARA</samp>.
+
+
+<p><dl>
+<dt>NOTE
+<dd> For the use of writers of <samp>SPECIAL_</samp> command specifications,
+<samp>SECTIONING_LEVEL=</samp> can be given some additional values. These are
+<samp>PARTm2</samp> and <samp>PARTm1</samp> for levels respectively two and one higher
+than <samp>PART</samp>, and <samp>SUBPARAp1</samp> and <samp>SUBPARAp2</samp> for levels respectively
+one and two lower than <samp>SUBPARA</samp>.
+</dl>
+
+
+<p>
+<h2>System installation</h2>
+ <a name="sec:install"></a>
+
+
+<p>This section describes how to install the LTX2X program and some of the
+internal size limits within LTX2X.
+
+
+<p>
+ The basic LTX2X system requires the following source files:
+<dl>
+<dt><tt>l2x.l</tt>
+<dd> the lexer source.
+<dt><tt>l2x.y</tt>
+<dd> the parser source.
+<dt><tt>l2xlib.c</tt>, <tt>l2xlib.h</tt>
+<dd> main program and support functions.
+<dt><tt>l2xlibtc.h</tt>
+<dd> header file containing keywords and their
+ representations as strings.
+<dt><tt>l2xcom.h</tt>
+<dd> header file for all system components
+ (except for getopt, srchenv and the interpreter).
+<dt><tt>l2xacts.c</tt>, <tt>l2xacts.h</tt>
+<dd> standard action functions.
+<dt><tt>l2xusrlb.c</tt>, <tt>l2xusrlb.h</tt>
+<dd> special actions and user-defined functions.
+<dt><tt>strtypes.h</tt>
+<dd> header file with some type definitions.
+<dt><tt>getopt.c</tt>, <tt>getopt.h</tt>
+<dd> functions for handling command line
+ options Chapter 6[<a href="#LIBES93">LIBES93</a>].
+<dt><tt>srchenv.c</tt>, <tt>srchenv.h</tt>
+<dd> functions for searching directories
+ for files page 747[<a href="#HOLUB90">HOLUB90</a>].
+</dl>
+
+
+<p>The EXPRESS-A interpreter also requires the following files:
+<dl>
+<dt><tt>l2xistup.c</tt>
+<dd> the interface between the main part of LTX2X
+ and the interpreter.
+<dt><tt>l2xicmon.h</tt>
+<dd> header file for the interface.
+<dt><tt>l2xirtne.c</tt>, <tt>l2xistd.c</tt>, <tt>l2xidecl.c</tt>,
+ <tt>l2xistmt.c</tt>, <tt>l2xiexpr.c</tt>
+<dd> the files that contain the code for
+ parsing EXPRESS-A. Respectively they deal with functions and procedures,
+ the built-in functions, declarations, statements, and expressions.
+<dt><tt>l2xiprse.h</tt>
+<dd> header file for parsing.
+<dt><tt>l2xixutl.c</tt>, <tt>l2xiexec.h</tt>
+<dd> utility routines
+ supporting the execution module and
+ for managing the interpreter's stack.
+<dt><tt>l2xixstd.c</tt>, <tt>l2xixstm.c</tt>, <tt>l2xixxpr.c</tt>
+<dd> functions for
+ executing the EXPRESS-A built in functions, statements and expressions.
+<dt><tt>l2xirexp.c</tt>, <tt>l2xirexpr.h</tt>
+<dd> general functions for processing
+ and executing regular expressions.
+<dt><tt>listsetc.c</tt>, <tt>listsetc.h</tt>
+<dd> general functions for processing
+ lists.
+<dt><tt>l2xiscan.c</tt>, <tt>l2xiscan.h</tt>
+<dd> lexing routines for the interpreter.
+<dt><tt>l2xisymt.c</tt>, <tt>l2xisymt.h</tt>
+<dd> routines for managing the
+ interpreter's symbol tables.
+<dt><tt>l2xidbug.c</tt>
+<dd> the source level debugger.
+<dt><tt>l2xierr.c</tt>, <tt>l2xierr.h</tt>
+<dd> EXPRESS-A language error handling
+ and diagnostic output for the user.
+<dt><tt>l2xiidbg.c</tt>, <tt>l2xiidbg.h</tt>, <tt>l2xisdcl.c</tt>
+<dd> diagnostics
+ for a developer of the interpreter.
+<dt><tt>licomsym.h</tt>
+<dd> general header file for the interpreter modules.
+<dt><tt>l2xidftc.h</tt>, <tt>l2xiertc.h</tt>, <tt>l2xisctc.h</tt>, <tt>l2xisftc.h</tt>
+<dd>
+header files containing keywords and their representations as strings.
+</dl>
+
+
+<p>The following files may be useful:
+<dl>
+<dt><tt>man</tt>
+<dd> the manpage
+<dt><tt>printct.c</tt>
+<dd> a program to print and update command table files;
+<dt><tt>ltx2html.sty</tt>
+<dd> a LaTeX package file to assist in retagging
+a LaTeX document to an HTML document.
+</dl>
+
+
+<p>Essentially, installing LTX2X consists of processing the file <tt>l2x.l</tt>
+through a lexer generator, processing the file <tt>l2x.y</tt> through a
+parser generator, and then compiling the results together with the other
+supplied source files.
+
+
+<p>The lexer source file <tt>l2x.l</tt> and the parser source file
+<tt>l2x.y</tt> have to be processed by flex (or equivalent) and bison
+(or equivalent) respectively to generate C code. This code, together
+with the code in the other source files must then be compiled
+and linked to form the executable.
+
+
+<p>The executable must then, after suitable testing, be moved to
+its final place in your system and the manpage (file <tt>man</tt>)
+also copied to its final position in your directory structure.
+
+
+<p>Included in the LTX2X distribution are several command table files. One is
+<tt>detex.ct</tt> which provides an example of commands for de-TeX ing
+a document. (Footnote: You may wish to try using <tt>detex.ct</tt> on the
+LaTeX source of this document to see what the effect is. This can
+also serve as a check on the system installation.)
+Another is <tt>remcom.ct</tt>
+which provides an example of commands to remove comments from a
+LaTeX document. The command table file <tt>bye.ct</tt> replaces a LaTeX
+document by "Goodbye document".
+Another is <tt>ltx2x.ct</tt> which does nothing except try and include
+another file named <tt>ZiLcH</tt>, which presumably is not on anyone's
+system. Running LTX2X with this file will prompt for another name of a
+file if it cannot find <tt>ZiLcH</tt>; enter an existing file (like <tt>detex.ct</tt>)
+at the prompt. (Footnote: This is one way of setting up LTX2X for interactive
+specification of the desired command table file(s).)
+
+
+<p>The command table file <tt>l2h.ct</tt> has proven to be adequate for converting
+the LaTeX source of this manual, and other LaTeX documents without
+pictures and only limited mathematics, into an ASCII file with HTML
+tags instead.
+
+
+<p>The file <tt>fun.ct</tt> contains some test code for the EXPRESS-A
+interpreter. The contents are similar to the example shown at the end of
+section <a href="#sec:expressa">sec:expressa</a>.
+
+
+<p>The <tt>l2xusrlb</tt> files are skeletons. The system does include
+the functions and parser constructs for the <samp>\GRAMMspecial</samp> and
+<samp>\CODEspecial</samp> commands used as examples previously. The last two
+entries in <tt>remcom.ct</tt> are the specification of these, and the
+implementation is as described previously.
+
+
+<p>
+<h3>Command table printing</h3>
+
+
+
+<p>The grammar of the command table has been changed slightly since the
+initial release of LTX2X. The utility C program in <tt>printct.c</tt> may be used to:
+<ul>
+
+
+ <li> Pretty-print a command table;
+
+ <li> Convert an original command table to one that conforms to the new grammar.
+</ul>
+
+
+
+<p>The syntax for running <tt>printct</tt> is:
+<pre>
+printct [-D dir_cat_char] [-P path_seperators] [-f table_file] [-t]
+</pre>
+where elements in square brackets are options. These options are identical
+to the corresponding ones for LTX2X and are as follows:
+<dl>
+<dt>-f
+<dd> By default, <tt>printct</tt> reads the command table from a file called
+ <tt>ltx2x.ct</tt>. If the required command table is in a file with another name this
+ option is used to change from the default file. For example,
+<pre>
+> printct
+</pre>
+reads a command table from <samp>ltx2x.ct</samp>, while
+<pre>
+> printct -f detex.ct
+</pre>
+reads a command table from file <samp>detex.ct</samp>.
+
+
+<p><dt>-t
+<dd> This generates some diagnostics related to the processing of
+ the command table file.
+
+
+<p><dt>-D
+<dd> The value of this option is the character that the operating system
+ uses to catenate directory names to form a path (see <a href="#sec:search">sec:search</a>).
+ The default value is a
+ slash (i.e. <samp>/</samp>). The default could be changed to a backslash, for example,
+ by <samp>-D \</samp>.
+
+
+<p><dt>-P
+<dd> The environment variable (see <a href="#sec:search">sec:search</a>)
+ contains a list of directories (also known
+ as path names). In the operating system that I use, these are separated by
+ the colon (<samp>:</samp>) character which, together with the semi-colon
+ and space characters, form
+ the LTX2X default separators. The path separator characters can be changed
+ with this option.
+ For example, <samp>-P :</samp> will make the separators be a colon
+ or a space (space is automatically included in the separator list).
+</dl>
+
+
+<p><tt>printct</tt> only reads a single command table file and outputs the
+pretty-printed and updated version to file <tt>printct.lis</tt>. It performs
+a very limited amount of error checking and writes error messages and
+statistics to the file <tt>printct.err</tt>.
+
+
+<p>
+
+<h3>A make file</h3>
+
+
+
+<p>
+ Here is a UNIX <tt>make</tt> file [<a href="#ORAM91">ORAM91</a>] for the LTX2X system.
+
+
+<p><pre>
+# makefile for program ltx2x --- LaTeX to X autotagger
+#
+##################### Change the following for your setup
+# The compiler
+CC = cc
+
+# We use flex (or equivalent, but not lex) to generate the lexer
+LEX = flex
+# and the options
+LEXFLAGS = -v
+
+# We use bison (or equivalent) to generate the parser
+YACC = bison
+# and the options
+YACCFLAGS = -y -d -v
+
+# Libraries to be used
+LIBS = -ly -ll -lm
+
+# The root directory for the installation (e.g., /usr/local )
+ROOTDIR = /proj/ltx/teTeX033
+
+# Where to place the running code (e.g. /usr/local/bin )
+BINDIR = ${ROOTDIR}/bin
+
+# Where to place the manpage (e.g., /usr/local/man/man1 )
+MANEXT = 1
+MANDIR = ${ROOTDIR}/man/man${MANEXT}
+
+# Just in case you want to change the name of the binary
+# (and then you should also change the man page and documentation).
+# So, do not change this.
+PROG = ltx2x
+
+# Where to place the user documentation (e.g., /usr/local/doc/ltx2x )
+DOCDIR = ${ROOTDIR}/doc/${PROG}
+
+# Where to place the example command tables (e.g., /usr/local/lib/config/ltx2x )
+CTDIR = ${ROOTDIR}/lib/config/${PROG}
+
+# The file copy command (copy but do not delete original)
+COPY = cp
+
+# The file move command (move and delete original)
+MOVE = mv
+
+# The file delete command
+DELETE = rm
+
+# The make directory (hierarchy) command
+MAKEDIR = mkdirhier
+
+# The stream editor command
+SED = sed
+
+# Command to write to the terminal (stdout)
+ECHO = echo
+
+################### You should not have to change anything after this
+
+# The source modules
+L2XSRCS = l2xytab.c l2xlexyy.c l2xlib.c l2xacts.c l2xusrlb.c
+getopt.c srchenv.c
+
+INTSRCS = l2xirtne.c l2xistd.c l2xidecl.c l2xistmt.c l2xiexpr.c
+l2xiscan.c l2xisymt.c l2xierr.c l2xiidbg.c l2xistup.c l2xistm.c
+l2xixxpr.c l2xixstd.c l2xidbug.c l2xisdcl.c l2xirexp.c listsetc.c
+
+# The object modules
+L2XOBJS = l2xytab.o l2xlexyy.o l2xlib.o l2xacts.o l2xusrlb.o
+ getopt.o srchenv.o
+
+INTSRCS = l2xirtne.o l2xistd.o l2xidecl.o l2xistmt.o l2xiexpr.o
+l2xiscan.o l2xisymt.o l2xierr.o l2xiidbg.o l2xistup.o l2xistm.o
+l2xixxpr.o l2xixstd.o l2xidbug.o l2xisdcl.o l2xirexp.o listsetc.o
+
+OBJS = ${L2XOBJS} ${INTOBJS}
+
+# Link object code together into PROG
+ltx2x : ${OBJS}
+ ${CC} -o ${PROG} ${OBJS} ${LIBS}
+
+# Compile C source code into object code
+getopt.o : getopt.c getopt.h
+ ${CC} -c getopt.c
+l2xytab.o : l2xytab.c l2xlib.h l2xusrlb.h l2xacts.h strtypes.h l2xcom.h
+ ${CC} -c l2xytab.c
+l2xlexyy.o : l2xlexyy.c l2xytab.h l2xlib.h l2xusrlb.h l2xcom.h
+ ${CC} -c l2xlexyy.c
+l2xlib.o : l2xlib.c getopt.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xlib.c
+l2xusrlb.o : l2xusrlb.c l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xusrlb.c
+l2xacts.o : l2xacts.c l2xusrlb.h l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xacts.c
+srchenv.o : srchenv.c srchenv.h
+ ${CC} -c srchenv.c
+
+# Generate C code for parsing
+l2xytab.c l2xytab.h: l2x.y
+ @ ${ECHO} "Expect 10 shift/reduce conflicts to be reported"
+ ${YACC} ${YACCFLAGS} l2x.y
+ ${MOVE} y.tab.c l2xytab.c
+ ${MOVE} y.tab.h l2xytab.h
+
+# Generate C code for lexing
+l2xlexyy.c : l2x.l
+ ${LEX} ${LEXFLAGS} l2x.l
+ ${MOVE} lex.yy.c l2xlexyy.c
+
+# the interpreter modules
+
+# compiler flags for analyze and execute modules
+ANLFLAG = -Danalyze
+RUNFLAG = -Dtrace
+
+# interpreter header files
+SOMEH = l2xicmon.h l2xierr.h l2xiscan.h l2xisymt.h licomsym.h l2xiidbg.h
+MOSTH = ${SOMEH} l2xiprse.h
+ALLH = ${MOSTH} l2xicpr.h l2xiexec.h
+
+# interpreter interface
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+# the parser module
+
+l2xirtne.o : l2xirtne.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xirtne.c
+
+l2xistd.o : l2xistd.c ${MOSTH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c l2xistd.c
+
+l2xidecl.o : l2xidecl.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xisdecl.c
+
+l2xistmt.o : l2xistmt.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xistmt.c
+
+l2xiexpr.o : l2xiexpr.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiexpr.c
+
+# the scanner module
+
+l2xiscan.o : l2xiscan.c ${SOMEH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiscan.c
+
+# symbol table module
+
+l2xisymt.o : l2xisymt.c l2xicmon.h l2xierr.h l2xisymt.h licomsym.h l2xiidbg.h
+ ${CC} -c l2xisymt.c
+
+# executor module
+
+l2xixutl.o : l2xixutl.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixutl.c
+
+l2xixstm.o : l2xixstm.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstm.c
+
+l2xixxpr.o : l2xixxpr.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixxpr.c
+
+l2xixstd.o : l2xixstd.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstd.c
+
+l2xidbug.o : l2xidbug.c ${SOMEH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xidbug.c
+
+# error and miscellaneous
+
+l2xisdcl.o : l2xisdcl.c ${SOMEH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xisdcl.c
+
+l2xiidbg.o : l2xiidbg.c ${SOMEH} l2xiexec.h
+ ${CC} -c l2xiidbg.c
+
+l2xirexp.o : l2xirexp.c l2xirexp.h
+ ${CC} -c l2xirexp.c
+
+listsetc.o : listsetc.c listsetc.h
+ ${CC} -c listsetc.c
+
+# only call make install if BINDIR has been set
+install : ltx2x
+ ${MAKEDIR} ${BINDIR}
+ ${MOVE} ${PROG} ${BINDIR}
+
+# Edit the file man to replace DOCUMENTDIR by the actual directory
+# where the user manual is to be placed, and CTDIR by the location
+# of the example command table files.
+# Then copy the manpage to the proper place
+manpage :
+ ${SED} 's!DOCUMENTDIR!${DOCDIR}!; s!CTDIR!${CTDIR}!' man > tman
+ ${MAKEDIR} ${MANDIR}
+ ${COPY} tman ${MANDIR}/${PROG}.${MANEXT}
+
+# Copy the user manuals to the proper place
+doc :
+ ${MAKEDIR} ${DOCDIR}
+ ${COPY} ltx2x.tex ${DOCDIR}/${PROG}.tex
+ ${COPY} ltx2x.ps ${DOCDIR}/${PROG}.ps
+ ${COPY} ltx2x.txt ${DOCDIR}/${PROG}.txt
+ ${COPY} ltx2x.html ${DOCDIR}/${PROG}.html
+
+# Copy the example command tables to their final location
+ctables :
+ ${MAKEDIR} ${CTDIR}
+ ${COPY} ltx2x.ct ${CTDIR}/ltx2x.ct
+ ${COPY} detex.ct ${CTDIR}/detex.ct
+ ${COPY} remcom.ct ${CTDIR}/remcom.ct
+ ${COPY} l2h.ct ${CTDIR}/l2h.ct
+ ${COPY} bye.ct ${CTDIR}/bye.ct
+ ${COPY} fun.ct ${CTDIR}/fun.ct
+
+# Do almost everything except clean up
+all : ltx2x install manpage doc ctables
+
+# call make clean to remove the object files, info from YACC,
+# and the edited version of the manpage
+clean :
+ ${DELETE} *.o
+ ${DELETE} y.output
+ ${DELETE} tman
+
+# Compile the command table printer
+printct : printct.o getopt.o srchenv.o
+ ${CC} -o printct printct.o getopt.o srchenv.o
+
+printct.o : printct.c getopt.h strtypes.h l2xcom.h
+ ${CC} -c printct.c
+</pre>
+
+<p>If you use the above makefile then the first part should be edited
+to reflect your system's configuration. You could do <samp>make all</samp>
+which should do everything for you, except the cleaning up.
+A more conservative approach is recommended. First
+just do <samp>make</samp> which will generate the executable. This can then be
+tested. When all is well do <samp>make install</samp> and <samp>make manpage</samp>
+which will put the executable and the manpage into their final positions.
+Finally, <samp>make clean</samp> will remove the intermediate files generated
+during the build process.
+
+
+<p>The above <tt>make</tt> file uses flex as the lexer generator. You can use your
+favorite one instead but it must, unlike lex, support exclusive start states.
+Also, bison is used above as the parser generator. Again, you can use your
+favorite one. As far as I am aware, there is nothing remarkable about the
+grammar, except that during early development I exceeded the size limits
+of yacc. The grammar has been simplified since then, so this may no longer
+be a problem. <br>
+NOTE: If bison is used it reports that there are 10 shift/reduce
+conflicts. It appears that these can be safely ignored.
+
+
+<p>One compilation problem has been noted by Uwe
+Sassenberg (Footnote: <tt>&lt;sassen@hal1.physik.uni-dortmund.de&gt;</tt>)
+on AIX 3.2 and
+IRIX 5.3 systems, but I could not reproduce it on a SunOS 4.1.3 system. This
+is when the main procedure of LTX2X is processing the optional command
+line arguments. For some reason it had difficulties with the C
+<samp>EOF</samp>. The symptom was that the program compiled but when it was
+run
+it sat there absorbing CPU cycles and doing nothing as it had got into
+an infinite <samp>while</samp> loop. The cure was to insert
+the following line of code in file <tt>l2xlib.c</tt>:
+<pre>
+main(argc,argv)
+...
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv, "l:ty:f:cp:wE:P:D:"))) {
+/* insert this line of code: if (optchar == 255) break; end insert */
+ switch(optchar) {
+...
+</pre>
+This code line which you may need to insert is supplied as a comment in
+the distributed source.
+
+
+<p>
+<h3>Limits and errors</h3>
+
+
+
+<p>The LTX2X system has some built-in limits which are defined in <tt>l2xlib.c</tt>.
+The following is a listing of the relevant sizes.
+
+
+<p><dl>
+<dt><samp>CLAUSE_STACK_SIZE</samp>
+<dd> The maximum nesting depth of
+document sectioning. This is set somewhat larger than the number of
+standard LaTeX sectioning command types.
+(Default 10)
+
+
+<p><dt><samp>EVERY_N_LINES</samp>
+<dd> Controls the frequency of printing
+processed line numbers to the terminal.
+(Default 100)
+
+
+<p><dt><samp>LIST_STACK_SIZE</samp>
+<dd> The maximum nesting depth of list
+environments. This is set somewhat larger than the standard LaTeX nesting depth.
+(Default 10)
+
+
+<p><dt><samp>MAX_BUFFER</samp>
+<dd> The maximum number of characters that can be held
+in the system buffer, and also the maximum number of characters in a
+pretty-printed output line.
+(Default 2000)
+
+
+<p><dt><samp>MAX_CT_STACK</samp>
+<dd> The maximum nesting depth for included
+command table files.
+(Default 20)
+
+
+<p><dt><samp>MAX_ERRORS</samp>
+<dd> The maximum number of non-fatal errors
+discovered in command table processing or in source file processing before
+LTX2X quits.
+(Default 10)
+
+
+<p><dt><samp>MAX_LINE</samp>
+<dd> The maximum number of characters in a line of
+a LaTeX source file.
+(Default 2000)
+
+
+<p><dt><samp>MAX_PRINT_STACK</samp>
+<dd> The maximum nesting depth for print
+control commands.
+(Default 100)
+
+
+<p><dt><samp>MAX_TABLE_ENTRIES</samp>
+<dd> The maximum number of
+<samp>TYPE</samp> specifications in a command table (including the built in
+type specifications).
+(Default 1000)
+
+
+<p><dt><samp>MAX_TABLE_LINE</samp>
+<dd> The maximum number of characters in a line in
+a command table file.
+(Default 254)
+
+
+<p><dt><samp>MAX_USER_BUFFS</samp>
+<dd> The maximum number of user buffers.
+(Default 20)
+
+
+<p><dt><samp>MAX_UBUFF_LEN</samp>
+<dd> The maximum number of characters that can be
+stored in a user buffer.
+(Default 510)
+
+
+<p><dt><samp>MAX_USER_FILES</samp>
+<dd> The maximum number of user files.
+(Default 16)
+</dl>
+
+
+<p>LTX2X prints out a summary of the program statistices at the end of
+the <tt>ltx2x.err</tt> file.
+ If the limits are not suitable for your purposes, then they may be changed and
+the system rebuilt.
+
+
+<p>LTX2X can produce a variety of error and warning messages, for example
+when any of the above limits are exceeded. Some of the messages are related
+to command table processing, while others are related to LaTeX document
+processing. Both these kinds of messages are targeted to the normal
+end user. There is another set of messages that are aimed at the implementor
+of new <samp>SPECIAL_</samp> commands. An implementor may also find some of the
+debugging options useful if things really fall apart.
+
+
+<p>
+
+<h3>Availability</h3>
+
+
+
+<p>Source code and documentation for LTX2X is available from the
+NIST SOLIS (SC4 On-Line Information Service) system [<a href="#RINAUDOT94">RINAUDOT94</a>]
+in directory <br>
+<tt>/subject/sc4/editing/latex/programs/ltx2x</tt>. <br>
+ SOLIS can be accessed by:
+<ul>
+
+
+ <li> Anonymous ftp to <tt>ftp.cme.nist.gov</tt> (<tt>cd</tt> to <tt>/pub/subject/sc4...</tt>)
+
+ <li> URL <a href="http://www.nist.gov/sc4">http://www.nist.gov/sc4</a>
+</ul>
+
+
+
+<p>Any comments should be directed to <tt>apde@cme.nist.gov</tt>.
+
+
+<p>
+<h4>Copyright</h4>
+
+
+<p>Development of this software was funded by the United States Government
+and is not subject to copyright. It was developed by the
+Manufacturing Systems Integration Division (MSID) of the
+Manufacturing Engineering Laboratory (MEL) of the
+National Institute of Standards and Technology (NIST).
+
+
+<p>
+<h4>Disclaimer</h4>
+
+
+<p>There is no warranty for the LTX2X software. If the LTX2X software
+is modified by someone else and passed on, NIST requests that the software's
+recipients be notified that what they have is not what NIST distributed.
+
+
+<p><dl>
+<dt>Policies
+<dd> <ol>
+
+
+ <li> Anyone may copy and distribute verbatim copies of the
+ source code as received in any medium.
+
+ <li> Anyone may modify your copy or copies of the LTX2X source
+ code or any portion of it, and copy and distribute such
+ modifications provided that all modifications are clearly
+ associated with the entity that performs the modifications.
+</ol>
+
+
+
+<p><dt>NO WARRANTY
+<dd>
+<p>NIST PROVIDES ABSOLUTELY NO WARRANTY. THE LTX2X SOFTWARE IS
+PROVIDED `AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+SHOULD ANY PORTION OF THE LTX2X SOFTWARE PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+
+<p>IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, INCLUDING ANY
+LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF
+THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY NIST)
+THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+</dl>
+
+
+<p>
+
+<h2>A grammar for the command table</h2>
+ <a name="sec:ctabgrammar"></a>
+
+
+<p>
+<h3>Notation</h3>
+
+
+
+<p>The syntactical constructs used correspond to a derivative of
+the Wirth Syntax Notation (WSN) [<a href="#WIRTH77">WIRTH77</a>]. The semantics of the
+enclosing braces are:
+<ul>
+
+
+ <li> curly braces `<tt>{ }</tt>' indicate xero or more repetitions;
+
+ <li> square brackets `<tt>[ ]</tt>' indicate an optional element;
+
+ <li> parenthesis `<tt>( )</tt>' indicates a group;
+
+ <li> vertical bar `<tt>|</tt>' indicates that exactly one of the
+ terms in the expression shall be chosen.
+</ul>
+
+
+
+<p>Here is the grammar for WSN defined in itself.
+<pre>
+syntax = { production } .
+production = identifier '=' expression '.' .
+expression = term { '|' term } .
+term = factor { factor } .
+factor = identifier | literal | group | option | repetition .
+identifier = character { character } .
+literal = '''' character { character } '''' .
+group = '(' expression ')' .
+option = '[' expression ']' .
+repetition = '{' expression '}' .
+</pre>
+
+<p>We also use the following shorthand notation for particular characters:
+<ul>
+
+
+ <li> <samp>\c</samp> --- any printable character
+
+ <li> <samp>\n</samp> --- the end of line character(s)
+
+ <li> <samp>eof</samp> --- the end of file character(s)
+</ul>
+
+
+
+<p>
+<h3>Grammar</h3>
+
+
+
+<p>First, the keywords. Note that these are case insensitive.
+<pre>
+AudibleAlertChar = 'AUDIBLE_ALERT_CHAR=' .
+BackspaceChar = 'BACKSPACE_CHAR=' .
+BeginDocument = 'BEGIN_DOCUMENT' .
+BeginDollar = 'BEGIN_DOLAR' .
+BeginEnv = 'BEGIN_ENV' .
+BeginListEnv = 'BEGIN_LIST_ENV' .
+BeginPictureCc = 'BEGIN_PICTURE_CC' .
+BeginVenv = 'BEGIN_VENV' .
+BeginVerb = 'BEGIN_VERB' .
+BeginVerbatim = 'BEGIN_VERBATIM' .
+Buffer = 'BUFFER' .
+CarriageReturnChar = 'CARRIAGE_RETURN_CHAR=' .
+Chapter = 'CHAPTER' .
+CharCommand = 'CHAR_COMMAND' .
+Command = 'COMMAND' .
+CommandOop = 'COMMAND_OOP' .
+CommandOoopp = 'COMMAND_OOOPP' .
+CommandOpo = 'COMMAND_OPO' .
+CommandPooop = 'COMMAND_POOOP' .
+CommandPoop = 'COMMAND_POOP' .
+CommandPoopp = 'COMMAND_POOPP' .
+Comment = 'C=' .
+EndCtfile = 'END_CTFILE=' .
+EndDocument = 'END_DOCUMENT' .
+EndDollar = 'END_DOLAR' .
+EndEnv = 'END_ENV' .
+EndItem = 'END_ITEM=' .
+EndItemParam = 'END_ITEM_PARAM=' .
+EndListEnv = 'END_LIST_ENV' .
+EndMode = 'END_MODE' .
+EndOpt = 'END_OPT=' .
+EndPicture = 'END_PICTURE' .
+EndTag = 'END_TAG=' .
+EndTag1 = 'END_TAG_1=' .
+EndTag2 = 'END_TAG_2=' .
+EndTag3 = 'END_TAG_3=' .
+EndTag4 = 'END_TAG_4=' .
+EndTag5 = 'END_TAG_5=' .
+EndTag6 = 'END_TAG_6=' .
+EndTag7 = 'END_TAG_7=' .
+EndTag8 = 'END_TAG_8=' .
+EndTag9 = 'END_TAG_9=' .
+EndType = 'END_TYPE' .
+EndVenv = 'END_VENV' .
+EndVerb = 'END_VERB' .
+EndVerbatim = 'END_VERBATIM' .
+EscapeChar = 'ESCAPE_CHAR=' .
+File = 'FILE' .
+First = 'FIRST' .
+FormfeedChar = 'FORMFEED_CHAR=' .
+HexChar = 'HEX_CHAR=' .
+HorizontalTabChar = 'HORIZONTAL_TAB_CHAR=' .
+Include = 'INCLUDE=' .
+InMode = 'IN_MODE=' .
+Last = 'LAST' .
+Lbrace = 'LBRACE' .
+Name = 'NAME=' .
+NewlineChar = 'NEWLINE_CHAR=' .
+NoOp = 'NO_OP' .
+NoPrint = 'NO_PRINT' .
+OptParam = 'OPT_PARAM=' .
+OtherBegin = 'OTHER_BEGIN' .
+OtherCommand = 'OTHER_COMMAND' .
+OtherEnd = 'OTHER_END' .
+Para = 'PARA' .
+Paragraph = 'PARAGRAPH' .
+Part = 'PART' .
+Partm1 = 'PARTm1' .
+Partm2 = 'PARTm2' .
+PcAtEnd = 'PC_AT_END=' .
+PcAtStart = 'PC_AT_START=' .
+PictureCcpp = 'PICTURE_CCPP' .
+PictureCo = 'PICTURE_CO' .
+PictureCop = 'PICTURE_COP' .
+PictureCp = 'PICTURE_CP' .
+PictureOcc = 'PICTURE_OCC' .
+PictureOccc = 'PICTURE_OCCC' .
+PictureOco = 'PICTURE_OCO' .
+PicturePcop = 'PICTURE_PCOP' .
+PrintControl = 'PRINT_CONTROL=' .
+PrintP1 = 'PRINT_P1=' .
+PrintP2 = 'PRINT_P2=' .
+PrintP3 = 'PRINT_P3=' .
+PrintP4 = 'PRINT_P4=' .
+PrintP5 = 'PRINT_P5=' .
+PrintP6 = 'PRINT_P6=' .
+PrintP7 = 'PRINT_P7=' .
+PrintP8 = 'PRINT_P8=' .
+PrintP9 = 'PRINT_P9=' .
+PrintOpt = 'PRINT_OPT=' .
+Rbrace = 'RBRACE' .
+Reqparams = 'REQPARAMS=' .
+Reset = 'RESET' .
+ResetBuffer = 'RESET_BUFFER:' .
+ResetMode = 'RESET_MODE:' .
+Sect = 'SECT' .
+Sectioning = 'SECTIONING' .
+SectioningLevel = 'SECTIONING_LEVEL=' .
+SetMode = 'SET_MODE:' .
+SlashSpace = 'SLASH_SPACE' .
+Source = 'SOURCE:' .
+Special = 'SPECIAL' .
+SpecialBeginEnv = 'SPECIAL_BEGIN_ENV' .
+SpecialBeginList = 'SPECIAL_BEGIN_LIST' .
+SpecialCommand = 'SPECIAL_COMMAND' .
+SpecialEndEnv = 'SPECIAL_END_ENV' .
+SpecialEndList = 'SPECIAL_END_LIST' .
+SpecialSectioning = 'SPECIAL_SECTIONING' .
+StartItem = 'START_ITEM=' .
+StartItemParam = 'START_ITEM_PARAM=' .
+StartOpt = 'START_OPT=' .
+StartTag = 'START_TAG=' .
+StartTag1 = 'START_TAG_1=' .
+StartTag2 = 'START_TAG_2=' .
+StartTag3 = 'START_TAG_3=' .
+StartTag4 = 'START_TAG_4=' .
+StartTag5 = 'START_TAG_5=' .
+StartTag6 = 'START_TAG_6=' .
+StartTag7 = 'START_TAG_7=' .
+StartTag8 = 'START_TAG_8=' .
+StartTag9 = 'START_TAG_9=' .
+String = 'STRING:' .
+SubPara = 'SUBPARA' .
+SubParap1 = 'SUBPARAp1' .
+SubParap2 = 'SUBPARAp2' .
+SubSect = 'SUBSECT' .
+SubSubSect = 'SUBSUBSECT' .
+SwitchBack = 'SWITCH_BACL: ' .
+SwitchToBuffer = 'SWITCH_TO_BUFFER: ' .
+SwitchToFile = 'SWITCH_TO_FILE: ' .
+SwitchToSysbuf = 'SWITCH_TO_SYSBUF: ' .
+Sysbuf = 'SYSBUF' .
+TexChar = 'TEX_CHAR' .
+ToBuffer = 'TO_BUFFER' .
+ToFile = 'TO_FILE' .
+ToSysbuf = 'TO_SYSBUF' .
+Type = 'TYPE=' .
+Vcommand = 'VCOMMAND' .
+VerticalTabChar = 'VERTICAL_TAB_CHAR=' .
+</pre>
+
+<p>Some utility productions.
+<pre>
+latex_id = \c { \c } .
+name = \c { \c } .
+text = '"' { \c } '"' .
+Eol = \n .
+digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+integer = digit { digit } .
+ct_file_name = name .
+file_id = name .
+buffer_id = integer .
+mode_id = name .
+</pre>
+
+<p>The starting production.
+<pre>
+table = [ special_chars ] { specification | inclusion | comment } eof .
+</pre>
+
+<p>Productions for <samp>inclusion</samp> and <samp>comment</samp> and <samp>eof</samp>.
+<pre>
+inclusion = Include ct_file_name Eol .
+comment = Comment { \c } Eol .
+eof = EndCtfile { \c } Eol .
+</pre>
+
+<p>Productions for <samp>special_chars</samp>.
+<pre>
+special_chars = [ escape ] [ alert ] [ backspace ] [ return ] [ feed ]
+ [ hex ] [ htab ] [ newline ] [ vtab ] { comment } .
+escape = EscapeChar \c Eol Eol .
+alert = AudibleAlertChar \c Eol .
+backspace = BackspaceChar \c Eol .
+return = CarriageReturnChar \c Eol .
+feed = FormfeedChar \c Eol .
+hex = HexChar \c Eol .
+htab = HorizontalTabChar \c Eol .
+newline = NewlineChar \c Eol .
+vtab = VerticalTabChar \c Eol .
+</pre>
+
+<p>
+
+Productions for <samp>specification</samp>.
+<pre>
+specification = built_in | normal | list | section | special | picture | odd .
+built_in = (Type built_in_type Eol) [ built_in_body ] end_type .
+end_type = EndType Eol .
+built_in_type = BeginDocument | BeginDollar | BeginVerb | BeginVerbatim |
+ EndDocument | EndDollar | EndVerb | EndVerbatim |
+ Lbrace | OtherBegin | OtherCommand | OtherEnd |
+ Paragraph | Rbrace | SlashSpace .
+normal = (Type normal_type Eol) type_name [ normal_body ] end_type .
+type_name = Name latex_id Eol .
+normal_type = BeginEnv | BeginVenv | CharCommand | Command |
+ EndEnv | EndVenv | TexChar | Vcommand .
+list = (Type list_type Eol) type_name [ list_body ] end_type .
+list_type = BeginListEnv | EndListEnv .
+section = (Type Sectioning Eol) type_name [ section_body ] end_type .
+special = (Type special_type Eol) type_name [ special_body ] end_type .
+special_type = Special | SpecialBeginEnv | SpecialBeginList |
+ SpecialCommand | SpecialEndEnv | SpecialEndList |
+ SpecialSectioning .
+picture = (Type picture_type Eol) type_name [ picture_body ] end_type .
+picture_type = BeginPictureCc | EndPicture | PictureCcpp | PictureCo |
+ PictureCop | PictureCp | PictureOcc |
+ PictureOccc | PictureOco | PicturePcop .
+odd = (Type odd_type Eol) type_name [ odd_body ] end_type .
+odd_type = CommandOop | CommandOoopp | CommandOpo |
+ CommandPooop | CommandPoop | CommandPoopp .
+</pre>
+
+<p>The <samp>X_body</samp> productions.
+<pre>
+built_in_body = [ basic_body ]
+ { start_mode [ basic_body ] end_mode } .
+start_mode = InMode mode_id Eol .
+end_mode = EndMode Eol .
+normal_body = [ basic_norm_body ]
+ { start_mode [ basic_norm_body ] end_mode } .
+sect_body = [ basic_sect_body ]
+ { start_mode [ basic_sect_body ] end_mode } .
+list_body = [ basic_list_body ]
+ { start_mode [ basic_list_body ] end_mode } .
+picture_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+odd_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+special_body = [ basic_special_body ]
+ { start_mode [ basic_special_body ] end_mode } .
+</pre>
+
+<p>
+Note: the ordering of the components of the following
+<samp>basic_X_body</samp> productions is immaterial.
+<pre>
+basic_body = [ start_it ] [ end_it ] .
+basic_norm_body = [ basic_body ] [ no_req_arg ] [ opt_arg_pos ]
+ { arg_print } { arg_action } .
+basic_sect_body = sect_level [ basic_norm_body ] .
+sect_level = SectioningLevel div_level Eol .
+div_level = Chapter | Para | Part | Partm1 | Partm2 | Sect | Subpara |
+ Subparap1 | Subparap2 | Subsect | Subsubsect .
+basic_defarg_body = [ basic_body ] { arg_print } { arg_action } .
+basic_list_body = [ basic_norm_body ] { item_action } .
+basic_special_body = [ sect_level ] [ basic_list_body ] .
+no_req_arg = Reqparams integer Eol .
+opt_arg_pos = OptParam ( First | Last ) Eol .
+</pre>
+
+<p>The <samp>start_it</samp> and <samp>end_it</samp> productions.
+<pre>
+start_it = [ start_print ] [start_action ] .
+start_print = PcAtStart ( basic_pc_kind | Reset ) Eol .
+basic_pc_kind = NoPrint | ToSysbuf | print_to_buffer | print_to_file .
+print_to_buffer = ToBuffer buffer_id .
+print_to_file = ToFile file_id .
+start_action = StartTag [ text ] Eol { tag_action } .
+tag_action = ( String text |
+ Source ( Sysbuf | user_buffer | user_file ) |
+ ResetBuffer buffer_id |
+ ResetFile file_id |
+ ResetSysbuf |
+ SwitchToBuffer buffer_id |
+ SwitchToFile file_id |
+ SwitchToSysbuf |
+ SwitchBack |
+ SetMode mode_id |
+ ResetMode )
+ Eol .
+user_buffer = Buffer buffer_id .
+user_file = File file_id .
+end_it = [ end_print ] [ end_action ] .
+end_print = PcAtEnd (basic_pc_kind | Reset) Eol .
+end_action = EndTag [ text ] Eol { tag_action } .
+</pre>
+
+<p>The <samp>arg_print</samp> productions.
+<pre>
+arg_print = print_arg_kind (basic_pc_kind | NoOp ) Eol .
+print_arg_kind = PrintOpt | PrintP1 | PrintP2 | PrintP3 | PrintP4 |
+ PrintP5 | PrintP6 | PrintP7 | PrintP8 | PrintP9 .
+</pre>
+
+<p>The <samp>arg_action</samp> productions.
+<pre>
+arg_action = arg_tag_kind [ text ] Eol { tag_action } .
+arg_tag_kind = EndOpt | EndTag1 | EndTag2 | EndTag3 | EndTag4 |
+ EndTag5 | EndTag6 | EndTag7 | EndTag8 | EndTag9 |
+ StartOpt | StartTag1 | StartTag2 | StartTag3 | StartTag4 |
+ StartTag5 | StartTag6 | StartTag7 | StartTag8 | StartTag9 .
+</pre>
+
+<p>The <samp>item_action</samp> productions.
+<pre>
+item_action = item_tag_kind [ text ] Eol { tag_action } .
+item_tag_kind = EndItem | EndItemParam | StartItem | StartItemParam .
+</pre>
+
+<p>The parser in LTX2X for the command table is very simple. For each <samp>TYPE=</samp>
+in the command table it creates a <samp>struct</samp> to hold the specification
+data. If any type is multiply defined, then which one will be finally used
+is somewhat random because of the sorting and searching algorithms employed
+internally. No checks are made for multiply defined entries.
+
+
+<p>Each command in the command table starts on a seperate line.
+ The parser reads only as much of a table line as is necessary to parse that
+line according to the first token that it finds on the line. The data in
+each line after parsing is added to the current <samp>struct</samp> for the
+LaTeX command.
+If any of the command lines within an entry are multiply defined,
+then the latest one will overwrite any earlier ones.
+
+
+<p>This line-based parsing means that effectively anything between the
+end of the required data on the line is ignored by the parser, and so could
+be treated as a comment. There is no guarantee that this behaviour will
+be maintained in future releases of LTX2X.
+
+
+<p>
+<h2>A grammar for EXPRESS-A</h2>
+ <a name="sec:expgrammar"></a>
+
+
+<p>The same WSN notation is used for the grammar for EXPRESS-A as
+for the command table grammar.
+
+
+<p>First the keywords. Note that these are case insensitive. Also
+not all of the keywords have been used in this implementation
+of EXPRESS-A; those that have not been used are reserved for the
+future.
+
+
+<p><pre>
+ ABS = 'abs' .
+ ABSTRACT = 'abstract' .
+ ACOS = 'acos' .
+ AGGREGATE = 'aggregate' .
+ ALIAS = 'alias' .
+ AND = 'and' .
+ ANDOR = 'andor' .
+ ARRAY = 'array' .
+ AS = 'as' .
+ ASIN = 'asin' .
+</pre>
+
+
+<p><pre>
+ ATAN = 'atan' .
+ BAG = 'bag' .
+ BEGIN = 'begin' .
+ BINARY = 'binary' .
+ BLENGTH = 'blength' .
+ BOOLEAN = 'boolean' .
+ BY = 'by' .
+ CALL = 'call' .
+ CASE = 'case' .
+ CONSTANT = 'constant' .
+</pre>
+
+
+<p><pre>
+ CONST_E = 'const_e' .
+ CONTEXT = 'context' .
+ COS = 'cos' .
+ CRITERIA = 'criteria' .
+ DERIVE = 'derive' .
+ DIV = 'div' .
+ ELSE = 'else' .
+ END = 'end' .
+ END_ALIAS = 'end_alias' .
+ END_CALL = 'end_call' .
+</pre>
+
+
+<p><pre>
+ END_CASE = 'end_case' .
+ END_CODE = 'end_code' .
+ END_CONSTANT = 'end_constant' .
+ END_CONTEXT = 'end_context' .
+ END_CRITERIA = 'end_criteria' .
+ END_ENTITY = 'end_entity' .
+ END_FUNCTION = 'end_function' .
+ END_IF = 'end_if' .
+ END_LOCAL = 'end_local' .
+ END_MODEL = 'end_model' .
+</pre>
+
+
+<p><pre>
+ END_NOTES = 'end_notes' .
+ END_OBJECTIVE = 'end_objective' .
+ END_PARAMETER = 'end_parameter' .
+ END_PROCEDURE = 'end_procedure' .
+ END_PURPOSE = 'end_purpose' .
+ END_REALIZATION = 'end_realization' .
+ END_REFERENCES = 'end_references' .
+ END_REPEAT = 'end_repeat' .
+ END_RULE = 'end_rule' .
+ END_SCHEMA = 'end_schema' .
+</pre>
+
+
+<p><pre>
+ END_SCHEMA_DATA = 'end_schema_data' .
+ END_TEST_CASE = 'end_test_case' .
+ END_TYPE = 'end_type' .
+ ENTITY = 'entity' .
+ ENUMERATION = 'enumeration' .
+ EOF = 'eof' .
+ EOLN = 'eoln' .
+ ESCAPE = 'escape' .
+ EXISTS = 'exists' .
+ EXP = 'exp' .
+ FALSE = 'false' .
+</pre>
+
+
+<p><pre>
+ FIXED = 'fixed' .
+ FOR = 'for' .
+ FORMAT = 'format' .
+ FROM = 'from' .
+ FUNCTION = 'function' .
+ GENERIC = 'generic' .
+ HIBOUND = 'hibound' .
+ HIINDEX = 'hiindex' .
+ IF = 'if' .
+ IMPORT = 'import' .
+</pre>
+
+
+<p><pre>
+ IN = 'in' .
+ INSERT = 'insert' .
+ INTEGER = 'integer' .
+ INVERSE = 'inverse' .
+ LENGTH = 'length' .
+ LIKE = 'like' .
+ LIST = 'list' .
+ LOBOUND = 'lobound' .
+ LOINDEX = 'loindex' .
+ LOCAL = 'local' .
+</pre>
+
+
+<p><pre>
+ LOG = 'log' .
+ LOG10 = 'log10' .
+ LOG2 = 'log2' .
+ LOGICAL = 'logical' .
+ MOD = 'mod' .
+ MODEL = 'model' .
+ NOT = 'not' .
+ NOTES = 'notes' .
+ NUMBER = 'number' .
+ NVL = 'nvl' .
+</pre>
+
+
+<p><pre>
+ OBJECTIVE = 'objective' .
+ ODD = 'odd' .
+ OF = 'of' .
+ ONEOF = 'oneof' .
+ OPTIONAL = 'optional' .
+ OR = 'or' .
+ ORD = 'ord' .
+ OTHERWISE = 'otherwise' .
+ PARAMETERi = 'parameter' .
+ PI = 'pi' .
+</pre>
+
+
+<p><pre>
+ PRED = 'pred' .
+ PROCEDURE = 'procedure' .
+ PURPOSE = 'purpose' .
+ QUERY = 'query' .
+ READ = 'read' .
+ READLN = 'readln' .
+ REAL = 'real' .
+ REALIZATION = 'realization' .
+ REFERENCE = 'reference' .
+ REFERENCES = 'references' .
+</pre>
+
+
+<p><pre>
+ REMOVE = 'remove' .
+ REPEAT = 'repeat' .
+ RETURN = 'return' .
+ REXPR = 'rexpr' .
+ ROLESOF = 'rolesof' .
+ ROUND = 'round' .
+ RULE = 'rule .
+ SCHEMA = 'schema' .
+ SCHEMA_DATA = 'schema_data' .
+ SELECT = 'select' .
+</pre>
+
+
+<p><pre>
+ SELF = 'self' .
+ SET = 'set' .
+ SIN = 'sin' .
+ SIZEOF = 'sizeof' .
+ SKIP = 'skip' .
+ SQRT = 'sqrt' .
+ STRING = 'string' .
+ SUBOF = 'subof' .
+ SUBTYPE = 'subtype' .
+ SUCC = 'succ' .
+</pre>
+
+
+<p><pre>
+ SUPERTYPE = 'supertype' .
+ SUPOF = 'supof' .
+ SYSTEM = 'system' .
+ TAN = 'tan' .
+ TEST_CASE = 'test_case' .
+ THE_DAY = 'the_day' .
+ THE_MONTH = 'the_month' .
+ THE_YEAR = 'the_year' .
+ THEN = 'then' .
+ TO = 'to' .
+</pre>
+
+
+<p><pre>
+ TRUE = 'true' .
+ TRUNC = 'trunc' .
+ TYPE = 'type' .
+ TYPEOF = 'typeof' .
+ UNIQUE = 'unique' .
+ UNKNOWN = 'unknown' .
+ UNTIL = 'until' .
+ USE = 'use' .
+ USEDIN = 'usedin' .
+ USING = 'using' .
+</pre>
+
+
+<p><pre>
+ VALUE = 'value' .
+ VALUE_IN = 'value_in' .
+ VALUE_UNIQUE = 'value_unique' .
+ VAR = 'var' .
+ WHERE = 'where' .
+ WHILE = 'while' .
+ WITH = 'with' .
+ WRITE = 'write' .
+ WRITELN = 'writeln' .
+ XOR = 'xor' .
+</pre>
+
+<p>The following rules define various classes of characters which are used in
+constructing the tokens.
+
+
+<p><pre>
+ digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+ digits = digit { digit } .
+ letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' |
+ 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' |
+ 'w' | 'x' | 'y' | 'z' .
+ lparen_not_star = '(' not_star .
+ not_lparen_star = not_paren_star | ')' .
+ not_paren_star = letter | digit | not_paren_star_special .
+ not_paren_star_quote_special = '!' | '"' | '#' | '$' | '%' | '&' | '+' |
+ ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' |
+ '@' | '[' | '\' | ']' | '^' | '_' | '`' | '{' | '|' | '}' |
+ '~' .
+ not_paren_star_special = not_paren_star_quote_special | '''' .
+ not_quote = not_paren_star_quote_special | letter | digit | '(' | ')' | '*' .
+ not_rparen = not_paren_star | '*' | '(' .
+</pre>
+
+
+<p><pre>
+ not_star = not_paren_star | '(' | ')' .
+ octet = hex_digit hex_digit .
+ special = not_paren_star_quote_special | '(' | ')' | '*' | '''' .
+ star_not_rparen = '*' not_rparen .
+</pre>
+
+<p>
+ The following rules specify how certain combinations of characters are
+interpreted as lexical elements within the language.
+
+
+<p><pre>
+ integer_literal = digits .
+ real_literal = digits '.' [ digits ] [ 'e' [ sign ] digits ] .
+ simple_id = letter { letter | digit | '_' } .
+ simple_string_literal = \q { ( \q \q ) | not_quote | \s | \o } \q .
+</pre>
+
+<p>The following rules specify the syntax of comments in EXPRESS-A.
+
+
+<p>
+<pre>
+ embedded_remark = '(*' { not_lparen_star | lparen_not_star |
+ star_not_rparen | embedded_remark } '*)' .
+ remark = embedded_remark | tail_remark .
+ tail_remark = '--' { \a | \s | \o } \n .
+</pre>
+
+<p>
+The following rules represent identifiers which are known to have a particular
+meaning (i.e., to be declared elsewhere as types or functions, etc.).
+
+
+<p>
+
+<pre>
+ attribute_ref = attribute_id .
+ constant_ref = constant_id .
+ entity_ref = entity_id .
+ enumeration_ref = enumeration_id .
+ function_ref = function_id .
+ parameter_ref = parameter_id .
+ procedure_ref = procedure_id .
+ type_ref = type_id .
+ variable_ref = variable_id .
+</pre>
+
+<p>
+
+ The following rules specify how the previous lexical elements may be
+combined into constructs of EXPRESS-A. White space and/or remark(s) may appear
+between any two tokens in these rules. The primary syntax rule for EXPRESS-A
+is <samp>express_a</samp>.
+
+
+<p>
+
+<pre>
+ actual_parameter_list = '(' parameter { ',' parameter } ')' .
+ add_like_op = '+' | '-' | OR | XOR .
+ aggregation_types = array_type | bag_type | list_type | set_type .
+ algorithm_head = { declaration } [ local_decl ] .
+ array_type = ARRAY bound_spec OF base_type .
+ assignment_stmt = general_ref { qualifier } ':=' expression ';' .
+ attribute_decl = attribute_id .
+ attribute_id = simple_id .
+ attribute_qualifier = '.' attribute_ref .
+ bag_type = BAG [ bound_spec ] OF base_type .
+</pre>
+
+
+<p><pre>
+ base_type = aggregation_types | simple_types | named_types .
+ boolean_type = BOOLEAN .
+ bound_1 = numeric_expression .
+ bound_2 = numeric_expression .
+ bound_spec = '[' bound_1 ':' bound_2 ']' .
+ built_in_constant = CONST_E | PI | THE_DAY | THE_MONTH | THE_YEAR | '?' .
+ built_in_function = ABS | COS | EOF | EOLN | EXISTS | EXP |
+ HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX |
+ LOG | LOG2 | LOG10 | NVL | ODD | ORD | PRED |
+ REXPR | ROUND | SIN | SIZEOF |
+ SQRT | SUCC | TAN | TRUNC .
+ built_in_procedure = INSERT | PRINT | PRINTLN | READ | READLN | REMOVE |
+ SYSTEM | WRITE | WRITELN .
+ case_action = case_label { ',' case_label } ':' stmt .
+ case_label = expression .
+</pre>
+
+
+<p><pre>
+ case_stmt = CASE selector OF { case_action } [ OTHERWISE ':' stmt ]
+ END_CASE ';' .
+ compound_stmt = BEGIN stmt { stmt } END ';' .
+ constant_factor = built_in_constant .
+ constructed_types = enumeration_type .
+ declaration = entity_decl | function_decl | procedure_decl | type_decl .
+ entity_body = { explicit_attr } .
+ entity_decl = entity_head entity_body END_ENTITY ';' .
+ entity_head = ENTITY entity_id ';' .
+ entity_id = simple_id .
+ enum_id = simple_id .
+</pre>
+
+
+<p><pre>
+ enumeration_reference = enum_id .
+ enumeration_type = ENUMERATION OF '(' enum_id { ',' enum_id } ')' .
+ escape_stmt = ESCAPE ';' .
+ explicit_attr = attribute_decl { ',' attribute_decl } ':' base_type ';' .
+ express_a = { declaration } [ local_decl ] { stmt } END_CODE .
+ expression = simple_expression [ rel_op_extended simple_expression ] .
+ factor = simple_factor [ '**' simple_factor ] .
+ formal_parameter = parameter_id { ',' parameter_id } ':' parameter_type .
+ function_call = ( built_in_function | function_ref )
+ [ actual_parameter_list ] .
+ function_decl = function_head [ algorithm_head ] stmt { stmt }
+ END_FUNCTION ';' .
+</pre>
+
+
+<p><pre>
+ function_head = FUNCTION function_id [ '(' formal_parameter
+ { ';' formal_parameter } ')' ] ':' parameter_type ';' .
+ function_id = simple_id .
+ generalized_types = general_aggregation_types .
+ general_aggregation_types = general_array_type | general_bag_type |
+ general_list_type | general_set_type .
+ general_array_type = ARRAY [ bound_spec ] OF parameter_type .
+ general_bag_type = BAG [ bound_spec ] OF parameter_type .
+ general_list_type = LIST [ bound_spec ] OF parameter_type .
+ general_ref = parameter_ref | variable_ref .
+ general_set_type = SET [ bound_spec ] OF parameter_type .
+ if_stmt = IF logical_expression THEN stmt { stmt } [ ELSE stmt { stmt } ]
+ END_IF ';' .
+</pre>
+
+
+<p><pre>
+ increment = numeric_expression .
+ increment_control = variable_id ':=' bound_1 TO bound_2 [ BY increment ] .
+ index = numeric_expression .
+ index_1 = index .
+ index_2 = index .
+ index_qualifier = '[' index_1 [ ':' index_2 ] ']' .
+ integer_type = INTEGER .
+ interval = '{' interval_low interval_op interval_item interval_op
+ interval_high '}' .
+ interval_high = simple_expression .
+ interval_item = simple_expression .
+</pre>
+
+
+<p><pre>
+ interval_low = simple_expression .
+ interval_op = '<' | '<=' .
+ list_type = LIST [ bound_spec ] OF base_type .
+ literal = integer_literal | logical_literal | real_literal |
+ string_literal .
+ local_decl = LOCAL local_variable { local_variable } END_LOCAL ';' .
+ local_variable = variable_id { ',' variable_id } ':' parameter_type ';' .
+ logical_expression = expression .
+ logical_literal = FALSE | TRUE | UNKNOWN .
+ logical_type = LOGICAL .
+ multiplication_like_op = '*' | '/' | DIV | MOD | AND | '||' .
+</pre>
+
+
+<p><pre>
+ named_types = entity_ref | type_ref .
+ null_stmt = ';' .
+ numeric_expression = simple_expression .
+ parameter = expression .
+ parameter_id = simple_id .
+ parameter_type = generalized_types | named_types | simple_types .
+ population = entity_ref .
+ primary = literal | ( qualifiable_factor { qualifier } ) .
+ procedure_call_stmt = ( built_in_procedure | procedure_ref )
+ [ actual_parameter_list ] ';' .
+ procedure_decl = procedure_head [ algorithm_head ] { stmt } END_PROCEDURE ';' .
+</pre>
+
+
+<p><pre>
+ procedure_head = PROCEDURE procedure_id [ '(' [ VAR ] formal_parameter
+ { ';' [ VAR ] formal_parameter } ')' ] ';' .
+ procedure_id = simple_id .
+ qualifiable_factor = attribute_ref | constant_factor | function_call |
+ general_ref | population .
+ qualifier = attribute_qualifier | index_qualifier .
+ real_type = REAL .
+ referenced_attribute = attribute_ref | qualified_attribute .
+ rel_op = '<' | '>' | '<=' | '>=' | '<>' | '=' | ':<>:' | ':=:' .
+ rel_op_extended = rel_op | IN | LIKE .
+ repeat_control = [ increment_control ] [ while_control ] [ until_control ] .
+ repeat_stmt = REPEAT repeat_control ';' stmt { stmt } END_REPEAT ';' .
+</pre>
+
+
+<p><pre>
+ return_stmt = RETURN [ '(' expression ')' ] ';' .
+ selector = expression .
+ set_type = SET [ bound_spec ] OF base_type .
+ sign = '+' | '-' .
+ simple_expression = term { add_like_op term } .
+ simple_factor = enumeration_reference | interval |
+ ( [ unary_op ] ( '(' expression ')' | primary ) ) .
+ simple_types = integer_type | logical_type | real_type | string_type .
+ skip_stmt = SKIP ';' .
+ stmt = assignment_stmt | case_stmt | compound_stmt | escape_stmt |
+ if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt |
+ skip_stmt .
+ string_literal = simple_string_literal .
+</pre>
+
+
+<p><pre>
+ string_type = STRING .
+ term = factor { multiplication_like_op factor } .
+ type_decl = TYPE type_id '=' underlying_type ';' END_TYPE ';' .
+ type_id = simple_id .
+ unary_op = '+' | '-' | NOT .
+ underlying_type = constructed_types | aggregation_types | simple_types |
+ type_ref .
+ until_control = UNTIL logical_expression .
+ variable_id = simple_id .
+ while_control = WHILE logical_expression .
+</pre>
+
+<p>
+
+
+
+<p><h2>REFERENCES</h2>
+<dl>
+
+
+
+<p>
+<dt>[<a name="LAMPORT94">LAMPORT94</a>]<dd>
+Leslie Lamport.
+ LaTeX: A Document Preparation System.
+ Addison-Wesley Publishing Company, second edition, 1994.
+
+
+<p>
+<dt>[<a name="KNUTH84a">KNUTH84a</a>]<dd>
+Donald E. Knuth.
+ The TeXbook.
+ Addison-Wesley Publishing Company, 1984.
+
+
+<p>
+<dt>[<a name="STEPIS">STEPIS</a>]<dd>
+ISO 10303.
+ Industrial automation systems and integration --- Product data
+ representation and exchange, 1994.
+
+
+<p>
+<dt>[<a name="GOLDFARB90">GOLDFARB90</a>]<dd>
+C. A. Goldfarb.
+ The SGML Handbook.
+ Oxford University Press, 1990.
+ (Edited and with a foreword by Yuri Rubinsky).
+
+
+<p>
+<dt>[<a name="MUSCIANO96">MUSCIANO96</a>]<dd>
+Chuck Musciano and Bill Kennedy.
+ .
+ O'Reilly &amp; Associates, Inc., 1996.
+
+
+<p>
+<dt>[<a name="KERNIGHAN88">KERNIGHAN88</a>]<dd>
+Brian W. Kernighan and Dennis M. Ritchie.
+ The C Programming Language.
+ Prentice Hall, second edition, 1988.
+
+
+<p>
+<dt>[<a name="EBOOK">EBOOK</a>]<dd>
+Douglas A. Schenck and Peter R. Wilson.
+ Information Modeling the EXPRESS Way.
+ Oxford University Press (ISBN 0-19-308714-3), 1994.
+
+
+<p>
+<dt>[<a name="EXPRESSIS">EXPRESSIS</a>]<dd>
+ISO 10303-11:1994.
+ Industrial automation systems and integration --- Product data
+ representation and exchange --- Part 11: Description methods: The EXPRESS
+ language reference manual, 1994.
+
+
+<p>
+<dt>[<a name="LEVINE92">LEVINE92</a>]<dd>
+John R. Levine, Tony Mason, and Doug Brown.
+ lex &amp; yacc.
+ O'Reilly &amp; Associates, Inc., second edition, 1992.
+
+
+<p>
+<dt>[<a name="LESK75">LESK75</a>]<dd>
+M. E. Lesk and E. Schmidt.
+ `LEX --- A Lexical Analyser Generator'.
+ In UNIX Programmer's Manual 2. AT&amp;T Bell Laboratories, Murray
+ Hill, NJ, 1975.
+
+
+<p>
+<dt>[<a name="JOHNSON75">JOHNSON75</a>]<dd>
+S. C. Johnson.
+ YACC --- Yet Another Compiler Compiler.
+ C S Technical Report 32, Bell Telephone Laboratories, Murray Hill,
+ NJ, 1975.
+
+
+<p>
+<dt>[<a name="EXPRESSITR">EXPRESSITR</a>]<dd>
+ISO/TR 10303-12:1997.
+ Industrial automation systems and integration --- Product data
+ representation and exchange --- Part 12: Description method: The EXPRESS-I
+ language reference manual, 1997.
+
+
+<p>
+<dt>[<a name="PRW94b">PRW94b</a>]<dd>
+Peter R. Wilson.
+ `FLaTTeN: A Program to Flatten LaTeX Source Files'.
+ NIST, Gaithersburg, MD 20899, December 1994.
+ (In draft).
+
+
+<p>
+<dt>[<a name="LIBES93">LIBES93</a>]<dd>
+Don Libes.
+ Obfuscated C and Other Mysteries.
+ John Wiley &amp; Sons, Inc., 1993.
+
+
+<p>
+<dt>[<a name="HOLUB90">HOLUB90</a>]<dd>
+A. I. Holub.
+ Compiler Design in C.
+ Prentice-Hall, Inc., 1990.
+
+
+<p>
+<dt>[<a name="ORAM91">ORAM91</a>]<dd>
+Andrew Oram and Steve Talbott.
+ Managing Projects with make.
+ O'Reilly &amp; Associates, Inc., second edition, 1991.
+
+
+<p>
+<dt>[<a name="RINAUDOT94">RINAUDOT94</a>]<dd>
+Gaylen R. Rinaudot.
+ .
+ NISTIR 5511, NIST, Gaithersburg, MD 20899, October 1994.
+
+
+<p>
+<dt>[<a name="WIRTH77">WIRTH77</a>]<dd>
+N. Wirth.
+ `What Can We Do About the Unnecessary Diversity of Notation for
+ Syntactic Definitions?'.
+ Communications of the ACM, 20(11):822--823, November 1977.
+
+
+<p>
+<dt>[<a name="MAKR91">MAKR91</a>]<dd>
+Ronald Mak.
+ Writing Compilers &amp; Interpreters --- An Applied Approach.
+ John Wiley &amp; Sons, Inc., 1991.
+
+
+<p></dl>
+
+
+
+<p>
+
+<a name="HtMlEoD"></a><a href="#HtMlSoD">To the start</a>
+</body>
+</html>
+
+
+<a name="HtMlEoD"></a><a href="#HtMlSoD">To the start</a>
+</body>
+</html>
diff --git a/support/ltx2x/ltx2x.ps b/support/ltx2x/ltx2x.ps
new file mode 100644
index 0000000000..ec2c408467
--- /dev/null
+++ b/support/ltx2x/ltx2x.ps
@@ -0,0 +1,14045 @@
+%!PS-Adobe-2.0
+%%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software
+%%Title: ltx2x.dvi
+%%Pages: 128
+%%PageOrder: Ascend
+%%BoundingBox: 0 0 596 842
+%%DocumentPaperSizes: A4
+%%EndComments
+%DVIPSCommandLine: dvips -o ltx2x.ps ltx2x
+%DVIPSParameters: dpi=600, comments removed
+%DVIPSSource: TeX output 1997.01.21:1348
+%%BeginProcSet: tex.pro
+/TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N
+/X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72
+mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1}
+ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale
+isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div
+hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul
+TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if}
+forall round exch round exch]setmatrix}N /@landscape{/isls true N}B
+/@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B
+/FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{
+/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N
+string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N
+end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{
+/sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]
+N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup
+length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{
+128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub
+get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data
+dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N
+/rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup
+/base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx
+0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff
+setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff
+.1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]}
+if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup
+length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{
+cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin
+0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul
+add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict
+/eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook
+known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X
+/IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for
+65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0
+0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V
+{}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7
+getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false}
+ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false
+RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1
+false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform
+round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg
+rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail
+{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M}
+B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{
+4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{
+p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p
+a}B /bos{/SS save N}B /eos{SS restore}B end
+%%EndProcSet
+TeXDict begin 39158280 55380996 1000 600 600 (ltx2x.dvi)
+@start /Fa 24 122 df<7FFFFFF8FFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFC7FFFFFF81E
+067C9927>45 D<1E007F807F80FFC0FFC0FFC0FFC07F807F801E000A0A728927>I<000E
+0000001F0000001F0000003F0000007F0000007F000000FF000001FF000003FF00007FFF
+0000FFFF0000FFFF0000FFBF00007E3F0000003F0000003F0000003F0000003F0000003F
+0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F
+0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F
+0000003F0000003F0000003F0000003F0000003F00003FFFFF807FFFFF807FFFFFC07FFF
+FF807FFFFF801A2F79AE27>49 D<00000038000000FC000001FC000007FC00000FFC0000
+3FF800007FE00000FFC00003FF000007FE00001FF800003FF000007FE00001FF800003FF
+00000FFC00001FF800007FF00000FFC00000FF800000FF800000FFC000007FF000001FF8
+00000FFC000003FF000001FF8000007FE000003FF000001FF8000007FE000003FF000000
+FFC000007FE000003FF800000FFC000007FC000001FC000000FC000000381E287CAA27>
+60 D<70000000FC000000FE000000FF800000FFC000007FF000001FF800000FFC000003
+FF000001FF8000007FE000003FF000001FF8000007FE000003FF000000FFC000007FE000
+003FF800000FFC000007FC000007FC00000FFC00003FF800007FE00000FFC00003FF0000
+07FE00001FF800003FF000007FE00001FF800003FF00000FFC00001FF800007FF00000FF
+C00000FF800000FE000000FC000000700000001E287CAA27>62 D<0001FE000007FF8000
+1FFFC0007FFFE000FFFFF001FF03F803FC01F807F000FC0FE01F7C0FC07FFE1F80FFFE1F
+01FFFE3F03FFFE3E07F1FF7E07E0FF7C0FC07F7C0F803F7C0F803FFC1F803FF81F001FF8
+1F001FF81F001FF81F001FF81F001FF81F001FF81F001FF81F001FFC1F803F7C0F803E7C
+0F803E7C0FC07E7E07E0FC3E07F1FC3F03FFF81F01FFF01F80FFE00FC07FC00FE01F1E07
+F0003F03FC007F01FF03FF00FFFFFE007FFFFC001FFFF00007FFC00001FF00202E7DAD27
+>64 D<03FFC000000FFFF000001FFFFC00003FFFFF00003FFFFF80003F80FF80003F801F
+C0001F000FC00004000FE000000007E000000007E000000FFFE000007FFFE00003FFFFE0
+000FFFFFE0001FFFFFE0003FFC07E0007FC007E0007F0007E000FE0007E000FC0007E000
+FC0007E000FC0007E000FC0007E000FE000FE0007F001FE0007FC0FFE0003FFFFFFF801F
+FFFFFFC00FFFFFFFC003FFF1FFC000FF807F8022207C9F27>97 D<000FFF00007FFFC001
+FFFFE003FFFFF007FFFFF00FF807F01FE007F03FC003E03F8000807F0000007E0000007E
+000000FE000000FC000000FC000000FC000000FC000000FC000000FC000000FE0000007E
+0000007E0000007F0000F03F8001F83FC001F81FE003F80FF80FF007FFFFF003FFFFE001
+FFFFC0007FFF00000FF8001D207B9F27>99 D<00003FF00000007FF80000007FF8000000
+7FF80000003FF800000001F800000001F800000001F800000001F800000001F800000001
+F800000001F800000001F800000001F800000FE1F800007FFDF80001FFFFF80003FFFFF8
+0007FFFFF8000FF83FF8001FE00FF8003FC007F8003F8003F8007F0003F8007E0001F800
+7E0001F800FE0001F800FC0001F800FC0001F800FC0001F800FC0001F800FC0001F800FC
+0001F800FE0001F8007E0003F8007E0003F8007F0003F8003F0007F8003F800FF8001FE0
+1FF8000FF03FF80007FFFFFFC003FFFFFFE001FFFDFFE0007FF9FFE0001FE0FFC0232E7E
+AD27>I<000FF800003FFE0000FFFF8003FFFFC007FFFFE00FFC0FF01FE003F81FC001F8
+3F8001FC7F0000FC7E0000FC7E00007EFE00007EFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFE
+FFFFFFFCFC000000FE0000007E0000007F0000003F00003C3F80007E1FC0007E1FF000FE
+0FFC07FC07FFFFFC01FFFFF800FFFFF0003FFFC00007FE001F207D9F27>I<7FE0000000
+FFF0000000FFF0000000FFF00000007FF000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F000000003F07F000003F1
+FFC00003F7FFF00003FFFFF00003FFFFF80003FFC1F80003FF01FC0003FE00FC0003FC00
+FC0003F800FC0003F800FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC
+0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC00
+03F000FC0003F000FC0003F000FC0003F000FC007FFF83FFE0FFFFC7FFF0FFFFC7FFF0FF
+FFC7FFF07FFF83FFE0242E7FAD27>104 D<000F0000001F8000003FC000003FC000003F
+C000003FC000001F8000000F000000000000000000000000000000000000000000000000
+0000000000003FFF80007FFFC0007FFFC0007FFFC0003FFFC000000FC000000FC000000F
+C000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000F
+C000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000F
+C000000FC0007FFFFFF0FFFFFFF0FFFFFFF8FFFFFFF07FFFFFF01D2F7BAE27>I<7FE000
+00007FF0000000FFF00000007FF00000007FF000000001F000000001F000000001F00000
+0001F000000001F000000001F000000001F000000001F000000001F000000001F03FFFC0
+01F07FFFE001F07FFFE001F07FFFE001F03FFFC001F003F80001F007F00001F00FE00001
+F01FC00001F03F800001F0FF000001F1FE000001F3FC000001F7F8000001FFFC000001FF
+FE000001FFFF000001FF3F000001FE1F800001FC0FC00001F80FE00001F007E00001F003
+F00001F001F80001F001FC0001F000FE0001F0007E007FFFC1FFF07FFFC3FFF8FFFFE3FF
+F87FFFC3FFF87FFFC3FFF0252E80AD27>107 D<7FFF8000FFFFC000FFFFC000FFFFC000
+7FFFC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC0007FFFFFF8FFFFFFFCFFFFFFFCFFFFFFFC7FFFFFF81E2E7CAD27>I<7F07C01F00
+00FF9FF07FC000FFFFF9FFE000FFFFFFFFF0007FFFFFFFF0000FFC7FF1F8000FF03FC0F8
+000FE03F80F8000FC03F00F8000FC03F00F8000FC03F00F8000F803E00F8000F803E00F8
+000F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F8
+000F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F8000F803E00F8
+000F803E00F8000F803E00F8007FF0FFC3FF00FFF8FFE3FF80FFF9FFE7FF80FFF8FFE3FF
+807FF0FFC3FF002920819F27>I<7FE07F0000FFF1FFC000FFF7FFF000FFFFFFF0007FFF
+FFF80003FFC1F80003FF01FC0003FE00FC0003FC00FC0003F800FC0003F800FC0003F000
+FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC
+0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC00
+03F000FC007FFF83FFE0FFFFC7FFF0FFFFC7FFF0FFFFC7FFF07FFF83FFE024207F9F27>
+I<001FE000007FF80001FFFE0003FFFF0007FFFF800FF03FC01FC00FE03F8007F03F0003
+F07F0003F87E0001F87E0001F8FC0000FCFC0000FCFC0000FCFC0000FCFC0000FCFC0000
+FCFC0000FCFE0001FC7E0001F87E0001F87F0003F83F8007F03F8007F01FE01FE00FF03F
+C007FFFF8003FFFF0001FFFE00007FF800001FE0001E207C9F27>I<7FE0FF0000FFF3FF
+C000FFFFFFF000FFFFFFF8007FFFFFFC0003FF81FE0003FE00FF0003FC003F8003F8001F
+8003F8001FC003F0000FC003F0000FC003F0000FE003F00007E003F00007E003F00007E0
+03F00007E003F00007E003F00007E003F0000FE003F0000FC003F8000FC003F8001FC003
+FC003F8003FC007F8003FE00FF0003FF83FE0003FFFFFC0003FFFFF80003FFFFF00003F3
+FFC00003F0FE000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F000000003F000000003F000000003F000000003F00000007FFF8000
+00FFFFC00000FFFFC00000FFFFC000007FFF80000023317F9F27>I<7FFC03FC00FFFE0F
+FF00FFFE3FFF80FFFE7FFFC07FFEFFFFC0007FFE1FC0007FF81FC0007FF00F80007FE002
+00007FC00000007F800000007F800000007F000000007F000000007E000000007E000000
+007E000000007E000000007E000000007E000000007E000000007E000000007E00000000
+7E000000007E000000007E000000007E0000007FFFFF8000FFFFFFC000FFFFFFC000FFFF
+FFC0007FFFFF800022207E9F27>114 D<00FFF38007FFFFC01FFFFFC03FFFFFC07FFFFF
+C07F803FC0FC000FC0F8000FC0F8000FC0F8000780FC0000007F8000007FFC00003FFFF0
+001FFFFC0007FFFF0001FFFF80000FFFC000003FE0000007E0780003F0FC0001F0FC0001
+F0FE0001F0FE0003F0FF0007E0FFE01FE0FFFFFFC0FFFFFF80FFFFFF00FBFFFC00707FF0
+001C207B9F27>I<003C0000007E0000007E0000007E0000007E0000007E0000007E0000
+007E0000007E00007FFFFFF0FFFFFFF8FFFFFFF8FFFFFFF87FFFFFF0007E0000007E0000
+007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000
+007E0000007E0000007E0000007E0018007E007E007E007E007E007E007E007E007E00FE
+003F00FC003F83FC003FFFF8001FFFF0000FFFE00003FFC00000FF001F297EA827>I<7F
+E01FF800FFF03FFC00FFF03FFC00FFF03FFC007FF01FFC0003F000FC0003F000FC0003F0
+00FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000
+FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC0003F000FC
+0003F000FC0003F001FC0003F001FC0003F003FC0003FC0FFC0001FFFFFFE001FFFFFFF0
+00FFFFFFF0003FFEFFF0000FF87FE024207F9F27>I<3FFC1FFF007FFE3FFF007FFE3FFF
+807FFE3FFF003FFC1FFF0001F807E00000FC0FC00000FC1F8000007E1F0000003F3F0000
+001F7E0000001FFC0000000FF800000007F800000003F000000003E000000003F0000000
+07F80000000FF80000001FFC0000001F3E0000003E3F0000007E1F0000007C0F800000F8
+0FC00001F807E00003F003E0007FFE1FFF807FFE1FFF80FFFF3FFFC07FFE1FFF807FFE1F
+FF8022207E9F27>120 D<7FFC0FFF80FFFE1FFFC0FFFE1FFFC0FFFE1FFFC07FFC0FFF80
+07E000F80003E001F80003E001F00003F001F00001F003F00001F803E00000F803E00000
+F803E00000FC07C000007C07C000007C07C000007E0F8000003E0F8000003E0F8000001F
+0F0000001F1F0000001F1F0000000F1F0000000F9E0000000FBE00000007BE00000007FC
+00000003FC00000003FC00000003F800000001F800000001F800000001F000000001F000
+000003F000000003E000000003E000000007E000000007C000000807C000003E0FC00000
+7F0F8000007F1F8000007E7F0000007FFE0000003FFC0000003FF80000001FF000000007
+C000000022317E9F27>I E /Fb 1 1 df<7FFFFFFFFFFCFFFFFFFFFFFEFFFFFFFFFFFE7F
+FFFFFFFFFC2F047A943C>0 D E /Fc 7 84 df<000000FE000000000001FF0000000000
+03FF800000000003FF800000000007FFC00000000007FFC00000000007FFC00000000007
+FFC0000000000FFFE0000000000FFFE0000000000FEFE0000000000FEFE0000000000FEF
+E0000000001FEFF0000000001FC7F0000000001FC7F0000000001FC7F0000000003FC7F8
+000000003FC7F8000000003FC7F8000000003F83F8000000007F83FC000000007F83FC00
+0000007F83FC000000007F83FC000000007F01FC00000000FF01FE00000000FF01FE0000
+0000FF01FE00000000FF01FE00000001FE00FF00000001FE00FF00000001FE00FF000000
+01FE00FF00000003FE00FF80000003FC007F80000003FC007F80000003FC007F80000003
+FC007F80000007F8003FC0000007F8003FC0000007F8003FC0000007F8003FC000000FF8
+003FE000000FF0001FE000000FF0001FE000000FF0001FE000000FF0001FE000001FFFFF
+FFF000001FFFFFFFF000001FFFFFFFF000001FFFFFFFF000003FFFFFFFF800003FFFFFFF
+F800003FFFFFFFF800003FC00007F800007FC00007FC00007F800003FC00007F800003FC
+00007F800003FC00007F800003FC0000FF800003FE0000FF000001FE0000FF000001FE00
+00FF000001FE0001FF000001FF0001FE000000FF0001FE000000FF003FFFF0001FFFF87F
+FFF8003FFFFCFFFFFC007FFFFEFFFFFC007FFFFEFFFFFC007FFFFE7FFFF8003FFFFC3FFF
+F0001FFFF8374B7DCA3E>65 D<000001FF0003C000000FFFF007E000003FFFFC0FE00000
+FFFFFE0FE00001FFFFFF9FE00007FFFFFFDFE0000FFFFFFFFFE0001FFF80FFFFE0003FFC
+001FFFE0007FF0000FFFE0007FE00007FFE000FFC00003FFE001FF800001FFE003FF0000
+00FFE003FE000000FFE007FC0000007FE007FC0000007FE00FF80000003FE00FF0000000
+3FE01FF00000003FE01FE00000001FE01FE00000001FE03FE00000001FE03FC00000001F
+E03FC00000001FE07FC00000000FC07F8000000000007F8000000000007F800000000000
+7F800000000000FF800000000000FF000000000000FF000000000000FF000000000000FF
+000000000000FF000000000000FF000000000000FF000000000000FF000000000000FF00
+0000000000FF000000000000FF000000000000FF000000000000FF000000000000FF8000
+000000007F8000000000007F8000000000007F8000000000007F8000000000007FC00000
+0000003FC00000000FC03FC00000001FE03FE00000001FE01FE00000001FE01FE0000000
+1FE01FF00000001FE00FF00000001FE00FF80000003FE007FC0000003FC007FC0000003F
+C003FE0000007FC003FF0000007F8001FF800000FF8000FFC00001FF00007FE00003FE00
+007FF00007FE00003FFC001FFC00001FFF80FFF800000FFFFFFFF0000007FFFFFFE00000
+01FFFFFFC0000000FFFFFF000000003FFFFC000000000FFFF00000000001FF800000334B
+7BC93E>67 D<7FFFFFFFFFFFF07FFFFFFFFFFFF0FFFFFFFFFFFFF8FFFFFFFFFFFFF8FFFF
+FFFFFFFFF87FFFFFFFFFFFF87FFFFFFFFFFFF800FF00000007F800FF00000007F800FF00
+000007F800FF00000007F800FF00000007F800FF00000007F800FF00000007F800FF0000
+0007F800FF00000007F800FF00000003F000FF00000003F000FF000000000000FF000000
+000000FF000000000000FF000000000000FF000000000000FF000000000000FF00000000
+0000FF000000000000FF00007E000000FF00007E000000FF0000FF000000FF0000FF0000
+00FF0000FF000000FF0000FF000000FFFFFFFF000000FFFFFFFF000000FFFFFFFF000000
+FFFFFFFF000000FFFFFFFF000000FFFFFFFF000000FFFFFFFF000000FF0000FF000000FF
+0000FF000000FF0000FF000000FF0000FF000000FF00007E000000FF00007E000000FF00
+0000000000FF000000000000FF000000000000FF000000000000FF000000000000FF0000
+00000000FF000000000000FF000000000000FF00000000FC00FF00000000FC00FF000000
+01FE00FF00000001FE00FF00000001FE00FF00000001FE00FF00000001FE00FF00000001
+FE00FF00000001FE00FF00000001FE00FF00000001FE00FF00000001FE00FF00000001FE
+7FFFFFFFFFFFFE7FFFFFFFFFFFFEFFFFFFFFFFFFFEFFFFFFFFFFFFFEFFFFFFFFFFFFFE7F
+FFFFFFFFFFFC7FFFFFFFFFFFFC37497DC83E>69 D<3FFFFFFFFF007FFFFFFFFF80FFFFFF
+FFFFC0FFFFFFFFFFC0FFFFFFFFFFC07FFFFFFFFF803FFFFFFFFF0000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
+80000000007F80000000007F80000000007F8000003FFFFFFFFF007FFFFFFFFF80FFFFFF
+FFFFC0FFFFFFFFFFC0FFFFFFFFFFC07FFFFFFFFF803FFFFFFFFF002A4976C83E>73
+D<3FFFFFC00000007FFFFFE0000000FFFFFFF0000000FFFFFFF0000000FFFFFFF0000000
+7FFFFFE00000003FFFFFC0000000007F8000000000007F8000000000007F800000000000
+7F8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F
+8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F80
+00000000007F8000000000007F8000000000007F8000000000007F8000000000007F8000
+000000007F8000000000007F8000000000007F8000000000007F8000000000007F800000
+0000007F8000000000007F8000000000007F8000000000007F8000000000007F80000000
+00007F8000000000007F8000000000007F8000000000007F8000000000007F8000000000
+007F8000000000007F8000000000007F8000000000007F8000000000007F800000000000
+7F8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F
+8000000000007F8000000000007F80000000C0007F80000003F0007F80000007F8007F80
+000007F8007F80000007F8007F80000007F8007F80000007F8007F80000007F8007F8000
+0007F8007F80000007F8007F80000007F8007F80000007F8007F80000007F83FFFFFFFFF
+FFF87FFFFFFFFFFFF8FFFFFFFFFFFFF8FFFFFFFFFFFFF8FFFFFFFFFFFFF87FFFFFFFFFFF
+F03FFFFFFFFFFFF035497CC83E>76 D<7FFFFFFFF000007FFFFFFFFE0000FFFFFFFFFF80
+00FFFFFFFFFFE000FFFFFFFFFFF8007FFFFFFFFFFC007FFFFFFFFFFE0000FF00007FFF00
+00FF00000FFF8000FF000003FF8000FF000000FFC000FF0000007FE000FF0000003FE000
+FF0000003FE000FF0000001FF000FF0000000FF000FF0000000FF000FF0000000FF800FF
+00000007F800FF00000007F800FF00000007F800FF00000007F800FF00000007F800FF00
+000007F800FF00000007F800FF0000000FF800FF0000000FF000FF0000000FF000FF0000
+001FF000FF0000003FE000FF0000003FE000FF0000007FE000FF000000FFC000FF000003
+FF8000FF00000FFF8000FF00007FFF0000FFFFFFFFFE0000FFFFFFFFFC0000FFFFFFFFF8
+0000FFFFFFFFE00000FFFFFFFF800000FFFFFFFE000000FFFFFFF0000000FF0000000000
+00FF000000000000FF000000000000FF000000000000FF000000000000FF000000000000
+FF000000000000FF000000000000FF000000000000FF000000000000FF000000000000FF
+000000000000FF000000000000FF000000000000FF000000000000FF000000000000FF00
+0000000000FF000000000000FF000000000000FF000000000000FF000000000000FF0000
+00000000FF00000000007FFFFE000000007FFFFE00000000FFFFFF00000000FFFFFF0000
+0000FFFFFF000000007FFFFE000000007FFFFE0000000035497DC83E>80
+D<0000FFF00078000007FFFE00FC00001FFFFF81FC00007FFFFFE1FC0000FFFFFFF9FC00
+01FFFFFFFFFC0003FFFFFFFFFC0007FFC03FFFFC000FFE0003FFFC001FF80001FFFC003F
+F000007FFC003FE000003FFC007FC000001FFC007F8000001FFC007F8000000FFC00FF80
+000007FC00FF00000007FC00FF00000007FC00FF00000007FC00FF00000003FC00FF0000
+0003FC00FF00000003FC00FF80000003FC00FF80000001F8007FC000000000007FC00000
+0000003FE000000000003FF000000000001FF800000000001FFE00000000000FFFE00000
+000007FFFE0000000003FFFFE000000001FFFFFE00000000FFFFFFE00000003FFFFFF800
+00000FFFFFFE00000003FFFFFF000000007FFFFFC000000003FFFFE0000000003FFFF000
+00000003FFF000000000007FF800000000001FFC000000000007FC000000000003FE0000
+00000003FE000000000001FF000000000000FF000000000000FF000000000000FF803E00
+0000007F807F000000007F80FF000000007F80FF000000007F80FF000000007F80FF0000
+00007F80FF000000007F80FF80000000FF80FF80000000FF00FF80000000FF00FFC00000
+01FF00FFE0000001FE00FFF0000003FE00FFF8000007FC00FFFE00000FF800FFFF80003F
+F800FFFFFC01FFF000FFFFFFFFFFE000FFFFFFFFFFC000FE7FFFFFFF8000FE1FFFFFFE00
+00FE07FFFFFC0000FC00FFFFE0000078000FFF000000314B7AC93E>83
+D E /Fd 8 121 df<FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE01B067E
+9826>45 D<000000003800000000000000007C00000000000000007C0000000000000000
+7C0000000000000000FE0000000000000000FE0000000000000000FE0000000000000001
+FF0000000000000001FF0000000000000003FF8000000000000003FF8000000000000003
+FF8000000000000007FFC0000000000000077FC0000000000000077FC00000000000000E
+7FE00000000000000E3FE00000000000000E3FE00000000000001C1FF00000000000001C
+1FF00000000000003C1FF8000000000000380FF8000000000000380FF800000000000078
+0FFC0000000000007007FC0000000000007007FC000000000000E007FE000000000000E0
+03FE000000000000E003FE000000000001C001FF000000000001C001FF000000000003C0
+01FF8000000000038000FF8000000000038000FF8000000000078000FFC0000000000700
+007FC0000000000700007FC0000000000E00007FE0000000000E00003FE0000000000E00
+003FE0000000001C00001FF0000000001C00001FF0000000003C00001FF8000000003800
+000FF8000000003800000FF8000000007FFFFFFFFC000000007FFFFFFFFC000000007FFF
+FFFFFC00000000E0000007FE00000000E0000003FE00000001E0000003FF00000001C000
+0001FF00000001C0000001FF00000003C0000001FF8000000380000000FF800000038000
+0000FF8000000700000000FFC0000007000000007FC0000007000000007FC000000E0000
+00003FE000000E000000003FE000001E000000003FF000001E000000001FF000003E0000
+00001FF000003E000000001FF800007E000000001FF80001FF000000001FFC0007FFC000
+00007FFF00FFFFFC00001FFFFFFEFFFFFC00001FFFFFFEFFFFFC00001FFFFFFE47477CC6
+51>65 D<FFFFFFFFFFFFFF80FFFFFFFFFFFFFF80FFFFFFFFFFFFFF8000FFF000000FFF80
+007FE0000000FFC0003FE00000003FC0003FE00000001FC0003FE00000000FC0003FE000
+000007C0003FE000000003C0003FE000000003C0003FE000000001E0003FE000000001E0
+003FE000000001E0003FE000000000E0003FE000000000E0003FE000000000E0003FE000
+000000E0003FE000000000F0003FE00001C00070003FE00001C00070003FE00001C00070
+003FE00001C00000003FE00001C00000003FE00001C00000003FE00003C00000003FE000
+03C00000003FE00003C00000003FE00007C00000003FE0000FC00000003FE0007FC00000
+003FFFFFFFC00000003FFFFFFFC00000003FFFFFFFC00000003FE0007FC00000003FE000
+0FC00000003FE00007C00000003FE00003C00000003FE00003C00000003FE00003C00000
+003FE00001C00000003FE00001C00000003FE00001C0000E003FE00001C0000E003FE000
+01C0000E003FE00001C0001C003FE0000000001C003FE0000000001C003FE0000000001C
+003FE0000000001C003FE0000000003C003FE0000000003C003FE00000000038003FE000
+00000038003FE00000000078003FE00000000078003FE000000000F8003FE000000000F8
+003FE000000001F0003FE000000003F0003FE000000003F0003FE00000000FF0003FE000
+00001FF0007FE00000007FF000FFF0000007FFF0FFFFFFFFFFFFFFE0FFFFFFFFFFFFFFE0
+FFFFFFFFFFFFFFE03F447BC34A>69 D<FFFFFFFFFFF0FFFFFFFFFFF0FFFFFFFFFFF003FE
+00003FF001FC000007F801FC000001F801FC000000F801FC000000F801FC0000007801FC
+0000007801FC0000003801FC0000003801FC0000003801FC0000001C01FC0007001C01FC
+0007001C01FC0007001C01FC0007000001FC0007000001FC000F000001FC000F000001FC
+001F000001FC007F000001FFFFFF000001FFFFFF000001FFFFFF000001FC007F000001FC
+001F000001FC000F000001FC000F000001FC0007000001FC0007000701FC0007000701FC
+0007000701FC0007000E01FC0000000E01FC0000000E01FC0000000E01FC0000000E01FC
+0000001E01FC0000001E01FC0000003C01FC0000003C01FC0000007C01FC000000FC01FC
+000001FC01FC000007FC03FE00003FFCFFFFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF83033
+7BB238>101 D<FFFFFFFF0000FFFFFFFFF000FFFFFFFFFC0003FE0003FF0001FC00007F
+8001FC00003FC001FC00001FE001FC00000FF001FC00000FF001FC000007F801FC000007
+F801FC000007FC01FC000007FC01FC000007FC01FC000007FC01FC000007FC01FC000007
+FC01FC000007F801FC000007F801FC00000FF001FC00000FF001FC00001FE001FC00003F
+C001FC0000FF0001FC0003FE0001FFFFFFF80001FFFFFFC00001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0003FE00000000FFFFF8000000FFFFF8000000FFFFF80000002E337BB238>112
+D<FFFFFFF8000000FFFFFFFF800000FFFFFFFFE0000003FE000FF8000001FC0003FE0000
+01FC0000FF000001FC00007F800001FC00003FC00001FC00003FE00001FC00001FE00001
+FC00001FE00001FC00001FF00001FC00001FF00001FC00001FF00001FC00001FF00001FC
+00001FF00001FC00001FE00001FC00001FE00001FC00003FC00001FC00003F800001FC00
+007F000001FC0000FE000001FC0003FC000001FC001FF0000001FFFFFF80000001FFFFFC
+00000001FC003F00000001FC000FC0000001FC0007E0000001FC0003F0000001FC0001F8
+000001FC0001FC000001FC0000FC000001FC0000FE000001FC0000FE000001FC0000FE00
+0001FC0000FF000001FC0000FF000001FC0000FF000001FC0000FF800001FC0000FF8000
+01FC0000FF800001FC0000FF800001FC0000FFC01C01FC0000FFC01C01FC00007FC01C01
+FC00007FE03C03FE00003FE038FFFFF8001FF078FFFFF8000FF8F0FFFFF80003FFE00000
+0000007F8036347BB23C>114 D<000FF00180007FFE038001FFFF878007F00FEF800FC0
+01FF801F0000FF803E00003F803E00001F807C00001F807C00000F80F800000F80F80000
+0780F800000780F800000780FC00000380FC00000380FE00000380FF000000007F800000
+007FC00000003FF80000003FFF8000001FFFFC00000FFFFFC00007FFFFF00003FFFFF800
+00FFFFFE00001FFFFF000003FFFF8000001FFFC0000001FFC00000003FE00000001FE000
+00000FE000000007F000000003F0E0000003F0E0000001F0E0000001F0E0000001F0F000
+0001F0F0000001F0F0000001E0F8000003E0F8000003E0FC000007C0FE00000F80FF8000
+1F00FFE0003E00FBFE00FC00F0FFFFF800E01FFFE000C003FF000024357BB32E>I<7FFF
+F8003FFFF07FFFF8003FFFF07FFFF8003FFFF001FFE0000FFF0000FFC00007F800007FC0
+0007F000003FC00007C000001FE000078000000FF0000F0000000FF0000E00000007F800
+1E00000003FC003C00000001FE003800000001FE007800000000FF00F0000000007F81E0
+000000003F81C0000000003FC3C0000000001FE780000000000FFF00000000000FFE0000
+00000007FE000000000003FC000000000001FE000000000001FE000000000000FF000000
+000001FF800000000001FF800000000003FFC000000000079FE0000000000F0FF0000000
+000E0FF0000000001E07F8000000003C03FC000000007801FE000000007001FE00000000
+F000FF00000001E0007F80000003C0003F8000000380003FC000000780001FE000000F00
+000FF000001E00000FF000003E000007F800007E000003FC0000FE000003FE0001FE0000
+03FF000FFF000007FF80FFFFC0001FFFFEFFFFC0001FFFFEFFFFC0001FFFFE37337DB23D
+>120 D E /Fe 4 102 df<001FFFFFFFFE007FFFFFFFFF01FFFFFFFFFF03FFFFFFFFFF07
+FFFFFFFFFE0FC03801C0001F003801C0003E003803C0003C0078038000780070038000F0
+0070038000F000F0078000E000F00780000000E00780000001E00700000001E007000000
+01E00F00000003C00F00000003C00F00000003C00F00000007C00F00000007800F000000
+07800F0000000F801F0000000F801F0000001F001F0000001F001F8000001F001F800000
+3E001F8000003E001F8000007E001F8000007E001FC00000FC001FC00000FC000FC00001
+FC000FE00001F8000FE00003F8000FE00003F80007E00003F00007E00000E00003800030
+287DA634>25 D<70000000000000FC000000000000FF0000000000007FC000000000001F
+F0000000000007FC000000000001FF0000000000007FC000000000001FF0000000000007
+FC000000000001FF0000000000007FC000000000001FF8000000000007FE000000000001
+FF8000000000007FE000000000000FF8000000000003FE000000000000FF800000000000
+3FE000000000000FF8000000000003FE000000000000FF8000000000003FE00000000000
+0FF8000000000003FE000000000000FF000000000000FF000000000003FE00000000000F
+F800000000003FE00000000000FF800000000003FE00000000000FF800000000003FE000
+00000000FF800000000003FE00000000000FF800000000007FE00000000001FF80000000
+0007FE00000000001FF800000000007FC00000000001FF000000000007FC00000000001F
+F000000000007FC00000000001FF000000000007FC00000000001FF000000000007FC000
+00000000FF000000000000FC00000000000070000000000000383679B147>62
+D<0001FFFF800001FFFFF80001FFFF800001FFFFF00001FFFF800001FFFFF0000000FFC0
+00000FFE00000001FFC0000003F000000001FFE0000003E000000001FFE0000001C00000
+0001DFE0000003C000000003DFF0000003C0000000038FF000000380000000038FF80000
+0380000000038FF8000007800000000787FC000007800000000707FC0000070000000007
+03FC000007000000000703FE00000F000000000F03FE00000F000000000E01FF00000E00
+0000000E01FF00000E000000000E00FF00001E000000001E00FF80001E000000001C007F
+80001C000000001C007FC0001C000000001C007FC0003C000000003C003FE0003C000000
+0038003FE000380000000038001FE000380000000038001FF000780000000078001FF000
+780000000070000FF800700000000070000FF8007000000000700007F800F000000000F0
+0007FC00F000000000E00003FC00E000000000E00003FE00E000000000E00003FE01E000
+000001E00001FF01E000000001C00001FF01C000000001C00000FF01C000000001C00000
+FF83C000000003C00000FF83C0000000038000007FC380000000038000007FC380000000
+038000003FC780000000078000003FE780000000070000001FE700000000070000001FF7
+00000000070000001FFF000000000F0000000FFF000000000E0000000FFE000000000E00
+000007FE000000000E00000007FE000000001E00000007FE000000001C00000003FC0000
+00001C00000003FC000000003C00000001FC000000007C00000001FC00000000FE000000
+00F800000003FF00000000F8000000FFFFFC000000F8000000FFFFFC00000078000000FF
+FFFC000000700000004D3E7DBD49>78 D<00001FE0000000FFFC000003F01E00000FC00F
+00003F800780007E0007C000FC0003C003F80003C007F80003C007F00007C00FE0000780
+1FE00007801FC0000F803FC0001F003FC0003E007F8001FC007F801FF000FFFFFF8000FF
+FFF80000FF00000000FF00000000FF00000000FF00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE000000C0FE000001C07E000003C07E0000
+07803F00000F003F00001E001F00003C000F8000F80007C003E00003E03F800000FFFE00
+00003FE0000022297CA72A>101 D E /Ff 8 121 df<FFFFFFFF80FFFFFFFF80FFFFFFFF
+80FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF8021077D9C2D>45
+D<00000000007000000000000000000000F800000000000000000001FC00000000000000
+000001FC00000000000000000001FC00000000000000000003FE00000000000000000003
+FE00000000000000000003FE00000000000000000007FF00000000000000000007FF0000
+0000000000000007FF0000000000000000000FFF8000000000000000000FFF8000000000
+000000001FFFC000000000000000001FFFC000000000000000001FFFC000000000000000
+003FFFE000000000000000003CFFE000000000000000003CFFE000000000000000007CFF
+F00000000000000000787FF00000000000000000787FF00000000000000000F07FF80000
+000000000000F03FF80000000000000001F03FFC0000000000000001E01FFC0000000000
+000001E01FFC0000000000000003E01FFE0000000000000003C00FFE0000000000000003
+C00FFE0000000000000007C00FFF00000000000000078007FF00000000000000078007FF
+000000000000000F0007FF800000000000000F0003FF800000000000001F0003FFC00000
+000000001E0001FFC00000000000001E0001FFC00000000000003E0001FFE00000000000
+003C0000FFE00000000000003C0000FFE00000000000007C0000FFF00000000000007800
+007FF00000000000007800007FF0000000000000F000007FF8000000000000F000003FF8
+000000000001F000003FFC000000000001E000001FFC000000000001E000001FFC000000
+000003E000001FFE000000000003C000000FFE000000000003C000000FFE000000000007
+C000000FFF00000000000780000007FF00000000000780000007FF00000000000FFFFFFF
+FFFF80000000000FFFFFFFFFFF80000000001FFFFFFFFFFFC0000000001FFFFFFFFFFFC0
+000000001E00000001FFC0000000003E00000001FFE0000000003C00000000FFE0000000
+003C00000000FFE0000000007C00000000FFF00000000078000000007FF0000000007800
+0000007FF000000000F0000000007FF800000000F0000000003FF800000001F000000000
+3FFC00000001E0000000001FFC00000001E0000000001FFC00000003E0000000001FFE00
+000003C0000000000FFE00000003C0000000000FFE00000007C0000000000FFF00000007
+800000000007FF0000000F800000000007FF0000000FC00000000007FF8000001FC00000
+000003FF8000003FE00000000007FFC00000FFF00000000007FFE00007FFFC000000003F
+FFF800FFFFFFC000000FFFFFFFF8FFFFFFC000000FFFFFFFF8FFFFFFC000000FFFFFFFF8
+FFFFFFC000000FFFFFFFF855567AD561>65 D<FFFFFFFFFFFFFFFFFC00FFFFFFFFFFFFFF
+FFFC00FFFFFFFFFFFFFFFFFC00FFFFFFFFFFFFFFFFFC00007FFF00000003FFFC00001FFE
+000000003FFE00000FFE0000000007FE00000FFE0000000003FE00000FFE0000000000FE
+00000FFE00000000007E00000FFE00000000007E00000FFE00000000003E00000FFE0000
+0000001E00000FFE00000000001E00000FFE00000000000F00000FFE00000000000F0000
+0FFE00000000000F00000FFE00000000000F00000FFE00000000000700000FFE00000000
+000700000FFE00000000000700000FFE00000000000700000FFE00000000000700000FFE
+000000E0000380000FFE000000E0000380000FFE000000E0000380000FFE000000E00003
+80000FFE000000E0000000000FFE000000E0000000000FFE000000E0000000000FFE0000
+01E0000000000FFE000001E0000000000FFE000001E0000000000FFE000003E000000000
+0FFE000007E0000000000FFE00000FE0000000000FFE00007FE0000000000FFFFFFFFFE0
+000000000FFFFFFFFFE0000000000FFFFFFFFFE0000000000FFFFFFFFFE0000000000FFE
+00007FE0000000000FFE00000FE0000000000FFE000007E0000000000FFE000003E00000
+00000FFE000001E0000000000FFE000001E0000000000FFE000001E0000000000FFE0000
+00E0000000000FFE000000E0000000000FFE000000E0000000000FFE000000E000003800
+0FFE000000E0000038000FFE000000E0000038000FFE000000E0000070000FFE00000000
+000070000FFE00000000000070000FFE00000000000070000FFE00000000000070000FFE
+000000000000F0000FFE000000000000E0000FFE000000000000E0000FFE000000000000
+E0000FFE000000000001E0000FFE000000000001E0000FFE000000000001E0000FFE0000
+00000003C0000FFE000000000003C0000FFE000000000007C0000FFE000000000007C000
+0FFE00000000000FC0000FFE00000000001FC0000FFE00000000003FC0000FFE00000000
+007F80000FFE0000000000FF80000FFE0000000003FF80001FFE000000001FFF80007FFF
+00000001FFFF80FFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF
+00FFFFFFFFFFFFFFFFFF004D5279D159>69 D<FFFFFFFFFFFFFC00FFFFFFFFFFFFFC00FF
+FFFFFFFFFFFC0001FFE000003FFC0000FFC0000007FC00007FC0000001FE00007FC00000
+007E00007FC00000007E00007FC00000003E00007FC00000001E00007FC00000001E0000
+7FC00000000E00007FC00000000E00007FC00000000E00007FC00000000E00007FC00000
+000F00007FC00000000700007FC00000000700007FC0000E000700007FC0000E00070000
+7FC0000E000000007FC0000E000000007FC0000E000000007FC0001E000000007FC0001E
+000000007FC0001E000000007FC0003E000000007FC001FE000000007FFFFFFE00000000
+7FFFFFFE000000007FFFFFFE000000007FC001FE000000007FC0003E000000007FC0001E
+000000007FC0001E000000007FC0001E000000007FC0000E000000007FC0000E00000000
+7FC0000E0001C0007FC0000E0001C0007FC0000E0001C0007FC000000001C0007FC00000
+000380007FC00000000380007FC00000000380007FC00000000380007FC0000000038000
+7FC00000000780007FC00000000780007FC00000000700007FC00000000F00007FC00000
+000F00007FC00000001F00007FC00000003F00007FC00000007F00007FC0000000FF0000
+FFC0000003FF0001FFE000003FFE00FFFFFFFFFFFFFE00FFFFFFFFFFFFFE00FFFFFFFFFF
+FFFE003A3D7CBC43>101 D<FFFFFFFFFE0000FFFFFFFFFFE000FFFFFFFFFFF80001FFE0
+000FFE0000FFC00001FF80007FC000007FC0007FC000003FE0007FC000001FF0007FC000
+000FF8007FC000000FFC007FC000000FFC007FC0000007FE007FC0000007FE007FC00000
+07FF007FC0000007FF007FC0000007FF007FC0000007FF007FC0000007FF007FC0000007
+FF007FC0000007FF007FC0000007FE007FC0000007FE007FC000000FFC007FC000000FFC
+007FC000000FF8007FC000001FF0007FC000003FE0007FC000007FC0007FC00001FF8000
+7FC0000FFE00007FFFFFFFF800007FFFFFFFE000007FFFFFFE0000007FC000000000007F
+C000000000007FC000000000007FC000000000007FC000000000007FC000000000007FC0
+00000000007FC000000000007FC000000000007FC000000000007FC000000000007FC000
+000000007FC000000000007FC000000000007FC000000000007FC000000000007FC00000
+0000007FC000000000007FC000000000007FC000000000007FC000000000007FC0000000
+00007FC00000000000FFE00000000001FFF000000000FFFFFFE0000000FFFFFFE0000000
+FFFFFFE0000000383D7CBC43>112 D<FFFFFFFFF000000000FFFFFFFFFF00000000FFFF
+FFFFFFE000000001FFE0003FF800000000FFC00007FC000000007FC00001FF000000007F
+C00000FF800000007FC000007FC00000007FC000003FE00000007FC000003FF00000007F
+C000003FF00000007FC000001FF80000007FC000001FF80000007FC000001FFC0000007F
+C000001FFC0000007FC000001FFC0000007FC000001FFC0000007FC000001FFC0000007F
+C000001FFC0000007FC000001FF80000007FC000001FF80000007FC000003FF00000007F
+C000003FF00000007FC000003FE00000007FC000007FC00000007FC00000FF800000007F
+C00001FF000000007FC00007FC000000007FC0003FF8000000007FFFFFFFE0000000007F
+FFFFFF00000000007FFFFFFF00000000007FC000FFC0000000007FC0001FE0000000007F
+C0000FF8000000007FC00007FC000000007FC00003FC000000007FC00001FE000000007F
+C00001FF000000007FC00000FF000000007FC00000FF800000007FC00000FF800000007F
+C00000FF800000007FC00000FF800000007FC00000FFC00000007FC00000FFC00000007F
+C00000FFC00000007FC00000FFE00000007FC00000FFE00000007FC00000FFE00000007F
+C00000FFE00000007FC00000FFF001C0007FC00000FFF001C0007FC00000FFF001C0007F
+C000007FF001C0007FC000007FF803C000FFE000003FF8038001FFF000001FFC0780FFFF
+FFE0001FFC0700FFFFFFE00007FE1F00FFFFFFE00003FFFE00000000000000FFFC000000
+000000001FF000423F7CBC48>114 D<0003FE000600001FFFE00E00007FFFF81E0001FE
+01FC3E0003F0003F7E0007E0000FFE000F800007FE001F800001FE001F000001FE003E00
+0000FE007E0000007E007C0000007E007C0000003E00FC0000003E00FC0000001E00FC00
+00001E00FC0000001E00FE0000000E00FE0000000E00FF0000000E00FF0000000E00FF80
+000000007FC0000000007FF0000000007FFC000000003FFF800000003FFFFC0000001FFF
+FFC000000FFFFFFC000007FFFFFF000003FFFFFFC00001FFFFFFE000007FFFFFF000001F
+FFFFF8000003FFFFFC0000003FFFFE00000003FFFE000000003FFF0000000007FF800000
+0001FF8000000000FF80000000007FC0000000003FC0000000003FC0E00000001FC0E000
+00001FC0E00000000FC0E00000000FC0E00000000FC0F00000000FC0F00000000FC0F000
+00000F80F80000000F80F80000001F80FC0000001F00FE0000003F00FE0000003E00FF80
+00007C00FFC00000FC00FFE00001F800FDFC0003F000F87FC01FC000F01FFFFF8000E003
+FFFE0000C0003FF000002A417ABE37>I<7FFFFF8000FFFFF07FFFFF8000FFFFF07FFFFF
+8000FFFFF001FFFE00003FFF00007FFC00001FFC00003FFC00001FF000001FF800001FC0
+00001FFC00001F8000000FFC00001F00000007FE00001E00000007FF00001C00000003FF
+00003C00000001FF80007800000000FFC0007000000000FFC000F0000000007FE001E000
+0000003FF003C0000000003FF80380000000001FF80780000000000FFC0F00000000000F
+FE1E000000000007FE1C000000000003FF3C000000000001FFF8000000000001FFF00000
+00000000FFF00000000000007FE00000000000007FF00000000000003FF0000000000000
+1FF80000000000000FFC0000000000001FFC0000000000001FFE0000000000003FFF0000
+000000007BFF80000000000071FF800000000000F0FFC00000000001E0FFE00000000003
+C07FE00000000003803FF00000000007801FF8000000000F001FFC000000001E000FFC00
+0000001C0007FE000000003C0007FF00000000780003FF00000000700001FF80000000F0
+0000FFC0000001E00000FFC0000003C000007FE00000038000003FF00000078000003FF8
+00000F8000001FF800001F8000000FFC00003F8000000FFE0000FF8000000FFF0003FF80
+00001FFF800FFFC000003FFFE0FFFFF00000FFFFFFFFFFF00000FFFFFFFFFFF00000FFFF
+FF403D7CBC49>120 D E /Fg 1 66 df<000000FC000000000000FC000000000001FE00
+0000000001FE000000000003FF000000000003FF000000000003FF000000000007FF8000
+00000007FF80000000000FFFC0000000000FFFC0000000000FFFC0000000001FFFE00000
+00001F7FE0000000003F7FF0000000003E3FF0000000007E3FF8000000007C1FF8000000
+007C1FF800000000FC1FFC00000000F80FFC00000001F80FFE00000001F007FE00000001
+F007FE00000003F007FF00000003E003FF00000007E003FF80000007C001FF80000007C0
+01FF8000000FC000FFC000000F8000FFC000001FFFFFFFE000001FFFFFFFE000003FFFFF
+FFF000003FFFFFFFF000003E00003FF000007E00003FF800007C00001FF80000FC00001F
+FC0000F800000FFC0000F800000FFC0001F800000FFE0001F0000007FE00FFFFC001FFFF
+FCFFFFC001FFFFFCFFFFC001FFFFFCFFFFC001FFFFFC362F7DAE3D>65
+D E /Fh 94 127 df<1C007F00FF80FF80FF80FF80FF80FF80FF80FF80FF80FF80FF80FF
+80FF80FF80FF80FF80FF807F007F007F007F007F007F007F007F007F007F007F007F007F
+007F007F003E00000000000000000000000000000000001C007F007F00FF80FF80FF807F
+007F001C0009346FB32C>33 D<3C001E007F007F00FF007F80FF007F80FF007F80FF007F
+80FF007F80FF007F807F007F007F007F007F007F007F007F007F007F007F007F007E003F
+007E003F007E003F007E003F007E003F007E003F003E003E003E003E003E003E003C001E
+001C001C00191977B32C>I<000F003C00001F807E00001F807E00001F807E00001F807E
+00001F807E00001F807E00001F807E00001F807E00003F80FE00003F00FC00003F00FC00
+003F00FC00003F00FC007FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF83F
+FFFFFFF0007E01F800007E01F800007E01F800007E01F800007E01F80000FE03F80000FC
+03F00000FC03F00000FC03F00000FC03F00000FC03F00000FC03F0003FFFFFFFF0FFFFFF
+FFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF87FFFFFFFF001F807E00001F807E00001F807E0
+0003F80FE00003F00FC00003F00FC00003F00FC00003F00FC00003F00FC00003F00FC000
+03F00FC00003F00FC00001E007800025337DB22C>I<0001C000000003E000000003E000
+000003E000000003E000000003E000000003E00000000FFC0000007FFF800001FFFFE000
+07FFFFF0000FFFFFF8001FFBEFFC003FC3E1FE003F03E07F007E03E03F007C03E03F00FC
+03E03F80F803E03F80F803E07F80F803E07F80F803E07F80FC03E03F00FC03E03F007E03
+E000007F03E000003FC3E000003FFBE000001FFFE000000FFFFC000007FFFF000001FFFF
+C000007FFFE000001FFFF8000003FFFC000003E7FC000003E1FE000003E07F000003E03F
+001803E01F007E03E01F807E03E00F80FF03E00F80FF03E00F80FF03E00F80FE03E00F80
+FE03E01F80FE03E01F007E03E03F007F03E03E003F83E0FE003FC3E1FC001FFBEFF8000F
+FFFFF00007FFFFE00003FFFFC00000FFFF0000001FF800000003E000000003E000000003
+E000000003E000000003E000000003E000000001C0000021417BB92C>I<07800007001F
+E0000F801FE0001F803FF0001F807FF8003F807FF8003F007CF8007F00FCFC007E00F87C
+007E00F87C00FE00F87C00FC00F87C01FC00F87C01F800F87C01F800F87C03F800FCFC03
+F0007CF803F0007FF807F0007FF807E0003FF00FE0001FE00FC0001FE00FC00007801FC0
+0000001F800000003F800000003F000000003F000000007F000000007E00000000FE0000
+0000FC00000000FC00000001FC00000001F800000001F800000003F800000003F0000000
+07F000000007E000000007E00000000FE00000000FC00000001FC00000001F800F00001F
+803FC0003F807FE0003F007FE0007F00FFF0007E00F9F0007E00F9F000FE01F9F800FC01
+F0F800FC01F0F801FC01F0F801F801F0F803F801F0F803F001F0F803F001F9F807F000F9
+F007E000F9F00FE000FFF00FC0007FE00FC0007FE007C0003FC00380000F0025417DB92C
+>I<000FC00000003FE00000007FF0000000FFF8000000FFFC000001F8FC000001F07C00
+0001F07E000003F03E000003E03E000003E03E000003E03E000003E03E000003E03E0000
+03E07E000003E07C000003E0FC3FF803F0F87FFC01F1F87FFC01F3F07FFC01F7F03FF801
+F7E01F0001FFC03F0000FF803E0000FF803E0000FF007E0000FE007C0001FC007C0003FE
+00FC0007FE00F80007FF01F8000FDF01F0001F9F81F0003F8F83F0003F0FC3E0007E07E7
+E0007E07E7C000FC03F7C000FC01FFC000FC01FF8000FC00FF8010FC00FF007CFC007F00
+7CFC007F007CFE00FF807C7E01FFC07C7F03FFE0FC3F87F7F1F83FFFE3FFF81FFFC1FFF0
+0FFF80FFF007FF007FC001FC001F8026357EB32C>I<0F801FC03FE03FF03FF03FF83FF8
+1FF80FF800F800F800F800F801F801F001F003F003E007E00FC01FC03F807F00FE00FC00
+F80070000D1B71B22C>I<0000380000FC0001FC0003FC0007F8000FF0001FC0003F8000
+7F0000FE0001FC0003F80003F00007F00007E0000FE0000FC0001F80001F80003F80003F
+00003F00007F00007E00007E00007E0000FE0000FC0000FC0000FC0000FC0000FC0000FC
+0000FC0000FC0000FC0000FC0000FC0000FC0000FE00007E00007E00007E00007F00003F
+00003F00003F80001F80001F80000FC0000FE00007E00007F00003F00003F80001FC0000
+FE00007F00003F80001FC0000FF00007F80003FC0001FC0000FC000038164272B92C>I<
+700000FC0000FE0000FF00007F80003FC0000FE00007F00003F80001FC0000FE00007F00
+003F00003F80001F80001FC0000FC00007E00007E00007F00003F00003F00003F80001F8
+0001F80001F80001FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC
+0000FC0000FC0000FC0001FC0001F80001F80001F80003F80003F00003F00007F00007E0
+0007E0000FC0001FC0001F80003F80003F00007F0000FE0001FC0003F80007F0000FE000
+3FC0007F8000FF0000FE0000FC0000700000164279B92C>I<000380000007C0000007C0
+000007C0000007C0000007C0000007C0002007C008F807C03EFE07C0FEFF07C1FEFFC7C7
+FEFFE7CFFE3FFFFFF80FFFFFE003FFFF8001FFFF00007FFC00007FFC0001FFFF0003FFFF
+800FFFFFE03FFFFFF8FFE7CFFEFFC7C7FEFF07C1FEFE07C0FEF807C03E2007C0080007C0
+000007C0000007C0000007C0000007C0000007C000000380001F247AAA2C>I<00007800
+000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC0000
+0000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC000000
+00FC00007FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF87FFFFFFFF00000
+FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC
+00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00
+00000078000025267DAB2C>I<0F801FE03FF07FF87FF87FFC7FFC7FFC3FFC1FFC0FFC00
+FC00F800F801F803F007F01FE07FC0FF80FF00FC0070000E17718A2C>I<7FFFFFFF00FF
+FFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF807FFFFFFF0021067B9B2C>I<1F003F807F
+C0FFE0FFE0FFE0FFE0FFE07FC03F801F000B0B708A2C>I<00000007000000000F800000
+001F800000001F800000003F800000003F000000007F000000007E00000000FE00000000
+FC00000001FC00000001F800000003F800000003F000000003F000000007F000000007E0
+0000000FE00000000FC00000001FC00000001F800000003F800000003F000000007F0000
+00007E00000000FE00000000FC00000000FC00000001FC00000001F800000003F8000000
+03F000000007F000000007E00000000FE00000000FC00000001FC00000001F800000001F
+800000003F800000003F000000007F000000007E00000000FE00000000FC00000001FC00
+000001F800000003F800000003F000000007F000000007E000000007E00000000FE00000
+000FC00000001FC00000001F800000003F800000003F000000007F000000007E00000000
+FE00000000FC00000000FC00000000F800000000780000000021417BB92C>I<0003F800
+00000FFE0000003FFF8000007FFFC00000FFFFE00001FE0FF00003F803F80007F001FC00
+07E000FC000FC0007E000FC0007E001F80003F001F80003F003F00001F803F00001F803E
+00000F807E00000FC07E00000FC07E00000FC07C000007C0FC000007E0FC000007E0FC00
+0007E0FC000007E0FC000007E0FC000007E0FC000007E0FC000007E0FC000007E0FC0000
+07E0FC000007E0FC000007E0FE00000FE07E00000FC07E00000FC07E00000FC07E00000F
+C03F00001F803F00001F803F00001F801F80003F001F80003F000FC0007E000FE000FE00
+07E000FC0007F001FC0003F803F80001FE0FF00000FFFFE000007FFFC000003FFF800000
+0FFE00000003F8000023357CB32C>I<00070000000F8000000F8000001F8000001F8000
+003F8000007F800000FF800001FF800007FF80007FFF8000FFFF8000FFDF8000FF9F8000
+7C1F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000
+001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000
+001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000
+001F8000001F8000001F8000001F8000001F8000001F80007FFFFFE0FFFFFFF0FFFFFFF0
+FFFFFFF07FFFFFE01C3477B32C>I<000FF80000007FFF800001FFFFE00007FFFFF0000F
+FFFFFC001FF80FFE003FE001FF003F80007F007F00003F807E00001F80FE00001FC0FE00
+000FC0FF00000FE0FF000007E0FF000007E0FF000007E07E000007E03C000007E0000000
+07E000000007E00000000FE00000000FC00000001FC00000001F800000003F800000003F
+000000007F00000000FE00000001FC00000003FC00000007F80000000FF00000001FE000
+00003FC0000000FF80000001FE00000003FC00000007F80000000FF00000003FE0000000
+7F80000000FF00000001FE00000003FC0003C007F80007E01FE00007E03FC00007E07FFF
+FFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE07FFFFFFFC023347CB32C>I<000FFC000000
+7FFF800001FFFFE00007FFFFF8000FFFFFFC001FF807FE001FC000FE003F80007F003FC0
+003F003FC0003F803FC0001F803FC0001F801F80001F800F00001F800000001F80000000
+3F800000003F000000007F00000000FE00000001FE00000003FC0000001FF800001FFFF0
+00003FFFE000003FFFE000003FFFF800001FFFFC00000007FE00000000FF000000007F00
+0000003F800000001FC00000000FC00000000FC00000000FE000000007E000000007E03C
+000007E07E000007E0FF000007E0FF00000FE0FF00000FC0FF00000FC0FE00001FC07F00
+003F807F80007F003FC000FF001FF807FE000FFFFFFC0007FFFFF80003FFFFE000007FFF
+8000000FFC000023357CB32C>I<000007F00000000FF80000001FF80000003FF8000000
+3FF80000007EF80000007EF8000000FCF8000001F8F8000001F8F8000003F0F8000007E0
+F8000007E0F800000FC0F800001F80F800001F80F800003F00F800007E00F800007E00F8
+0000FC00F80001F800F80001F800F80003F000F80003E000F80007E000F8000FC000F800
+0FC000F8001F8000F8003F0000F8003F0000F8007E0000F800FC0000F800FFFFFFFFFCFF
+FFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC000000F800000000F800000000F8000000
+00F800000000F800000000F800000000F800000000F800000000F800000000F80000007F
+FFF00000FFFFF80000FFFFF80000FFFFF800007FFFF027347EB32C>I<0FFFFFFE001FFF
+FFFF001FFFFFFF001FFFFFFF001FFFFFFE001F800000001F800000001F800000001F8000
+00001F800000001F800000001F800000001F800000001F800000001F800000001F800000
+001F800000001F800000001F83FE00001F9FFF80001FFFFFE0001FFFFFF8001FFFFFFC00
+1FFE03FE001FF000FF001FC0007F001F80003F801F00001F800F00001FC00000000FC000
+00000FC000000007E000000007E000000007E000000007E03C000007E07E000007E0FF00
+0007E0FF00000FE0FF00000FC0FF00000FC0FE00001FC07E00003F807F00007F003F8000
+FF003FC001FE001FF80FFC000FFFFFF80007FFFFF00001FFFFC000007FFF0000000FF800
+0023347CB22C>I<00003FC0000001FFF8000007FFFC00001FFFFE00003FFFFF00007FE0
+7F0000FF003F8001FE007F8003F8007F8007F0007F8007E0007F800FE0003F001FC0001E
+001F800000003F800000003F000000003F000000007F000000007E000000007E03FE0000
+7E1FFF8000FC7FFFE000FDFFFFF000FFFFFFF800FFFE07FC00FFF001FE00FFC0007F00FF
+80003F80FF00001F80FF00001FC0FE00000FC0FE00000FE0FE000007E0FE000007E0FE00
+0007E07E000007E07E000007E07E000007E07E000007E03F000007E03F00000FE03F8000
+0FC01F80001FC01FC0001F800FC0003F800FE0007F0007F801FE0003FE07FC0001FFFFF8
+0000FFFFF000007FFFE000001FFF80000007FC000023357CB32C>I<7800000000FFFFFF
+FFC0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFC0FC00003F80FC00007F00FC0000FE
+00780000FC00000001FC00000003F800000007F000000007E00000000FE00000000FC000
+00001F800000003F800000003F000000007F000000007E00000000FE00000000FC000000
+01FC00000001F800000001F800000003F000000003F000000007F000000007E000000007
+E000000007E00000000FC00000000FC00000000FC00000000FC00000001F800000001F80
+0000001F800000001F800000001F800000003F800000003F000000003F000000003F0000
+00003F000000003F000000003F000000003F000000003F000000003F000000003F000000
+001E00000023357CB32C>I<0007FC0000003FFF800000FFFFE00003FFFFF80007FFFFFC
+000FFC07FE001FF001FF001FC0007F003F80003F803F00001F807F00001FC07E00000FC0
+7E00000FC07E00000FC07E00000FC07E00000FC03F00001F803F00001F801F80003F001F
+C0007F000FF001FE0003FC07F80001FFFFF000007FFFC0000007FC0000007FFFC00001FF
+FFF00003FC07F8000FF001FE001FC0007F001F80003F003F00001F807E00000FC07E0000
+0FC0FC000007E0FC000007E0FC000007E0FC000007E0FC000007E0FC000007E0FC000007
+E07E00000FC07E00000FC07F00001FC03F80003F801FC0007F001FF001FF000FFC07FE00
+07FFFFFC0003FFFFF80000FFFFE000003FFF80000007FC000023357CB32C>I<0007FC00
+00003FFF000000FFFFC00001FFFFE00003FFFFF00007FC07F8000FF001FC001FE000FE00
+3F80007E003F80007F007F00003F007E00001F80FE00001F80FC00001F80FC00000FC0FC
+00000FC0FC00000FC0FC00000FC0FC00000FE0FC00000FE0FC00000FE0FE00000FE07E00
+000FE07F00001FE03F00001FE03F80003FE01FC0007FE00FF001FFE007FC0FFFE003FFFF
+FFE001FFFFF7E000FFFFC7E0003FFF0FE0000FF80FC00000000FC00000000FC00000001F
+C00000001F800000003F800000003F000F00007F001F80007E003FC000FE003FC001FC00
+3FC003F8003FC007F8003F801FF0001FE07FE0001FFFFFC0000FFFFF000007FFFE000001
+FFF80000007FC0000023357CB32C>I<1F003F807FC0FFE0FFE0FFE0FFE0FFE07FC03F80
+1F00000000000000000000000000000000000000000000000000000000001F003F807FC0
+FFE0FFE0FFE0FFE0FFE07FC03F801F000B2470A32C>I<0F801FC03FE07FF07FF07FF07F
+F07FF03FE01FC00F80000000000000000000000000000000000000000000000000000000
+000F801FC03FE07FE07FF07FF07FF07FF03FF01FF00FF001F003F003E007E00FC00FC03F
+807F00FF00FE00F80070000C3071A32C>I<00000007000000001F800000003F80000000
+FF80000003FF80000007FF0000001FFC0000003FF8000000FFE0000001FF80000007FF00
+00000FFC0000003FF80000007FE0000001FFC0000003FF0000000FFE0000001FF8000000
+7FF0000000FFC0000000FF80000000FF80000000FFC00000007FF00000001FF80000000F
+FE00000003FF00000001FFC00000007FE00000003FF80000000FFC00000007FF00000001
+FF80000000FFE00000003FF80000001FFC00000007FF00000003FF80000000FF80000000
+3F800000001F800000000700212A7BAD2C>I<7FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFF
+FFFFF8FFFFFFFFF83FFFFFFFF00000000000000000000000000000000000000000000000
+00000000000000000000000000000000003FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFFFFFF
+F8FFFFFFFFF87FFFFFFFF025147DA22C>I<7000000000FC00000000FE00000000FF8000
+0000FFE00000007FF00000001FFC0000000FFE00000003FF80000000FFC00000007FF000
+00001FF80000000FFE00000003FF00000001FFC00000007FE00000003FF80000000FFC00
+000007FF00000001FF80000000FF80000000FF80000001FF80000007FF0000000FFC0000
+003FF80000007FE0000001FFC0000003FF0000000FFE0000001FF80000007FF0000000FF
+C0000003FF8000000FFE0000001FFC0000007FF0000000FFE0000000FF80000000FE0000
+0000FC000000007000000000212A7BAD2C>I<003FFE000003FFFFC0000FFFFFF0001FFF
+FFFC003FFFFFFE007FE007FF007F0000FF00FE00003F80FF00001F80FF00001F80FF0000
+1F80FF00003F807E00007F003C0000FF00000003FE0000000FFC0000001FF80000003FE0
+0000007FC0000000FF00000001FE00000003FC00000003F800000007F800000007F00000
+000FF00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE0000000
+0FE000000007C00000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000003800000000FE00000000FE00000001FF00000001FF0
+0000001FF00000000FE00000000FE00000000380000021337BB22C>I<00007F80000003
+FFE000000FFFF000003FFFF800007FFFFC0000FFC0FE0001FE007F0003F8003F0007F000
+1F8007E00FCF800FC03FFF801F807FFFC01F80FFFFC03F01FFFFC03E03F87FC03E07F03F
+E07E07E01FE07C0FC00FE07C0F8007E07C0F8007E0FC1F8007E0F81F0003E0F81F0003E0
+F81F0003E0F81F0003E0F81F0003E0F81F0003E0F81F0003E0F81F0003E0F81F0003E0FC
+1F8007E07C0F8007C07C0F8007C07C0FC00FC07E07E01F803E07F03F803E03F87F003F01
+FFFE001F80FFFC001F807FF8000FC03FF00007E00FC00007F00007C003F8000FE001FE00
+1FE000FFC0FFE0007FFFFFC0003FFFFF80000FFFFE000003FFF80000007FC00023337CB2
+2C>I<0000FE00000001FF00000001FF00000001FF00000001FF00000003FF80000003FF
+80000003EF80000003EF80000007EF80000007EFC0000007EFC0000007C7C0000007C7C0
+00000FC7E000000FC7E000000FC7E000000FC3E000001F83F000001F83F000001F83F000
+001F83F000001F83F000003F01F800003F01F800003F01F800003F01F800007E00FC0000
+7E00FC00007E00FC00007E00FC00007E00FC0000FC007E0000FFFFFE0000FFFFFE0000FF
+FFFE0001FFFFFF0001FFFFFF0001F8003F0001F8003F0001F8003F0003F0001F8003F000
+1F8003F0001F8003F0001F8007F0001FC007E0000FC07FFE00FFFC7FFF01FFFCFFFF01FF
+FE7FFF01FFFC7FFE00FFFC27347EB32C>I<7FFFFFE0007FFFFFF800FFFFFFFE007FFFFF
+FF007FFFFFFFC003F0003FC003F0000FE003F00007F003F00003F003F00003F003F00001
+F803F00001F803F00001F803F00001F803F00001F803F00001F803F00003F003F00003F0
+03F00007F003F0000FE003F0001FC003F000FF8003FFFFFF0003FFFFFE0003FFFFFC0003
+FFFFFF0003FFFFFFC003F0001FE003F00007F003F00003F803F00001F803F00000FC03F0
+0000FC03F00000FE03F000007E03F000007E03F000007E03F000007E03F000007E03F000
+007E03F00000FE03F00000FC03F00001FC03F00003F803F0000FF803F0003FF07FFFFFFF
+E07FFFFFFFC0FFFFFFFF807FFFFFFE007FFFFFF00027337FB22C>I<0000FF00700007FF
+E0F8000FFFF9F8003FFFFDF8007FFFFFF800FF81FFF801FE007FF803FC001FF807F0000F
+F807F00007F80FE00007F80FC00003F81F800003F81F800001F83F000001F83F000001F8
+7F000001F87E000000F07E000000007E00000000FE00000000FC00000000FC00000000FC
+00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00
+000000FC00000000FE000000007E000000007E000000007E000000007F000000F03F0000
+01F83F000001F81F800001F81F800001F80FC00003F80FE00003F007F00007F007F00007
+E003FC001FE001FE003FC000FF81FF80007FFFFF00003FFFFE00000FFFFC000007FFF000
+0000FF800025357DB32C>I<7FFFFF0000FFFFFFC000FFFFFFF000FFFFFFF8007FFFFFFC
+0007E003FE0007E000FF0007E0007F8007E0003F8007E0001FC007E0000FE007E0000FE0
+07E00007E007E00007F007E00003F007E00003F807E00001F807E00001F807E00001F807
+E00001F807E00000FC07E00000FC07E00000FC07E00000FC07E00000FC07E00000FC07E0
+0000FC07E00000FC07E00000FC07E00000FC07E00000FC07E00000FC07E00001F807E000
+01F807E00001F807E00003F807E00003F007E00003F007E00007F007E00007E007E0000F
+E007E0001FC007E0003FC007E0007F8007E000FF0007E003FE007FFFFFFC00FFFFFFF800
+FFFFFFF000FFFFFFC0007FFFFF000026337EB22C>I<7FFFFFFFF0FFFFFFFFF8FFFFFFFF
+F8FFFFFFFFF87FFFFFFFF803F00001F803F00001F803F00001F803F00001F803F00001F8
+03F00001F803F00001F803F00000F003F000000003F000000003F000000003F000000003
+F001E00003F003F00003F003F00003F003F00003F003F00003FFFFF00003FFFFF00003FF
+FFF00003FFFFF00003FFFFF00003F003F00003F003F00003F003F00003F003F00003F001
+E00003F000000003F000000003F000000003F000000003F000000003F000003C03F00000
+7E03F000007E03F000007E03F000007E03F000007E03F000007E03F000007E03F000007E
+7FFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC27337EB22C>I<7FFFFFFF
+F8FFFFFFFFFCFFFFFFFFFCFFFFFFFFFC7FFFFFFFFC03F00000FC03F00000FC03F00000FC
+03F00000FC03F00000FC03F00000FC03F00000FC03F000007803F000000003F000000003
+F000000003F000000003F000000003F000F00003F001F80003F001F80003F001F80003F0
+01F80003FFFFF80003FFFFF80003FFFFF80003FFFFF80003FFFFF80003F001F80003F001
+F80003F001F80003F001F80003F000F00003F000000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000003F00000007FFFE00000FFFFE00000FFFFF00000FFFFE000007FFFE0000026
+337EB22C>I<0001FC0380000FFF87C0001FFFEFC0007FFFFFC000FFFFFFC001FF07FFC0
+03FC01FFC003F800FFC007F0007FC00FE0003FC00FC0001FC01FC0001FC01F80001FC03F
+80000FC03F00000FC03F00000FC07E00000FC07E000007807E000000007E00000000FE00
+000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC0000
+0000FC00000000FC0003FFF8FC0007FFFCFC0007FFFCFE0007FFFC7E0003FFF87E00000F
+C07E00000FC07E00000FC03F00001FC03F00001FC03F80001FC01F80001FC01FC0003FC0
+0FC0003FC00FE0007FC007F0007FC003F800FFC003FC01FFC001FF07FFC000FFFFFFC000
+7FFFEFC0001FFFCFC0000FFF07800001FC000026357DB32C>I<7FFE00FFFCFFFF01FFFE
+FFFF01FFFEFFFF01FFFE7FFE00FFFC07E0000FC007E0000FC007E0000FC007E0000FC007
+E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0
+000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007FFFFFFC007FFFF
+FFC007FFFFFFC007FFFFFFC007FFFFFFC007E0000FC007E0000FC007E0000FC007E0000F
+C007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC0
+07E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007E0000FC007
+E0000FC07FFE00FFFCFFFF01FFFEFFFF01FFFEFFFF01FFFE7FFE00FFFC27337EB22C>I<
+7FFFFFF8FFFFFFFCFFFFFFFCFFFFFFFC7FFFFFF8000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000
+000FC0007FFFFFF8FFFFFFFCFFFFFFFCFFFFFFFC7FFFFFF81E3379B22C>I<0007FFFF80
+000FFFFFC0000FFFFFC0000FFFFFC00007FFFF80000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F000000003F000000003F0
+00000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000180003F0007E0003F0007E0003F000FF0003F000FF0003F000FF0007E000FE
+000FE0007F001FE0007FC07FC0003FFFFF80001FFFFF00000FFFFE000003FFF80000007F
+C0000022347BB22C>I<7FFC007FF8FFFE00FFFCFFFE00FFFCFFFE00FFFC7FFC007FF807
+C0001F8007C0003F8007C0007F0007C0007E0007C000FC0007C001F80007C003F80007C0
+07F00007C007E00007C00FC00007C01F800007C03F800007C07F000007C07E000007C0FC
+000007C1F8000007C3F8000007C7FC000007C7FC000007CFFE000007DFBE000007FFBF00
+0007FF1F000007FE1F800007FC0FC00007F80FC00007F807E00007F003E00007E003F000
+07C001F00007C001F80007C000FC0007C000FC0007C0007E0007C0003E0007C0003F0007
+C0001F0007C0001F8007C0000FC007C0000FC007C00007E07FFC001FFCFFFE003FFEFFFE
+003FFEFFFE003FFE7FFC001FFC27337EB22C>I<7FFFE00000FFFFF00000FFFFF00000FF
+FFF000007FFFE0000003F000000003F000000003F000000003F000000003F000000003F0
+00000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F00000F003F00001F803
+F00001F803F00001F803F00001F803F00001F803F00001F803F00001F803F00001F87FFF
+FFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF87FFFFFFFF025337DB22C>I<7FE0000FFCFF
+F0001FFEFFF0001FFEFFF8003FFE7FF8003FFC0FF8003FE00FBC007BE00FBC007BE00FBC
+007BE00FBC007BE00F9E00F3E00F9E00F3E00F9E00F3E00F9F01F3E00F9F01F3E00F8F01
+E3E00F8F01E3E00F8F83E3E00F8F83E3E00F8783C3E00F87C7C3E00F87C7C3E00F83C783
+E00F83C783E00F83EF83E00F83EF83E00F81EF03E00F81EF03E00F81FF03E00F80FE03E0
+0F80FE03E00F80FE03E00F807C03E00F803803E00F800003E00F800003E00F800003E00F
+800003E00F800003E00F800003E00F800003E00F800003E00F800003E00F800003E00F80
+0003E00F800003E07FF0001FFCFFF8003FFEFFF8003FFEFFF8003FFE7FF0001FFC27337E
+B22C>I<7FF0007FFCFFF800FFFEFFF800FFFEFFFC00FFFE7FFC007FFC07FE0007C007DE
+0007C007DE0007C007DF0007C007CF0007C007CF0007C007CF8007C007C78007C007C7C0
+07C007C7C007C007C3C007C007C3E007C007C3E007C007C1E007C007C1F007C007C1F007
+C007C0F007C007C0F807C007C0F807C007C07C07C007C07C07C007C07C07C007C03E07C0
+07C03E07C007C01E07C007C01F07C007C01F07C007C00F07C007C00F87C007C00F87C007
+C00787C007C007C7C007C007C7C007C003C7C007C003E7C007C001E7C007C001E7C007C0
+01F7C007C000F7C007C000F7C007C000FFC07FFC007FC0FFFE007FC0FFFE003FC0FFFE00
+3FC07FFC001F8027337EB22C>I<007FFF000003FFFFE0000FFFFFF8001FFFFFFC003FFF
+FFFE003FE003FE003F8000FE007F00007F007F00007F007E00003F007E00003F007E0000
+3F00FE00003F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F
+80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80
+FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC
+00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FE00003F80FE00
+003F807E00003F007E00003F007E00003F007F00007F007F00007F003F8000FE003FF007
+FE003FFFFFFE001FFFFFFC000FFFFFF80003FFFFE000007FFF000021357BB32C>I<7FFF
+FFC000FFFFFFF800FFFFFFFC00FFFFFFFF007FFFFFFF8003F000FFC003F0003FC003F000
+0FE003F00007F003F00007F003F00003F003F00003F803F00001F803F00001F803F00001
+F803F00001F803F00001F803F00001F803F00003F803F00003F003F00007F003F00007F0
+03F0000FE003F0003FC003F000FFC003FFFFFF8003FFFFFF0003FFFFFC0003FFFFF80003
+FFFFC00003F000000003F000000003F000000003F000000003F000000003F000000003F0
+00000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F00000007FFF800000FFFFC00000FFFFC00000FFFFC000007FFF8000
+0025337EB22C>I<007FFF000003FFFFE0000FFFFFF8001FFFFFFC003FFFFFFE003FF007
+FE003F8000FE007F00007F007F00007F007E00003F007E00003F007E00003F00FE00003F
+80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80
+FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC
+00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00001F80FC00
+001F80FC00001F80FC00001F80FC00001F80FC01F01F80FC03F81F80FE03F83F807E01FC
+3F007E01FC3F007E00FE3F007F00FE7F007F007F7F003F807FFE003FF03FFE003FFFFFFE
+001FFFFFFC000FFFFFF80003FFFFE000007FFFE000000007F000000007F000000003F800
+000003F800000001FC00000001FC00000000FE00000000FE000000007F000000007F0000
+00003E0021407BB32C>I<7FFFFC000000FFFFFF800000FFFFFFE00000FFFFFFF800007F
+FFFFFC000007E007FE000007E001FE000007E0007F000007E0003F800007E0001F800007
+E0001F800007E0000FC00007E0000FC00007E0000FC00007E0000FC00007E0000FC00007
+E0000FC00007E0001F800007E0001F800007E0003F800007E0007F000007E001FE000007
+E007FE000007FFFFFC000007FFFFF8000007FFFFE0000007FFFFF0000007FFFFF8000007
+E007FC000007E001FE000007E000FE000007E0007F000007E0003F000007E0003F000007
+E0003F000007E0003F000007E0003F000007E0003F000007E0003F000007E0003F000007
+E0003F0F0007E0003F1F8007E0003F1F8007E0003F1F8007E0003F1F8007E0003F1F807F
+FE001FBF80FFFF001FFF00FFFF000FFF00FFFF000FFE007FFE0007FC0000000001F00029
+347EB22C>I<001FF8070000FFFF0F8001FFFFCF8007FFFFFF800FFFFFFF801FF01FFF80
+3FC003FF803F8001FF807F0000FF807E00007F80FE00003F80FC00003F80FC00001F80FC
+00001F80FC00001F80FC00001F80FE00000F007E000000007F000000007F800000003FE0
+0000001FFC0000001FFFC000000FFFFC000003FFFFC00001FFFFF000007FFFF8000007FF
+FC0000007FFE00000007FF00000000FF800000003F800000001FC00000001FC00000000F
+E00000000FE078000007E0FC000007E0FC000007E0FC000007E0FC000007E0FC000007E0
+FE00000FC0FE00000FC0FF00001F80FF80003F80FFE0007F00FFFE01FF00FFFFFFFE00FF
+FFFFFC00F9FFFFF000F83FFFC0007007FF000023357CB32C>I<7FFFFFFFFCFFFFFFFFFE
+FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFC007E007EFC007E007EFC007E007EFC007E007EFC
+007E007EFC007E007EFC007E007E78007E003C00007E000000007E000000007E00000000
+7E000000007E000000007E000000007E000000007E000000007E000000007E000000007E
+000000007E000000007E000000007E000000007E000000007E000000007E000000007E00
+0000007E000000007E000000007E000000007E000000007E000000007E000000007E0000
+00007E000000007E000000007E000000007E000000007E000000007E000000007E000000
+007E0000003FFFFC00003FFFFC00007FFFFE00003FFFFC00003FFFFC0027337EB22C>I<
+7FFF803FFFC0FFFFC07FFFE0FFFFC07FFFE0FFFFC07FFFE07FFF803FFFC003F00001F800
+03F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F800
+03F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F800
+03F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F800
+03F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F800
+03F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F800
+03F00001F80003F00001F80003F80003F80001F80003F00001F80003F00001FC0007F000
+00FC0007E00000FE000FE000007F001FC000003F803F8000003FE0FF8000001FFFFF0000
+000FFFFE00000003FFF800000001FFF0000000003F8000002B3480B22C>I<7FFC007FFC
+FFFE00FFFEFFFE00FFFEFFFE00FFFE7FFC007FFC0FC00007E00FE0000FE007E0000FC007
+E0000FC007E0000FC007F0001FC003F0001F8003F0001F8003F0001F8003F8003F8001F8
+003F0001F8003F0001F8003F0001FC007F0000FC007E0000FC007E0000FC007E0000FC00
+7E00007E00FC00007E00FC00007E00FC00007E00FC00003F01F800003F01F800003F01F8
+00003F01F800001F83F000001F83F000001F83F000001F83F000000F83E000000FC7E000
+000FC7E000000FC7E0000007C7C0000007C7C0000007EFC0000007EFC0000003EF800000
+03EF80000003FF80000003FF80000001FF00000001FF00000001FF00000001FF00000000
+FE000027347EB22C>I<7FF00007FF00FFF8000FFF80FFF8000FFF80FFF8000FFF807FF0
+0007FF001F0000007C001F0000007C001F0000007C001F0000007C000F800000F8000F80
+0000F8000F800000F8000F800000F8000F800000F8000F800000F8000F800000F80007C0
+0001F00007C00001F00007C00001F00007C00001F00007C03E01F00007C07F01F00007C0
+7F01F00007C07F01F00003E0FF83E00003E0FF83E00003E0F783E00003E0F783E00003E1
+F7C3E00003E1F7C3E00003E1F7C3E00001E1E3C3C00001E1E3C3C00001F1E3C7C00001F3
+E3E7C00001F3E3E7C00001F3E3E7C00001F3C1E7C00001F3C1E7C00000F3C1E7800000F3
+C1E7800000F7C1F7800000F780F7800000F780F7800000F780F7800000FF80FF8000007F
+80FF0000007F007F0000007F007F0000007F007F0000007F007F0000003E003E00002934
+7FB22C>I<3FFF03FFE07FFF07FFF07FFF87FFF07FFF07FFF03FFF03FFE001F800FE0001
+FC00FE0000FC01FC0000FE01FC00007E01F800007F03F800003F03F000003F87F000001F
+87E000001FCFE000000FCFC000000FFFC0000007FF80000007FF80000003FF00000003FF
+00000001FE00000001FE00000000FC00000000FC00000001FE00000001FE00000003FF00
+000003FF00000007FF80000007FFC000000FCFC000000FCFE000001FC7E000001F87F000
+003F83F000003F03F800007F01F800007E01FC0000FE00FC0000FC00FE0001FC007E0001
+F8007F0003F8003F0003F0003F8003F0001F807FFE00FFFC7FFF01FFFCFFFF01FFFE7FFF
+01FFFC7FFE00FFFC27337EB22C>I<7FFC007FFCFFFE00FFFEFFFE00FFFEFFFE00FFFE7F
+FC007FFC07F0000FC007F0001FC003F0001F8003F8003F8001F8003F8001FC007F0000FC
+007F0000FE007E00007E00FE00007F00FC00003F01FC00003F81F800001F81F800001F83
+F000000FC3F000000FC7F0000007E7E0000007E7E0000003E7C0000003EFC0000001FF80
+000001FF80000001FF00000000FF00000000FE000000007E000000007E000000007E0000
+00007E000000007E000000007E000000007E000000007E000000007E000000007E000000
+007E000000007E000000007E000000007E000000007E000000007E00000007FFE000000F
+FFF000000FFFF000000FFFF0000007FFE00027337EB22C>I<3FFFFFFFC07FFFFFFFE07F
+FFFFFFE07FFFFFFFE07FFFFFFFE07E00001FC07E00003F807E00003F807E00007F007E00
+007E007E0000FE007E0001FC003C0001F800000003F800000007F000000007F00000000F
+E00000001FC00000001FC00000003F800000007F000000007F00000000FE00000001FC00
+000001FC00000003F800000007F000000007F00000000FE00000001FC00000001FC00000
+003F800000007F000000007F00000000FE00000001FC00000001FC00000003F80003C003
+F00007E007F00007E00FE00007E00FC00007E01FC00007E03F800007E03F800007E07F00
+0007E0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE07FFFFFFFC023337CB22C>I<7F
+FFFCFFFFFEFFFFFEFFFFFEFFFFFCFC0000FC0000FC0000FC0000FC0000FC0000FC0000FC
+0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC
+0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC
+0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC
+0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FF
+FFFCFFFFFEFFFFFEFFFFFE7FFFFC17416FB92C>I<7800000000F800000000FC00000000
+FC00000000FE000000007E000000007F000000003F000000003F800000001F800000001F
+C00000000FC00000000FE000000007E000000007E000000007F000000003F000000003F8
+00000001F800000001FC00000000FC00000000FE000000007E000000007F000000003F00
+0000003F800000001F800000001F800000001FC00000000FC00000000FE000000007E000
+000007F000000003F000000003F800000001F800000001FC00000000FC00000000FC0000
+0000FE000000007E000000007F000000003F000000003F800000001F800000001FC00000
+000FC00000000FE000000007E000000007F000000003F000000003F000000003F8000000
+01F800000001FC00000000FC00000000FE000000007E000000007F000000003F00000000
+3F800000001F800000001F800000000F80000000070021417BB92C>I<7FFFFCFFFFFEFF
+FFFEFFFFFE7FFFFE00007E00007E00007E00007E00007E00007E00007E00007E00007E00
+007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00
+007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00
+007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00007E00
+007E00007E00007E00007E00007E00007E00007E00007E00007E00007E7FFFFEFFFFFEFF
+FFFEFFFFFE7FFFFC17417DB92C>I<000E0000003F800000FFE00003FFF8000FFFFE001F
+FFFF007FF1FFC0FFE0FFE0FF803FE0FE000FE07C0007C0300001801B0C78B22C>I<7FFF
+FFFF00FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF807FFFFFFF0021067B7D2C>I<00
+7000F801F803F807F00FE01FC01F803F003E007E007C007C00FC00F800F800F800F800FF
+80FFC0FFE0FFE07FE07FE03FE01FC00F800D1B71B82C>I<01FFF0000007FFFE00001FFF
+FF80001FFFFFE0003FFFFFF0003FC01FF8003FC007F8003FC001FC001F8000FC00060000
+FE000000007E000000007E000000007E000000FFFE00001FFFFE0000FFFFFE0003FFFFFE
+000FFFFFFE001FFF807E003FF8007E007FC0007E007F00007E00FE00007E00FC00007E00
+FC00007E00FC00007E00FC00007E00FE00007E007F0000FE007F8003FE003FE01FFE001F
+FFFFFFFC0FFFFFFFFE07FFFFBFFE01FFFE1FFE003FF007FC27247CA32C>I<7FF0000000
+FFF8000000FFF8000000FFF80000007FF800000001F800000001F800000001F800000001
+F800000001F800000001F800000001F800000001F800000001F800000001F800000001F8
+1FE00001F8FFF80001FBFFFE0001FFFFFF0001FFFFFF8001FFF07FC001FF801FE001FF00
+07F001FE0003F801FC0003F801FC0001FC01F80000FC01F80000FC01F80000FE01F80000
+7E01F800007E01F800007E01F800007E01F800007E01F800007E01F800007E01F800007E
+01F80000FE01FC0000FC01FC0000FC01FC0001F801FE0003F801FF0007F001FF000FF001
+FF801FE001FFE07FC001FFFFFF8001FFFFFF0001FBFFFE0001F8FFF80000F03FC0002733
+7FB22C>I<0003FFE000001FFFF800007FFFFE0001FFFFFE0003FFFFFF0007FE00FF000F
+F000FF001FE000FF001FC0007E003F800018003F000000007F000000007E000000007E00
+000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC0000
+0000FC000000007E000000007E000000007F000000003F00000F003F80001F801FC0001F
+801FE0003F800FF0007F0007FE03FF0003FFFFFE0001FFFFFC00007FFFF800001FFFE000
+0003FF000021247AA32C>I<00000FFE0000001FFF0000001FFF0000001FFF0000000FFF
+000000003F000000003F000000003F000000003F000000003F000000003F000000003F00
+0000003F000000003F000000003F000007F83F00003FFE3F0000FFFFBF0001FFFFFF0003
+FFFFFF0007FC0FFF000FF003FF001FE001FF001FC000FF003F80007F003F00007F007E00
+003F007E00003F00FE00003F00FC00003F00FC00003F00FC00003F00FC00003F00FC0000
+3F00FC00003F00FC00003F00FC00003F00FE00003F007E00007F007E00007F007F0000FF
+003F8000FF003F8001FF001FC003FF000FF007FF0007FC1FFF0003FFFFFFFC01FFFFBFFE
+00FFFF3FFE003FFC3FFE000FF01FFC27337DB22C>I<0003FE0000001FFFC000007FFFF0
+0001FFFFF80003FFFFFC0007FE03FE000FF800FF001FE0003F801FC0003F803F80001FC0
+3F00000FC07F00000FC07E00000FE07E000007E0FC000007E0FFFFFFFFE0FFFFFFFFE0FF
+FFFFFFE0FFFFFFFFE0FFFFFFFFC0FC00000000FE000000007E000000007E000000007F00
+0000003F000003C03F800007E01FC00007E00FF0000FE007F8003FC007FF00FFC001FFFF
+FF8000FFFFFF00003FFFFC00000FFFF0000001FF800023247CA32C>I<00000FF8000000
+3FFE000000FFFF000001FFFF800003FFFF800007FC7F800007F07F80000FE03F00000FC0
+3F00000FC00000000FC00000000FC00000000FC00000000FC00000000FC000007FFFFFFE
+00FFFFFFFF00FFFFFFFF00FFFFFFFF007FFFFFFE00000FC00000000FC00000000FC00000
+000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC0000000
+0FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000F
+C00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC0
+0000000FC000003FFFFFF0007FFFFFF8007FFFFFF8007FFFFFF8003FFFFFF00021337DB2
+2C>I<00000003F80007F80FFC001FFE3FFE007FFFFFFF01FFFFFFFF03FFFFFE7F03FC0F
+F87F07F003F83E0FE001FC1C0FC000FC001FC000FE001F80007E001F80007E001F80007E
+001F80007E001F80007E001F80007E001FC000FE000FC000FC000FE001FC0007F003F800
+03FC0FF00007FFFFF00007FFFFE0000FFFFF80000F9FFE00000F87F800000F800000000F
+800000000F800000000FC000000007E000000007FFFFF00003FFFFFE0007FFFFFF800FFF
+FFFFE01FFFFFFFF03FC0001FF87F000003FC7E000000FC7C0000007CFC0000007EF80000
+003EF80000003EF80000003EF80000003EFC0000007E7E000000FC7F800003FC3FE0000F
+F81FFC007FF00FFFFFFFE003FFFFFF8001FFFFFF00003FFFF8000007FFC00028387EA42C
+>I<7FF000000000FFF800000000FFF800000000FFF8000000007FF80000000001F80000
+000001F80000000001F80000000001F80000000001F80000000001F80000000001F80000
+000001F80000000001F80000000001F80000000001F81FE0000001F87FFC000001F9FFFE
+000001FBFFFF000001FFFFFF000001FFF03F800001FFC01F800001FF801FC00001FF000F
+C00001FE000FC00001FC000FC00001FC000FC00001F8000FC00001F8000FC00001F8000F
+C00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000F
+C00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000F
+C00001F8000FC00001F8000FC00001F8000FC00001F8000FC0007FFFE0FFFF00FFFFF1FF
+FF80FFFFF1FFFF80FFFFF1FFFF807FFFE0FFFF0029337FB22C>I<00070000001FC00000
+1FC000003FE000003FE000003FE000001FC000001FC00000070000000000000000000000
+000000000000000000000000000000000000007FFFC0007FFFE000FFFFE0007FFFE0007F
+FFE0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0007F
+FFFFFCFFFFFFFEFFFFFFFEFFFFFFFE7FFFFFFC1F3479B32C>I<00000E0000003F800000
+3F8000007FC000007FC000007FC000003F8000003F8000000E0000000000000000000000
+00000000000000000000000000000000000001FFFF8003FFFFC003FFFFC003FFFFC001FF
+FFC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000
+0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000
+0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000
+0FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000
+0FC000000FC000000FC000001FC03C001F807E003F80FF003F00FF007F00FF01FE00FFFF
+FC007FFFF8007FFFF0001FFFE00007FF00001A467CB32C>I<7FE0000000FFF0000000FF
+F0000000FFF00000007FF000000001F000000001F000000001F000000001F000000001F0
+00000001F000000001F000000001F000000001F000000001F000000001F01FFFF001F03F
+FFF801F03FFFF801F03FFFF801F01FFFF001F000FE0001F001FC0001F003F80001F007F0
+0001F00FE00001F01FC00001F03F800001F07F000001F0FE000001F1FC000001F3FC0000
+01F7FE000001FFFF000001FFFF000001FF9F800001FF0FC00001FE0FE00001FC07E00001
+F803F00001F001F80001F001FC0001F000FC0001F0007E0001F0003F0001F0003F8001F0
+001F807FFFC0FFFCFFFFE1FFFEFFFFE1FFFEFFFFE1FFFE7FFFC0FFFC27337EB22C>I<7F
+FFE00000FFFFF00000FFFFF00000FFFFF000007FFFF000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F000000003F000000003F0
+00000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000007FFFFFFF80FFFFFFFFC0FFFFFFFFC0FFFFFFFFC07FFFFF
+FF8022337BB22C>I<7F83F007E0007FCFFC1FF800FFDFFE3FFC007FFFFEFFFC007FFFFF
+FFFE0007FE1FFC3E0007FC1FF83F0007F80FF01F0007F00FE01F0007E00FC01F0007E00F
+C01F0007E00FC01F0007C00F801F0007C00F801F0007C00F801F0007C00F801F0007C00F
+801F0007C00F801F0007C00F801F0007C00F801F0007C00F801F0007C00F801F0007C00F
+801F0007C00F801F0007C00F801F0007C00F801F0007C00F801F0007C00F801F0007C00F
+801F0007C00F801F0007C00F801F007FFC3FF87FF07FFC7FF8FFF0FFFE7FFCFFF87FFC7F
+F8FFF07FFC3FF87FF02D2481A32C>I<7FF01FE00000FFF87FFC0000FFF9FFFE0000FFFB
+FFFF00007FFFFFFF000001FFF03F800001FFC01F800001FF801FC00001FF000FC00001FE
+000FC00001FC000FC00001FC000FC00001F8000FC00001F8000FC00001F8000FC00001F8
+000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8
+000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8
+000FC00001F8000FC00001F8000FC00001F8000FC0007FFFE0FFFF00FFFFF1FFFF80FFFF
+F1FFFF80FFFFF1FFFF807FFFE0FFFF0029247FA32C>I<0007FC0000001FFF0000007FFF
+C00001FFFFF00003FFFFF80007FC07FC000FF001FE001FE000FF001F80003F003F80003F
+803F00001F807E00000FC07E00000FC07E00000FC0FC000007E0FC000007E0FC000007E0
+FC000007E0FC000007E0FC000007E0FC000007E0FE00000FE07E00000FC07E00000FC07F
+00001FC03F00001F803F80003F801FC0007F001FE000FF000FF001FE0007FC07FC0003FF
+FFF80001FFFFF000007FFFC000001FFF00000007FC000023247CA32C>I<7FF01FE000FF
+F8FFF800FFFBFFFE00FFFFFFFF007FFFFFFF8001FFF07FC001FF801FE001FF0007F001FE
+0003F801FC0003F801FC0001FC01F80000FC01F80000FC01F80000FE01F800007E01F800
+007E01F800007E01F800007E01F800007E01F800007E01F800007E01F800007E01F80000
+FE01FC0000FC01FC0000FC01FC0001F801FE0003F801FF0007F001FF000FF001FF801FE0
+01FFE07FC001FFFFFF8001FFFFFF0001FBFFFE0001F8FFF80001F83FC00001F800000001
+F800000001F800000001F800000001F800000001F800000001F800000001F800000001F8
+00000001F800000001F800000001F800000001F80000007FFFE00000FFFFF00000FFFFF0
+0000FFFFF000007FFFE0000027367FA32C>I<0003FC078000001FFF0FC000007FFFCFC0
+0001FFFFEFC00003FFFFFFC00007FE07FFC0000FF001FFC0001FE000FFC0001FC0007FC0
+003F80003FC0003F00003FC0007F00001FC0007E00001FC0007E00000FC000FC00000FC0
+00FC00000FC000FC00000FC000FC00000FC000FC00000FC000FC00000FC000FC00000FC0
+00FC00000FC000FE00000FC0007E00001FC0007E00001FC0003F00003FC0003F80003FC0
+001FC0007FC0001FE000FFC0000FF003FFC00007FC0FFFC00003FFFFFFC00001FFFFEFC0
+00007FFF8FC000003FFF0FC0000007F80FC0000000000FC0000000000FC0000000000FC0
+000000000FC0000000000FC0000000000FC0000000000FC0000000000FC0000000000FC0
+000000000FC0000000000FC0000000000FC0000000000FC000000003FFFF00000007FFFF
+80000007FFFF80000007FFFF80000003FFFF0029367DA32C>I<7FFE003FC0FFFF01FFF0
+FFFF07FFF8FFFF1FFFFC7FFF3FFFFC003F7FE1FC003FFF01FC003FFC00F8003FF8007000
+3FF00000003FE00000003FE00000003FC00000003F800000003F800000003F800000003F
+000000003F000000003F000000003F000000003F000000003F000000003F000000003F00
+0000003F000000003F000000003F000000003F000000003F000000003F000000003F0000
+007FFFFFE000FFFFFFF000FFFFFFF000FFFFFFF0007FFFFFE00026247EA32C>I<007FF8
+7003FFFFF80FFFFFF81FFFFFF83FFFFFF87FC00FF87E0003F8FC0001F8F80001F8F80001
+F8F80001F8FC0000F07F0000007FF000003FFFC0001FFFFE000FFFFF8003FFFFE0007FFF
+F80001FFFC000007FC000000FE7800007FFC00003FFC00001FFE00001FFE00001FFF0000
+3FFF80003EFFC000FEFFF007FCFFFFFFFCFFFFFFF8FFFFFFE0F8FFFF80701FFC0020247A
+A32C>I<001E000000003F000000003F000000003F000000003F000000003F000000003F
+000000003F000000003F000000003F0000007FFFFFFF00FFFFFFFF80FFFFFFFF80FFFFFF
+FF807FFFFFFF00003F000000003F000000003F000000003F000000003F000000003F0000
+00003F000000003F000000003F000000003F000000003F000000003F000000003F000000
+003F000000003F000000003F000000003F000000003F0003C0003F0007E0003F0007E000
+3F0007E0003F0007E0003F0007E0003F800FE0001F801FC0001FE07FC0000FFFFF80000F
+FFFF000003FFFE000001FFF80000003FE000232E7EAD2C>I<7FF003FF8000FFF807FFC0
+00FFF807FFC000FFF807FFC0007FF803FFC00001F8000FC00001F8000FC00001F8000FC0
+0001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC0
+0001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC0
+0001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC00001F8000FC0
+0001F8001FC00001F8001FC00001F8003FC00001FC007FC00000FE03FFC00000FFFFFFFF
+00007FFFFFFF80003FFFFFFF80001FFFCFFF800003FE07FF0029247FA32C>I<7FFF01FF
+FCFFFF01FFFEFFFF83FFFEFFFF01FFFE7FFF01FFFC03E0000F8003E0000F8003F0001F80
+01F0001F0001F0001F0001F8003F0000F8003E0000F8003E0000FC007E00007C007C0000
+7C007C00007E00FC00003E00F800003E00F800003F01F800001F01F000001F01F000001F
+83F000000F83E000000F83E000000FC7E0000007C7C0000007C7C0000007EFC0000003EF
+80000003EF80000003FF80000001FF00000001FF00000000FE000000007C000027247EA3
+2C>I<7FFF007FFF007FFF80FFFF00FFFF80FFFF807FFF80FFFF007FFF007FFF0007C000
+01F00007C00001F00007C00001F00007C00001F00007C00001F00007C00001F00003E000
+03E00003E00003E00003E00003E00003E03E03E00003E07F03E00003E07F03E00001F07F
+07C00001F0FF87C00001F0FF87C00001F0F787C00001F0F787C00001F1F7C7C00000F1F7
+C7800000F9E3CF800000F9E3CF800000FBE3EF800000FBE3EF800000FBE3EF8000007BC1
+EF0000007FC1FF0000007FC1FF0000007F80FF0000007F80FF0000003F80FE0000001F00
+7C000029247FA32C>I<3FFF03FFF07FFF87FFF87FFF87FFF87FFF87FFF83FFF03FFF000
+FC007E0000FC00FC00007E01F800003F01F000001F83F000001F87E000000FCFC0000007
+EF80000003FF80000001FF00000001FE00000000FC000000007C00000000FE00000001FE
+00000001FF00000003EF80000007CFC000000FC7C000000F83E000001F01F000003F01F8
+00007E00F800007C007C0000F8007E0001F8003F007FFF01FFFC7FFF83FFFCFFFF83FFFE
+7FFF83FFFC7FFF01FFFC27247EA32C>I<7FFF01FFFCFFFF81FFFEFFFF83FFFEFFFF81FF
+FE7FFF01FFFC03E0000F8001F0000F8001F0001F8001F8001F0000F8001F0000F8003F00
+00FC003E00007C003E00007E007E00003E007C00003E007C00003F00FC00001F00F80000
+1F00F800000F81F800000F81F000000F81F0000007C1F0000007C3E0000007C3E0000003
+E3E0000003E7C0000001E7C0000001F7C0000001F780000000FF80000000FF80000000FF
+000000007F000000007F000000003E000000003E000000007E000000007C000000007C00
+000000FC00000000F800000000F800000C01F800003F01F000007F83F000007F87E00000
+7E0FE000007E1FC000007FFF8000003FFF0000001FFE0000000FFC00000007E000000027
+367EA32C>I<3FFFFFFFE07FFFFFFFF07FFFFFFFF07FFFFFFFF07FFFFFFFF07E00001FE0
+7E00003FC07E00007F807E0000FF007E0001FE003C0003FC00000007F80000000FF00000
+001FE00000003FC00000007F80000000FF00000001FC00000003F80000000FF00000001F
+E00000003FC00000007F80000000FF00000001FE0001E003FC0003F007F80003F00FF000
+03F01FE00003F03FC00003F07F800003F0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFF
+F07FFFFFFFE024247DA32C>I<000000FF00000007FF8000001FFF8000007FFF800000FF
+FF000001FFC0000001FE00000003F800000003F000000003F000000003F000000003F000
+000003F000000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000007F00000001FE0000000FFE000007FFFC00000FFFF800000FFFE000000FFFF
+8000007FFFC0000000FFE00000001FE000000007F000000003F000000003F000000003F0
+00000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F000000003F000000003F800000001FE00000001FFC0000000FFFF0000007FFF8000
+001FFF80000007FF80000000FF0021417BB92C>I<78FCFCFCFCFCFCFCFCFCFCFCFCFCFC
+FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
+FCFCFCFCFCFCFCFCFCFCFCFCFC7806416DB92C>I<7FC0000000FFF8000000FFFE000000
+FFFF8000007FFFC0000000FFE00000001FE000000007F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F000000003F000000003F0
+00000003F000000003F000000003F800000001FE00000001FFC0000000FFFF0000007FFF
+8000001FFF8000007FFF800000FFFF000001FFC0000001FE00000003F800000003F00000
+0003F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000007F00000001FE0000000FFE000007FFFC0
+0000FFFF800000FFFE000000FFF80000007FC000000021417BB92C>I<00F8007003FE00
+F80FFF01F81FFF87F83FFFCFF07F9FFFE0FF0FFFC0FC07FF80F803FE007000F8001D0A79
+B22C>I E /Fi 56 125 df<0000000007FF80000000003FFFE000000000FE00F8000000
+01F0003E00000007E0000E0000000FC0001F0000000F80007F0000001F8000FF0000003F
+0000FF0000003F0000FF0000003F0000FE0000007E0000FE0000007E0000780000007E00
+0000000000FE000000000000FC000000000000FC000000000000FC000000000001FC0000
+00000001FC000000000001F8000000000001F8000000000001F8000000000001F8000000
+000003F80000000003FFFFFFFFF00003FFFFFFFFF00003FFFFFFFFE0000003F00007E000
+0007F0000FE0000007E0000FC0000007E0000FC0000007E0000FC0000007E0001FC00000
+0FE0001F8000000FC0001F8000000FC0001F8000000FC0003F8000000FC0003F0000001F
+C0003F0000001F80003F0000001F80007F0000001F80007E0000001F80007E0000003F80
+007E0000003F0000FE0000003F0000FC0000003F0000FC0000003F0000FC0000007F0001
+FC0000007E0001F81C00007E0001F81C00007E0001F81C00007E0003F81C0000FE0003F0
+3C0000FC0003F0380000FC0003F0380000FC0003F0780000FC0003F0700001FC0003F070
+0001F80001F0F00001F80001F0E00001F80000F1C00001F800007F800003F000001F0000
+03F0000000000003F0000000000003F0000000000003E0000000000007E0000000000007
+E0000000001E07C0000000007F07C0000000007F0FC000000000FF0F8000000000FF0F80
+00000000FF1F0000000000FE1F0000000000F81E0000000000703C000000000078780000
+0000001FF0000000000007C00000000000385383BF33>12 D<000000FC00000000000007
+FF0000000000001F03800000F000003E01C00001F800007C00E00003F80000F800E00003
+F80001F000700003F80003E000700003F00007E000700001F0000FC000700000F0000F80
+01F00000E0001F8007F00001E0001F800FF00001C0003F000FF00003C0003F000FF00007
+80007F000FE0000780007E000FE0000F00007E000780001E00007E000000003C0000FE00
+000000780000FC00000000F00000FC00000003E00000FC00000007C00000FC1F00001FC0
+0000FCFFC0003FE00000FBE1C000F8F00000FFC0E001F0F00000FF80E007C0780000FF00
+E00F807800007E00E01E00380000FC01E03C003C0001FC01C038001C0001FE01C078001C
+0003FF038070001C0007FF870070001C0007E3FE00F0001C000FE0F800E3801C000FC000
+00EFC01C001FC000007FE01C001FC000007FE01C003F8000007FC01C003F8000003FC01C
+003F8000000F003C007F800000000038007F000000000038007F000000000038007F0000
+00000078007F00000000007000FE0000000000F000FE0000000000E0007E0000000000E0
+007E0000000001C0007E0000000003C0007E000000000380007F000000000780003F0000
+00000F00003F000000001E00001F800000001C00001F800000007800000FC0000000F000
+0007E0000001E0000003F0000007C0000001F800001F000000007E00007C000000001FC0
+07F00000000007FFFF8000000000007FF8000000003D4375C046>38
+D<01E007F80FF80FFC1FFC1FFC1FFC1FFC0FFC03D800180018003800300070006000E000
+C001C00380030007000E001C0038007000E000C0000E1C6DBE1C>I<7FFFFE7FFFFE7FFF
+FEFFFFFEFFFFFE1705799521>45 D<0F003FC07FC07FC0FFC0FFC0FFC0FF807F003C000A
+0A77891C>I<000000000000380000000000007C0000000000007C000000000000F80000
+00000001F8000000000001F0000000000003E0000000000003E0000000000007C0000000
+000007C000000000000F8000000000001F8000000000001F0000000000003E0000000000
+003E0000000000007C0000000000007C000000000000F8000000000001F8000000000001
+F0000000000003E0000000000003E0000000000007C0000000000007C000000000000F80
+00000000001F8000000000001F0000000000003E0000000000003E0000000000007C0000
+000000007C000000000000F8000000000001F8000000000001F0000000000003E0000000
+000003E0000000000007C0000000000007C000000000000F8000000000001F8000000000
+001F0000000000003E0000000000003E0000000000007C0000000000007C000000000000
+F8000000000001F8000000000001F0000000000003E0000000000003E0000000000007C0
+000000000007C000000000000F8000000000001F8000000000001F0000000000003E0000
+000000003E0000000000007C0000000000007C000000000000F8000000000001F8000000
+000001F0000000000003E0000000000003E0000000000007C0000000000007C000000000
+000F8000000000001F8000000000001F0000000000003E0000000000003E000000000000
+7C0000000000007C000000000000F8000000000001F8000000000001F0000000000003E0
+000000000003E0000000000007C0000000000007C000000000000F8000000000001F8000
+000000001F0000000000003E0000000000003E0000000000007C0000000000007C000000
+000000F8000000000000F8000000000000F0000000000000E0000000000000365B7FC32E
+>I<00000003000000070000000F0000001F0000001E0000003E0000007E000001FE0000
+03FC000007FC00001FFC0001FFFC000FFBF8001FC3F8000E07F8000007F8000007F00000
+07F000000FF000000FF000000FE000000FE000001FE000001FE000001FC000001FC00000
+3FC000003FC000003F8000003F8000007F8000007F8000007F0000007F000000FF000000
+FF000000FE000000FE000001FE000001FE000001FC000001FC000003FC000003FC000003
+F8000003F8000007F8000007F8000007F0000007F000000FF000000FF000000FE000000F
+E000001FE000001FE000001FC000007FE000FFFFFFF0FFFFFFF0FFFFFFE0203D77BC2E>
+49 D<000000FE0000000003FFC00000000F01F00000003C00F800000078007C000000F0
+003E000001E0003F000003C0001F00000380001F80000700001F80000F00001F80000E0C
+001F80001E0C001FC0001C0E001FC0003C06001FC0003806001FC0007806001FC0007006
+001FC000700E003FC000F00C003F8000E00C003F8000E01C003F8000E018007F8001E018
+007F0001C038007F0001C07000FE0001C06001FE0001C0E001FC0000E3C003F80000FF00
+07F000003C000FE0000000001FC0000000001F80000000007F0000000000FC0000000001
+F80000000003F0000000000FC0000000001F00000000007E0000000000F80000000003E0
+0000000007C0000000001F00000000003E00000000007C0000180000F000003C0001E000
+00380003C00000380003C0000078000780000078000F000000F0000E000000F0001E0000
+01E0003FE00003E0003FFF0007C0007C3FF01FC000780FFFFF80007003FFFF0000F001FF
+FE0000E0007FFC0000E0003FF80000E00007C000002A3F79BC2E>I<001E00003F80007F
+8000FFC001FFC001FFC001FF8000FF0000FE00003C000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000F00003FC0007FC0007FC000FFC000FFC000FFC000FF80007F00003C00
+00122777A61C>58 D<00000000001C000000000000003C000000000000007C0000000000
+00007C00000000000000FC00000000000000FC00000000000001FC00000000000003FC00
+000000000003FC00000000000007FC00000000000007FC0000000000000FFE0000000000
+000FFE0000000000001DFE0000000000001DFE00000000000039FE00000000000079FE00
+000000000071FE000000000000E1FE000000000000E1FE000000000001C1FE0000000000
+01C1FE00000000000381FE00000000000781FE00000000000701FE00000000000E01FE00
+000000000E01FE00000000001C01FF00000000001C01FF00000000003800FF0000000000
+3800FF00000000007000FF0000000000F000FF0000000000E000FF0000000001C000FF00
+00000001C000FF00000000038000FF00000000038000FF00000000070000FF000000000F
+0000FF000000000E0000FF000000001C0000FF000000001FFFFFFF000000003FFFFFFF80
+0000003FFFFFFF800000007000007F800000007000007F80000000E000007F80000001E0
+00007F80000001C000007F800000038000007F800000038000007F800000070000007F80
+0000070000007F8000000E0000007F8000001E0000007F8000001C0000007F8000003C00
+00007F800000780000007F800000F80000007FC00001FC0000007FC00007FE000001FFC0
+00FFFFE0007FFFFF80FFFFE0007FFFFF80FFFFC0007FFFFF8039417BC044>65
+D<00000000FF8001C00000000FFFE001C00000003FFFF80380000000FF807E0780000003
+FC001F0F8000000FF000071F8000001FC00007BF0000007F800003FF000000FF000001FF
+000001FE000001FF000003F8000000FE000007F0000000FE00000FF0000000FE00001FE0
+0000007E00003FC00000007C00007F800000007C0000FF800000007C0000FF000000007C
+0001FE00000000780003FE00000000780003FC00000000780007FC00000000780007F800
+00000070000FF80000000070000FF80000000070001FF00000000070001FF00000000000
+003FE00000000000003FE00000000000003FE00000000000007FE00000000000007FC000
+00000000007FC00000000000007FC0000000000000FFC0000000000000FF800000000000
+00FF80000000000000FF80000000000000FF80000000000000FF00000000000000FF0000
+0000000000FF000000000F0000FF000000000F0000FF000000000E0000FF000000000E00
+00FF000000001E0000FF000000001C0000FF000000003C0000FF00000000380000FF0000
+00007800007F000000007000007F80000000F000007F80000001E000003F80000001C000
+003FC0000003C000001FC00000078000001FE000000F0000000FE000001E00000007F000
+003C00000003F80000F800000001FC0001F000000000FE0007C0000000007FC03F800000
+00001FFFFE000000000007FFF0000000000000FF80000000003A4272BF41>67
+D<0001FFFFFFFFC0000001FFFFFFFFF8000001FFFFFFFFFE00000003FE0003FF00000003
+FE00007F80000003FC00001FC0000003FC00000FE0000003FC000007F0000007FC000007
+F0000007F8000003F8000007F8000001FC000007F8000001FC00000FF8000001FC00000F
+F0000000FE00000FF0000000FE00000FF0000000FE00001FF0000000FE00001FE0000000
+FF00001FE0000000FF00001FE0000000FF00003FE0000000FF00003FC0000000FF00003F
+C0000000FF00003FC0000000FF00007FC0000001FF00007F80000001FF00007F80000001
+FF00007F80000001FE0000FF80000001FE0000FF00000003FE0000FF00000003FE0000FF
+00000003FE0001FF00000003FC0001FE00000007FC0001FE00000007FC0001FE00000007
+F80003FE00000007F80003FC0000000FF80003FC0000000FF00003FC0000000FF00007FC
+0000001FE00007F80000001FE00007F80000003FC00007F80000003FC0000FF80000007F
+80000FF00000007F00000FF0000000FF00000FF0000000FE00001FF0000001FC00001FE0
+000003F800001FE0000007F000001FE0000007F000003FE000000FE000003FC000003FC0
+00003FC000007F0000007FC00000FE0000007FC00003FC0000007F80000FF0000000FF80
+007FE00000FFFFFFFFFF800000FFFFFFFFFC000000FFFFFFFFE0000000403E7BBD45>I<
+0001FFFFFFFFFFF80001FFFFFFFFFFF80001FFFFFFFFFFF8000003FE00001FF8000003FE
+000007F8000003FC000003F8000003FC000001F8000003FC000000F0000007FC000000F0
+000007F8000000F0000007F8000000F0000007F8000000F000000FF8000000F000000FF0
+000000F000000FF0000000E000000FF0000000E000001FF0000000E000001FE0003800E0
+00001FE0003800E000001FE0007801E000003FE0007001C000003FC00070000000003FC0
+0070000000003FC000F0000000007FC000E0000000007F8001E0000000007F8003E00000
+00007F800FE000000000FFFFFFC000000000FFFFFFC000000000FFFFFFC000000000FF00
+1FC000000001FF00078000000001FE00078000000001FE00078000000001FE0007800000
+0003FE00070000000003FC00070000000003FC00070003800003FC000F0007800007FC00
+0E0007000007F8000E0007000007F80000000F000007F80000000E00000FF80000001E00
+000FF00000001C00000FF00000003C00000FF00000003C00001FF00000007800001FE000
+00007800001FE0000000F000001FE0000000F000003FE0000001F000003FC0000003E000
+003FC0000007E000007FC000000FE000007FC000001FC000007F8000007FC00000FF8000
+07FF8000FFFFFFFFFFFF8000FFFFFFFFFFFF8000FFFFFFFFFFFF00003D3E7BBD3E>I<00
+01FFFFFFFFFFF00001FFFFFFFFFFF00001FFFFFFFFFFF0000003FE00003FF0000003FE00
+000FF0000003FC000003F0000003FC000003F0000003FC000001E0000007FC000001E000
+0007F8000001E0000007F8000001E0000007F8000001E000000FF8000001E000000FF000
+0001E000000FF0000001C000000FF0000001C000001FF0000001C000001FE0000001C000
+001FE0007001C000001FE000F003C000003FE000E0038000003FC000E0000000003FC000
+E0000000003FC001E0000000007FC001C0000000007F8003C0000000007F8003C0000000
+007F8007C000000000FF801F8000000000FFFFFF8000000000FFFFFF8000000000FFFFFF
+8000000001FF003F0000000001FE001F0000000001FE000F0000000001FE000F00000000
+03FE000E0000000003FC000E0000000003FC000E0000000003FC001E0000000007FC001C
+0000000007F8001C0000000007F8001C0000000007F80000000000000FF8000000000000
+0FF00000000000000FF00000000000000FF00000000000001FF00000000000001FE00000
+000000001FE00000000000001FE00000000000003FE00000000000003FC0000000000000
+3FC00000000000007FC00000000000007FC00000000000007F80000000000000FFC00000
+000000FFFFFFE000000000FFFFFFE000000000FFFFFFE0000000003C3E7BBD3B>I<0000
+0000FF8000E000000007FFF000E00000003FFFFC01C0000000FFC03E03C0000003FC000F
+07C000000FF000078FC000001FE00003DF8000007F800001FF800000FF000000FF800001
+FE000000FF800003FC0000007F000007F80000007F00000FF00000007F00001FE0000000
+3F00003FC00000003E00007F800000003E0000FF800000003E0000FF000000003E0001FE
+000000003C0003FE000000003C0003FC000000003C0007FC000000003C0007F800000000
+38000FF80000000038000FF80000000038001FF00000000038001FF00000000000003FE0
+0000000000003FE00000000000003FE00000000000007FE00000000000007FC000000000
+00007FC00000000000007FC0000000000000FFC0000000000000FF80000000000000FF80
+000000000000FF80000000000000FF800001FFFFFE00FF000001FFFFFE00FF000001FFFF
+FE00FF00000000FF8000FF00000000FF8000FF00000000FF0000FF00000000FF0000FF00
+000001FF0000FF00000001FF0000FF00000001FE0000FF00000001FE0000FF00000003FE
+00007F00000003FE00007F80000003FC00007F80000003FC00003F80000007FC00003FC0
+000007FC00001FC0000007F800001FE000000FF800000FF000001FF8000007F000003FF8
+000003F800007BF0000001FE0000F1F0000000FF0003E0F00000003FE01F80F00000001F
+FFFF006000000007FFF80000000000007FC0000000003B4273BF46>I<0001FFFFFF01FF
+FFFF0003FFFFFF03FFFFFF0003FFFFFF03FFFFFF000003FF000003FF00000003FE000003
+FE00000003FC000003FC00000003FC000003FC00000003FC000007FC00000007FC000007
+FC00000007F8000007F800000007F8000007F800000007F800000FF80000000FF800000F
+F80000000FF000000FF00000000FF000000FF00000000FF000001FF00000001FF000001F
+F00000001FE000001FE00000001FE000001FE00000001FE000003FE00000003FE000003F
+E00000003FC000003FC00000003FC000003FC00000003FC000007FC00000007FC000007F
+C00000007F8000007F800000007F8000007F800000007F800000FF80000000FFFFFFFFFF
+80000000FFFFFFFFFF00000000FFFFFFFFFF00000000FF000001FF00000001FF000001FF
+00000001FE000001FE00000001FE000001FE00000001FE000003FE00000003FE000003FE
+00000003FC000003FC00000003FC000003FC00000003FC000007FC00000007FC000007FC
+00000007F8000007F800000007F8000007F800000007F800000FF80000000FF800000FF8
+0000000FF000000FF00000000FF000000FF00000000FF000001FF00000001FF000001FF0
+0000001FE000001FE00000001FE000001FE00000001FE000003FE00000003FE000003FE0
+0000003FC000003FC00000003FC000003FC00000007FC000007FC00000007FC000007FC0
+0000007F8000007F80000000FFC00000FFC00000FFFFFF80FFFFFF8000FFFFFF80FFFFFF
+8000FFFFFF80FFFFFF8000483E7BBD44>I<0001FFFFFF0003FFFFFF0003FFFFFF000003
+FF00000003FE00000003FC00000003FC00000003FC00000007FC00000007F800000007F8
+00000007F80000000FF80000000FF00000000FF00000000FF00000001FF00000001FE000
+00001FE00000001FE00000003FE00000003FC00000003FC00000003FC00000007FC00000
+007F800000007F800000007F80000000FF80000000FF00000000FF00000000FF00000001
+FF00000001FE00000001FE00000001FE00000003FE00000003FC00000003FC00000003FC
+00000007FC00000007F800000007F800000007F80000000FF80000000FF00000000FF000
+00000FF00000001FF00000001FE00000001FE00000001FE00000003FE00000003FC00000
+003FC00000007FC00000007FC00000007F80000000FFC00000FFFFFF8000FFFFFF8000FF
+FFFF8000283E7BBD23>I<0001FFFFFFC0000001FFFFFFC0000001FFFFFF8000000003FF
+000000000003FE000000000003FC000000000003FC000000000003FC000000000007FC00
+0000000007F8000000000007F8000000000007F800000000000FF800000000000FF00000
+0000000FF000000000000FF000000000001FF000000000001FE000000000001FE0000000
+00001FE000000000003FE000000000003FC000000000003FC000000000003FC000000000
+007FC000000000007F8000000000007F8000000000007F800000000000FF800000000000
+FF000000000000FF000000000000FF000000000001FF000000000001FE000000000001FE
+000000000001FE000000000003FE000000000003FC000000000003FC000000C00003FC00
+0001E00007FC000001C00007F8000001C00007F8000003C00007F800000380000FF80000
+0380000FF000000780000FF000000700000FF000000F00001FF000000F00001FE000001E
+00001FE000001E00001FE000003E00003FE000007C00003FC00000FC00003FC00001FC00
+007FC00003F800007FC00007F800007F80001FF80000FF8000FFF000FFFFFFFFFFF000FF
+FFFFFFFFF000FFFFFFFFFFE000333E7BBD39>76 D<0001FFFF0000000007FFFC0003FFFF
+000000000FFFFC0003FFFF000000001FFFFC000003FF000000001FFC00000003FF000000
+003FF800000003BF800000003FF000000003BF8000000077F000000003BF80000000EFF0
+00000007BF80000000EFF0000000073F80000001CFE0000000073F80000001CFE0000000
+073F800000039FE00000000F3F800000071FE00000000E3F800000071FC00000000E1FC0
+00000E1FC00000000E1FC000000E3FC00000001E1FC000001C3FC00000001C1FC0000038
+3F800000001C1FC00000383F800000001C1FC00000707F800000003C1FC00000707F8000
+0000381FC00000E07F00000000381FC00001C07F00000000381FC00001C0FF0000000078
+0FE0000380FF00000000700FE0000380FE00000000700FE0000700FE00000000700FE000
+0E01FE00000000F00FE0000E01FE00000000E00FE0001C01FC00000000E00FE0001C01FC
+00000000E00FE0003803FC00000001E00FE0007003FC00000001C007F0007003F8000000
+01C007F000E003F800000001C007F000E007F800000003C007F001C007F8000000038007
+F0038007F0000000038007F0038007F0000000038007F007000FF0000000078007F00700
+0FF0000000070007F00E000FE0000000070007F01C000FE0000000070003F81C001FE000
+00000F0003F838001FE00000000E0003F870001FC00000000E0003F870001FC00000000E
+0003F8E0003FC00000001E0003F8E0003FC00000001C0003F9C0003F800000001C0003FB
+80003F800000001C0003FB80007F800000003C0001FF00007F80000000380001FF00007F
+00000000380001FE00007F00000000780001FC0000FF00000000F80001FC0000FF000000
+01FC0001F80000FE00000007FE0001F80001FF000000FFFFF001F001FFFFFE0000FFFFF0
+01E001FFFFFE0000FFFFF000E001FFFFFE0000563E7BBD52>I<0001FFFE00000FFFFF00
+03FFFF00001FFFFF0003FFFF00001FFFFF000001FF800000FFC0000003FF8000003F0000
+0003FF8000003E00000003FFC000001C00000003FFC000003C00000007BFC000003C0000
+00073FE0000038000000071FE0000038000000071FE00000780000000F1FF00000780000
+000E0FF00000700000000E0FF80000700000000E0FF80000F00000001E07F80000F00000
+001C07FC0000E00000001C07FC0000E00000001C03FC0001E00000003C03FE0001E00000
+003801FE0001C00000003801FE0001C00000003801FF0003C00000007800FF0003C00000
+007000FF8003800000007000FF80038000000070007F800780000000F0007FC007800000
+00E0003FC00700000000E0003FC00700000000E0003FE00F00000001E0001FE00F000000
+01C0001FF00E00000001C0001FF00E00000001C0000FF01E00000003C0000FF81E000000
+0380000FF81C00000003800007F81C00000003800007FC3C00000007800003FC3C000000
+07000003FC3800000007000003FE3800000007000001FE780000000F000001FF78000000
+0E000001FF700000000E000000FF700000000E000000FFF00000001E000000FFF0000000
+1C0000007FE00000001C0000007FE00000001C0000003FE00000003C0000003FE0000000
+380000003FC0000000380000001FC0000000780000001FC0000000F80000001FC0000001
+FC0000000F80000007FE0000000F800000FFFFF0000007800000FFFFF0000007800000FF
+FFF0000007000000483E7BBD44>I<00000000FFC0000000000007FFF800000000003F80
+FE0000000000FC003F0000000003F0000F8000000007E00007C00000001F800007E00000
+003F000003F00000007E000001F8000000FC000001FC000001F8000000FC000003F00000
+00FE000007F0000000FE00000FE0000000FE00001FC00000007F00003FC00000007F0000
+3F800000007F00007F000000007F0000FF000000007F8000FE000000007F8001FE000000
+007F8003FC000000007F8003FC000000007F8007FC000000007F8007F8000000007F800F
+F800000000FF800FF800000000FF800FF000000000FF801FF000000000FF801FF0000000
+00FF003FE000000001FF003FE000000001FF003FE000000001FF003FE000000001FF007F
+C000000003FE007FC000000003FE007FC000000003FE007FC000000007FC007FC0000000
+07FC007F8000000007FC007F800000000FF800FF800000000FF800FF800000000FF000FF
+800000001FF000FF800000001FE0007F800000003FE0007F800000003FC0007F80000000
+7F80007F800000007F80007F80000000FF00007F80000000FE00003F80000001FE00003F
+80000003FC00003FC0000003F800001FC0000007F000001FC000000FE000000FE000001F
+C000000FE000003F80000007F000007F00000003F00000FC00000001F80001F800000000
+FC0007E0000000007F001F80000000001FC07E000000000007FFF8000000000000FF8000
+000000394273BF46>I<0001FFFFFFFF80000001FFFFFFFFF0000001FFFFFFFFFC000000
+03FE0003FE00000003FE0000FF00000003FC00007F80000003FC00003FC0000007FC0000
+1FC0000007FC00001FE0000007F800001FE0000007F800001FE000000FF800001FF00000
+0FF800001FF000000FF000001FF000000FF000001FF000001FF000001FF000001FF00000
+3FE000001FE000003FE000001FE000003FE000003FE000003FC000003FE000007FC00000
+3FC000007F8000003FC000007F8000007FC00000FF0000007FC00000FE0000007F800001
+FC0000007F800003F8000000FF800007F0000000FF80000FE0000000FF00003FC0000000
+FF0001FF00000001FFFFFFFC00000001FFFFFFE000000001FE00000000000001FE000000
+00000003FE00000000000003FE00000000000003FC00000000000003FC00000000000007
+FC00000000000007FC00000000000007F800000000000007F80000000000000FF8000000
+0000000FF80000000000000FF00000000000000FF00000000000001FF00000000000001F
+F00000000000001FE00000000000001FE00000000000003FE00000000000003FE0000000
+0000003FC00000000000003FC00000000000007FC00000000000007FC00000000000007F
+80000000000000FFC00000000000FFFFFF8000000000FFFFFF8000000000FFFFFF800000
+00003C3E7BBD3E>I<0001FFFFFFFC00000001FFFFFFFF80000001FFFFFFFFF000000003
+FE000FF800000003FE0003FE00000003FC0000FF00000003FC00007F00000003FC00007F
+80000007FC00003FC0000007F800003FC0000007F800003FC0000007F800003FE000000F
+F800003FE000000FF000003FE000000FF000003FE000000FF000003FE000001FF000007F
+C000001FE000007FC000001FE000007FC000001FE00000FF8000003FE00000FF8000003F
+C00000FF0000003FC00001FE0000003FC00001FC0000007FC00003F80000007F800007F0
+0000007F80000FE00000007F80003F80000000FF8000FE00000000FF0007F800000000FF
+FFFFE000000000FFFFFF8000000001FF000FE000000001FE0007F000000001FE0003F800
+000001FE0001FC00000003FE0001FE00000003FC0000FE00000003FC0000FF00000003FC
+0000FF00000007FC0000FF00000007F80000FF00000007F80000FF00000007F80001FF00
+00000FF80001FF0000000FF00001FF0000000FF00001FE0000000FF00003FE0000001FF0
+0003FE0000001FE00003FE0000001FE00003FE0000001FE00003FE0000003FE00007FE00
+40003FC00007FE00E0003FC00007FC00E0007FC00007FC01E0007FC00007FC01C0007F80
+0003FC03C000FFC00003FC0380FFFFFF8001FC0780FFFFFF8001FE0F00FFFFFF80007E1E
+0000000000003FFC00000000000007F0003B407BBD42>82 D<0000000FF001C00000007F
+FE01C0000001FFFF0380000007F80FC78000000FC003EF8000001F8001FF8000003F0000
+FF0000007E00007F000000FC00007F000001F800007F000003F000003E000003F000003E
+000007E000003E000007E000003E00000FE000003C00000FC000003C00000FC000003C00
+000FC000003C00001FC000003800001FC000003800001FC000003800001FE00000380000
+1FE000000000001FF000000000001FF000000000001FFC00000000000FFF00000000000F
+FFF0000000000FFFFE0000000007FFFFC000000003FFFFF000000001FFFFFC00000000FF
+FFFE000000003FFFFE000000000FFFFF0000000001FFFF80000000001FFF800000000003
+FF800000000000FFC000000000007FC000000000003FC000000000003FC000000000001F
+C000000000001FC000070000001FC0000F0000001FC0000F0000001F80000E0000001F80
+000E0000001F80001E0000003F80001E0000003F00001E0000003F00001E0000003E0000
+3E0000007E00003E0000007C00003F000000FC00003F000001F800007F800001F000007F
+800003E000007FC00007C000007DE0001F800000F8F8003F000000F87F00FE000000F03F
+FFF8000000E00FFFE0000000C000FF0000000032427ABF33>I<01FFFFFFFFFFFF01FFFF
+FFFFFFFF03FFFFFFFFFFFF03FE001FF001FF03F8001FE0007F07E0001FE0003E07C0003F
+E0001E0780003FE0001E0F00003FC0001E0F00003FC0001E1E00007FC0001E1E00007FC0
+001E1C00007F80001C3C00007F80001C380000FF80001C380000FF80001C780000FF0000
+1C700000FF00001C700001FF00003CF00001FF000038E00001FE000038000001FE000000
+000003FE000000000003FE000000000003FC000000000003FC000000000007FC00000000
+0007FC000000000007F8000000000007F800000000000FF800000000000FF80000000000
+0FF000000000000FF000000000001FF000000000001FF000000000001FE000000000001F
+E000000000003FE000000000003FE000000000003FC000000000003FC000000000007FC0
+00000000007FC000000000007F8000000000007F800000000000FF800000000000FF8000
+00000000FF000000000000FF000000000001FF000000000001FF000000000001FE000000
+000001FE000000000003FE000000000003FE000000000003FC00000000000FFE00000000
+3FFFFFFF8000007FFFFFFF8000007FFFFFFF800000383D71BC41>I<1FFFFFF000FFFFF0
+3FFFFFF001FFFFF03FFFFFF001FFFFF0003FF000000FFC00003FE0000003F000003FC000
+0003E000003FC0000001C000007FC0000003C000007FC0000003C000007F800000038000
+007F80000003800000FF80000007800000FF80000007000000FF00000007000000FF0000
+0007000001FF0000000F000001FF0000000E000001FE0000000E000001FE0000000E0000
+03FE0000001E000003FE0000001C000003FC0000001C000003FC0000001C000007FC0000
+003C000007FC00000038000007F800000038000007F80000003800000FF8000000780000
+0FF80000007000000FF00000007000000FF00000007000001FF0000000F000001FF00000
+00E000001FE0000000E000001FE0000000E000003FE0000001E000003FE0000001E00000
+3FC0000001C000003FC0000001C000007FC0000003C000007FC0000003C000007F800000
+038000007F800000038000007F800000078000007F80000007000000FF00000007000000
+FF0000000F000000FF0000000E000000FF0000001E0000007F0000001C0000007F000000
+3C0000007F000000780000007F000000F00000007F000000E00000003F800001E0000000
+3F800003C00000001F800007800000000FC0001F000000000FE0003E0000000007F000F8
+0000000003FC07F00000000000FFFFC000000000003FFF00000000000007F80000000000
+3C406FBD44>I<7FFFFE01FFFFFC00FFFFE0FFFFFE01FFFFFC00FFFFE0FFFFFE01FFFFFC
+00FFFFE003FF800007FF00000FFC0001FF000007FC000007F00001FE000007FC000003E0
+0001FE000003FC000003C00001FE000003FC000003C00001FE000003FC000003800001FE
+000003FC000007000001FE000003FC000007000001FE000007FC00000E000001FE000007
+FC00000E000001FE00000FFC00001C000001FE00000FFC00003C000001FE00001FFC0000
+38000001FE00001FFC000070000001FE00003BFC000070000001FE00003BFC0000E00000
+01FE000073FC0000E0000001FE000073FC0001C0000001FF0000E3FC0001C0000001FF00
+01E3FC000380000000FF0001C3FC000380000000FF0003C3FC000700000000FF000383FC
+000700000000FF000703FC000E00000000FF000703FC001E00000000FF000E03FC001C00
+000000FF000E03FC003800000000FF001C03FE003800000000FF001C03FE007000000000
+FF003801FE007000000000FF003801FE00E000000000FF007001FE00E000000000FF00F0
+01FE01C000000000FF00E001FE01C000000000FF01E001FE038000000000FF01C001FE03
+8000000000FF038001FE070000000000FF038001FE0F0000000000FF070001FE0E000000
+0000FF070001FE1C0000000000FF0E0001FE1C0000000000FF0E0001FE380000000000FF
+1C0001FE380000000000FF9C0001FE700000000000FFB80001FE7000000000007FF80001
+FEE000000000007FF00001FEE000000000007FF00001FFC000000000007FE00001FFC000
+000000007FC00001FF8000000000007FC00001FF8000000000007F800001FF0000000000
+007F800001FE0000000000007F000001FE0000000000007F000000FC0000000000007E00
+0000FC0000000000007E000000F80000000000007C000000F80000000000007C000000F0
+00000000000078000000F000000000000070000000E0000000000053406EBD5B>87
+D<0000FFFFFF003FFFFC0000FFFFFF007FFFFC0000FFFFFE007FFFFC000001FFE0000FFF
+00000000FFC00007F800000000FF800003F000000000FF800003C0000000007FC0000780
+000000007FC0000700000000003FC0000E00000000003FE0001C00000000003FE0003C00
+000000001FE0007800000000001FF000F000000000001FF001E000000000000FF001C000
+000000000FF8038000000000000FF80700000000000007F80E00000000000007FC1E0000
+0000000007FC3C00000000000003FC7800000000000003FE7000000000000003FEE00000
+0000000001FFC000000000000001FF8000000000000001FF8000000000000000FF000000
+0000000000FF8000000000000000FF80000000000000007FC0000000000000007FC00000
+0000000000FFC000000000000001FFE000000000000003FFE0000000000000079FE00000
+00000000071FF00000000000000E1FF00000000000001C0FF0000000000000380FF80000
+00000000780FF8000000000000F007F8000000000001E007FC000000000001C007FC0000
+000000038003FC0000000000070003FE00000000000E0003FE00000000001E0001FE0000
+0000003C0001FF0000000000780001FF0000000000700000FF0000000000E00000FF8000
+000001C00000FF80000000038000007F80000000078000007FC00000000F0000007FC000
+00003F0000003FE00000007F8000007FE0000003FFC00001FFF00000FFFFF8001FFFFFE0
+00FFFFF8001FFFFFE000FFFFF8001FFFFFC000463E7CBD44>I<FFFFFF00003FFFF0FFFF
+FF00003FFFF0FFFFFE00003FFFF003FFC0000007FE0001FF80000003F80000FF80000003
+E00000FF80000003C00000FF800000078000007F800000070000007FC000000E0000007F
+C000001C0000003FC000003C0000003FE00000780000003FE00000700000003FE00000E0
+0000001FF00001C00000001FF00003C00000001FF00007800000000FF00007000000000F
+F8000E000000000FF8001C0000000007F8003C0000000007FC00780000000007FC007000
+00000007FC00E00000000003FE01C00000000003FE03C00000000003FE07800000000001
+FE07000000000001FF0E000000000001FF1C000000000000FF3C000000000000FFF80000
+00000000FFF0000000000000FFE00000000000007FC00000000000007FC0000000000000
+7F800000000000007F800000000000007F00000000000000FF00000000000000FF000000
+00000000FF00000000000000FE00000000000001FE00000000000001FE00000000000001
+FE00000000000001FC00000000000003FC00000000000003FC00000000000003FC000000
+00000003F800000000000007F800000000000007F800000000000007F80000000000000F
+F00000000000000FF00000000000000FF00000000000001FF000000000001FFFFFF00000
+00001FFFFFF0000000001FFFFFF0000000003C3E6EBD44>I<000C001C007800E001C001
+80038007000E000C001C00180038003000700060006000E000CF00FFC0FFC0FFC0FFC0FF
+C0FFC0FF807F003C000E1C6EBE1C>96 D<00007E00000001FF80000007C1C380001F80EF
+C0003F00FFC0007E007FC000FC007F8001F8003F8003F0003F8003F0003F8007E0003F00
+0FE0003F000FC0003F001FC0007F001FC0007E003F80007E003F80007E003F8000FE007F
+8000FC007F0000FC007F0000FC007F0001FC00FF0001F800FE0001F800FE0001F800FE00
+03F800FE0003F038FC0003F038FC0003F038FC0007F038FC0007E078FC000FE0707C000F
+E0707C001FE0F07E003FE0E03E007FE0E03E00F3E1E01F01E3E1C00F8781E38003FF00FF
+0000FC003E00252977A72E>I<001FC0000FFFC0000FFF80000FFF8000003F8000003F80
+00003F0000003F0000007F0000007F0000007E0000007E000000FE000000FE000000FC00
+0000FC000001FC000001FC000001F8000001F8000003F8000003F8000003F0000003F07E
+0007F1FF8007F783E007EF01F007FE01F00FF800F80FF800F80FF000FC0FE0007C1FC000
+7C1FC0007E1F80007E1F8000FE3F8000FE3F8000FE3F0000FE3F0000FE7F0001FE7F0001
+FC7E0001FC7E0001FC7E0003FCFE0003F8FC0003F8FC0003F8FC0007F0FC0007F0FC0007
+E0F8000FE0F8000FC0F8001FC0F8001F8078003F007C003F007C007E003C00FC003E01F8
+001E03E0000F07C00007FF000001F800001F4076BE2A>I<00001FE0000000FFF8000003
+F03E000007C00F00001F800700003F000780007E001F8000FC007F8001F8007F8003F000
+7F8007F0007F0007E0007F000FE0007E001FC00000001FC00000003F800000003F800000
+003F800000007F800000007F000000007F000000007F00000000FF00000000FE00000000
+FE00000000FE00000000FE00000000FE00000000FE00000000FC000003007E000007007E
+00000F007E00001E003E00003C003E000078001F0000F0001F0003E0000F800F800003E0
+7E000001FFF80000003FC00000212977A72A>I<000000003F800000001FFF800000001F
+FF000000001FFF00000000007F00000000007F00000000007E00000000007E0000000000
+FE0000000000FE0000000000FC0000000000FC0000000001FC0000000001FC0000000001
+F80000000001F80000000003F80000000003F80000000003F00000000003F00000000007
+F00000000007F00000000007E00000007E07E0000001FF8FE0000007C1CFE000001F80EF
+C000003F00FFC000007E007FC00000FC007FC00001F8003F800003F0003F800003F0003F
+800007E0003F80000FE0003F00000FC0003F00001FC0007F00001FC0007F00003F80007E
+00003F80007E00003F8000FE00007F8000FE00007F0000FC00007F0000FC00007F0001FC
+0000FF0001FC0000FE0001F80000FE0001F80000FE0003F80000FE0003F83800FC0003F0
+3800FC0003F03800FC0007F03800FC0007F07800FC000FE070007C000FE070007C001FE0
+F0007E003FE0E0003E007FE0E0003E00F3E1E0001F01E3E1C0000F8781E3800003FF00FF
+000000FC003E0000294077BE2E>I<00003F800001FFE00007E0F8001F803C003E003C00
+FC001E01F8001E03F0001E07F0001E0FE0003E0FC0003C1FC0003C3F80007C3F8000F83F
+8003F07F000FE07F00FF80FFFFFC00FFFFC000FE000000FE000000FE000000FE000000FC
+000000FC000000FC000000FC000000FC000000FC000000FC000006FC00000EFC00001E7C
+00003C7C0000783E0000F03E0001E01F0007C00F801F0007C0FC0001FFF000007F80001F
+2976A72A>I<000000007C0000000001FF0000000007C7800000000F83C00000001F87C0
+0000001F1FC00000003F3FC00000003F3FC00000007E3FC00000007E3FC00000007E3F80
+0000007E0E00000000FC0000000000FC0000000000FC0000000000FC0000000001FC0000
+000001F80000000001F80000000001F80000000001F80000000003F80000000003F00000
+000003F00000000003F000000003FFFFF8000003FFFFF8000003FFFFF800000007E00000
+000007E00000000007E0000000000FE0000000000FC0000000000FC0000000000FC00000
+00000FC0000000000FC0000000001FC0000000001F80000000001F80000000001F800000
+00001F80000000003F80000000003F00000000003F00000000003F00000000003F000000
+00007F00000000007E00000000007E00000000007E00000000007E0000000000FE000000
+0000FC0000000000FC0000000000FC0000000000FC0000000001FC0000000001F8000000
+0001F80000000001F80000000001F80000000003F00000000003F00000000003F0000000
+0003F00000000007E00000000007E00000000007E00000000007E0000000000FC0000000
+1E0FC00000007F0FC00000007F0F80000000FF0F80000000FF1F00000000FF1F00000000
+FE1E00000000F83C00000000703C000000007878000000003FE0000000000F8000000000
+2A5383BF1C>I<000003F00000000FFC0000003E0E1C0000FC077E0001F003FE0003F003
+FE0007E001FE000FC001FC001F8001FC001F8001FC003F0001FC007F0001F8007E0001F8
+00FE0003F800FE0003F801FC0003F001FC0003F001FC0007F003FC0007F003F80007E003
+F80007E003F8000FE007F8000FE007F0000FC007F0000FC007F0001FC007F0001FC007F0
+001F8007E0001F8007E0003F8003E0003F8003E0007F0003F000FF0003F000FF0001F001
+FF0000F003FE0000F80F7E00007C1EFE00001FF8FE000007E0FC00000000FC00000001FC
+00000001FC00000001F800000001F800000003F800000003F800000003F0001C0007F000
+7F0007E000FF000FE000FF000FC000FF001F8000FF003F0000FE007E0000F800FC00007C
+03F000001FFFC0000003FE000000273B7CA72A>I<0001FC000000FFFC000000FFF80000
+00FFF800000003F800000003F800000003F000000003F000000007F000000007F0000000
+07E000000007E00000000FE00000000FE00000000FC00000000FC00000001FC00000001F
+C00000001F800000001F800000003F800000003F800000003F000000003F03F800007F0F
+FE00007F3E0F80007E780FC0007EE007C000FFC007E000FF8007E000FF0007E000FF0007
+E001FE0007E001FC0007E001FC0007E001F80007E003F8000FE003F8000FC003F0000FC0
+03F0000FC007F0001FC007F0001F8007E0001F8007E0001F800FE0003F800FE0003F000F
+C0003F000FC0007F001FC0007E001FC000FE071F8000FC071F8000FC073F8001FC0F3F80
+01F80E3F0001F80E3F0001F81E7F0001F01C7F0001F01C7E0001F0387E0001F038FE0001
+F070FE0000F0E0FC00007FC03800001F0028407ABE2E>I<0000780001FC0001FC0003FC
+0003FC0003FC0003F80000E0000000000000000000000000000000000000000000000000
+000000000000000000000000000000007C0001FF00038F800707800E07C01E07C01C07C0
+3C0FC0380FC0380FC0781FC0701F80701F80F03F80F03F00003F00007F00007E0000FE00
+00FC0000FC0001FC0001F80001F80003F80003F00003F03807F03807E0380FE0780FC070
+0FC0700FC0F00F80E00F80E00F81C00F83C00F838007870003FE0000F800163E79BC1C>
+I<00000007000000001FC00000001FC00000003FC00000003FC00000003FC00000003F80
+0000000E0000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+07C00000003FF000000078F8000000E07C000001C07C000003C07C000003807E00000700
+7E000007007E00000E00FE00000E00FC00001E00FC00001C00FC00003C01FC00003C01FC
+00000001F800000001F800000003F800000003F800000003F000000003F000000007F000
+000007F000000007E000000007E00000000FE00000000FE00000000FC00000000FC00000
+001FC00000001FC00000001F800000001F800000003F800000003F800000003F00000000
+3F000000007F000000007F000000007E000000007E00000000FE00000000FE00000000FC
+00000000FC00000001FC00000001F800000001F800001C01F800007F03F00000FF03F000
+00FF07E00000FF07C00000FF0F800000FE1F000000F83E000000707C0000003FF0000000
+0FC0000000225083BC1C>I<0001FC000000FFFC000000FFF8000000FFF800000003F800
+000003F800000003F000000003F000000007F000000007F000000007E000000007E00000
+000FE00000000FE00000000FC00000000FC00000001FC00000001FC00000001F80000000
+1F800000003F800000003F800000003F000000003F0003E0007F000FF8007F003C3C007E
+00707C007E00E1FC00FE01C1FC00FE0383FC00FC0703FC00FC0E03FC01FC1C03F801FC38
+00E001F870000001F860000003F8E0000003F9C0000003F780000003FE00000007FE0000
+0007FFE0000007E7F8000007E0FE00000FE07F00000FE03F80000FC01F80000FC00FC000
+1FC00FC0001FC00FC0701F800FC0701F800FC0703F800FC0F03F801FC0E03F001F80E03F
+001F80E07F001F81E07F001F81C07E000F83C07E000F8380FE000F8780FE00078F00FC00
+03FE00380000F80026407ABE2A>I<0007F003FFF003FFE003FFE0000FE0000FE0000FC0
+000FC0001FC0001FC0001F80001F80003F80003F80003F00003F00007F00007F00007E00
+007E0000FE0000FE0000FC0000FC0001FC0001FC0001F80001F80003F80003F80003F000
+03F00007F00007F00007E00007E0000FE0000FE0000FC0000FC0001FC0001FC0001F8000
+1F80003F80003F80003F00003F00007F00007F07007E07007E0700FE0F00FE0E00FC0E00
+FC0E00FC1E00FC1C00FC1C007C38007C78003C70001FE000078000144079BE17>I<01F0
+003F80007F000007FC01FFE003FFC0000F3E07C1F80F83F0000E1F0F00FC1E01F8001E1F
+1C007C3800F8001C1F38007E7000FC003C1FF0007EE000FC00381FF0007FE000FC00381F
+E0007FC000FC00783FC0007F8000FC00703FC0007F8000FC00703F80007F0000FC00703F
+00007E0000FC00F03F0000FE0001FC00F07F0000FC0001F800007E0000FC0001F800007E
+0000FC0001F800007E0001FC0003F80000FE0001FC0003F00000FC0001F80003F00000FC
+0001F80003F00000FC0003F80007F00001FC0003F80007E00001F80003F00007E00001F8
+0003F0000FE00001F80007F0000FC00003F80007F0001FC0E003F00007E0001F80E003F0
+0007E0001F80E003F0000FE0003F81E007F0000FE0003F01C007E0000FC0003F01C007E0
+000FC0003F01C007E0001FC0003E03800FE0001FC0003E03800FC0001F80003E07000FC0
+001F80003E07000FC0003F80003E0E001FC0003F80001E1C001F80003F00000FF8000700
+000E000003E000432979A74A>I<01F0003F800007FC01FFE0000F3E07C1F8000E1F0F00
+FC001E1F1C007C001C1F38007E003C1FF0007E00381FF0007E00381FE0007E00783FC000
+7E00703FC0007E00703F80007E00703F00007E00F03F0000FE00F07F0000FC00007E0000
+FC00007E0000FC00007E0001FC0000FE0001F80000FC0001F80000FC0001F80000FC0003
+F80001FC0003F00001F80003F00001F80007F00001F80007E00003F8000FE07003F0000F
+C07003F0000FC07003F0001FC0F007F0001F80E007E0001F80E007E0001F81E007E0001F
+01C00FE0001F01C00FC0001F03800FC0001F03800FC0001F07001FC0000F0E001F800007
+FC0007000001F0002C2979A733>I<00001FC0000000FFF8000003F07C00000FC01F0000
+1F801F00003F000F80007E000FC000FC0007C001F80007E003F00007E007F00007E007E0
+0007E00FE00007F01FC00007F01FC00007F03F800007F03F800007F03F80000FE07F8000
+0FE07F00000FE07F00000FE07F00001FE0FF00001FC0FE00001FC0FE00001FC0FE00003F
+80FE00003F80FE00007F00FE00007F00FC00007E007C0000FC007E0001FC007E0001F800
+7E0003F0003E0007E0001F000FC0001F001F80000F803E000007C0FC000001FFF0000000
+3F800000242977A72E>I<0003E001F800000FF807FE00001E7C1E0F80001C3E3C07C000
+3C3E7807C000383EE003E000783FE003E000703FC003F000703F8001F000F07F0001F000
+E07F0001F800E07E0001F800E07E0003F801E0FE0003F801E0FE0003F80000FC0003F800
+00FC0003F80001FC0007F80001FC0007F00001F80007F00001F80007F00003F8000FF000
+03F8000FE00003F0000FE00003F0000FE00007F0001FC00007F0001FC00007E0001F8000
+07E0003F80000FE0003F00000FE0007F00000FE0007E00000FE000FC00001FE000FC0000
+1FE001F800001FF003F000001FF007E000003FB80F8000003F9C1F0000003F0FFC000000
+3F03E00000007F00000000007F00000000007E00000000007E0000000000FE0000000000
+FE0000000000FC0000000000FC0000000001FC0000000001FC0000000001F80000000001
+F80000000003F80000000003F8000000007FFFE0000000FFFFE0000000FFFFE00000002D
+3A80A72E>I<01F000FC0007FC07FF800F3E0F03C00E1F1C03E01E1F380FE01C1F700FE0
+3C1FE01FE0381FE01FE0381FC01FE0783FC01FC0703F800700703F800000703F000000F0
+3F000000F07F000000007E000000007E000000007E00000000FE00000000FC00000000FC
+00000000FC00000001FC00000001F800000001F800000001F800000003F800000003F000
+000003F000000003F000000007F000000007E000000007E000000007E00000000FE00000
+000FC00000000FC00000000FC00000001FC00000001F800000000700000000232979A726
+>114 D<00007F800001FFE00007C0F8001F003C003E001C003C001E007C003E00F8007E
+00F800FE00F800FE01F800FC01F800FC01F8007001FC000001FE000001FFC00001FFFC00
+00FFFF0000FFFF80007FFFC0003FFFE0000FFFF00000FFF000000FF0000007F0000003F0
+0C0003F03F0003F07F8001F07F8003F0FF0003E0FF0003E0FF0003E0FC0007C0F0000F80
+70000F8078001F003C003C001F01F80007FFE00000FF00001F297AA725>I<0001C00000
+03F0000007F0000007F0000007E0000007E000000FE000000FE000000FC000000FC00000
+1FC000001FC000001F8000001F8000003F8000003F8000003F0000003F00007FFFFF80FF
+FFFF80FFFFFF00007E000000FE000000FE000000FC000000FC000001FC000001FC000001
+F8000001F8000003F8000003F8000003F0000003F0000007F0000007F0000007E0000007
+E000000FE000000FE000000FC000000FC000001FC000001FC01C001F801C001F801C003F
+803C003F8038003F0078003F0070003F00F0003F00E0003F01C0001F03C0001F0780000F
+0F000007FC000001F00000193A78B81E>I<007C0000000001FF00001C00038F80007E00
+070780007E000E07C0007E001E07C000FE001C07C000FE003C0FC000FC00380FC000FC00
+380FC001FC00781FC001FC00701F8001F800701F8001F800F03F8003F800F03F0003F800
+003F0003F000007F0003F000007E0007F000007E0007F00000FE0007E00000FC0007E000
+00FC000FE00001FC000FE00001F8000FC00001F8000FC00001F8001FC00003F8001FC1C0
+03F0001F81C003F0001F81C003F0003F81C003F0003F83C003F0003F038003F0003F0380
+03F0007F078001F000FF070001F001FF070001F801DF0F0000F8079F0E00007C0F0F1C00
+001FFC07F8000007F001F0002A2979A731>I<007C0001C001FF0007F0038F8007F00707
+8007F00E07C007F81E07C007F81C07C003F83C0FC003F8380FC001F0380FC001F0781FC0
+00F0701F8000F0701F8000F0F03F8000F0F03F0000E0003F0000E0007F0000E0007E0001
+E0007E0001C000FE0001C000FC0001C000FC0003C001FC00038001F800038001F8000380
+01F800070003F800070003F0000F0003F0000E0003F0000E0003F0001C0003F0001C0003
+F000380003F000780001F000700001F800E00000F801C00000FC038000007E0F0000001F
+FE00000003F00000252979A72A>I<007C000000007001FF00007001FC038F8001F801FC
+07078001F801FC0E07C001F801FE1E07C003F801FE1C07C003F000FE3C0FC003F000FE38
+0FC003F0007C380FC007F0007C781FC007E0003C701F8007E0003C701F8007E0003CF03F
+800FE0003CF03F000FC00038003F000FC00038007F000FC00038007E001FC00078007E00
+1F80007000FE001F80007000FC001F80007000FC003F8000F001FC003F0000E001F8003F
+0000E001F8003F0000E001F8003F0001E003F8007F0001C003F0007E0001C003F0007E00
+03C003F0007E00038003F0007E00038003F0007E00070003F000FE00070003F000FE000E
+0001F001FE001E0001F801FF001C0000F8039F00380000FC079F807000003E0F07C1E000
+001FFC03FFC0000003F0007F0000372979A73C>I<0003F001F800000FFC07FE00003C1E
+0E0F0000780F1C0F8000F00FB83F8001E00FF83F8001C007F07F80038007F07F80078007
+E07F8007000FE07F000F000FE01C000E000FC000000E000FC000001E001FC000001E001F
+C0000000001F80000000001F80000000003F80000000003F00000000003F00000000003F
+00000000007F00000000007E00000000007E00000000007E0000000000FE0000000000FC
+001C000000FC001C000000FC001C000001FC003C001E01FC0038003F01F80078007F81F8
+0070007F83F800F000FF83F800E000FF077801C000FE0F7C03C0007C0E3C078000783C1E
+1E00001FF80FFC000007E003F0000029297CA72A>I<007C00000001FF000038038F8000
+FC07078000FC0E07C000FC1E07C001FC1C07C001F83C0FC001F8380FC001F8380FC003F8
+781FC003F0701F8003F0701F8003F0F03F8007F0F03F0007E0003F0007E0007F0007E000
+7E000FE0007E000FC000FE000FC000FC000FC000FC001FC001FC001FC001F8001F8001F8
+001F8001F8003F8003F8003F0003F0003F0003F0003F0003F0007F0003F0007E0003F000
+7E0003F0007E0003F000FE0003F000FC0001F001FC0001F803FC0000F807FC00007C1FF8
+00003FF9F8000007E1F800000003F800000003F000000003F000000007F0000E0007E000
+3F8007E0007F800FC0007F800FC0007F801F8000FF001F0000FF003E00007C007E000070
+00FC00007801F000003803E000001E0FC000000FFF00000003F8000000263B79A72C>I<
+0001F000700007FC00F0000FFC00E0001FFE01E0003FFF03C0007FFF8380007C0FCF8000
+F803FF0000F0007E0000E0003C0001E000380000C0007800000000F000000001E0000000
+03C000000007800000000F000000001E000000003C000000007800000000F000000001E0
+00000003C000000007800000000F000000001E000000003C000700007800070000F00007
+0001E0000F0003C0001E000780001E0007F0003C000FFE007C001F1F81F8003E0FFFF800
+3C07FFF0007803FFE0007003FFC000F001FF0000E0007C000024297BA725>I<FFFFFFFF
+FFFFFFFFFFFFE0FFFFFFFFFFFFFFFFFFFFE0530276985D>124 D
+E /Fj 53 123 df<0000000FFF0000000001FFFFC00000000FFFFFF00000007FFFFFF800
+0001FFF803FC000003FFC000FE00000FFF0003FE00001FFE0007FF00003FFC000FFF0000
+3FF8000FFF00007FF0000FFF00007FF0001FFF8000FFF0000FFF0000FFE0000FFF0000FF
+E0000FFF0000FFE0000FFF0000FFE00007FE0000FFE00001F80000FFE00000000000FFE0
+0000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE000
+00000000FFE001FFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFF
+FF80FFFFFFFFFFFF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF
+8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF80
+00FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000
+FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FF
+E00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE0
+0003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE000
+03FF8000FFE00003FF8000FFE00003FF8000FFE00003FF8000FFE00003FF807FFFFFC1FF
+FFFF7FFFFFC1FFFFFF7FFFFFC1FFFFFF7FFFFFC1FFFFFF7FFFFFC1FFFFFF38467EC53E>
+12 D<07C01FF03FF87FFCFFFEFFFEFFFEFFFEFFFEFFFEFFFE7FFC3FF81FF007C00F0F78
+8E1F>46 D<00003FF800000001FFFF0000000FFFFFE000003FFFFFF800007FF01FFC0000
+FFC007FE0001FF0001FF0003FE0000FF8007FE0000FFC007FC00007FC00FFC00007FE00F
+F800003FE01FF800003FF01FF800003FF03FF800003FF83FF800003FF83FF000001FF87F
+F000001FFC7FF000001FFC7FF000001FFC7FF000001FFC7FF000001FFC7FF000001FFCFF
+F000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFF
+F000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFF
+F000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFFF000001FFEFF
+F000001FFEFFF000001FFEFFF000001FFE7FF000001FFC7FF000001FFC7FF000001FFC7F
+F000001FFC7FF000001FFC3FF800003FF83FF800003FF83FF800003FF81FF800003FF01F
+F800003FF00FF800003FE00FFC00007FE007FC00007FC007FE0000FFC003FF0001FF8001
+FF8003FF0000FFC007FE00007FF01FFC00003FFFFFF800000FFFFFE0000003FFFF800000
+003FF800002F427CC038>48 D<000003C000000007C00000001FC00000007FC0000003FF
+C000003FFFC000FFFFFFC000FFFFFFC000FFFFFFC000FFFFFFC000FFC3FFC0000003FFC0
+000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC000
+0003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC00000
+03FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003
+FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FF
+C0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0
+000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC0000003FFC000
+0003FFC0000003FFC0000003FFC0000003FFC0000003FFC000FFFFFFFFFCFFFFFFFFFCFF
+FFFFFFFCFFFFFFFFFCFFFFFFFFFC264177C038>I<0000FFE00000000FFFFE0000003FFF
+FF800000FFFFFFE00003FFFFFFF80007FC03FFFE000FE0007FFF001F80003FFF803F0000
+0FFFC07F000007FFC07FC00007FFE07FF00003FFE0FFF00001FFF0FFF80001FFF0FFF800
+01FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF87FF00000FFF83FE000
+00FFF81FC00000FFF800000000FFF800000000FFF000000001FFF000000001FFF0000000
+01FFE000000003FFE000000003FFC000000007FF800000000FFF000000000FFF00000000
+1FFC000000003FF8000000003FF0000000007FE000000000FFC000000001FF0000000003
+FE0000000007FC000000000FF0000000001FE0000000003F80000000007F0000780000FE
+0000780001FC0000780003F80000F80007E00000F0000FC00000F0001F800000F0003F00
+0000F0007C000001F000F8000003F001FFFFFFFFF003FFFFFFFFE007FFFFFFFFE00FFFFF
+FFFFE01FFFFFFFFFE03FFFFFFFFFE07FFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFC0FFFFFF
+FFFFC0FFFFFFFFFFC0FFFFFFFFFFC02D417BC038>I<0000FFF000000007FFFF0000001F
+FFFFC000007FFFFFF00000FF007FF80003F8003FFE0007E0001FFF0007E0000FFF000FF8
+0007FF800FFE0007FF801FFE0007FFC01FFF0007FFC01FFF0007FFC01FFF0007FFC01FFF
+0007FFC01FFF0007FFC01FFF0007FFC00FFE0007FFC007FC0007FF8003F8000FFF800000
+000FFF000000001FFF000000001FFE000000003FFC000000007FF800000000FFF0000000
+01FFE00000000FFF80000007FFFE00000007FFF800000007FFFF00000007FFFFC0000000
+00FFF0000000003FFC000000000FFE000000000FFF8000000007FF8000000003FFC00000
+0003FFE000000003FFE000000001FFF000000001FFF000000001FFF800000001FFF80000
+0001FFF80FC00001FFF83FF00001FFF87FF80001FFF87FF80001FFF8FFFC0001FFF8FFFC
+0001FFF8FFFC0001FFF0FFFC0001FFF0FFFC0003FFF0FFFC0003FFE07FF80003FFE07FF0
+0007FFC07FE00007FFC03F80000FFF801FF0001FFF000FFE00FFFE0007FFFFFFF80001FF
+FFFFF000007FFFFFC000001FFFFE00000001FFE000002D427BC038>I<000000003F0000
+000000003F0000000000007F000000000000FF000000000001FF000000000003FF000000
+000003FF000000000007FF00000000000FFF00000000001FFF00000000003FFF00000000
+003FFF00000000007FFF0000000000FFFF0000000001F7FF0000000003E7FF0000000007
+E7FF0000000007C7FF000000000F87FF000000001F07FF000000003E07FF000000007E07
+FF000000007C07FF00000000F807FF00000001F007FF00000003E007FF00000007E007FF
+00000007C007FF0000000F8007FF0000001F0007FF0000003E0007FF0000007C0007FF00
+00007C0007FF000000F80007FF000001F00007FF000003E00007FF000007C00007FF0000
+0FC00007FF00000F800007FF00001F000007FF00003E000007FF00007C000007FF0000FC
+000007FF0000FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFF
+FFFFFFFF800000000FFF00000000000FFF00000000000FFF00000000000FFF0000000000
+0FFF00000000000FFF00000000000FFF00000000000FFF00000000000FFF00000000000F
+FF00000000000FFF00000000000FFF000000007FFFFFFF8000007FFFFFFF8000007FFFFF
+FF8000007FFFFFFF8000007FFFFFFF8031417DC038>I<07000000030007E000003F0007
+FF0007FF0007FFFFFFFF0007FFFFFFFE0007FFFFFFFC0007FFFFFFF80007FFFFFFF00007
+FFFFFFE00007FFFFFF800007FFFFFE000007FFFFFC000007FFFFE0000007FFFF00000007
+C00000000007C00000000007C00000000007C00000000007C00000000007C00000000007
+C00000000007C00000000007C00000000007C00000000007C03FF0000007C1FFFF000007
+C7FFFFC00007DFFFFFF00007FFE03FFC0007FF000FFE0007FC0007FF0007F00003FF8007
+E00003FFC007C00001FFC003800001FFE000000001FFE000000000FFF000000000FFF000
+000000FFF000000000FFF800000000FFF800000000FFF800000000FFF80F800000FFF83F
+E00000FFF87FF00000FFF8FFF00000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF8FF
+F80000FFF0FFF00000FFF0FFF00001FFF07FE00001FFE07FC00001FFE07E000003FFC03E
+000003FFC03F000007FF801FC0000FFF000FF0001FFE0007FE00FFFC0003FFFFFFF00000
+FFFFFFE000003FFFFF8000000FFFFC00000001FFC000002D427BC038>I<000001FF8000
+00001FFFF00000007FFFFC000001FFFFFF000007FF807F80000FFC001F80003FF0001FC0
+007FE0007FC000FFC000FFE001FF8001FFE003FF8001FFE003FF0001FFE007FE0001FFE0
+0FFE0001FFE00FFE0001FFE01FFC0000FFC01FFC00007F801FFC00001E003FFC00000000
+3FFC000000003FF8000000007FF8000000007FF8000000007FF807FC00007FF81FFF8000
+FFF87FFFE000FFF8FFFFF800FFF9F01FFC00FFFBC007FE00FFFF8003FF00FFFF8003FF80
+FFFF0001FFC0FFFE0001FFC0FFFE0000FFE0FFFE0000FFE0FFFC0000FFF0FFFC0000FFF0
+FFFC0000FFF0FFFC0000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF8FFF80000FFF8
+7FF80000FFF87FF80000FFF87FF80000FFF87FF80000FFF87FF80000FFF83FF80000FFF8
+3FF80000FFF83FF80000FFF03FFC0000FFF01FFC0000FFF01FFC0000FFF00FFC0001FFE0
+0FFC0001FFE007FE0001FFC007FF0003FF8003FF8003FF0001FFC007FE0000FFE01FFC00
+007FFFFFF800001FFFFFF0000007FFFFC0000001FFFF000000003FF000002D427BC038>
+I<1E00000000001F00000000001FFC000000001FFFFFFFFFFE1FFFFFFFFFFE1FFFFFFFFF
+FE1FFFFFFFFFFE3FFFFFFFFFFE3FFFFFFFFFFC3FFFFFFFFFF83FFFFFFFFFF03FFFFFFFFF
+E03FFFFFFFFFC03FFFFFFFFFC07FFFFFFFFF807E0000003F007C0000007E007C000000FC
+0078000000F80078000001F80078000003F000F8000007E000F000000FC000F000000F80
+00F000001F80000000003F00000000007E0000000000FC0000000000FC0000000001F800
+00000003F80000000003F00000000007F0000000000FE0000000000FE0000000001FE000
+0000001FC0000000003FC0000000003FC0000000007FC0000000007F8000000000FF8000
+000000FF8000000001FF8000000001FF8000000001FF8000000003FF8000000003FF0000
+000003FF0000000003FF0000000007FF0000000007FF0000000007FF0000000007FF0000
+000007FF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0000
+00000FFF000000000FFF000000000FFF000000000FFF000000000FFF0000000007FE0000
+000003FC0000000001F80000002F447AC238>I<00007FF000000003FFFF0000000FFFFF
+C000003FFFFFF000007F801FFC0001FC0003FE0003F80001FF0003F00000FF0007E00000
+7F8007E000003F800FC000003FC00FC000003FC01FC000001FC01FC000001FC01FE00000
+1FC01FE000001FC01FF000001FC01FF800001FC01FFE00003FC01FFF00003F801FFFC000
+7F801FFFF0007F000FFFFC00FF000FFFFE01FE0007FFFF83FC0007FFFFE7F80003FFFFFF
+E00001FFFFFFC00000FFFFFF0000007FFFFFC000003FFFFFE000000FFFFFF800000FFFFF
+FC00003FFFFFFE0000FFFFFFFF0001FF3FFFFF8007FC0FFFFFC00FF803FFFFE01FF000FF
+FFE01FE0007FFFF03FE0001FFFF07FC00007FFF07F800003FFF87F800000FFF8FF800000
+7FF8FF0000003FF8FF0000001FF8FF0000000FF8FF0000000FF8FF00000007F8FF000000
+07F8FF00000007F8FF80000007F07F80000007F07F8000000FF07FC000000FE03FE00000
+1FE03FF000003FC01FF800007F800FFE0001FF0007FFC00FFE0003FFFFFFFC0000FFFFFF
+F000003FFFFFC000000FFFFF00000000FFF000002D427BC038>I<00007FF000000007FF
+FE0000001FFFFF8000007FFFFFE00000FFE03FF00001FF800FF80003FF0007FC0007FE00
+07FE000FFC0003FF001FFC0001FF003FFC0001FF803FFC0001FF807FF80001FFC07FF800
+00FFC07FF80000FFE07FF80000FFE0FFF80000FFE0FFF80000FFF0FFF80000FFF0FFF800
+00FFF0FFF80000FFF0FFF80000FFF0FFF80000FFF0FFF80000FFF8FFF80000FFF8FFF800
+00FFF8FFF80000FFF8FFF80001FFF87FF80001FFF87FF80001FFF87FF80001FFF83FF800
+03FFF83FF80003FFF81FFC0003FFF81FFC0007FFF80FFE000FFFF807FE000FFFF803FF00
+1EFFF801FFC07CFFF800FFFFF8FFF8003FFFF0FFF8000FFFC0FFF00001FF00FFF0000000
+00FFF000000000FFF000000000FFE000000001FFE000000001FFE003C00001FFE00FF000
+01FFC01FF80001FFC03FFC0003FF803FFC0003FF803FFC0003FF003FFC0007FE003FFC00
+0FFE003FFC000FFC003FF8001FF8001FF0003FF0001FC000FFE0000FF003FFC00007FFFF
+FF800003FFFFFE000001FFFFF80000007FFFE000000007FE0000002D427BC038>I<0000
+00001F8000000000000000001F8000000000000000003FC000000000000000003FC00000
+0000000000007FE000000000000000007FE000000000000000007FE00000000000000000
+FFF00000000000000000FFF00000000000000001FFF80000000000000001FFF800000000
+00000001FFF80000000000000003FFFC0000000000000003FFFC0000000000000007FFFE
+0000000000000007FFFE0000000000000007FFFE000000000000000FFFFF000000000000
+000F9FFF000000000000001F9FFF800000000000001F1FFF800000000000001F0FFF8000
+00000000003F0FFFC00000000000003E07FFC00000000000007E07FFE00000000000007C
+07FFE00000000000007C03FFE0000000000000FC03FFF0000000000000F801FFF0000000
+000001F801FFF8000000000001F001FFF8000000000001F000FFF8000000000003F000FF
+FC000000000003E0007FFC000000000007E0007FFE000000000007C0007FFE0000000000
+07C0003FFE00000000000FC0003FFF00000000000F80001FFF00000000001F80001FFF80
+000000001F00000FFF80000000001F00000FFF80000000003F00000FFFC0000000003E00
+0007FFC0000000007E000007FFE0000000007FFFFFFFFFE0000000007FFFFFFFFFE00000
+0000FFFFFFFFFFF000000000FFFFFFFFFFF000000001FFFFFFFFFFF800000001F0000000
+FFF800000001F0000000FFF800000003F0000000FFFC00000003E00000007FFC00000007
+E00000007FFE00000007C00000003FFE00000007C00000003FFE0000000F800000003FFF
+0000000F800000001FFF0000001F800000001FFF8000001F000000000FFF8000003F0000
+00000FFFC000003E000000000FFFC000007E0000000007FFC000FFFFFF00000FFFFFFFF0
+FFFFFF00000FFFFFFFF0FFFFFF00000FFFFFFFF0FFFFFF00000FFFFFFFF0FFFFFF00000F
+FFFFFFF04C457CC455>65 D<FFFFFFFFFFFF000000FFFFFFFFFFFFF00000FFFFFFFFFFFF
+FE0000FFFFFFFFFFFFFF8000FFFFFFFFFFFFFFE000003FFC000007FFF000003FFC000001
+FFF800003FFC0000007FFC00003FFC0000003FFE00003FFC0000001FFF00003FFC000000
+1FFF00003FFC0000000FFF80003FFC0000000FFF80003FFC0000000FFF80003FFC000000
+07FFC0003FFC00000007FFC0003FFC00000007FFC0003FFC00000007FFC0003FFC000000
+07FFC0003FFC00000007FFC0003FFC00000007FFC0003FFC0000000FFF80003FFC000000
+0FFF80003FFC0000001FFF00003FFC0000001FFF00003FFC0000003FFE00003FFC000000
+7FFC00003FFC000000FFF800003FFC000001FFF000003FFC000007FFE000003FFC0000FF
+FF8000003FFFFFFFFFFC0000003FFFFFFFFFF00000003FFFFFFFFFFF0000003FFFFFFFFF
+FFE000003FFC000001FFF800003FFC0000007FFC00003FFC0000001FFE00003FFC000000
+0FFF00003FFC00000007FF80003FFC00000007FFC0003FFC00000003FFE0003FFC000000
+03FFE0003FFC00000001FFF0003FFC00000001FFF0003FFC00000001FFF0003FFC000000
+01FFF8003FFC00000001FFF8003FFC00000001FFF8003FFC00000001FFF8003FFC000000
+01FFF8003FFC00000001FFF8003FFC00000001FFF8003FFC00000001FFF0003FFC000000
+01FFF0003FFC00000003FFF0003FFC00000003FFE0003FFC00000007FFE0003FFC000000
+0FFFC0003FFC0000001FFFC0003FFC0000003FFF80003FFC000000FFFF00003FFC000007
+FFFE00FFFFFFFFFFFFFFF800FFFFFFFFFFFFFFF000FFFFFFFFFFFFFFC000FFFFFFFFFFFF
+FE0000FFFFFFFFFFFFE0000045447CC350>I<00000000FFF00000700000001FFFFF0000
+F0000001FFFFFFE001F0000007FFFFFFF803F000003FFFFFFFFE07F00000FFFFE001FF0F
+F00001FFFE00003F9FF00007FFF000000FFFF0000FFFC0000007FFF0001FFF00000003FF
+F0003FFE00000001FFF0007FFC00000000FFF000FFF8000000007FF001FFF0000000003F
+F003FFE0000000001FF007FFE0000000001FF007FFC0000000000FF00FFF80000000000F
+F00FFF800000000007F01FFF000000000007F01FFF000000000003F03FFF000000000003
+F03FFE000000000003F03FFE000000000003F07FFE000000000001F07FFE000000000001
+F07FFE000000000001F07FFC00000000000000FFFC00000000000000FFFC000000000000
+00FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC000000000000
+00FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC000000000000
+00FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC000000000000
+007FFC000000000000007FFE000000000000007FFE000000000000F07FFE000000000000
+F03FFE000000000000F03FFE000000000000F03FFF000000000000F01FFF000000000001
+F01FFF000000000001E00FFF800000000001E00FFF800000000003E007FFC00000000003
+C007FFE00000000007C003FFE00000000007C001FFF0000000000F8000FFF8000000001F
+00007FFC000000003F00003FFE000000007E00001FFF80000000FC00000FFFC0000001F8
+000007FFF0000007F0000001FFFE00001FE0000000FFFFF001FF800000003FFFFFFFFF00
+00000007FFFFFFFC0000000001FFFFFFF000000000001FFFFF80000000000000FFF80000
+0044467AC451>I<FFFFFFFFFFFF00000000FFFFFFFFFFFFF0000000FFFFFFFFFFFFFE00
+0000FFFFFFFFFFFFFF800000FFFFFFFFFFFFFFE00000003FFE00001FFFF80000003FFE00
+0001FFFC0000003FFE0000003FFF0000003FFE0000000FFF8000003FFE00000007FFC000
+003FFE00000003FFE000003FFE00000001FFF000003FFE00000000FFF000003FFE000000
+007FF800003FFE000000003FFC00003FFE000000003FFC00003FFE000000001FFE00003F
+FE000000001FFE00003FFE000000000FFF00003FFE000000000FFF00003FFE000000000F
+FF80003FFE000000000FFF80003FFE0000000007FF80003FFE0000000007FFC0003FFE00
+00000007FFC0003FFE0000000007FFC0003FFE0000000007FFC0003FFE0000000007FFC0
+003FFE0000000007FFE0003FFE0000000007FFE0003FFE0000000007FFE0003FFE000000
+0007FFE0003FFE0000000007FFE0003FFE0000000007FFE0003FFE0000000007FFE0003F
+FE0000000007FFE0003FFE0000000007FFE0003FFE0000000007FFE0003FFE0000000007
+FFE0003FFE0000000007FFE0003FFE0000000007FFE0003FFE0000000007FFC0003FFE00
+00000007FFC0003FFE0000000007FFC0003FFE0000000007FFC0003FFE0000000007FFC0
+003FFE0000000007FF80003FFE000000000FFF80003FFE000000000FFF80003FFE000000
+000FFF00003FFE000000001FFF00003FFE000000001FFE00003FFE000000003FFE00003F
+FE000000003FFC00003FFE000000007FF800003FFE00000000FFF800003FFE00000000FF
+F000003FFE00000001FFE000003FFE00000007FFC000003FFE0000000FFF8000003FFE00
+00003FFF0000003FFE000001FFFE0000003FFE00000FFFF80000FFFFFFFFFFFFFFF00000
+FFFFFFFFFFFFFFC00000FFFFFFFFFFFFFE000000FFFFFFFFFFFFF0000000FFFFFFFFFFFF
+000000004B447CC356>I<FFFFFFFFFFFFFFF800FFFFFFFFFFFFFFF800FFFFFFFFFFFFFF
+F800FFFFFFFFFFFFFFF800FFFFFFFFFFFFFFFC00001FFF000001FFFC00001FFF0000003F
+FC00001FFF0000000FFC00001FFF00000003FC00001FFF00000001FC00001FFF00000000
+FC00001FFF00000000FC00001FFF000000007E00001FFF000000003E00001FFF00000000
+3E00001FFF000000003E00001FFF000000001E00001FFF000000001E00001FFF00007800
+1E00001FFF000078001E00001FFF000078000F00001FFF000078000F00001FFF00007800
+0F00001FFF000078000F00001FFF0000F8000000001FFF0000F8000000001FFF0000F800
+0000001FFF0001F8000000001FFF0003F8000000001FFF001FF8000000001FFFFFFFF800
+0000001FFFFFFFF8000000001FFFFFFFF8000000001FFFFFFFF8000000001FFFFFFFF800
+0000001FFF001FF8000000001FFF0003F8000000001FFF0001F8000000001FFF0000F800
+0000001FFF0000F8000000001FFF0000F80001E0001FFF0000780001E0001FFF00007800
+01E0001FFF0000780003C0001FFF0000780003C0001FFF0000780003C0001FFF00007800
+03C0001FFF0000000003C0001FFF0000000007C0001FFF0000000007C0001FFF00000000
+0780001FFF000000000780001FFF000000000F80001FFF000000000F80001FFF00000000
+1F80001FFF000000001F80001FFF000000003F80001FFF000000007F00001FFF00000000
+FF00001FFF00000001FF00001FFF00000007FF00001FFF0000001FFF00001FFF000001FF
+FF00FFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFE00FFFFFFFFFFFFFFFE00FFFFFFFFFFFFFF
+FE00FFFFFFFFFFFFFFFE0043447DC34A>I<FFFFFFFFFFFFFF80FFFFFFFFFFFFFF80FFFF
+FFFFFFFFFF80FFFFFFFFFFFFFF80FFFFFFFFFFFFFFC0003FFE00001FFFC0003FFE000001
+FFC0003FFE0000007FC0003FFE0000003FC0003FFE0000001FC0003FFE0000000FC0003F
+FE00000007C0003FFE00000007E0003FFE00000003E0003FFE00000003E0003FFE000000
+03E0003FFE00000001E0003FFE00000001E0003FFE00000001E0003FFE0001E001E0003F
+FE0001E000F0003FFE0001E000F0003FFE0001E000F0003FFE0001E000F0003FFE0001E0
+0000003FFE0003E00000003FFE0003E00000003FFE0003E00000003FFE0007E00000003F
+FE000FE00000003FFE007FE00000003FFFFFFFE00000003FFFFFFFE00000003FFFFFFFE0
+0000003FFFFFFFE00000003FFFFFFFE00000003FFE007FE00000003FFE000FE00000003F
+FE0007E00000003FFE0003E00000003FFE0003E00000003FFE0003E00000003FFE0001E0
+0000003FFE0001E00000003FFE0001E00000003FFE0001E00000003FFE0001E00000003F
+FE0001E00000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000
+0000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003F
+FE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000
+0000003FFE0000000000003FFE0000000000FFFFFFFFF0000000FFFFFFFFF0000000FFFF
+FFFFF0000000FFFFFFFFF0000000FFFFFFFFF00000003C447CC346>I<00000000FFF000
+0070000000001FFFFF0000F000000001FFFFFFE001F000000007FFFFFFF803F00000003F
+FFFFFFFE07F0000000FFFFE001FF0FF0000001FFFE00003F9FF0000007FFF000000FFFF0
+00000FFFC0000007FFF000001FFF00000003FFF000003FFE00000001FFF000007FFC0000
+0000FFF00000FFF8000000007FF00001FFF0000000003FF00003FFE0000000001FF00007
+FFE0000000001FF00007FFC0000000000FF0000FFF80000000000FF0000FFF8000000000
+07F0001FFF000000000007F0001FFF000000000003F0003FFF000000000003F0003FFE00
+0000000003F0003FFE000000000003F0007FFE000000000001F0007FFE000000000001F0
+007FFE000000000001F0007FFC0000000000000000FFFC0000000000000000FFFC000000
+0000000000FFFC0000000000000000FFFC0000000000000000FFFC0000000000000000FF
+FC0000000000000000FFFC0000000000000000FFFC0000000000000000FFFC0000000000
+000000FFFC0000000000000000FFFC0000000000000000FFFC0000000000000000FFFC00
+00000000000000FFFC0000007FFFFFFFF07FFC0000007FFFFFFFF07FFE0000007FFFFFFF
+F07FFE0000007FFFFFFFF07FFE0000007FFFFFFFF03FFE0000000001FFF0003FFE000000
+0001FFF0003FFF0000000001FFF0001FFF0000000001FFF0001FFF0000000001FFF0000F
+FF8000000001FFF0000FFF8000000001FFF00007FFC000000001FFF00007FFE000000001
+FFF00003FFE000000001FFF00001FFF000000001FFF00000FFF800000001FFF000007FFC
+00000001FFF000003FFE00000003FFF000001FFF80000003FFF000000FFFC0000007FFF0
+000007FFF000000FFFF0000001FFFE00003FFFF0000000FFFFF001FF9FF00000003FFFFF
+FFFF0FF000000007FFFFFFFC03F000000001FFFFFFF000F0000000001FFFFFC000300000
+000000FFFC000000004C467AC458>I<FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0
+FFFFFFFFE0001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF000000
+1FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001F
+FF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF
+0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF00
+00001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000
+001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF000000
+1FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001F
+FF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF
+0000001FFF0000FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE023447DC3
+2A>73 D<FFFFFFFFF0000000FFFFFFFFF0000000FFFFFFFFF0000000FFFFFFFFF0000000
+FFFFFFFFF0000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE00
+00000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000
+003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE00
+00000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000
+003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE00
+00000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000
+003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE00
+00000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000
+003FFE0000000780003FFE0000000780003FFE0000000780003FFE0000000780003FFE00
+00000F80003FFE0000000F00003FFE0000000F00003FFE0000000F00003FFE0000000F00
+003FFE0000001F00003FFE0000001F00003FFE0000001F00003FFE0000003F00003FFE00
+00003F00003FFE0000007E00003FFE0000007E00003FFE000000FE00003FFE000001FE00
+003FFE000003FE00003FFE000007FE00003FFE00001FFE00003FFE00007FFE00003FFE00
+03FFFE00FFFFFFFFFFFFFC00FFFFFFFFFFFFFC00FFFFFFFFFFFFFC00FFFFFFFFFFFFFC00
+FFFFFFFFFFFFFC0039447CC343>76 D<FFFFFF00000001FFFFFEFFFFFF80000001FFFFFE
+FFFFFFC0000001FFFFFEFFFFFFC0000001FFFFFEFFFFFFE0000001FFFFFE003FFFF00000
+00007800003FFFF8000000007800003DFFFC000000007800003DFFFE000000007800003C
+FFFE000000007800003C7FFF000000007800003C3FFF800000007800003C1FFFC0000000
+7800003C0FFFE00000007800003C07FFF00000007800003C07FFF80000007800003C03FF
+F80000007800003C01FFFC0000007800003C00FFFE0000007800003C007FFF0000007800
+003C003FFF8000007800003C003FFFC000007800003C001FFFC000007800003C000FFFE0
+00007800003C0007FFF000007800003C0003FFF800007800003C0001FFFC00007800003C
+0000FFFE00007800003C0000FFFF00007800003C00007FFF00007800003C00003FFF8000
+7800003C00001FFFC0007800003C00000FFFE0007800003C000007FFF0007800003C0000
+07FFF8007800003C000003FFF8007800003C000001FFFC007800003C000000FFFE007800
+003C0000007FFF007800003C0000003FFF807800003C0000001FFFC07800003C0000001F
+FFE07800003C0000000FFFE07800003C00000007FFF07800003C00000003FFF87800003C
+00000001FFFC7800003C00000000FFFE7800003C00000000FFFF7800003C000000007FFF
+7800003C000000003FFFF800003C000000001FFFF800003C000000000FFFF800003C0000
+000007FFF800003C0000000003FFF800003C0000000003FFF800003C0000000001FFF800
+003C0000000000FFF800003C00000000007FF800003C00000000003FF800003C00000000
+001FF800003C00000000001FF800003C00000000000FF800003C000000000007F800FFFF
+FF0000000003F800FFFFFF0000000001F800FFFFFF0000000000F800FFFFFF0000000000
+7800FFFFFF000000000078004F447CC358>78 D<00000007FFC0000000000000FFFFFE00
+0000000007FFFFFFC0000000001FFFFFFFF0000000007FFE00FFFC00000001FFF0001FFF
+00000007FF800003FFC000000FFF000001FFE000001FFC0000007FF000003FF80000003F
+F800007FF00000001FFC0000FFF00000001FFE0001FFE00000000FFF0003FFC000000007
+FF8003FFC000000007FF8007FF8000000003FFC007FF8000000003FFC00FFF0000000001
+FFE00FFF0000000001FFE01FFF0000000001FFF01FFE0000000000FFF03FFE0000000000
+FFF83FFE0000000000FFF83FFE0000000000FFF87FFE0000000000FFFC7FFC0000000000
+7FFC7FFC00000000007FFC7FFC00000000007FFC7FFC00000000007FFCFFFC0000000000
+7FFEFFFC00000000007FFEFFFC00000000007FFEFFFC00000000007FFEFFFC0000000000
+7FFEFFFC00000000007FFEFFFC00000000007FFEFFFC00000000007FFEFFFC0000000000
+7FFEFFFC00000000007FFEFFFC00000000007FFEFFFC00000000007FFEFFFC0000000000
+7FFE7FFC00000000007FFC7FFE0000000000FFFC7FFE0000000000FFFC7FFE0000000000
+FFFC3FFE0000000000FFF83FFE0000000000FFF83FFF0000000001FFF81FFF0000000001
+FFF01FFF0000000001FFF01FFF8000000003FFF00FFF8000000003FFE00FFF8000000003
+FFE007FFC000000007FFC003FFC000000007FF8003FFE00000000FFF8001FFF00000001F
+FF0000FFF80000003FFE00007FFC0000007FFC00003FFE000000FFF800001FFF000001FF
+F000000FFFC00007FFE0000007FFF0001FFFC0000001FFFE00FFFF00000000FFFFFFFFFE
+000000003FFFFFFFF80000000007FFFFFFC00000000000FFFFFE00000000000007FFC000
+000047467AC454>I<FFFFFFFFFFFF000000FFFFFFFFFFFFF00000FFFFFFFFFFFFFE0000
+FFFFFFFFFFFFFF8000FFFFFFFFFFFFFFE000001FFF00000FFFF000001FFF000001FFF800
+001FFF0000007FFC00001FFF0000003FFE00001FFF0000001FFF00001FFF0000000FFF80
+001FFF0000000FFF80001FFF0000000FFFC0001FFF00000007FFC0001FFF00000007FFC0
+001FFF00000007FFE0001FFF00000007FFE0001FFF00000007FFE0001FFF00000007FFE0
+001FFF00000007FFE0001FFF00000007FFE0001FFF00000007FFE0001FFF00000007FFE0
+001FFF00000007FFE0001FFF00000007FFC0001FFF00000007FFC0001FFF0000000FFF80
+001FFF0000000FFF80001FFF0000000FFF00001FFF0000001FFF00001FFF0000003FFE00
+001FFF0000007FFC00001FFF000001FFF800001FFF00000FFFF000001FFFFFFFFFFFC000
+001FFFFFFFFFFF0000001FFFFFFFFFFC0000001FFFFFFFFFC00000001FFF000000000000
+001FFF000000000000001FFF000000000000001FFF000000000000001FFF000000000000
+001FFF000000000000001FFF000000000000001FFF000000000000001FFF000000000000
+001FFF000000000000001FFF000000000000001FFF000000000000001FFF000000000000
+001FFF000000000000001FFF000000000000001FFF000000000000001FFF000000000000
+001FFF000000000000001FFF000000000000001FFF000000000000001FFF000000000000
+001FFF000000000000001FFF000000000000001FFF000000000000001FFF000000000000
+FFFFFFFFE000000000FFFFFFFFE000000000FFFFFFFFE000000000FFFFFFFFE000000000
+FFFFFFFFE00000000043447DC34D>I<FFFFFFFFFFF800000000FFFFFFFFFFFFC0000000
+FFFFFFFFFFFFF8000000FFFFFFFFFFFFFE000000FFFFFFFFFFFFFF800000001FFF00003F
+FFE00000001FFF000003FFF00000001FFF000000FFF80000001FFF0000007FFC0000001F
+FF0000003FFE0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000001FFF
+8000001FFF0000000FFF8000001FFF0000000FFF8000001FFF0000000FFFC000001FFF00
+00000FFFC000001FFF0000000FFFC000001FFF0000000FFFC000001FFF0000000FFFC000
+001FFF0000000FFFC000001FFF0000000FFFC000001FFF0000000FFF8000001FFF000000
+0FFF8000001FFF0000001FFF0000001FFF0000001FFF0000001FFF0000003FFE0000001F
+FF0000003FFC0000001FFF0000007FFC0000001FFF000001FFF00000001FFF000007FFE0
+0000001FFF00003FFF800000001FFFFFFFFFFF000000001FFFFFFFFFF8000000001FFFFF
+FFFFE0000000001FFFFFFFFFF8000000001FFF0000FFFC000000001FFF00003FFF000000
+001FFF00000FFF800000001FFF000007FFC00000001FFF000003FFE00000001FFF000003
+FFE00000001FFF000001FFF00000001FFF000001FFF00000001FFF000000FFF80000001F
+FF000000FFF80000001FFF000000FFF80000001FFF000000FFF80000001FFF000000FFF8
+0000001FFF000000FFF80000001FFF000000FFF80000001FFF000000FFFC0000001FFF00
+0000FFFC0000001FFF000000FFFC0000001FFF000000FFFC0000001FFF000000FFFC0000
+001FFF000000FFFC0000001FFF000000FFFC000F001FFF000000FFFE000F001FFF000000
+FFFE000F001FFF0000007FFE000F001FFF0000007FFF001F001FFF0000003FFF001EFFFF
+FFFFE0001FFF803EFFFFFFFFE0000FFFE0FCFFFFFFFFE00007FFFFF8FFFFFFFFE00001FF
+FFF0FFFFFFFFE000007FFFE00000000000000007FF8050457DC354>82
+D<0000FFE0001C000007FFFE003C00003FFFFF807C0000FFFFFFE0FC0001FFFFFFF9FC00
+03FF801FFFFC0007FC0001FFFC000FF800007FFC001FF000003FFC003FE000000FFC003F
+C0000007FC007FC0000003FC007F80000003FC007F80000001FC007F80000000FC00FF80
+000000FC00FF800000007C00FF800000007C00FFC00000007C00FFC00000007C00FFE000
+00003C00FFF00000003C00FFF80000003C00FFFC00000000007FFE00000000007FFFE000
+0000007FFFFE000000003FFFFFF00000003FFFFFFF0000001FFFFFFFE000001FFFFFFFFC
+00000FFFFFFFFE000007FFFFFFFF800003FFFFFFFFC00001FFFFFFFFE000007FFFFFFFF0
+00001FFFFFFFF8000007FFFFFFFC000000FFFFFFFC0000000FFFFFFE00000000FFFFFE00
+00000007FFFF00000000007FFF00000000003FFF00000000000FFF800000000007FF8000
+00000003FF80F000000003FF80F000000001FF80F000000001FF80F000000000FF80F000
+000000FF80F800000000FF80F800000000FF80F800000000FF00FC00000000FF00FC0000
+0000FF00FE00000001FF00FF00000001FE00FF80000003FE00FFC0000003FC00FFE00000
+07FC00FFF800000FF800FFFF00003FF000FFFFF800FFE000FE7FFFFFFFC000FC1FFFFFFF
+0000F807FFFFFC0000F000FFFFF00000E00007FF80000031467AC43E>I<3FFFFFFFFFFF
+FFFFE03FFFFFFFFFFFFFFFE03FFFFFFFFFFFFFFFE03FFFFFFFFFFFFFFFE03FFFFFFFFFFF
+FFFFE03FFE000FFF8003FFE07FE0000FFF80003FF07FC0000FFF80001FF07F00000FFF80
+0007F07F00000FFF800007F07E00000FFF800003F07C00000FFF800001F07C00000FFF80
+0001F07C00000FFF800001F07800000FFF800000F07800000FFF800000F07800000FFF80
+0000F07800000FFF800000F0F800000FFF800000F8F000000FFF80000078F000000FFF80
+000078F000000FFF80000078F000000FFF80000078F000000FFF800000780000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000000000FFF800000000000000FFF800000000000000FFF80
+0000000000000FFF800000000007FFFFFFFFFF00000007FFFFFFFFFF00000007FFFFFFFF
+FF00000007FFFFFFFFFF00000007FFFFFFFFFF000045437CC24E>I<FFFFFFFF000000FF
+FFFFFFFFFFFF000000FFFFFFFFFFFFFF000000FFFFFFFFFFFFFF000000FFFFFFFFFFFFFF
+000000FFFFFF003FFE0000000000FC00003FFF0000000000FC00001FFF0000000000F800
+001FFF8000000001F800000FFF8000000001F000000FFFC000000001F000000FFFC00000
+0003F0000007FFC000000003E0000007FFE000000007E0000003FFE000000007C0000003
+FFF00000000FC0000001FFF00000000F80000001FFF80000000F80000001FFF80000001F
+80000000FFFC0000001F00000000FFFC0000003F000000007FFC0000003E000000007FFE
+0000007E000000003FFE0000007C000000003FFF0000007C000000003FFF000000FC0000
+00001FFF800000F8000000001FFF800001F8000000000FFF800001F0000000000FFFC000
+03F00000000007FFC00003E00000000007FFE00003E00000000007FFE00007E000000000
+03FFF00007C00000000003FFF0000FC00000000001FFF0000F800000000001FFF8001F80
+0000000000FFF8001F000000000000FFFC003F0000000000007FFC003E0000000000007F
+FE003E0000000000007FFE007E0000000000003FFE007C0000000000003FFF00FC000000
+0000001FFF00F80000000000001FFF81F80000000000000FFF81F00000000000000FFFC1
+F00000000000000FFFC3F000000000000007FFC3E000000000000007FFE7E00000000000
+0003FFE7C000000000000003FFFFC000000000000001FFFF8000000000000001FFFF8000
+000000000001FFFF8000000000000000FFFF0000000000000000FFFF0000000000000000
+7FFE00000000000000007FFE00000000000000003FFC00000000000000003FFC00000000
+000000003FFC00000000000000001FF800000000000000001FF800000000000000000FF0
+00000000000000000FF0000000000000000007E0000000000000000007E0000000005045
+7EC355>86 D<7FFFFFFFC003FFFFFF807FFFFFFFC003FFFFFF807FFFFFFFC003FFFFFF80
+7FFFFFFFC003FFFFFF807FFFFFFFC003FFFFFF80000FFFE0000001F800000007FFE00000
+03F000000007FFF0000007F000000003FFF8000007E000000001FFFC00000FC000000001
+FFFC00001F8000000000FFFE00003F80000000007FFF00003F00000000003FFF00007E00
+000000003FFF8000FC00000000001FFFC001FC00000000000FFFE001F800000000000FFF
+E003F0000000000007FFF007E0000000000003FFF80FE0000000000001FFFC0FC0000000
+000001FFFC1F80000000000000FFFE3F000000000000007FFF7F000000000000003FFF7E
+000000000000003FFFFC000000000000001FFFF8000000000000000FFFF8000000000000
+000FFFF00000000000000007FFF00000000000000003FFF80000000000000001FFF80000
+000000000001FFFC0000000000000000FFFE00000000000000007FFF0000000000000000
+FFFF0000000000000000FFFF8000000000000001FFFFC000000000000003FFFFC0000000
+00000007FFFFE000000000000007E7FFF00000000000000FC3FFF80000000000001F83FF
+F80000000000003F81FFFC0000000000003F00FFFE0000000000007E007FFE0000000000
+00FC007FFF000000000001FC003FFF800000000001F8001FFFC00000000003F0001FFFC0
+0000000007E0000FFFE0000000000FE00007FFF0000000000FC00003FFF0000000001F80
+0003FFF8000000003F000001FFFC000000003F000000FFFE000000007E000000FFFE0000
+0000FC0000007FFF00000001FC0000003FFF80000001F80000001FFF80000003F0000000
+1FFFC0000007E00000000FFFE000000FE000000007FFF000FFFFFFE00003FFFFFFFCFFFF
+FFE00003FFFFFFFCFFFFFFE00003FFFFFFFCFFFFFFE00003FFFFFFFCFFFFFFE00003FFFF
+FFFC4E447DC355>88 D<0001FFE0000000001FFFFE000000007FFFFF80000001FFFFFFE0
+000003FE007FF8000007FC001FFC000007FE000FFE00000FFF0007FF00000FFF0007FF00
+000FFF0003FF80000FFF0003FF80000FFF0003FF80000FFF0001FFC00007FE0001FFC000
+03FC0001FFC00000F00001FFC00000000001FFC00000000001FFC00000000001FFC00000
+000001FFC000000003FFFFC0000000FFFFFFC0000007FFFFFFC000003FFFF1FFC00000FF
+FC01FFC00003FFE001FFC0000FFF8001FFC0001FFE0001FFC0003FFC0001FFC0003FF800
+01FFC0007FF80001FFC0007FF00001FFC000FFF00001FFC000FFE00001FFC000FFE00001
+FFC000FFE00001FFC000FFE00003FFC000FFE00003FFC000FFF00007FFC0007FF8000FFF
+C0007FF8001FFFF0003FFE003EFFFFC01FFF80FC7FFFC007FFFFF87FFFC003FFFFE01FFF
+C0007FFF8007FFC0000FFC00000000322F7DAD36>97 D<007FC000000000FFFFC0000000
+00FFFFC000000000FFFFC000000000FFFFC000000000FFFFC00000000003FFC000000000
+01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001
+FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FF
+C00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0
+0000000001FFC00000000001FFC00FF8000001FFC0FFFF800001FFC3FFFFE00001FFCFFF
+FFF80001FFDFC03FFC0001FFFF000FFE0001FFFC0003FF0001FFF80001FF8001FFF00001
+FFC001FFE00000FFE001FFC00000FFE001FFC000007FF001FFC000007FF001FFC000007F
+F801FFC000003FF801FFC000003FF801FFC000003FF801FFC000003FFC01FFC000003FFC
+01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01
+FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FF
+C000003FF801FFC000003FF801FFC000007FF801FFC000007FF001FFC000007FF001FFC0
+00007FF001FFC00000FFE001FFE00000FFC001FFF00001FFC001FFF80003FF8001FF7C00
+07FF0001FE3E000FFE0001FC1FC07FFC0001F80FFFFFF00001F003FFFFC00001E000FFFF
+00000000001FF0000036467DC43E>I<00003FFC00000001FFFFC000000FFFFFF000003F
+FFFFFC00007FF003FE0000FFC001FF0003FF8003FF0007FF0007FF8007FE0007FF800FFE
+0007FF801FFC0007FF801FFC0007FF803FF80007FF803FF80003FF007FF80001FE007FF8
+000078007FF0000000007FF000000000FFF000000000FFF000000000FFF000000000FFF0
+00000000FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF0
+00000000FFF000000000FFF0000000007FF8000000007FF8000000007FF8000000003FF8
+000000003FFC000003C03FFC000003C01FFE000007C00FFE000007800FFF00000F8007FF
+80001F0003FFC0003E0001FFF0007C00007FFC03F800003FFFFFF000000FFFFFC0000003
+FFFF000000003FF800002A2F7CAD32>I<0000000003FE0000000007FFFE0000000007FF
+FE0000000007FFFE0000000007FFFE0000000007FFFE00000000001FFE00000000000FFE
+00000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE00
+000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE0000
+0000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE000000
+00000FFE0000003FE00FFE000003FFFC0FFE00000FFFFF8FFE00003FFFFFCFFE0000FFF8
+07FFFE0001FFC001FFFE0003FF80007FFE0007FF00003FFE000FFE00001FFE000FFC0000
+0FFE001FFC00000FFE003FF800000FFE003FF800000FFE003FF800000FFE007FF800000F
+FE007FF000000FFE007FF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE
+00FFF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE00
+FFF000000FFE00FFF000000FFE00FFF000000FFE00FFF000000FFE007FF000000FFE007F
+F000000FFE007FF000000FFE007FF800000FFE003FF800000FFE003FF800000FFE001FFC
+00001FFE001FFC00001FFE000FFE00003FFE0007FE00007FFE0003FF0000FFFF0001FFC0
+03FFFFFC00FFF01FEFFFFC007FFFFF8FFFFC001FFFFE0FFFFC0007FFF80FFFFC00007FC0
+0FF80036467CC43E>I<00003FF800000003FFFF8000000FFFFFE000003FFFFFF000007F
+F83FF80000FFC007FC0001FF8003FE0003FF0001FF0007FE0000FF800FFC0000FF801FFC
+00007FC01FF800007FC03FF800003FE03FF800003FE07FF800003FE07FF000003FE07FF0
+00003FF07FF000001FF0FFF000001FF0FFF000001FF0FFFFFFFFFFF0FFFFFFFFFFF0FFFF
+FFFFFFF0FFFFFFFFFFF0FFF000000000FFF000000000FFF000000000FFF000000000FFF0
+000000007FF0000000007FF0000000007FF8000000007FF8000000003FF8000000003FF8
+000000F01FFC000000F01FFC000001F00FFE000001E007FF000003E003FF800007C001FF
+C0000F8000FFF0003F00007FFE01FE00001FFFFFFC000007FFFFF0000001FFFFC0000000
+1FFE00002C2F7DAD33>I<000000FF8000000FFFE000007FFFF00001FFFFF80003FF8FFC
+000FFE0FFE001FFC1FFE001FF81FFE003FF81FFE007FF01FFE007FF01FFE007FF00FFC00
+FFE00FFC00FFE003F000FFE000C000FFE0000000FFE0000000FFE0000000FFE0000000FF
+E0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00000FFFFFF
+F800FFFFFFF800FFFFFFF800FFFFFFF800FFFFFFF80000FFE0000000FFE0000000FFE000
+0000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00000
+00FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000
+FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FF
+E0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0
+000000FFE0000000FFE000007FFFFFE0007FFFFFE0007FFFFFE0007FFFFFE0007FFFFFE0
+0027467DC522>I<0000FFE0007E00000FFFFE03FF80003FFFFF8FFF8000FFFFFFFFFFC0
+01FFC07FFF3FC003FF001FF83FC007FE000FFC3FC00FFC0007FE1F801FFC0007FF0F001F
+F80003FF00001FF80003FF00003FF80003FF80003FF80003FF80003FF80003FF80003FF8
+0003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80001FF800
+03FF00001FF80003FF00001FFC0007FF00000FFC0007FE000007FE000FFC000003FF001F
+F8000001FFC07FF0000003FFFFFFE0000003FFFFFF800000078FFFFE0000000780FFE000
+00000F8000000000000F8000000000000F8000000000000F8000000000000FC000000000
+000FE000000000000FF000000000000FFFFFFFC000000FFFFFFFFC000007FFFFFFFF8000
+07FFFFFFFFE00003FFFFFFFFF00001FFFFFFFFFC0000FFFFFFFFFC0003FFFFFFFFFE000F
+FFFFFFFFFF001FF000007FFF003FC0000007FF007F80000001FF807F80000000FF80FF00
+000000FF80FF000000007F80FF000000007F80FF000000007F80FF000000007F80FF8000
+0000FF807F80000000FF007FC0000001FF003FE0000003FE001FF0000007FC000FFE0000
+3FF80007FFC001FFF00001FFFFFFFFC000007FFFFFFF0000000FFFFFF8000000007FFF00
+000032427DAC38>I<007FC000000000FFFFC000000000FFFFC000000000FFFFC0000000
+00FFFFC000000000FFFFC00000000003FFC00000000001FFC00000000001FFC000000000
+01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001
+FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FF
+C00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0
+07FE000001FFC03FFF800001FFC0FFFFE00001FFC1FFFFF80001FFC7F03FFC0001FFCF80
+1FFC0001FFDF000FFE0001FFDE000FFE0001FFFC000FFE0001FFF80007FF0001FFF00007
+FF0001FFF00007FF0001FFE00007FF0001FFE00007FF0001FFE00007FF0001FFC00007FF
+0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF00
+01FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001
+FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FF
+C00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC0
+0007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF00FFFFFF83FFFFFEFFFFFF83
+FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFE37457CC43E>I<007C0001FF
+0003FF8007FFC007FFC00FFFE00FFFE00FFFE00FFFE00FFFE007FFC007FFC003FF8001FF
+00007C00000000000000000000000000000000000000000000000000000000000000007F
+C07FFFC07FFFC07FFFC07FFFC07FFFC003FFC001FFC001FFC001FFC001FFC001FFC001FF
+C001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FF
+C001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FFC001FF
+C001FFC001FFC001FFC0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18467CC520>I<007FC000
+000000FFFFC000000000FFFFC000000000FFFFC000000000FFFFC000000000FFFFC00000
+000003FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0000000
+0001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC000000000
+01FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001
+FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0007FFFE001FF
+C0007FFFE001FFC0007FFFE001FFC0007FFFE001FFC0007FFFE001FFC0000FE00001FFC0
+001FC00001FFC0003F000001FFC0007E000001FFC000FC000001FFC003F8000001FFC007
+E0000001FFC00FC0000001FFC01F80000001FFC07F00000001FFC0FE00000001FFC1FC00
+000001FFC3FE00000001FFC7FE00000001FFDFFF00000001FFFFFF80000001FFFFFFC000
+0001FFFFFFC0000001FFF9FFE0000001FFE1FFF0000001FFC0FFF8000001FF807FF80000
+01FF803FFC000001FF803FFE000001FF801FFF000001FF800FFF000001FF8007FF800001
+FF8007FFC00001FF8003FFE00001FF8001FFE00001FF8000FFF00001FF8000FFF80001FF
+80007FFC0001FF80003FFC00FFFFFF03FFFFF8FFFFFF03FFFFF8FFFFFF03FFFFF8FFFFFF
+03FFFFF8FFFFFF03FFFFF835457DC43B>107 D<007FC000FFFFC000FFFFC000FFFFC000
+FFFFC000FFFFC00003FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC000
+01FFC00001FFC00001FFC00001FFC00001FFC00001FFC000FFFFFF80FFFFFF80FFFFFF80
+FFFFFF80FFFFFF8019457CC420>I<007F8007FE00000FFC0000FFFF803FFFC0007FFF80
+00FFFF80FFFFF001FFFFE000FFFF81FFFFF803FFFFF000FFFF87F01FFC0FE03FF800FFFF
+8FC00FFE1F801FFC0003FF9F000FFF3E001FFE0001FF9E0007FF3C000FFE0001FFBC0007
+FF78000FFE0001FFF80003FFF00007FF0001FFF80003FFF00007FF0001FFF00003FFE000
+07FF0001FFE00003FFC00007FF0001FFE00003FFC00007FF0001FFE00003FFC00007FF00
+01FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC0
+0003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF
+800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007
+FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001
+FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC000
+03FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF80
+0007FF0001FFC00003FF800007FF0001FFC00003FF800007FF0001FFC00003FF800007FF
+0001FFC00003FF800007FF0001FFC00003FF800007FF00FFFFFF81FFFFFF03FFFFFEFFFF
+FF81FFFFFF03FFFFFEFFFFFF81FFFFFF03FFFFFEFFFFFF81FFFFFF03FFFFFEFFFFFF81FF
+FFFF03FFFFFE572D7CAC5E>I<007F8007FE0000FFFF803FFF8000FFFF80FFFFE000FFFF
+81FFFFF800FFFF87F03FFC00FFFF8F801FFC0003FF9F000FFE0001FF9E000FFE0001FFBC
+000FFE0001FFF80007FF0001FFF00007FF0001FFF00007FF0001FFE00007FF0001FFE000
+07FF0001FFE00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007
+FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF
+0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF00
+01FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001
+FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FF
+C00007FF00FFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF83FFFFFEFFFFFF
+83FFFFFE372D7CAC3E>I<00001FFC0000000001FFFFC000000007FFFFF00000001FFFFF
+FC0000007FF80FFF000000FFC001FF800001FF8000FFC00003FE00003FE00007FE00003F
+F0000FFC00001FF8000FF800000FF8001FF800000FFC001FF800000FFC003FF800000FFE
+003FF0000007FE007FF0000007FF007FF0000007FF007FF0000007FF007FF0000007FF00
+FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF80FF
+F0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF80FFF0000007FF807FF0
+000007FF007FF0000007FF007FF0000007FF007FF0000007FF003FF800000FFE003FF800
+000FFE001FF800000FFC001FFC00001FFC000FFC00001FF80007FE00003FF00007FE0000
+3FF00003FF8000FFE00001FFC001FFC000007FF80FFF0000003FFFFFFE0000000FFFFFF8
+00000001FFFFC0000000001FFC000000312F7DAD38>I<007FC00FF80000FFFFC0FFFF80
+00FFFFC3FFFFE000FFFFCFFFFFF800FFFFDFC03FFC00FFFFFF001FFE0003FFFC0007FF00
+01FFF80003FF8001FFF00003FFC001FFE00001FFE001FFC00001FFE001FFC00000FFF001
+FFC00000FFF001FFC000007FF801FFC000007FF801FFC000007FF801FFC000007FF801FF
+C000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC0
+00003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000003FFC01FFC000
+003FFC01FFC000003FFC01FFC000007FF801FFC000007FF801FFC000007FF801FFC00000
+7FF001FFC00000FFF001FFC00000FFF001FFC00001FFE001FFE00001FFC001FFF00003FF
+C001FFF80007FF8001FFFC000FFF0001FFFE001FFE0001FFDFC07FFC0001FFCFFFFFF000
+01FFC3FFFFC00001FFC0FFFF000001FFC01FF0000001FFC00000000001FFC00000000001
+FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FF
+C00000000001FFC00000000001FFC00000000001FFC00000000001FFC00000000001FFC0
+00000000FFFFFF80000000FFFFFF80000000FFFFFF80000000FFFFFF80000000FFFFFF80
+00000036407DAC3E>I<007F807F00FFFF81FFE0FFFF83FFF0FFFF8FFFF8FFFF8F8FFCFF
+FF9F1FFE03FFBE1FFE01FFBC1FFE01FFF81FFE01FFF81FFE01FFF01FFE01FFF00FFC01FF
+E007F801FFE001E001FFE0000001FFE0000001FFE0000001FFC0000001FFC0000001FFC0
+000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC000
+0001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC00000
+01FFC0000001FFC0000001FFC0000001FFC0000001FFC0000001FFC00000FFFFFFE000FF
+FFFFE000FFFFFFE000FFFFFFE000FFFFFFE000272D7DAC2E>114
+D<001FFC038000FFFF878003FFFFFF800FFFFFFF801FF003FF803FC000FF803F80003F80
+7F00001F807E00001F80FE00000F80FE00000F80FE00000780FF00000780FF00000780FF
+80000780FFE0000000FFFE0000007FFFF000007FFFFF00003FFFFFC0003FFFFFF0001FFF
+FFFC000FFFFFFE0003FFFFFF0001FFFFFF80007FFFFF80000FFFFFC000003FFFC0000003
+FFE0000000FFE0F000003FE0F000003FE0F800001FE0F800000FE0F800000FE0FC00000F
+E0FC00000FE0FE00000FC0FF00001FC0FF00001FC0FF80003F80FFE0007F00FFF803FE00
+FFFFFFFC00FCFFFFF800F03FFFE000E007FE0000232F7CAD2C>I<0001E000000001E000
+000001E000000001E000000001E000000003E000000003E000000003E000000003E00000
+0007E000000007E00000000FE00000000FE00000001FE00000001FE00000003FE0000000
+7FE0000000FFE0000003FFE000000FFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFF
+FFFF8000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0
+000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000
+0000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE00000
+00FFE001E000FFE001E000FFE001E000FFE001E000FFE001E000FFE001E000FFE001E000
+FFE001E000FFE001E000FFE003E000FFF003C0007FF003C0007FF007C0003FF80F80001F
+FC1F00000FFFFF000007FFFC000001FFF80000003FE00023407EBE2C>I<007FC00001FF
+00FFFFC003FFFF00FFFFC003FFFF00FFFFC003FFFF00FFFFC003FFFF00FFFFC003FFFF00
+03FFC0000FFF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001
+FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FF
+C00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC0
+0007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC000
+07FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007FF0001FFC00007
+FF0001FFC00007FF0001FFC0000FFF0001FFC0000FFF0001FFC0001FFF0001FFC0001FFF
+0001FFC0003FFF0000FFC0003FFF0000FFE0007FFF80007FE001F7FFFE007FF807E7FFFE
+003FFFFFC7FFFE000FFFFF07FFFE0003FFFE07FFFE00007FF007FC00372E7CAC3E>I<FF
+FFFF0003FFFCFFFFFF0003FFFCFFFFFF0003FFFCFFFFFF0003FFFCFFFFFF0003FFFC01FF
+E000003E0000FFE000003C0000FFF000003C00007FF000007800007FF800007800007FF8
+0000F800003FF80000F000003FFC0001F000001FFC0001E000001FFE0003E000000FFE00
+03C000000FFF0007C0000007FF000780000007FF800F80000003FF800F00000003FFC00F
+00000003FFC01F00000001FFE01E00000001FFE03E00000000FFE03C00000000FFF07C00
+0000007FF078000000007FF8F8000000003FF8F0000000003FFDF0000000001FFDE00000
+00001FFFE0000000000FFFC0000000000FFFC0000000000FFFC00000000007FF80000000
+0007FF800000000003FF000000000003FF000000000001FE000000000001FE0000000000
+00FC000000000000FC00000000000078000000362C7EAB3B>I<FFFFFE1FFFFF801FFFF0
+FFFFFE1FFFFF801FFFF0FFFFFE1FFFFF801FFFF0FFFFFE1FFFFF801FFFF0FFFFFE1FFFFF
+801FFFF001FFC0003FE000007C0001FFC0003FF00000780001FFE0003FF00000F80000FF
+E0001FF80000F00000FFF0001FF80001F000007FF0000FFC0001E000007FF0000FFC0001
+E000007FF8001FFC0003E000003FF8001FFE0003C000003FFC003FFE0007C000001FFC00
+3FFF00078000001FFC003FFF00078000001FFE0079FF000F8000000FFE0079FF800F0000
+000FFF00F9FF801F00000007FF00F0FFC01E00000007FF80F0FFC01E00000003FF81E07F
+C03C00000003FF81E07FE03C00000003FFC3E07FE07C00000001FFC3C03FF07800000001
+FFE7C03FF07800000000FFE7801FF0F000000000FFE7801FF8F000000000FFFF801FF9F0
+000000007FFF000FFDE0000000007FFF000FFFE0000000003FFE0007FFC0000000003FFE
+0007FFC0000000003FFE0007FFC0000000001FFC0003FF80000000001FFC0003FF800000
+00000FF80001FF00000000000FF80001FF00000000000FF00000FF000000000007F00000
+FE000000000007F00000FE000000000003E000007C000000000003C000003C0000004C2C
+7EAB51>I<FFFFFE003FFFF0FFFFFE003FFFF0FFFFFE003FFFF0FFFFFE003FFFF0FFFFFE
+003FFFF000FFF00003E000007FF80007C000003FF8000F8000001FFC001F0000001FFE00
+3F0000000FFF007E00000007FF807C00000003FFC0F800000001FFC1F000000001FFE3E0
+00000000FFF7C0000000007FFF80000000003FFF80000000001FFF00000000001FFE0000
+0000000FFF000000000007FF800000000003FFC00000000003FFC00000000007FFE00000
+00000FFFF0000000000FFFF8000000001F3FFC000000003E1FFC000000007C1FFE000000
+00F80FFF00000001F007FF80000003F003FFC0000007E001FFC0000007C001FFE000000F
+8000FFF000001F00007FF800003E00003FFC00007E00001FFC00FFFFE000FFFFFCFFFFE0
+00FFFFFCFFFFE000FFFFFCFFFFE000FFFFFCFFFFE000FFFFFC362C7EAB3B>I<FFFFFF00
+03FFFCFFFFFF0003FFFCFFFFFF0003FFFCFFFFFF0003FFFCFFFFFF0003FFFC01FFE00000
+3E0000FFE000003C0000FFF000003C00007FF000007800007FF800007800007FF80000F8
+00003FF80000F000003FFC0001F000001FFC0001E000001FFE0003E000000FFE0003C000
+000FFF0007C0000007FF000780000007FF800F80000003FF800F00000003FFC00F000000
+03FFC01F00000001FFE01E00000001FFE03E00000000FFE03C00000000FFF07C00000000
+7FF078000000007FF8F8000000003FF8F0000000003FFDF0000000001FFDE0000000001F
+FFE0000000000FFFC0000000000FFFC0000000000FFFC00000000007FF800000000007FF
+800000000003FF000000000003FF000000000001FE000000000001FE000000000000FC00
+0000000000FC0000000000007800000000000078000000000000F8000000000000F00000
+00000001F0000000000001E00000001F0003E00000003F8003C00000007FC007C0000000
+FFE00780000000FFE00F80000000FFE00F00000000FFE01F00000000FFE03E00000000FF
+C07C000000007FC1F8000000007F07F0000000003FFFE0000000001FFFC00000000007FF
+000000000001FC000000000036407EAB3B>I<1FFFFFFFFF801FFFFFFFFF801FFFFFFFFF
+801FFFFFFFFF801FFC001FFF001FE0003FFE001FC0003FFE001F80007FFC001F0000FFF8
+003F0001FFF0003E0001FFF0003E0003FFE0003E0007FFC0003C000FFF80003C000FFF80
+003C001FFF00003C003FFE00003C007FFC000000007FFC00000000FFF800000001FFF000
+000003FFE000000003FFE000000007FFC00000000FFF800780001FFF000780001FFF0007
+80003FFE000780007FFC000F8000FFF8000F0000FFF8000F0001FFF0000F0003FFE0001F
+0007FFC0001F0007FFC0001F000FFF80003F001FFF00007F003FFE0000FF003FFE0003FF
+007FFC001FFE00FFFFFFFFFE00FFFFFFFFFE00FFFFFFFFFE00FFFFFFFFFE00292C7DAB32
+>I E /Fk 8 121 df<FFFFF0FFFFF0FFFFF0FFFFF014047E911C>45
+D<00000060000000000000F0000000000000F0000000000000F0000000000001F8000000
+000001F8000000000001F8000000000003FC000000000003FC000000000007FE00000000
+0006FE000000000006FE00000000000EFF00000000000C7F00000000000C7F0000000000
+187F8000000000183F8000000000183F8000000000301FC000000000301FC00000000070
+1FE000000000600FE000000000600FE000000000C00FF000000000C007F000000000C007
+F0000000018003F8000000018003F8000000018003F8000000030001FC000000030001FC
+000000070001FE000000060000FE000000060000FE0000000FFFFFFF0000000FFFFFFF00
+00000FFFFFFF0000001800003F8000001800003F8000001800003F8000003000001FC000
+003000001FC000007000001FE000006000000FE000006000000FE00000C000000FF00000
+C0000007F00001C0000007F00001C0000003F80003E0000003F8000FF000000FFC00FFFE
+0000FFFFF0FFFE0000FFFFF0FFFE0000FFFFF034367CB53D>65 D<FFFFFFFFFFE0FFFFFF
+FFFFE0FFFFFFFFFFE003FC00003FE001FC000007E001FC000001F001FC000000F001FC00
+0000F001FC0000007001FC0000007001FC0000003001FC0000003001FC0000003001FC00
+00003001FC0006001801FC0006001801FC0006001801FC0006001801FC0006000001FC00
+0E000001FC000E000001FC001E000001FC007E000001FFFFFE000001FFFFFE000001FFFF
+FE000001FC007E000001FC001E000001FC000E000001FC000E000001FC0006000001FC00
+06000601FC0006000601FC0006000601FC0006000C01FC0000000C01FC0000000C01FC00
+00000C01FC0000000C01FC0000001C01FC0000001C01FC0000003801FC0000003801FC00
+00007801FC000000F801FC000001F801FC000007F803FC00003FF8FFFFFFFFFFF0FFFFFF
+FFFFF0FFFFFFFFFFF02F337CB237>69 D<FFFFFFFF80FFFFFFFF800FE0003F8007E00007
+8007E000038007E000038007E000018007E00001C007E00001C007E00000C007E00000C0
+07E00300C007E00300C007E003000007E003000007E007000007E00F000007FFFF000007
+FFFF000007E00F000007E007000007E003000007E003000007E003006007E003006007E0
+00006007E00000E007E00000C007E00000C007E00000C007E00001C007E00001C007E000
+03C007E00003C007E0000F800FE0003F80FFFFFFFF80FFFFFFFF8023267DA52A>101
+D<FFFFFF0000FFFFFFE0000FE003F80007E000FC0007E0003E0007E0003F0007E0001F80
+07E0001F8007E0001FC007E0001FC007E0001FC007E0001FC007E0001FC007E0001F8007
+E0001F8007E0003F0007E0003E0007E000FC0007E003F80007FFFFE00007FFFF000007E0
+00000007E000000007E000000007E000000007E000000007E000000007E000000007E000
+000007E000000007E000000007E000000007E000000007E000000007E00000000FF00000
+00FFFF000000FFFF00000022267DA52A>112 D<FFFFFC0000FFFFFFC0000FE007F00007
+E001F80007E000FC0007E0007E0007E0003F0007E0003F8007E0003F8007E0003F8007E0
+003F8007E0003F8007E0003F8007E0003F0007E0007E0007E000FC0007E001F80007E007
+F00007FFFFC00007FFFF000007E00FC00007E003F00007E001F00007E001F80007E000FC
+0007E000FC0007E000FC0007E000FC0007E000FE0007E000FE0007E000FE0007E000FE00
+07E000FE0307E000FF0307E0007F030FF0007F07FFFF003F8EFFFF000FFC00000003F028
+277DA52D>114 D<00FE010003FFC3000F01E7001E007F0038001F0038000F0070000F00
+70000700F0000700F0000700F0000300F8000300F8000300FC0000007F0000007FE00000
+3FFE00003FFFE0001FFFF80007FFFC0003FFFE00007FFF000007FF0000007F8000001F80
+00000FC0000007C0C00007C0C00003C0C00003C0C00003C0E00003C0E0000380F0000780
+F0000700FC000E00FE001E00E7C07800C1FFF000803FC0001A287DA622>I<7FFF007FFC
+7FFF007FFC0FFE003FE003FC001F8001FC001E0001FC001C0000FE003800007F00300000
+3F007000003F806000001FC0C000000FE1C000000FE380000007F300000003FE00000001
+FE00000001FC00000000FE000000007E000000007F00000000FF80000000DFC00000019F
+C00000038FE000000307F000000603F000000E03F800001C01FC00001800FE00003000FE
+000070007F0000E0003F8001E0001F8003E0001FC007E0001FE01FE0003FF0FFF8007FFF
+FFF8007FFF28267EA52E>120 D E /Fl 11 66 df<00FF0003FFC00781E00F00F01E0078
+3C003C3C003C78001E78001E78001E78001EF8001FF8001FF8001FF8001FF8001FF8001F
+F8001FF8001FF8001FF8001FF8001FF8001FF8001F78001E78001E7C003E3C003C3C003C
+1E00780F00F00781E003FFC000FF0018227DA01E>48 D<00E00001E00007E000FFE000F9
+E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001
+E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001E00001
+E00001E00003F000FFFFC0FFFFC012217AA01E>I<01FC0007FF801C0FC03003E06001F0
+6000F8F800F8FC00FCFC00FCFC007C78007C3000FC0000FC0000F80000F80001F00003E0
+0003C0000780000F00001E0000380000700000E00001C00C03800C0600180C0018180018
+3FFFF87FFFF8FFFFF0FFFFF016217CA01E>I<00FF0003FFC00F03E01C00F01C00F83E00
+FC3E007C3E007C1E00FC0C00FC0000F80000F80001F00003E0000FC001FF0001FF000003
+E00000F000007800007C00003E00003F30003F78003FFC003FFC003FFC003EF8007E6000
+7C3800F81E03F00FFFC001FF0018227DA01E>I<0000E00001E00001E00003E00007E000
+07E0000DE0001DE00039E00031E00061E000E1E000C1E00181E00381E00701E00601E00C
+01E01C01E01801E03001E07001E0E001E0FFFFFFFFFFFF0001E00001E00001E00001E000
+01E00001E00003F0003FFF003FFF18227DA11E>I<1000301E01F01FFFE01FFFC01FFF80
+1FFE001BF00018000018000018000018000018000018FE001BFF801F03C01C01E01800F0
+1800F800007800007800007C00007C30007C78007CF8007CF8007CF80078F000F86000F0
+7001E03801E01E078007FF0001F80016227CA01E>I<000FC0007FF001F03803C0180780
+3C0F007C1E007C1C00383C00003C00007C0000780000787FC0F9FFE0FB80F0FE0038FE00
+3CFC001EFC001EF8001FF8001FF8001FF8001F78001F78001F78001F3C001E3C001E1C00
+3C1E00380F00700781E001FFC0007F0018227DA01E>I<3000003C00003FFFFF3FFFFF7F
+FFFE7FFFFC60001C600038600070C000E0C000C00001C0000380000700000600000E0000
+1C00001C0000380000380000780000780000780000F00000F00000F00000F00001F00001
+F00001F00001F00001F00001F00001F00000E00018237CA11E>I<007F0003FFC00781E0
+0E00701C003818001C38001C38001C38001C3C001C3F00381FC0781FE0F00FF9E007FF80
+01FF8001FFC007FFF00F0FF81C03FC3801FE70007E70001FE0000FE00007E00007E00007
+E0000670000E78000C3C00381F00F007FFC000FF0018227DA01E>I<00FE0003FFC00781
+E00E00701C00783C003878003C78003CF8001EF8001EF8001EF8001FF8001FF8001FF800
+1F78003F78003F3C007F1C007F0F01DF07FF9F03FE1E00001E00001E00003E00003C1C00
+383E00783E00703C00E01801C01C07800FFE0003F80018227DA01E>I<00003800000000
+38000000007C000000007C000000007C00000000FE00000000FE00000001FF000000019F
+000000019F000000030F800000030F800000060FC000000607C000000E07E000000C03E0
+00000C03E000001801F000001801F000003801F800003000F800003000F8000060007C00
+007FFFFC0000FFFFFE0000C0003E0000C0003E000180001F000180001F000380001F8003
+00000F800700000F800700000FC01F80000FE0FFE0007FFEFFE0007FFE27247DA32D>65
+D E /Fm 4 104 df<000FFC0000003FFF000000FFFFC00003FFFFF00007FFFFF8000FFF
+FFFC001FFFFFFE003FFFFFFF003FFFFFFF007FFFFFFF807FFFFFFF807FFFFFFF80FFFFFF
+FFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFF
+C0FFFFFFFFC0FFFFFFFFC07FFFFFFF807FFFFFFF807FFFFFFF803FFFFFFF003FFFFFFF00
+1FFFFFFE000FFFFFFC0007FFFFF80003FFFFF00000FFFFC000003FFF0000000FFC000022
+227BA72D>15 D<0000000000000E0000000000003F000000000000FF000000000003FE00
+000000000FF800000000003FE00000000000FF800000000003FE00000000000FF8000000
+00003FE00000000000FF800000000003FE00000000000FF800000000007FE00000000001
+FF800000000007FE00000000001FF800000000007FC00000000001FF000000000007FC00
+000000001FF000000000007FC00000000001FF000000000007FC00000000001FF0000000
+00007FC00000000000FF000000000000FF0000000000007FC000000000001FF000000000
+0007FC000000000001FF0000000000007FC000000000001FF0000000000007FC00000000
+0001FF0000000000007FC000000000001FF0000000000007FE000000000001FF80000000
+00007FE000000000001FF8000000000003FE000000000000FF8000000000003FE0000000
+00000FF8000000000003FE000000000000FF8000000000003FE000000000000FF8000000
+000003FE000000000000FF0000000000003F0000000000000E0000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000007FFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+7FFFFFFFFFFFFE384879B947>20 D<0000003F000003FF00000FE000003F8000007E0000
+01FC000001F8000003F0000003F0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E000000FE000000FC000001FC000003F800000
+3F000000FE000003F800007FE00000FF0000007FE0000003F8000000FE0000003F000000
+3F8000001FC000000FC000000FE0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E00000
+07E0000007E0000007E0000007E0000007E0000003F0000003F0000001F8000001FC0000
+007E0000003F8000000FE0000003FF0000003F205B7AC32D>102
+D<FC000000FFC0000007F0000001FC0000007E0000003F8000001F8000000FC000000FC0
+000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0
+000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0
+000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0
+000007E0000007F0000003F0000003F8000001FC000000FC0000007F0000001FC0000007
+FE000000FF000007FE00001FC000007F000000FC000001FC000003F8000003F0000007F0
+000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0
+000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0
+000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0000007E0
+000007E000000FC000000FC000001F8000003F8000007E000001FC000007F00000FFC000
+00FC000000205B7AC32D>I E /Fn 93 127 df<600000000CF00000001EF00000001EF0
+0000001EF00000001EF00000001EF00000001EF00000001EF00000001EF00000001EF000
+00001EF00000001EF00000001EF00000001EF00000001EF00000001EF00000001EF00000
+001EF00000001EF00000001EF00000001EF00000001EF00000001EF00000001EF0000000
+1EF00000001EF00000001EF00000001EF00000001EF00000001EFFFFFFFFFEFFFFFFFFFE
+FFFFFFFFFE7FFFFFFFFC27227C9530>32 D<1C007F00FF80FF80FF80FF80FF80FF80FF80
+FF80FF80FF80FF80FF80FF80FF80FF80FF80FF80FF80FF807F007F007F007F007F007F00
+7F007F007F007F007F007F007F007F007F007F007F007F003E0000000000000000000000
+0000000000001C007F007F00FF80FF80FF807F007F001C0009396DB830>I<100004007C
+001F00FE003F80FE003F80FF007F80FF007F80FE003F80FE003F80FE003F80FE003F80FE
+003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE003F80FE
+003F80FE003F80FE003F80FE003F80FE003F807E003F007C001F003C001E001000040019
+1C75B830>I<0007C007C0000007C007C000000FE00FE000000FE00FE000000FE00FE000
+000FE00FE000000FE00FE000000FE00FE000000FE00FE000000FE00FE000001FE01FE000
+001FE01FE000001FC01FC000001FC01FC000001FC01FC0007FFFFFFFFF007FFFFFFFFF00
+FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF807FFFFFFFFF003FFFFFFFFE00007F807F8000
+007F807F8000007F007F0000007F007F0000007F007F0000007F007F0000007F007F0000
+007F007F0000007F007F0000007F007F0000007F007F000000FF00FF000000FF00FF0000
+3FFFFFFFFE007FFFFFFFFF00FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF807FFFFFFFFF00
+7FFFFFFFFF0001FC01FC000001FC01FC000001FC01FC000003FC03FC000003FC03FC0000
+03F803F8000003F803F8000003F803F8000003F803F8000003F803F8000003F803F80000
+03F803F8000001F001F0000001F001F0000029387DB730>I<000038000000007C000000
+00FC00000000FC00000000FC00000000FC00000003FF0000001FFFE00000FFFFFC0001FF
+FFFE0007FFFFFF000FFFFFFF801FFEFDFFC01FF0FC3FE03FC0FC1FE07F80FC0FF07F00FC
+07F07E00FC07F8FE00FC03F8FC00FC03F8FC00FC07F8FC00FC07F8FC00FC07F8FE00FC03
+F0FE00FC03F07F00FC00007F80FC00007FC0FC00003FF0FC00001FFEFC00001FFFFC0000
+0FFFFF000007FFFFE00001FFFFF800007FFFFC00001FFFFE000003FFFF000000FFFF8000
+00FDFFC00000FC7FE00000FC1FE00000FC0FF00000FC07F01800FC03F87E00FC03F87E00
+FC01F8FF00FC01F8FF00FC01F8FF00FC01F8FE00FC01F8FE00FC01F8FF00FC03F07F00FC
+03F07F80FC07F07F80FC0FE03FC0FC1FE03FF0FC7FC01FFEFFFF800FFFFFFF0007FFFFFE
+0003FFFFFC0000FFFFF000003FFFC0000007FE00000000FC00000000FC00000000FC0000
+0000FC00000000FC000000007C0000000038000025477BBE30>I<03C00001E0000FF000
+03E0001FF80007F0003FFC0007F0003FFC000FF0007FFE000FF0007E7E001FE000FE7F00
+1FE000FE7F001FC000FC3F003FC000FC3F003FC000FC3F003F8000FC3F007F8000FC3F00
+7F8000FC3F00FF0000FE7F00FF0000FE7F00FE00007E7E01FE00007FFE01FE00003FFC01
+FC00003FFC03FC00001FF803FC00000FF007F8000003C007F80000000007F0000000000F
+F0000000000FF0000000000FE0000000001FE0000000001FE0000000003FC0000000003F
+C0000000003F80000000007F80000000007F80000000007F0000000000FF0000000000FF
+0000000001FE0000000001FE0000000001FC0000000003FC0000000003FC0000000003F8
+0000000007F80000000007F8000000000FF001E000000FF007F800000FE00FFC00001FE0
+1FFE00001FE01FFE00001FC03FFF00003FC03FFF00003FC03F3F00007F807F3F80007F80
+7E1F80007F007E1F8000FF007E1F8000FF007E1F8000FE007E1F8001FE007E1F8001FE00
+7E1F8003FC007F3F8003FC003F3F0003F8003FFF0007F8003FFF0007F8001FFE0007F000
+1FFE0007F0000FFC0003E00007F80001E00001E00029477DBE30>I<0007E0000000001F
+F8000000003FFC000000007FFC00000000FFFE00000000FFFF00000001FC7F00000001F8
+3F00000001F83F80000003F81F80000003F01F80000003F01F80000003F01F80000003F0
+1F80000003F01F80000003F01F80000003F03F80000003F03F00000003F07F0FFF0003F8
+7E1FFF8001F8FE1FFF8001F9FC1FFF8001FBFC1FFF8001FBF80FFF0001FFF00FC00000FF
+E00FC00000FFE01FC00000FFC01F8000007F801F800000FF003F800001FF003F000003FF
+007F000007FF807E00000FFF807E00000FFF80FE00001FDFC0FC00003F8FE0FC00003F8F
+E1FC00007F07F1F800007F03F3F80000FE03FBF00000FE01FFF00000FE01FFE00000FE00
+FFE00000FE00FFC00600FE007FC00F00FE003F801F80FE003FC01F80FF007FC01F807F00
+FFE01F807F01FFF83F807F87FFFC3F003FFFFBFFFF001FFFF1FFFE001FFFE0FFFE000FFF
+C03FFC0003FF001FF80001FC0007E000293A7DB830>I<07C00FF01FF81FF81FFC1FFC1F
+FE0FFE07FE007E007E007E007E007E00FE00FC00FC01FC01F803F807F00FF01FE07FE0FF
+C0FF80FF007C0038000F1D70B730>I<00001E00007F0000FF0001FF0003FE0007FC000F
+F0001FE0003FC0007F8000FF0001FE0001FC0003FC0003F80007F0000FF0000FE0000FE0
+001FC0001FC0003FC0003F80003F80007F80007F00007F00007F00007F0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00007F00
+007F00007F00007F00007F80003F80003F80003FC0001FC0001FC0000FE0000FE0000FF0
+0007F00003F80003FC0001FC0001FE0000FF00007F80003FC0001FE0000FF00007FC0003
+FE0001FF0000FF00007F00001E184771BE30>I<780000FE0000FF0000FF80007FC0003F
+E0000FF00007F80003FC0001FE0000FF00007F80003F80003FC0001FC0000FE0000FF000
+07F00007F00003F80003F80003FC0001FC0001FC0001FE0000FE0000FE0000FE0000FE00
+007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00
+007F0000FE0000FE0000FE0000FE0001FE0001FC0001FC0003FC0003F80003F80007F000
+07F0000FF0000FE0001FC0003FC0003F80007F8000FF0001FE0003FC0007F8000FF0003F
+E0007FC000FF8000FF0000FE0000780000184778BE30>I<0000E000000001F000000003
+F800000003F800000003F800000003F800000003F800000003F800003803F803807E03F8
+0FC0FF83F83FE0FFC3F87FE0FFF3F9FFE07FFBFBFFC03FFFFFFF800FFFFFFE0003FFFFF8
+0001FFFFF000007FFFC000001FFF0000007FFFC00001FFFFF00003FFFFF8000FFFFFFE00
+3FFFFFFF807FFBFBFFC0FFF3F9FFE0FFC3F87FE0FF83F83FE07E03F80FC03803F8038000
+03F800000003F800000003F800000003F800000003F800000003F800000001F000000000
+E0000023277AAE30>I<00003E00000000003E00000000007F00000000007F0000000000
+7F00000000007F00000000007F00000000007F00000000007F00000000007F0000000000
+7F00000000007F00000000007F00000000007F00000000007F00000000007F0000000000
+7F0000007FFFFFFFFF007FFFFFFFFF00FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF807FFF
+FFFFFF007FFFFFFFFF0000007F00000000007F00000000007F00000000007F0000000000
+7F00000000007F00000000007F00000000007F00000000007F00000000007F0000000000
+7F00000000007F00000000007F00000000007F00000000007F00000000003E0000000000
+3E00000029297DAF30>I<03E00FF01FF81FFC3FFE3FFE3FFF3FFF1FFF1FFF0FFF03FF00
+7F007F007E00FE01FC03FC07F83FF07FF0FFE07F807F003C001019708B30>I<7FFFFFFF
+F07FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFFFFFFF87FFFFFFFF07FFFFFFFF025077B9E30
+>I<0F003FC07FE07FE0FFF0FFF0FFF0FFF07FE07FE03FC00F000C0C6E8B30>I<00000000
+F000000001F000000003F800000003F800000007F800000007F80000000FF00000000FF0
+0000001FE00000001FE00000003FC00000003FC00000007F800000007F80000000FF0000
+0000FF00000001FE00000001FE00000001FC00000003FC00000003FC00000007F8000000
+07F80000000FF00000000FF00000001FE00000001FE00000003FC00000003FC00000007F
+800000007F80000000FF00000000FF00000001FE00000001FE00000001FC00000003FC00
+000003FC00000007F800000007F80000000FF00000000FF00000001FE00000001FE00000
+003FC00000003FC00000007F800000007F80000000FF00000000FF00000001FE00000001
+FE00000001FC00000003FC00000003FC00000007F800000007F80000000FF00000000FF0
+0000001FE00000001FE00000003FC00000003FC00000007F800000007F80000000FF0000
+0000FF00000000FE00000000FE000000007C000000007C0000000025477BBE30>I<0000
+FE00000007FFC000000FFFE000003FFFF800007FFFFC0000FFFFFE0001FF83FF0003FE00
+FF8003FC007F8007F8003FC00FF0001FE00FE0000FE01FE0000FF01FC00007F01FC00007
+F03F800003F83F800003F83F000001F87F000001FC7F000001FC7F000001FC7F000001FC
+FE000000FEFE000000FEFE000000FEFE000000FEFE000000FEFE000000FEFE000000FEFE
+000000FEFE000000FEFE000000FEFE000000FEFE000000FEFE000000FEFF000001FE7F00
+0001FC7F000001FC7F000001FC7F800003FC3F800003F83F800003F83FC00007F81FC000
+07F01FC00007F01FE0000FF00FF0001FE00FF0001FE007F8003FC003FC007F8003FE00FF
+8001FF83FF0000FFFFFE00007FFFFC00003FFFF800000FFFE0000007FFC0000000FE0000
+273A7CB830>I<0003C0000007E0000007E000000FE000000FE000001FE000001FE00000
+3FE000007FE00000FFE00003FFE0003FFFE000FFFFE000FFFFE000FFEFE000FF8FE0007E
+0FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00000
+0FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00000
+0FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00000
+0FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE0003FFFFFF87F
+FFFFFCFFFFFFFEFFFFFFFE7FFFFFFC3FFFFFF81F3977B830>I<0007FC0000003FFFC000
+00FFFFF00003FFFFF80007FFFFFE000FFFFFFF001FF80FFF803FE001FFC03FC0007FC07F
+80003FE07F00001FE07F00000FF0FF000007F0FE000007F0FF000007F8FF000003F8FF00
+0003F8FF000003F87E000003F818000003F800000003F800000003F800000007F8000000
+07F00000000FF00000000FE00000001FE00000001FC00000003FC00000007F80000000FF
+80000001FF00000001FE00000007FC0000000FF80000001FF00000003FE00000007FC000
+0000FF80000001FF00000003FE00000007FC0000000FF00000003FE00000007FC0000000
+FF80000001FF00000003FE0001F007FC0003F80FF80003F81FE00003F83FFFFFFFF8FFFF
+FFFFF8FFFFFFFFF8FFFFFFFFF87FFFFFFFF83FFFFFFFF025397BB830>I<0003FF000000
+3FFFE00000FFFFF80001FFFFFE0003FFFFFF0007FFFFFF800FFE01FFC00FF0007FC01FE0
+001FE01FE0000FE01FE0000FF01FE00007F01FE00007F00FC00007F007800007F0000000
+07F00000000FF00000000FE00000000FE00000001FE00000003FC00000007FC0000000FF
+80000007FF000007FFFE00000FFFFC00000FFFF800000FFFFC00000FFFFF000007FFFF80
+000001FFC00000003FE00000001FF000000007F800000003F800000003FC00000001FC00
+000001FE00000000FE00000000FE18000000FE7E000000FEFF000000FEFF000000FEFF00
+0001FEFF000001FCFE000003FCFF000003F87F800007F87FC0001FF03FF0003FF01FFE01
+FFE00FFFFFFFC007FFFFFF8003FFFFFE0000FFFFFC00003FFFF0000003FF8000273A7CB8
+30>I<000003FC0000000007FE000000000FFE000000001FFE000000001FFE000000003F
+FE000000007FFE000000007F7E00000000FE7E00000000FE7E00000001FC7E00000003F8
+7E00000003F87E00000007F07E00000007F07E0000000FE07E0000001FC07E0000001FC0
+7E0000003F807E0000003F807E0000007F007E000000FE007E000000FE007E000001FC00
+7E000003F8007E000003F8007E000007F0007E000007F0007E00000FE0007E00001FC000
+7E00001FC0007E00003F80007E00003F80007E00007F00007E0000FE00007E0000FFFFFF
+FFFF00FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF807FFFFFFFFF00000000
+7E00000000007E00000000007E00000000007E00000000007E00000000007E0000000000
+7E00000000007E00000000007E00000000007E000000007FFFFE000000FFFFFF000000FF
+FFFF000000FFFFFF000000FFFFFF0000007FFFFE0029397DB830>I<0FFFFFFF801FFFFF
+FFC03FFFFFFFC03FFFFFFFC03FFFFFFFC03FFFFFFF803F800000003F800000003F800000
+003F800000003F800000003F800000003F800000003F800000003F800000003F80000000
+3F800000003F800000003F800000003F800000003F83FF00003F9FFFC0003FFFFFF0003F
+FFFFFC003FFFFFFE003FFFFFFF003FFE03FF803FF0007FC03FE0003FC03F80001FE01F00
+000FE00E00000FF000000007F000000007F000000007F800000003F800000003F8000000
+03F818000003F87E000003F87E000003F8FF000003F8FF000007F8FF000007F0FE00000F
+F0FF00000FE07F00001FE07F80003FC07FC0007FC03FE001FF801FFC0FFF000FFFFFFE00
+07FFFFFC0003FFFFF80001FFFFE000007FFF8000000FFC000025397BB730>I<00000FF8
+0000007FFF000001FFFF800007FFFFE0001FFFFFE0003FFFFFF0007FF80FF000FFC007F8
+01FF8007F803FE0007F803FC0007F807F80007F80FF00003F00FF00001E01FE00000001F
+C00000003FC00000003F800000003F800000007F800000007F000C00007F03FFE0007F0F
+FFF800FF3FFFFE00FEFFFFFF00FFFFFFFF80FFFFFFFFC0FFFE007FE0FFF8001FF0FFE000
+0FF0FFC00007F8FFC00003FCFF800003FCFF000001FCFF000001FEFF000000FEFF000000
+FEFF000000FE7F000000FE7F000000FE7F000000FE7F000000FE3F800000FE3F800001FE
+3FC00001FC1FC00001FC1FE00003FC0FE00007F80FF0000FF807F8001FF007FC003FE003
+FF81FFC001FFFFFF8000FFFFFF00007FFFFE00001FFFF8000007FFE0000001FF8000273A
+7CB830>I<7C00000000FFFFFFFFFCFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFF
+FFFFFFFCFE00000FF8FE00000FF0FE00001FE07C00003FC00000007F80000000FF000000
+00FF00000001FE00000003FC00000003F800000007F800000007F00000000FF00000000F
+E00000001FC00000001FC00000003F800000003F800000007F000000007F00000000FF00
+000000FE00000001FE00000001FC00000001FC00000003FC00000003F800000003F80000
+0007F800000007F000000007F000000007F000000007F00000000FE00000000FE0000000
+0FE00000000FE00000000FE00000000FE00000001FE00000001FC00000001FC00000001F
+C00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000000F80
+00000007000000273A7CB830>I<0001FF0000001FFFF000007FFFFC0000FFFFFE0003FF
+FFFF8007FFFFFFC00FFF01FFE01FF8003FF01FF0001FF03FC00007F83FC00007F87F8000
+03FC7F000001FC7F000001FC7F000001FC7F000001FC7F000001FC7F800003FC3F800003
+F83FC00007F81FE0000FF00FF0001FE007FC007FC003FF83FF8001FFFFFF00007FFFFC00
+001FFFF000003FFFF80000FFFFFE0001FFFFFF0007FE00FFC00FF8003FE01FE0000FF03F
+C00007F83F800003F87F800003FC7F000001FCFF000001FEFE000000FEFE000000FEFE00
+0000FEFE000000FEFE000000FEFE000000FEFF000001FE7F000001FC7F800003FC3F8000
+03F83FC00007F81FF0001FF01FF8003FF00FFF01FFE007FFFFFFC003FFFFFF8000FFFFFE
+00007FFFFC00001FFFF0000001FF0000273A7CB830>I<0001FF0000000FFFE000003FFF
+F80000FFFFFC0001FFFFFE0003FFFFFF0007FF01FF800FFC007FC01FF0003FE03FE0001F
+E03FC0000FF07F800007F07F800007F07F000003F8FF000003F8FE000003FCFE000001FC
+FE000001FCFE000001FCFE000001FCFE000001FEFE000001FEFE000001FEFF000001FE7F
+000001FE7F800003FE7F800007FE3FC00007FE1FE0000FFE1FF0003FFE0FFC00FFFE07FF
+FFFFFE03FFFFFFFE01FFFFFEFE00FFFFF9FE003FFFE1FC000FFF81FC00006001FC000000
+01FC00000003F800000003F800000007F800000007F00000000FF00F00000FE01F80001F
+E03FC0003FC03FC0007FC03FC000FF803FC001FF003FC007FE001FF01FFC001FFFFFF800
+0FFFFFF00007FFFFE00003FFFF800000FFFE0000003FF00000273A7CB830>I<0F003FC0
+7FE07FE0FFF0FFF0FFF0FFF07FE07FE03FC00F0000000000000000000000000000000000
+00000000000000000000000000000F003FC07FE07FE0FFF0FFF0FFF0FFF07FE07FE03FC0
+0F000C276EA630>I<03C00FF01FF81FF83FFC3FFC3FFC3FFC1FF81FF80FF003C0000000
+00000000000000000000000000000000000000000000000000000003C00FF01FF01FF83F
+F83FFC3FFC3FFC1FFC1FFC0FFC03FC00FC01FC01F803F803F007F01FE03FE07FC0FF807F
+007E0038000E3470A630>I<00000000F000000003F000000007F80000001FF80000007F
+F8000000FFF0000003FFF0000007FFC000001FFF8000003FFE000000FFF8000001FFF000
+0007FFC000000FFF8000003FFE0000007FFC000001FFF0000003FFE000000FFF8000001F
+FF0000007FFC0000007FF8000000FFE0000000FFC0000000FFE00000007FF80000007FFC
+0000001FFF0000000FFF80000003FFE0000001FFF00000007FFC0000003FFE0000000FFF
+80000007FFC0000001FFF0000000FFF80000003FFE0000001FFF80000007FFC0000003FF
+F0000000FFF00000007FF80000001FF800000007F800000003F000000000F0252F7BB230
+>I<7FFFFFFFFF007FFFFFFFFF00FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF807FFFFFFF
+FF003FFFFFFFFE0000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000003FFFFFFFFE007FFFFFFFFF00FFFFFFFFFF80FFFFFFFF
+FF80FFFFFFFFFF807FFFFFFFFF007FFFFFFFFF0029157DA530>I<78000000007E000000
+00FF00000000FFC0000000FFE00000007FF80000007FFE0000001FFF0000000FFFC00000
+03FFE0000001FFF80000007FFC0000001FFF0000000FFF80000003FFE0000001FFF00000
+007FFC0000003FFE0000000FFF80000007FFC0000001FFF0000000FFF00000003FF80000
+001FF80000003FF8000000FFF0000001FFF0000007FFC000000FFF8000003FFE0000007F
+FC000001FFF0000003FFE000000FFF8000001FFF0000007FFC000001FFF8000003FFE000
+000FFFC000001FFF0000007FFE0000007FF8000000FFE0000000FFC0000000FF00000000
+7E000000007800000000252F7BB230>I<001FFE000000FFFFE00003FFFFF8000FFFFFFE
+001FFFFFFF003FFFFFFF807FF803FFC07FC0007FC0FF00001FC0FF00001FE0FF00000FE0
+FF00000FE0FF00000FE07E00000FE07E00001FE01800007FC0000000FFC0000003FF8000
+0007FF0000000FFE0000001FF80000003FF00000007FC0000000FF80000000FF00000001
+FE00000001FE00000003FC00000003F800000003F800000007F800000007F000000007F0
+00000007F000000007F000000007F000000007F000000007F000000007F000000003E000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000001C000000007F000000007F00000000FF80000000FF80000000FF8000000
+07F000000007F000000001C0000023397AB830>I<00001FE0000000FFF8000003FFFE00
+000FFFFF00001FFFFF80003FFFFFC0007FF03FE000FF800FE001FF0007F003FC0003F007
+F801FBF807F007FFF80FE01FFFF80FE03FFFFC1FC03FFFFC1F807FFFFC3F80FF0FFC3F00
+FE07FC3F01FC03FE7F01F801FE7E03F801FE7E03F000FE7E03F000FEFE07F000FEFC07E0
+007EFC07E0007EFC07E0007EFC07E0007EFC07E0007EFC07E0007EFC07E0007EFC07E000
+7EFC07E0007EFC07E0007EFE07F000FE7E03F000FC7E03F000FC7E03F801FC7F01F801F8
+3F01FC03F83F00FE07F03F80FF0FF01F807FFFE01FC03FFFC00FE03FFFC00FE01FFF8007
+F007FE0007F801F80003FC00007C01FF0000FE00FF8003FE007FF01FFE003FFFFFFC001F
+FFFFF8000FFFFFE00003FFFFC00000FFFE0000001FF000273A7CB830>I<00007F000000
+0000FF8000000000FF8000000001FFC000000001FFC000000001FFC000000001FFC00000
+0003FFE000000003F7E000000003F7E000000003F7E000000003F7E000000007F7F00000
+0007E3F000000007E3F000000007E3F00000000FE3F80000000FE3F80000000FE3F80000
+000FC1F80000000FC1F80000001FC1FC0000001FC1FC0000001FC1FC0000001FC1FC0000
+003F80FE0000003F80FE0000003F80FE0000003F80FE0000003F80FE0000007F007F0000
+007F007F0000007F007F0000007F007F000000FF007F800000FE003F800000FFFFFF8000
+00FFFFFF800000FFFFFF800001FFFFFFC00001FFFFFFC00001FFFFFFC00001FC001FC000
+03FC001FE00003F8000FE00003F8000FE00003F8000FE00003F8000FE00007F8000FF000
+07F00007F00007F00007F0007FFF007FFF00FFFF80FFFF80FFFF80FFFF80FFFF80FFFF80
+FFFF80FFFF807FFF007FFF0029397DB830>I<7FFFFFF00000FFFFFFFE0000FFFFFFFF80
+00FFFFFFFFC000FFFFFFFFE0007FFFFFFFF00003F8001FF80003F80007F80003F80003FC
+0003F80001FC0003F80001FC0003F80000FE0003F80000FE0003F80000FE0003F80000FE
+0003F80000FE0003F80000FE0003F80001FE0003F80001FC0003F80001FC0003F80003F8
+0003F80007F80003F8001FF00003F8007FE00003FFFFFFC00003FFFFFF800003FFFFFE00
+0003FFFFFF800003FFFFFFE00003FFFFFFF00003F8000FF80003F80003FC0003F80001FE
+0003F80000FE0003F800007F0003F800007F0003F800007F0003F800003F8003F800003F
+8003F800003F8003F800003F8003F800003F8003F800003F8003F800007F8003F800007F
+0003F800007F0003F80000FF0003F80001FE0003F80003FE0003F8001FFC007FFFFFFFFC
+00FFFFFFFFF800FFFFFFFFF000FFFFFFFFC000FFFFFFFF80007FFFFFFC000029387EB730
+>I<00007F803C0003FFF03E0007FFFC7E001FFFFE7E003FFFFFFE007FFFFFFE00FFE07F
+FE01FF801FFE03FE000FFE07FC0007FE07F80007FE0FF00003FE0FF00003FE1FE00001FE
+1FC00001FE3FC00001FE3F800000FE3F800000FE7F800000FE7F000000FE7F0000007C7F
+00000000FF00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FF0000
+00007F000000007F000000007F0000007C7F800000FE3F800000FE3F800000FE3FC00000
+FE1FC00000FE1FE00001FE0FF00001FC0FF00001FC07F80003F807FC0007F803FE000FF0
+01FF801FF000FFE07FE0007FFFFFC0003FFFFF80001FFFFF000007FFFC000003FFF00000
+007FC000273A7CB830>I<3FFFFFE000007FFFFFFC0000FFFFFFFE0000FFFFFFFF80007F
+FFFFFFC0003FFFFFFFE00003F8007FF00003F8001FF80003F8000FF80003F80007FC0003
+F80003FE0003F80001FE0003F80000FF0003F80000FF0003F800007F8003F800007F8003
+F800003F8003F800003FC003F800001FC003F800001FC003F800001FC003F800001FC003
+F800000FE003F800000FE003F800000FE003F800000FE003F800000FE003F800000FE003
+F800000FE003F800000FE003F800000FE003F800000FE003F800000FE003F800000FE003
+F800001FE003F800001FC003F800001FC003F800001FC003F800003FC003F800003F8003
+F800003F8003F800007F8003F800007F0003F80000FF0003F80001FE0003F80003FE0003
+F80007FC0003F8000FFC0003F8001FF80003F8007FF0003FFFFFFFE0007FFFFFFFC000FF
+FFFFFF8000FFFFFFFF00007FFFFFFC00003FFFFFE000002B387FB730>I<7FFFFFFFFF00
+FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF807FFFFFFFFF8003F800003F80
+03F800003F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F80
+03F800003F8003F800001F0003F80000000003F80000000003F80000000003F800000000
+03F8007C000003F800FE000003F800FE000003F800FE000003F800FE000003FFFFFE0000
+03FFFFFE000003FFFFFE000003FFFFFE000003FFFFFE000003FFFFFE000003F800FE0000
+03F800FE000003F800FE000003F800FE000003F8007C000003F80000000003F800000000
+03F80000000003F80000000003F80000000003F8000007C003F800000FE003F800000FE0
+03F800000FE003F800000FE003F800000FE003F800000FE003F800000FE003F800000FE0
+03F800000FE07FFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE0
+7FFFFFFFFFC02B387EB730>I<3FFFFFFFFF807FFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFF
+C07FFFFFFFFFC03FFFFFFFFFC001FC00001FC001FC00001FC001FC00001FC001FC00001F
+C001FC00001FC001FC00001FC001FC00001FC001FC00001FC001FC00000F8001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC003E000001FC007F00
+0001FC007F000001FC007F000001FC007F000001FFFFFF000001FFFFFF000001FFFFFF00
+0001FFFFFF000001FFFFFF000001FFFFFF000001FC007F000001FC007F000001FC007F00
+0001FC007F000001FC003E000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC000000003FFFF80000007FFFFC0000
+00FFFFFC000000FFFFFC0000007FFFFC0000003FFFF80000002A387EB730>I<0000FF00
+F0000003FFC0F800000FFFF1F800003FFFFDF800007FFFFFF80000FFFFFFF80001FFC1FF
+F80001FF007FF80003FE003FF80007FC001FF80007F8000FF8000FF0000FF8000FE00007
+F8001FE00007F8001FC00007F8003FC00007F8003F800003F8003F800003F8007F800003
+F8007F000003F8007F000001F0007F0000000000FF0000000000FE0000000000FE000000
+0000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE000000
+0000FE0000FFFF00FE0001FFFF80FE0003FFFF80FE0003FFFF80FF0001FFFF807F0000FF
+FF007F000003F8007F000003F8007F800003F8003F800007F8003F800007F8003FC00007
+F8001FC00007F8001FE0000FF8000FE0000FF8000FF0000FF80007F8001FF80007F8001F
+F80003FE003FF80001FF007FF80001FFC1FFF80000FFFFFFF800007FFFFFF800003FFFFB
+F800000FFFF3F8000003FFC1F0000000FF000000293A7DB830>I<3FFF800FFFE07FFFC0
+1FFFF0FFFFE03FFFF8FFFFE03FFFF87FFFC01FFFF03FFF800FFFE003F80000FE0003F800
+00FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F800
+00FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F800
+00FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003FFFFFFFE0003FFFF
+FFFE0003FFFFFFFE0003FFFFFFFE0003FFFFFFFE0003FFFFFFFE0003F80000FE0003F800
+00FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F800
+00FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F800
+00FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F80000FE0003F800
+00FE003FFF800FFFE07FFFC01FFFF0FFFFE03FFFF8FFFFE03FFFF87FFFC01FFFF03FFF80
+0FFFE02D387FB730>I<7FFFFFFF00FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF807F
+FFFFFF000007F000000007F000000007F000000007F000000007F000000007F000000007
+F000000007F000000007F000000007F000000007F000000007F000000007F000000007F0
+00000007F000000007F000000007F000000007F000000007F000000007F000000007F000
+000007F000000007F000000007F000000007F000000007F000000007F000000007F00000
+0007F000000007F000000007F000000007F000000007F000000007F000000007F0000000
+07F000000007F000000007F000000007F000000007F000000007F000000007F000000007
+F000000007F000007FFFFFFF00FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF807FFFFF
+FF00213879B730>I<3FFF000FFF807FFF801FFFC0FFFFC03FFFC0FFFFC03FFFC07FFF80
+1FFFC03FFF000FFF8003F00003F80003F00007F00003F0000FE00003F0001FE00003F000
+3FC00003F0003F800003F0007F000003F000FE000003F001FE000003F003FC000003F003
+F8000003F007F0000003F00FE0000003F01FE0000003F01FC0000003F03F80000003F07F
+00000003F0FF00000003F1FF00000003F1FF80000003F3FFC0000003F7FFC0000003FFFF
+E0000003FFEFE0000003FFC7F0000003FF83F0000003FF03F8000003FF01F8000003FE01
+FC000003FC00FE000003F800FE000003F8007F000003F0003F000003F0003F800003F000
+1F800003F0001FC00003F0000FC00003F0000FE00003F00007F00003F00007F00003F000
+03F80003F00001F80003F00001FC0003F00000FC003FFF0003FFC07FFF8007FFE0FFFFC0
+0FFFE0FFFFC00FFFE07FFF8007FFE03FFF0003FFC02B387FB730>75
+D<3FFFF80000007FFFFC000000FFFFFE000000FFFFFE0000007FFFFC0000003FFFF80000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC00000F8001FC00001F
+C001FC00001FC001FC00001FC001FC00001FC001FC00001FC001FC00001FC001FC00001F
+C001FC00001FC001FC00001FC03FFFFFFFFFC07FFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFF
+C07FFFFFFFFFC03FFFFFFFFF802A387EB730>I<3FF80000FFE07FFC0001FFF0FFFE0003
+FFF8FFFE0003FFF87FFE0003FFF03FFF0007FFE007FF0007FF0007EF0007BF0007EF800F
+BF0007EF800FBF0007EF800FBF0007E7C01F3F0007E7C01F3F0007E7C01F3F0007E7C01F
+3F0007E7E03F3F0007E3E03E3F0007E3E03E3F0007E3F07E3F0007E3F07E3F0007E1F07C
+3F0007E1F07C3F0007E1F8FC3F0007E1F8FC3F0007E0F8F83F0007E0F8F83F0007E0FDF8
+3F0007E07DF03F0007E07DF03F0007E07DF03F0007E07FF03F0007E03FE03F0007E03FE0
+3F0007E03FE03F0007E01FC03F0007E01FC03F0007E007003F0007E000003F0007E00000
+3F0007E000003F0007E000003F0007E000003F0007E000003F0007E000003F0007E00000
+3F0007E000003F0007E000003F0007E000003F0007E000003F0007E000003F003FFC0001
+FFE07FFE0003FFF0FFFF0007FFF8FFFF0007FFF87FFE0003FFF03FFC0001FFE02D387FB7
+30>I<3FFC001FFF807FFE003FFFC0FFFF007FFFE0FFFF007FFFE07FFF803FFFC03FFF80
+1FFF8003FF8001F80003F7C001F80003F7C001F80003F7C001F80003F3E001F80003F3E0
+01F80003F3E001F80003F3F001F80003F1F001F80003F1F001F80003F1F801F80003F1F8
+01F80003F0F801F80003F0FC01F80003F0FC01F80003F07C01F80003F07E01F80003F07E
+01F80003F03E01F80003F03F01F80003F03F01F80003F01F01F80003F01F01F80003F01F
+81F80003F01F81F80003F00F81F80003F00FC1F80003F00FC1F80003F007C1F80003F007
+E1F80003F007E1F80003F003E1F80003F003F1F80003F003F1F80003F001F1F80003F001
+F1F80003F001F9F80003F000F9F80003F000F9F80003F000F9F80003F0007DF80003F000
+7DF80003F0007DF80003F0003FF8003FFF003FF8007FFF803FF800FFFFC01FF800FFFFC0
+1FF8007FFF800FF8003FFF0007F0002B387EB730>I<003FFFE00001FFFFFC0007FFFFFF
+000FFFFFFF801FFFFFFFC03FFFFFFFE03FF800FFE03FE0003FE07F80000FF07F80000FF0
+7F000007F07F000007F07F000007F07F000007F0FF000007F8FE000003F8FE000003F8FE
+000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE00
+0003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE0000
+03F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003
+F8FE000003F8FE000003F8FE000003F8FF000007F8FF000007F87F000007F07F000007F0
+7F000007F07F80000FF07F80000FF07FC0001FF03FE0003FE03FF800FFE03FFFFFFFE01F
+FFFFFFC00FFFFFFF8007FFFFFF0001FFFFFC00003FFFE000253A7BB830>I<7FFFFFF000
+00FFFFFFFE0000FFFFFFFF8000FFFFFFFFE000FFFFFFFFF0007FFFFFFFF80003F8003FF8
+0003F8000FFC0003F80003FE0003F80001FE0003F80000FF0003F80000FF0003F800007F
+0003F800007F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F
+8003F800003F8003F800007F8003F800007F0003F80000FF0003F80000FF0003F80001FE
+0003F80003FE0003F8000FFC0003F8003FF80003FFFFFFF80003FFFFFFF00003FFFFFFE0
+0003FFFFFF800003FFFFFE000003FFFFF0000003F80000000003F80000000003F8000000
+0003F80000000003F80000000003F80000000003F80000000003F80000000003F8000000
+0003F80000000003F80000000003F80000000003F80000000003F80000000003F8000000
+0003F8000000007FFFC0000000FFFFE0000000FFFFE0000000FFFFE0000000FFFFE00000
+007FFFC000000029387EB730>I<003FFFE00001FFFFFC0007FFFFFF000FFFFFFF801FFF
+FFFFC03FFFFFFFE03FF800FFE03FE0003FE07FC0001FF07F80000FF07F000007F07F0000
+07F07F000007F07F000007F0FF000007F8FE000003F8FE000003F8FE000003F8FE000003
+F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8
+FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE
+000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE000003F8FE00
+0003F8FE007E03F8FE00FE03F8FF00FF07F87F00FF07F07F007F87F07F007F87F07F003F
+C7F07F803FCFF07FC01FFFF03FE01FFFE03FF80FFFE03FFFFFFFE01FFFFFFFC00FFFFFFF
+8007FFFFFF0001FFFFFC00003FFFFE00000001FE00000000FF00000000FF00000000FF80
+0000007F800000007FC00000003FC00000003FE00000001FE00000001FF00000000FF000
+000007E025467BB830>I<3FFFFF8000007FFFFFF00000FFFFFFFC0000FFFFFFFF00007F
+FFFFFF80003FFFFFFFC00003F801FFE00003F8003FF00003F8001FF00003F8000FF80003
+F80007F80003F80003F80003F80003FC0003F80001FC0003F80001FC0003F80001FC0003
+F80001FC0003F80001FC0003F80003FC0003F80003F80003F80007F80003F8000FF80003
+F8001FF00003F8003FF00003F801FFE00003FFFFFFC00003FFFFFF800003FFFFFF000003
+FFFFFE000003FFFFFF000003FFFFFF800003F800FFC00003F8003FE00003F8001FE00003
+F8000FE00003F8000FF00003F80007F00003F80007F00003F80007F00003F80007F00003
+F80007F00003F80007F00003F80007F00003F80007F00003F80007F0F803F80007F1FC03
+F80007F1FC03F80007F1FC03F80007F1FC03F80007F1FC3FFF8003FBFC7FFFC003FFF8FF
+FFE001FFF8FFFFE001FFF07FFFC000FFE03FFF80007FC0000000001F002E397FB730>I<
+000FF803C0007FFF03E001FFFFC7E003FFFFF7E007FFFFFFE00FFFFFFFE01FF80FFFE03F
+E001FFE03FC000FFE07F80007FE07F00003FE0FF00003FE0FE00001FE0FE00001FE0FE00
+000FE0FE00000FE0FE00000FE0FF00000FE0FF000007C07F000000007F800000007FC000
+00003FF00000001FFE0000001FFFF000000FFFFF000007FFFFE00001FFFFF80000FFFFFC
+00001FFFFF000003FFFF8000003FFFC0000001FFC00000007FE00000001FE00000000FF0
+0000000FF000000007F800000007F87C000003F8FE000003F8FE000003F8FE000003F8FE
+000003F8FE000003F8FF000007F8FF000007F0FF800007F0FFC0000FE0FFE0001FE0FFF8
+003FC0FFFF00FFC0FFFFFFFF80FFFFFFFF00FDFFFFFE00FC7FFFF800F81FFFF0007801FF
+8000253A7BB830>I<3FFFFFFFFFC07FFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFFE0FFFFFF
+FFFFE0FFFFFFFFFFE0FE003F800FE0FE003F800FE0FE003F800FE0FE003F800FE0FE003F
+800FE0FE003F800FE0FE003F800FE0FE003F800FE07C003F8007C000003F80000000003F
+80000000003F80000000003F80000000003F80000000003F80000000003F80000000003F
+80000000003F80000000003F80000000003F80000000003F80000000003F80000000003F
+80000000003F80000000003F80000000003F80000000003F80000000003F80000000003F
+80000000003F80000000003F80000000003F80000000003F80000000003F80000000003F
+80000000003F80000000003F80000000003F80000000003F80000000003F80000000003F
+80000000003F80000000003F80000000003F800000001FFFFF0000003FFFFF8000003FFF
+FF8000003FFFFF8000003FFFFF8000001FFFFF00002B387EB730>I<7FFFC007FFFCFFFF
+E00FFFFEFFFFE00FFFFEFFFFE00FFFFEFFFFE00FFFFE7FFFC007FFFC03F800003F8003F8
+00003F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F8003F8
+00003F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F8003F8
+00003F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F8003F8
+00003F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F8003F8
+00003F8003F800003F8003F800003F8003F800003F8003F800003F8003F800003F8003F8
+00003F8003F800003F8003F800003F8003F800003F8003FC00007F8001FC00007F0001FC
+00007F0001FC00007F0000FE0000FE0000FF0001FE00007F0001FC00007F8003FC00003F
+E00FF800001FF83FF000000FFFFFE0000007FFFFC0000003FFFF80000001FFFF00000000
+7FFC000000001FF000002F3980B730>I<7FFE000FFFC0FFFF001FFFE0FFFF803FFFE0FF
+FF803FFFE0FFFF001FFFE07FFE000FFFC007F00001FC0007F00001FC0007F80003FC0003
+F80003F80003F80003F80003F80003F80003F80003F80001FC0007F00001FC0007F00001
+FC0007F00001FC0007F00000FE000FE00000FE000FE00000FE000FE00000FE000FE00000
+FF001FE000007F001FC000007F001FC000007F001FC000007F803FC000003F803F800000
+3F803F8000003F803F8000003F803F8000001FC07F0000001FC07F0000001FC07F000000
+1FC07F0000000FE0FE0000000FE0FE0000000FE0FE0000000FE0FE00000007E0FC000000
+07F1FC00000007F1FC00000007F1FC00000003F1F800000003F1F800000003F1F8000000
+03FBF800000001FBF000000001FBF000000001FBF000000001FFF000000001FFF0000000
+00FFE000000000FFE000000000FFE000000000FFE0000000007FC0000000003F8000002B
+397EB730>I<3FFC0001FFE07FFE0003FFF0FFFE0003FFF8FFFE0003FFF87FFE0003FFF0
+3FFC0001FFE01FC000001FC00FC000001F800FC000001F800FC000001F800FC000001F80
+0FC000001F800FC000001F800FC000001F800FE000003F8007E000003F0007E000003F00
+07E000003F0007E000003F0007E000003F0007E000003F0007E000003F0003E00F803E00
+03F01FC07E0003F03FE07E0003F03FE07E0003F03FE07E0003F07FF07E0003F07FF07E00
+03F07DF07E0001F07DF07C0001F07DF07C0001F8FDF8FC0001F8FDF8FC0001F8FDF8FC00
+01F8F8F8FC0001F8F8F8FC0001F8F8F8FC0000F8F8F8F80000F9F8FCF80000F9F8FCF800
+00F9F07CF80000F9F07CF80000FDF07DF80000FDF07DF800007DF07DF000007DE03DF000
+007DE03DF000007DE03DF000007FE03FF000007FE03FF000007FC01FF000007FC01FF000
+003FC01FE000003FC01FE000003F800FE000001F0007C0002D397FB730>I<3FFF01FFF8
+007FFF83FFFC007FFFC7FFFE007FFFC7FFFE007FFF83FFFC003FFF01FFF80001FC007F80
+0001FE007F000000FE00FF000000FF00FE0000007F01FE0000007F81FC0000003F83FC00
+00003FC3FC0000001FC3F80000001FE7F80000000FE7F00000000FFFF000000007FFE000
+000007FFE000000003FFC000000003FFC000000001FF8000000001FF8000000000FF0000
+000000FF0000000000FF0000000000FF0000000001FF8000000001FF8000000003FFC000
+000003FFC000000003FFE000000007FFE000000007FFF00000000FE7F00000000FE7F800
+00001FC3F80000001FC3FC0000003F81FC0000003F81FE0000007F00FE0000007F00FF00
+0000FF007F000000FE007F800001FE003F800001FC003FC00003FC001FC00003F8001FE0
+0007F8000FE0007FFE007FFF00FFFF00FFFF80FFFF80FFFF80FFFF80FFFF80FFFF00FFFF
+807FFE007FFF0029387DB730>I<7FFF001FFFC0FFFF803FFFE0FFFF803FFFE0FFFF803F
+FFE0FFFF803FFFE07FFF001FFFC003F80003F80003FC0007F80003FC0007F80001FE000F
+F00001FE000FF00000FF000FE00000FF001FE000007F001FC000007F803FC000003F803F
+8000003FC07F8000001FC07F0000001FC07F0000000FE0FE0000000FE0FE0000000FF1FE
+00000007F1FC00000007F1FC00000003FBF800000003FBF800000001FBF000000001FFF0
+00000000FFE000000000FFE0000000007FC0000000007FC0000000007FC0000000003F80
+000000003F80000000003F80000000003F80000000003F80000000003F80000000003F80
+000000003F80000000003F80000000003F80000000003F80000000003F80000000003F80
+000000003F80000000003F80000000003F80000000003F8000000003FFF800000007FFFC
+0000000FFFFE0000000FFFFE00000007FFFC00000003FFF800002B387EB730>I<1FFFFF
+FFFC3FFFFFFFFE7FFFFFFFFE7FFFFFFFFE7FFFFFFFFE7FFFFFFFFE7F000003FC7F000007
+F87F000007F07F00000FF07F00001FE07F00001FC07F00003FC07F00007F803E00007F00
+000000FF00000001FE00000001FC00000003FC00000007F800000007F00000000FF00000
+001FE00000001FC00000003FC00000007F800000007F00000000FF00000001FE00000001
+FC00000003FC00000007F800000007F00000000FF00000001FE00000001FC00000003FC0
+0000007F800000007F00000000FF00000001FE00007C01FC0000FE03FC0000FE07F80000
+FE07F00000FE0FF00000FE1FE00000FE1FC00000FE3FC00000FE7F800000FE7FFFFFFFFE
+FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC27387CB730>I<7FFFFF00
+FFFFFF80FFFFFF80FFFFFF80FFFFFF80FFFFFF00FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FFFFFF00FFFFFF80FFFFFF80FFFFFF80FFFFFF807FFFFF0019476DBE30>I<7C
+000000007C00000000FE00000000FE00000000FF00000000FF000000007F800000007F80
+0000003FC00000003FC00000001FE00000001FE00000000FF00000000FF000000007F800
+000007F800000003FC00000003FC00000001FC00000001FE00000001FE00000000FF0000
+0000FF000000007F800000007F800000003FC00000003FC00000001FE00000001FE00000
+000FF00000000FF000000007F800000007F800000003FC00000003FC00000001FC000000
+01FE00000001FE00000000FF00000000FF000000007F800000007F800000003FC0000000
+3FC00000001FE00000001FE00000000FF00000000FF000000007F800000007F800000003
+FC00000003FC00000001FC00000001FE00000001FE00000000FF00000000FF000000007F
+800000007F800000003FC00000003FC00000001FE00000001FE00000000FF00000000FF0
+00000007F800000007F800000003F800000003F800000001F000000000F025477BBE30>
+I<7FFFFF00FFFFFF80FFFFFF80FFFFFF80FFFFFF807FFFFF8000003F8000003F8000003F
+8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F
+8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F
+8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F
+8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F
+8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F
+8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F
+8000003F8000003F807FFFFF80FFFFFF80FFFFFF80FFFFFF80FFFFFF807FFFFF0019477D
+BE30>I<00070000001FC000007FF00000FFF80003FFFE000FFFFF803FFFFFE07FFDFFF0
+FFF07FF8FFC01FF8FF800FF8FE0003F87C0001F0100000401D0E77B730>I<7FFFFFFFF0
+7FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFFFFFFF87FFFFFFFF07FFFFFFFF025077B7D30>
+I<003FFC00000001FFFF80000003FFFFE0000007FFFFF000000FFFFFF800001FFFFFFC00
+001FF00FFE00001FE001FF00001FE000FF00001FE0007F80000FC0003F80000780003FC0
+000000001FC0000000001FC0000000001FC0000000001FC0000000FFFFC000000FFFFFC0
+00007FFFFFC00001FFFFFFC00007FFFFFFC0000FFFFFFFC0001FFFC01FC0003FFC001FC0
+007FE0001FC0007F80001FC000FF00001FC000FE00001FC000FE00001FC000FE00001FC0
+00FE00001FC000FF00003FC000FF00003FC0007F80007FC0007FC001FFC0003FF80FFFFF
+C01FFFFFFFFFE01FFFFFFFFFE007FFFFF7FFE003FFFFC3FFE000FFFF00FFC0003FF00000
+002B2A7CA830>97 D<3FFC000000007FFE00000000FFFE00000000FFFE000000007FFE00
+0000003FFE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00
+00000000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE03
+FE000000FE1FFF800000FE7FFFE00000FEFFFFF00000FFFFFFFC0000FFFFFFFE0000FFFE
+07FE0000FFF001FF0000FFE000FF8000FFC0007F8000FF80003FC000FF00001FC000FE00
+001FE000FE00000FE000FE00000FE000FE00000FF000FE000007F000FE000007F000FE00
+0007F000FE000007F000FE000007F000FE000007F000FE000007F000FE000007F000FE00
+000FF000FE00000FF000FE00000FE000FF00000FE000FF00001FE000FF80003FC000FF80
+003FC000FFC0007F8000FFE000FF8000FFF003FF0000FFFC0FFE0000FFFFFFFC0000FFFF
+FFF80000FEFFFFF000007E7FFFC000003C1FFF0000000003FC00002C3980B730>I<0000
+FFE0000007FFFC00001FFFFE00007FFFFF0000FFFFFF8001FFFFFFC003FF807FC007FC00
+3FC00FF8003FC01FF0003FC01FE0001F803FC0000F003F800000007F800000007F000000
+007F00000000FF00000000FE00000000FE00000000FE00000000FE00000000FE00000000
+FE00000000FE00000000FE00000000FF000000007F000000007F000000007F800000003F
+800007C03FC0000FE01FE0000FE01FF0001FE00FF8001FC007FE003FC007FFC0FF8003FF
+FFFF8000FFFFFF00007FFFFE00001FFFF8000007FFF0000001FF8000232A7AA830>I<00
+0001FFE000000003FFF000000007FFF000000007FFF000000003FFF000000001FFF00000
+000007F00000000007F00000000007F00000000007F00000000007F00000000007F00000
+000007F00000000007F00000000007F00000000007F0000003FE07F000001FFF87F00000
+3FFFE7F00000FFFFFFF00001FFFFFFF00003FFFFFFF00007FF03FFF0000FFC00FFF0001F
+F0003FF0001FE0001FF0003FC0001FF0003FC0000FF0007F800007F0007F000007F0007F
+000007F000FF000007F000FF000007F000FE000007F000FE000007F000FE000007F000FE
+000007F000FE000007F000FE000007F000FE000007F000FE000007F000FF000007F0007F
+00000FF0007F00000FF0007F80000FF0003F80001FF0003FC0003FF0001FE0003FF0001F
+F0007FF0000FF801FFF00007FE07FFFFC003FFFFFFFFE001FFFFFFFFF000FFFFF7FFF000
+7FFFC7FFE0001FFF03FFC00007FC0000002C397DB730>I<0001FF00000007FFE000001F
+FFF800007FFFFC0000FFFFFE0001FFFFFF0003FF81FF8007FC007FC00FF8003FC01FE000
+1FE01FE0000FE03FC0000FF03F800007F07F800007F07F000007F07F000003F8FF000003
+F8FE000003F8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF0
+FE00000000FF000000007F000000007F000000007F800000003F800001F03FC00003F81F
+E00003F80FF00003F80FF80007F807FE001FF003FFC07FE001FFFFFFE000FFFFFFC0003F
+FFFF80001FFFFE000007FFF8000000FFC000252A7CA830>I<000000FF80000007FFE000
+001FFFF000003FFFF000007FFFF80000FFFFF80001FF87F80003FE07F80003FC03F00007
+F800C00007F000000007F000000007F000000007F000000007F000000007F000000007F0
+00000007F000003FFFFFFFC07FFFFFFFE0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE07FFFFFFF
+C00007F000000007F000000007F000000007F000000007F000000007F000000007F00000
+0007F000000007F000000007F000000007F000000007F000000007F000000007F0000000
+07F000000007F000000007F000000007F000000007F000000007F000000007F000000007
+F000000007F000000007F000000007F000000007F000000007F000003FFFFFFE007FFFFF
+FF00FFFFFFFF80FFFFFFFF807FFFFFFF003FFFFFFE0025397DB830>I<0003FC00FF0000
+1FFF87FFC0003FFFDFFFC000FFFFFFFFE001FFFFFFFFE003FFFFFFFFE007FE07FF8FE007
+F801FE07C00FF000FF00000FF000FF00000FE0007F00001FE0007F80001FC0003F80001F
+C0003F80001FC0003F80001FC0003F80001FC0003F80001FE0007F80000FE0007F00000F
+F000FF00000FF000FF000007F801FE000007FE07FE000007FFFFFC000007FFFFF800000F
+FFFFF000000FFFFFC000000FDFFF8000000FC3FC0000000FC0000000000FC0000000000F
+C0000000000FE0000000000FF00000000007FFFFF0000007FFFFFF000003FFFFFFC00007
+FFFFFFF0000FFFFFFFF8001FFFFFFFFC003FE0001FFE003F800001FE007F0000007F007E
+0000003F00FE0000003F80FC0000001F80FC0000001F80FC0000001F80FC0000001F80FC
+0000001F80FE0000003F807F0000007F007F800000FF003FC00001FE003FF00007FE001F
+FF007FFC000FFFFFFFF80007FFFFFFF00001FFFFFFC000007FFFFF0000001FFFFC000000
+01FFC000002B3E7DA730>I<3FFC000000007FFE00000000FFFE00000000FFFE00000000
+7FFE000000003FFE0000000000FE0000000000FE0000000000FE0000000000FE00000000
+00FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00000000
+00FE01FE000000FE0FFF800000FE3FFFE00000FEFFFFF00000FFFFFFF80000FFFFFFF800
+00FFFE07FC0000FFF803FC0000FFE001FE0000FFC001FE0000FF8000FE0000FF8000FE00
+00FF0000FE0000FF0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE003FFFF81FFFF87FFFFC3FFFFC
+FFFFFE3FFFFEFFFFFE3FFFFE7FFFFC3FFFFC3FFFF81FFFF82F3880B730>I<0000E00000
+0003F800000003F800000007FC00000007FC00000007FC00000003F800000003F8000000
+00E000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000001FFFF800003FFFFC00007FFFFC00007FFFFC00003FFFFC
+00001FFFFC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00
+000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC0000
+0001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC000000
+01FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00003FFF
+FFFFC07FFFFFFFE0FFFFFFFFE0FFFFFFFFE07FFFFFFFE03FFFFFFFC023397AB830>I<00
+0001C0000007F0000007F000000FF800000FF800000FF8000007F0000007F0000001C000
+000000000000000000000000000000000000000000000000000000000000000000000000
+FFFFF001FFFFF801FFFFF801FFFFF801FFFFF800FFFFF8000003F8000003F8000003F800
+0003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F800
+0003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F800
+0003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F800
+0003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F8000003F800
+0003F8000003F8000007F0000007F03C0007F07E000FE0FF001FE0FF003FC0FF007FC0FF
+FFFF807FFFFF007FFFFE003FFFFC000FFFF00003FFC0001D4E7CB830>I<7FF800000000
+FFFC00000000FFFC00000000FFFC00000000FFFC000000007FFC0000000000FC00000000
+00FC0000000000FC0000000000FC0000000000FC0000000000FC0000000000FC00000000
+00FC0000000000FC0000000000FC0000000000FC0000000000FC03FFFF8000FC07FFFFC0
+00FC07FFFFE000FC07FFFFE000FC07FFFFC000FC03FFFF8000FC001FE00000FC003FC000
+00FC007F800000FC00FF000000FC01FE000000FC03FC000000FC0FF8000000FC1FF00000
+00FC3FE0000000FC7FC0000000FCFF80000000FDFFC0000000FFFFE0000000FFFFF00000
+00FFF7F0000000FFE3F8000000FFC1FC000000FF81FE000000FF00FF000000FE007F0000
+00FC003F800000FC001FC00000FC001FE00000FC000FF00000FC0007F00000FC0003F800
+00FC0001FC007FFFF81FFFE0FFFFFC3FFFF0FFFFFC3FFFF8FFFFFC3FFFF8FFFFFC3FFFF0
+7FFFF81FFFE02D387FB730>I<7FFFF80000FFFFFC0000FFFFFC0000FFFFFC0000FFFFFC
+00007FFFFC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00
+000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC0000
+0001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC000000
+01FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001
+FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC
+00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00
+000001FC00000001FC00007FFFFFFFF0FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8FFFFFFFFF8
+7FFFFFFFF025387BB730>I<0000FC007E00007FC3FF01FF8000FFEFFF87FFC000FFFFFF
+CFFFE000FFFFFFDFFFE000FFFFFFFFFFF0007FFF0FFF87F00007FE07FF03F80007FC07FE
+03F80007F803FC01F80007F803FC01F80007F003F801F80007F003F801F80007F003F801
+F80007E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F8
+0007E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F800
+07E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F80007
+E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F8007FFE
+0FFF07FF80FFFF1FFF8FFFC0FFFF1FFF8FFFC0FFFF1FFF8FFFC0FFFF1FFF8FFFC07FFE0F
+FF07FF80322881A730>I<000001FE00003FFC0FFF80007FFE3FFFE000FFFEFFFFF000FF
+FFFFFFF8007FFFFFFFF8003FFFFE07FC0000FFF803FC0000FFE001FE0000FFC001FE0000
+FF8000FE0000FF8000FE0000FF0000FE0000FF0000FE0000FE0000FE0000FE0000FE0000
+FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000
+FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000
+FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE003F
+FFF81FFFF87FFFFC3FFFFCFFFFFE3FFFFEFFFFFE3FFFFE7FFFFC3FFFFC3FFFF81FFFF82F
+2880A730>I<0001FF0000000FFFE000003FFFF800007FFFFC0000FFFFFE0003FFFFFF80
+03FF01FF8007FC007FC00FF8003FE01FE0000FF01FE0000FF03FC00007F83F800003F87F
+800003FC7F000001FC7F000001FC7F000001FCFE000000FEFE000000FEFE000000FEFE00
+0000FEFE000000FEFE000000FEFE000000FEFE000000FEFF000001FE7F000001FC7F0000
+01FC7F800003FC3F800003F83FC00007F83FE0000FF81FF0001FF00FF8003FE00FFC007F
+E007FF01FFC003FFFFFF8001FFFFFF00007FFFFC00003FFFF800000FFFE0000001FF0000
+272A7CA830>I<000003FE00003FFC1FFF80007FFE7FFFE000FFFEFFFFF000FFFFFFFFFC
+007FFFFFFFFE003FFFFE07FE0000FFF001FF0000FFE000FF8000FFC0007F8000FF80003F
+C000FF00001FC000FE00001FE000FE00000FE000FE00000FE000FE00000FF000FE000007
+F000FE000007F000FE000007F000FE000007F000FE000007F000FE000007F000FE000007
+F000FE000007F000FE00000FF000FE00000FF000FE00000FE000FF00000FE000FF00001F
+E000FF80003FC000FF80003FC000FFC0007F8000FFE000FF8000FFF003FF0000FFFC0FFE
+0000FFFFFFFC0000FFFFFFF80000FEFFFFF00000FE7FFFC00000FE1FFF000000FE03FC00
+0000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE000000
+0000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE000000
+0000FE000000003FFFF80000007FFFFC000000FFFFFE000000FFFFFE0000007FFFFC0000
+003FFFF80000002C3C80A730>I<0001FF00F800000FFFC1FC00003FFFF1FC00007FFFFD
+FC0001FFFFFFFC0003FFFFFFFC0007FF81FFFC000FFC007FFC000FF8001FFC001FF0000F
+FC001FE00007FC003FC00007FC003F800003FC007F800003FC007F000003FC007F000001
+FC00FF000001FC00FE000001FC00FE000001FC00FE000001FC00FE000001FC00FE000001
+FC00FE000001FC00FE000001FC00FF000001FC007F000001FC007F000003FC007F800003
+FC007F800003FC003FC00007FC003FC0000FFC001FE0001FFC000FF0003FFC000FFC007F
+FC0007FF01FFFC0003FFFFFFFC0001FFFFFDFC0000FFFFF9FC00003FFFF1FC00000FFFC1
+FC000003FE01FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC00000000FFFFF8000001FFFFFC000001FFFFFC000001FF
+FFFC000001FFFFFC000000FFFFF82E3C7DA730>I<00000007F8003FFF803FFF007FFFC0
+FFFF80FFFFC3FFFF80FFFFCFFFFFC07FFFDFFFFFC03FFFFFFC3FC0001FFFE03FC0001FFF
+801F80001FFF000F00001FFE000000001FFC000000001FF8000000001FF0000000001FF0
+000000001FE0000000001FE0000000001FE0000000001FE0000000001FC0000000001FC0
+000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0
+000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0
+000000001FC00000003FFFFFFC00007FFFFFFE0000FFFFFFFF0000FFFFFFFF00007FFFFF
+FE00003FFFFFFC00002A287EA730>I<001FFC1E0001FFFF9F0007FFFFFF000FFFFFFF00
+1FFFFFFF003FFFFFFF007FF007FF007F8001FF00FE0000FF00FC00007F00FC00007F00FC
+00007F00FC00007F00FE00003E007F000000007FE00000003FFF0000001FFFFC00000FFF
+FF800007FFFFE00001FFFFF800007FFFFC000003FFFE0000000FFF00000000FF807C0000
+7F80FE00001FC0FE00001FC0FE00000FC0FF00000FC0FF00000FC0FF80000FC0FF80001F
+C0FFC0003F80FFE0007F80FFFC03FF00FFFFFFFF00FFFFFFFE00FFFFFFFC00FCFFFFF000
+F83FFFC000780FFE0000222A79A830>I<0007800000000FC00000001FC00000001FC000
+00001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000
+3FFFFFFFE07FFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF07FFFFFFFE0001FC0000000
+1FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001F
+C00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC0
+0000001FC00000001FC00000001FC000F8001FC001FC001FC001FC001FC001FC001FC001
+FC001FC001FC001FE003FC000FE007F8000FF007F8000FFC1FF00007FFFFE00003FFFFC0
+0003FFFF800001FFFF0000007FFC0000001FF00026337EB130>I<3FFC003FFC007FFE00
+7FFE00FFFE00FFFE00FFFE00FFFE007FFE007FFE003FFE003FFE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0001FE0000FE0001FE0000FE0003FE0000FE00
+07FE0000FF000FFE00007FC07FFFF8007FFFFFFFFC003FFFFFFFFE001FFFFFFFFE000FFF
+FEFFFC0007FFF87FF80000FFC000002F2880A630>I<3FFFC07FFF807FFFE0FFFFC0FFFF
+E0FFFFE0FFFFE0FFFFE07FFFE0FFFFC03FFFC07FFF8001F80003F00001F80003F00001FC
+0007F00000FC0007E00000FC0007E00000FE000FE000007E000FC000007E000FC000007F
+001FC000003F001F8000003F001F8000003F803F8000001F803F0000001F803F0000001F
+C07F0000000FC07E0000000FC07E0000000FE0FE00000007E0FC00000007E0FC00000007
+F1FC00000003F1F800000003F1F800000003F1F800000001FBF000000001FBF000000001
+FBF000000001FFF000000000FFE000000000FFE000000000FFE0000000007FC000000000
+3F8000002B277EA630>I<3FFFC01FFFE07FFFE03FFFF0FFFFE03FFFF8FFFFE03FFFF87F
+FFE03FFFF03FFFC01FFFE007E000003F0007E000003F0007F000007F0003F000007E0003
+F000007E0003F000007E0003F000007E0003F000007E0003F80000FE0001F80000FC0001
+F80F80FC0001F81FC0FC0001F83FE0FC0001F83FE0FC0001F83FE0FC0000FC7FF1F80000
+FC7FF1F80000FC7DF1F80000FC7DF1F80000FCFDF9F800007CFDF9F000007CF8F9F00000
+7CF8F9F000007CF8F9F000007EF8FBF000007EF8FBF000003FF07FE000003FF07FE00000
+3FF07FE000003FE03FE000003FE03FE000001FE03FC000000F800F80002D277FA630>I<
+3FFF81FFFC007FFFC3FFFE00FFFFC3FFFF00FFFFC3FFFF007FFFC3FFFE003FFF81FFFC00
+00FE007F0000007F007F0000007F80FE0000003F81FC0000001FC3F80000000FE3F80000
+000FE7F000000007FFE000000003FFC000000001FFC000000000FF8000000000FF000000
+00007E00000000007F0000000000FF0000000001FF8000000001FFC000000003F7E00000
+0007E7E00000000FE3F00000000FC1F80000001F81FC0000003F80FE0000007F007E0000
+007E007F000000FE003F800001FC001FC0007FFF80FFFF00FFFFC1FFFF80FFFFE3FFFF80
+FFFFE3FFFF80FFFFC1FFFF807FFF80FFFF0029277DA630>I<3FFFC07FFF807FFFE0FFFF
+C0FFFFE0FFFFE0FFFFE0FFFFE07FFFE0FFFFC03FFFC07FFF8001FC0003F00001FC0003F0
+0000FC0007F00000FE0007E000007E0007E000007E000FE000007F000FC000003F000FC0
+00003F001FC000001F801F8000001F801F8000001FC01F8000000FC03F0000000FC03F00
+00000FE03F00000007E07E00000007E07E00000003F07E00000003F07C00000003F0FC00
+000001F8FC00000001F8F800000001F8F800000000F9F800000000FDF0000000007DF000
+0000007FF0000000007FF0000000003FE0000000003FE0000000003FE0000000001FC000
+0000001FC0000000001FC0000000001F80000000001F80000000003F80000000003F0000
+0000003F00000000007F00000000007E00000000007E0000000F00FE0000001F80FC0000
+003FC1FC0000003FC3F80000003F87F80000003F8FF00000003FFFE00000001FFFC00000
+001FFF800000000FFF0000000007FE0000000001F0000000002B3C7EA630>I<1FFFFFFF
+FC3FFFFFFFFE7FFFFFFFFE7FFFFFFFFE7FFFFFFFFE7FFFFFFFFC7F00000FF87F00001FF0
+7F00003FE07F00007FC07F0000FF803E0001FF00000003FE00000007FC0000000FF80000
+001FF00000003FE00000007FC0000000FF80000001FF00000003FE00000007FC0000000F
+F80000001FF00000003FE00000007FC0000000FF80003E01FF00007F03FE00007F07FC00
+007F0FF800007F1FF000007F3FE000007F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFF7FFFFFFFFE28277DA630>I<0000003FF0000003FFF800000FFFF800001F
+FFF800007FFFF800007FFFF00000FFF0000000FF00000001FE00000001FC00000001FC00
+000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC0000
+0001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC000000
+01FC00000001FC00000001FC00000001FC00000003FC00000007F80000003FF800003FFF
+F00000FFFFE00000FFFFC00000FFFF000000FFFFC00000FFFFE000003FFFF00000003FF8
+00000007F800000003FC00000001FC00000001FC00000001FC00000001FC00000001FC00
+000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC0000
+0001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC000000
+01FC00000001FE00000000FF00000000FFF00000007FFFF000007FFFF800001FFFF80000
+0FFFF8000003FFF80000003FF025477BBE30>I<7C7CFEFEFEFEFEFEFEFEFEFEFEFEFEFE
+FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE
+FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE7C7C07476CBE30>I<7FE0000000FFFE000000
+FFFF800000FFFFC00000FFFFF000007FFFF00000007FF800000007F800000003FC000000
+01FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001
+FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC
+00000001FC00000001FC00000001FC00000001FC00000001FC00000001FE00000000FF00
+000000FFE00000007FFFE000003FFFF800001FFFF8000007FFF800001FFFF800003FFFF8
+00007FFFE00000FFE0000000FF00000001FE00000001FC00000001FC00000001FC000000
+01FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001
+FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC
+00000001FC00000001FC00000003FC00000007F80000007FF800007FFFF00000FFFFF000
+00FFFFC00000FFFF800000FFFE0000007FE000000025477BBE30>I<007C003801FF007C
+03FF80FE07FFC1FE0FFFC3FE1FFFEFFC7FEFFFF0FF87FFE0FF07FFC0FE03FF807C01FF00
+38007C001F0C78B730>I E /Fo 10 121 df<FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FF18067E9622>45 D<00000003C000000000000003C000000000000003C0000000000000
+07E000000000000007E00000000000000FF00000000000000FF00000000000000FF00000
+000000001FF80000000000001FF80000000000001FF80000000000003BFC000000000000
+3BFC0000000000003BFC00000000000071FE00000000000071FE000000000000F1FF0000
+00000000E0FF000000000000E0FF000000000001E0FF800000000001C07F800000000001
+C07F800000000003807FC00000000003803FC00000000003803FC00000000007001FE000
+00000007001FE0000000000F001FF0000000000E000FF0000000000E000FF0000000001E
+000FF8000000001C0007F8000000001C0007F8000000003C0007FC00000000380003FC00
+000000380003FC00000000700001FE00000000700001FE00000000700001FE00000000E0
+0000FF00000000E00000FF00000001FFFFFFFF80000001FFFFFFFF80000001FFFFFFFF80
+000003C000007FC00000038000003FC00000038000003FC00000070000003FE000000700
+00001FE00000070000001FE000000E0000000FF000000E0000000FF000001E0000000FF8
+00001C00000007F800001C00000007F800003C00000007FC00003800000003FC00007800
+000003FC00007800000003FE0000FC00000001FE0001FE00000003FF000FFF0000000FFF
+80FFFFF00001FFFFFFFFFFF00001FFFFFFFFFFF00001FFFFFF40417CC04A>65
+D<FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF001FFC00000FFF0007F8000001FF0
+007F80000007F8007F80000003F8007F80000001F8007F80000000F8007F800000007800
+7F8000000078007F8000000078007F8000000038007F8000000038007F8000000038007F
+8000000038007F800000001C007F80001C001C007F80001C001C007F80001C001C007F80
+001C001C007F80001C0000007F80001C0000007F80003C0000007F80003C0000007F8000
+7C0000007F8000FC0000007F8003FC0000007FFFFFFC0000007FFFFFFC0000007FFFFFFC
+0000007F8003FC0000007F8000FC0000007F80007C0000007F80003C0000007F80003C00
+00007F80001C0000007F80001C0000007F80001C0007007F80001C0007007F80001C0007
+007F80001C000E007F800000000E007F800000000E007F800000000E007F800000000E00
+7F800000001E007F800000001C007F800000001C007F800000003C007F800000003C007F
+800000007C007F800000007C007F80000000F8007F80000001F8007F80000003F8007F80
+000007F8007F8000001FF801FFC00001FFF8FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFF
+FFFFF0383E7BBD43>69 D<0000001FF8000180000001FFFF80038000000FFFFFE0078000
+003FF803F80F800000FF80007C0F800001FE00001E1F800007FC00000FBF80000FF00000
+07FF80001FE0000003FF80003FC0000001FF80007F80000000FF8000FF000000007F8001
+FE000000003F8003FE000000003F8003FC000000001F8007FC000000001F800FF8000000
+000F800FF8000000000F801FF0000000000F801FF00000000007803FF00000000007803F
+E00000000007803FE00000000003807FE00000000003807FE00000000003807FE0000000
+0003807FC0000000000000FFC0000000000000FFC0000000000000FFC0000000000000FF
+C0000000000000FFC0000000000000FFC0000000000000FFC0000000000000FFC0000000
+000000FFC0000000000000FFC0000000000000FFC0000000000000FFC0000007FFFFFE7F
+C0000007FFFFFE7FE0000007FFFFFE7FE000000001FFC07FE0000000007F803FE0000000
+007F803FE0000000007F803FF0000000007F801FF0000000007F801FF0000000007F800F
+F8000000007F800FF8000000007F8007FC000000007F8003FC000000007F8003FE000000
+007F8001FF000000007F8000FF000000007F80007F80000000FF80003FC0000000FF8000
+1FE0000001FF80000FF0000001FF800007FC000003DF800001FF00000F8F800000FFC000
+3F078000003FF801FC038000000FFFFFF00180000001FFFFC000000000001FFC0000003F
+427ABF4D>71 D<FFFFFFF0FFFFFFF0FFFFFFF000FFF000003FC000003FC000003FC00000
+3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000
+3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000
+3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000
+3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000
+3FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC00000
+3FC000003FC000003FC000003FC000003FC000003FC00000FFF000FFFFFFF0FFFFFFF0FF
+FFFFF01C3E7CBD25>73 D<FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF8003FE0000FF8001
+FC00001FC001FC00000FC001FC000007C001FC000003C001FC000003C001FC000001C001
+FC000001C001FC000001C001FC000001E001FC000E00E001FC000E00E001FC000E00E001
+FC000E000001FC000E000001FC001E000001FC003E000001FC007E000001FFFFFE000001
+FFFFFE000001FFFFFE000001FC007E000001FC003E000001FC001E000001FC000E000001
+FC000E000001FC000E003801FC000E003801FC000E003801FC0000007001FC0000007001
+FC0000007001FC0000007001FC000000F001FC000000F001FC000001E001FC000001E001
+FC000003E001FC000007E001FC00001FE003FE0000FFE0FFFFFFFFFFC0FFFFFFFFFFC0FF
+FFFFFFFFC02D2F7DAE33>101 D<FFFFFFFE0000FFFFFFFFC000FFFFFFFFF00003FE0007
+FC0001FC0001FE0001FC00007F0001FC00003F8001FC00003F8001FC00001FC001FC0000
+1FC001FC00001FE001FC00001FE001FC00001FE001FC00001FE001FC00001FE001FC0000
+1FE001FC00001FC001FC00001FC001FC00003F8001FC00003F8001FC00007F0001FC0001
+FC0001FC0007F80001FFFFFFE00001FFFFFF800001FC0000000001FC0000000001FC0000
+000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000
+000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000
+000001FC0000000001FC0000000001FC0000000003FE00000000FFFFF8000000FFFFF800
+0000FFFFF80000002B2F7DAE33>112 D<FFFFFFF0000000FFFFFFFF000000FFFFFFFFC0
+000003FE001FF0000001FC0003FC000001FC0000FE000001FC00007F000001FC00007F00
+0001FC00007F800001FC00003F800001FC00003FC00001FC00003FC00001FC00003FC000
+01FC00003FC00001FC00003FC00001FC00003F800001FC00007F800001FC00007F000001
+FC0000FE000001FC0001FC000001FC0003F8000001FC001FE0000001FFFFFF00000001FF
+FFFE00000001FC003F80000001FC000FC0000001FC0007E0000001FC0007F0000001FC00
+03F8000001FC0003F8000001FC0001FC000001FC0001FC000001FC0001FC000001FC0001
+FC000001FC0001FC000001FC0001FE000001FC0001FE000001FC0001FE000001FC0001FE
+000001FC0001FE00E001FC0001FF00E001FC0001FF00E001FC0000FF00E003FE0000FF01
+C0FFFFF8007F81C0FFFFF8001FC380FFFFF8000FFF000000000001FC0033307DAE37>
+114 D<003FC00C00FFF81C03FFFE3C0FE03FFC1F8007FC1F0003FC3E0001FC7C0000FC7C
+00007CF800007CF800003CF800003CF800003CFC00001CFC00001CFE00001CFF0000007F
+8000007FE000007FFE00003FFFE0001FFFFE000FFFFF8007FFFFE001FFFFF0007FFFF800
+0FFFFC0000FFFC000007FE000001FE000000FE0000007F0000003FE000003FE000001FE0
+00001FE000001FF000001FF000001FF000001EF800003EFC00003CFE00007CFF0000F8FF
+C001F0FBF807E0F1FFFFC0E07FFF00C007FC0020317BAF2A>I<7FFFF001FFFE007FFFF0
+01FFFE007FFFF001FFFE0003FFC000FFE00000FF80007F8000007F80007E0000007F8000
+7C0000003FC000780000001FE000F00000000FF000E00000000FF001E000000007F803C0
+00000003FC038000000003FC078000000001FE0F0000000000FF1E00000000007F9C0000
+0000007FBC00000000003FF800000000001FF000000000001FF000000000000FF0000000
+000007F8000000000003F8000000000007FC00000000000FFE00000000001EFF00000000
+001CFF00000000003C7F8000000000783FC000000000703FC000000000F01FE000000001
+E00FF000000003C007F8000000038007F8000000078003FC0000000F0001FE0000000E00
+01FE0000001E0000FF0000003C00007F8000007C00003FC00000FC00003FC00003FC0000
+3FE0000FFE00007FF800FFFF0001FFFFC0FFFF0001FFFFC0FFFF0001FFFFC0322F7DAE38
+>120 D E /Fp 48 122 df<00003FE00FE00001FFF83FF80007E01EF83C001F800FF07E
+003F001FE0FE007E003FE0FE00FC003FC0FE01F8003FC0FE01F8003FC03803F0001F8000
+03F0001F800003F0001F800003F0001F800003F0001F800003F0001F800003F0001F8000
+03F0001F800003F0001F800003F0001F800003F0001F800003F0001F8000FFFFFFFFFFC0
+FFFFFFFFFFC0FFFFFFFFFFC003F0001F800003F0001F800003F0001F800003F0001F8000
+03F0001F800003F0001F800003F0001F800003F0001F800003F0001F800003F0001F8000
+03F0001F800003F0001F800003F0001F800003F0001F800003F0001F800003F0001F8000
+03F0001F800003F0001F800003F0001F800003F0001F800003F0001F800003F0001F8000
+03F0001F800003F0001F800003F0001F800007F8003FC000FFFF83FFFF00FFFF83FFFF00
+FFFF83FFFF002F357FB42D>11 D<00001FE0000000FFFC000003F01E00000FC00780001F
+800780003F000FC0007E001FC000FC001FC000FC001FC001F8001FC001F8000F8001F800
+000001F800000001F800000001F800000001F800000001F800000001F800000001F80000
+0001F800000001F8000FC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC001F8001FC001F8000FC0
+01F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001
+F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8
+000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F8000FC001F800
+0FC001F8000FC003FC001FE07FFFC1FFFF7FFFC1FFFF7FFFC1FFFF28357FB42B>I<0000
+1FE000FF00000000FFFC07FFE0000003F01E1F80F000000FC0077E003C00001F8007FC00
+3C00003F001FF8007E00007E001FF000FE0000FC001FE000FE0000FC001FE000FE0001F8
+001FC000FE0001F8000FC0007C0001F8000FC000000001F8000FC000000001F8000FC000
+000001F8000FC000000001F8000FC000000001F8000FC000000001F8000FC000000001F8
+000FC000000001F8000FC000000001F8000FC0007E00FFFFFFFFFFFFFE00FFFFFFFFFFFF
+FE00FFFFFFFFFFFFFE0001F8000FC000FE0001F8000FC0007E0001F8000FC0007E0001F8
+000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC000
+7E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8
+000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC000
+7E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8
+000FC0007E0001F8000FC0007E0001F8000FC0007E0001F8000FC0007E0003FC001FE000
+FF007FFFC1FFFE0FFFF87FFFC1FFFE0FFFF87FFFC1FFFE0FFFF83D357FB440>14
+D<0000C00001C0000380000F00000E00001C00003C0000780000F00000F00001E00003C0
+0003C00007C0000780000F80000F00001F00001F00001E00003E00003E00003E00003C00
+007C00007C00007C00007C00007C0000F80000F80000F80000F80000F80000F80000F800
+00F80000F80000F80000F80000F80000F80000F80000F80000F800007C00007C00007C00
+007C00007C00003C00003E00003E00003E00001E00001F00001F00000F00000F80000780
+0007C00003C00003C00001E00000F00000F000007800003C00001C00000E00000F000003
+800001C00000C0124A79B71E>40 D<C00000E000007000003C00001C00000E00000F0000
+07800003C00003C00001E00000F00000F00000F800007800007C00003C00003E00003E00
+001E00001F00001F00001F00000F00000F80000F80000F80000F80000F800007C00007C0
+0007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C0
+0007C00007C0000F80000F80000F80000F80000F80000F00001F00001F00001F00001E00
+003E00003E00003C00007C0000780000F80000F00000F00001E00003C00003C000078000
+0F00000E00001C00003C0000700000E00000C00000124A7CB71E>I<3C007E00FF00FF00
+FF80FF807F803D800180018001800180038003000300070006000E000C001C0038007000
+600009177A8715>44 D<FFFFF0FFFFF0FFFFF0FFFFF0FFFFF014057F921A>I<3C7EFFFF
+FFFF7E3C08087A8715>I<00070000000F0000001F0000007F000007FF0000FFFF0000FF
+BF0000F83F0000003F0000003F0000003F0000003F0000003F0000003F0000003F000000
+3F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F000000
+3F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F000000
+3F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F000000
+3F0000003F0000003F0000003F0000007F80007FFFFF807FFFFF807FFFFF8019327AB126
+>49 D<003FC00000FFF00003FFFC000F80FF001E007F801C003FC038001FE070000FE070
+000FF0600007F0FC0007F0FE0007F8FF0007F8FF0003F8FF0003F8FF0003F87E0007F83C
+0007F8000007F8000007F0000007F000000FF000000FE000001FC000001FC000003F8000
+003F0000007E000000FC000001F8000001F0000003E0000007C000000F8000001F000000
+3E0000003C00000078001800F0001801E0001803C00030078000300F0000301C0000701F
+FFFFF03FFFFFF07FFFFFF0FFFFFFE0FFFFFFE0FFFFFFE01D327CB126>I<FFFFFFFFFFC0
+FFFFFFFFFFC0FFFFFFFFFFC003FC00007FC001FC00000FC001FC000003E001FC000001E0
+01FC000001E001FC000000E001FC000000E001FC0000006001FC0000006001FC00000060
+01FC0000006001FC0006003001FC0006003001FC0006003001FC0006003001FC00060000
+01FC000E000001FC000E000001FC001E000001FC007E000001FFFFFE000001FFFFFE0000
+01FFFFFE000001FC007E000001FC001E000001FC000E000001FC000E000001FC00060000
+01FC0006000C01FC0006000C01FC0006000C01FC0006001801FC0000001801FC00000018
+01FC0000001801FC0000001801FC0000003801FC0000003801FC0000007001FC00000070
+01FC000000F001FC000001F001FC000003F001FC000007F003FC00007FF0FFFFFFFFFFE0
+FFFFFFFFFFE0FFFFFFFFFFE02E337DB234>69 D<000003FE000C0000003FFF801C000000
+FFFFE01C000003FE01F83C00000FF0003C7C00001FC0000EFC00007F800007FC0000FE00
+0003FC0001FC000001FC0003FC000000FC0003F8000000FC0007F00000007C000FE00000
+007C000FE00000003C001FC00000003C001FC00000001C003FC00000001C003F80000000
+1C007F800000000C007F800000000C007F800000000C007F000000000C00FF0000000000
+00FF000000000000FF000000000000FF000000000000FF000000000000FF000000000000
+FF000000000000FF000000000000FF000000000000FF000000000000FF000003FFFFE07F
+000003FFFFE07F800003FFFFE07F80000003FE007F80000001FC003F80000001FC003FC0
+000001FC001FC0000001FC001FC0000001FC000FE0000001FC000FF0000001FC0007F000
+0001FC0003F8000001FC0003FC000001FC0001FE000003FC0000FF000003FC00007F8000
+07FC00001FC0000E7C00000FF0001C3C000003FE00F81C000000FFFFF00C0000003FFFC0
+0000000003FE00000033377CB43C>71 D<FFFFFE03FFFFF8FFFFFE03FFFFF8FFFFFE03FF
+FFF801FF000007FC0000FE000003F80000FE000003F80000FE000003F80000FE000003F8
+0000FE000003F80000FE000003F80000FE000003F80000FE000003F80000FE000003F800
+00FE000003F80000FE000003F80000FE000003F80000FE000003F80000FE000003F80000
+FE000003F80000FE000003F80000FE000003F80000FE000003F80000FE000003F80000FF
+FFFFFFF80000FFFFFFFFF80000FFFFFFFFF80000FE000003F80000FE000003F80000FE00
+0003F80000FE000003F80000FE000003F80000FE000003F80000FE000003F80000FE0000
+03F80000FE000003F80000FE000003F80000FE000003F80000FE000003F80000FE000003
+F80000FE000003F80000FE000003F80000FE000003F80000FE000003F80000FE000003F8
+0000FE000003F80000FE000003F80000FE000003F80001FF000007FC00FFFFFE03FFFFF8
+FFFFFE03FFFFF8FFFFFE03FFFFF835337EB23A>I<FFFFFEFFFFFEFFFFFE01FF0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE00
+00FE0000FE0000FE0000FE0000FE0000FE0001FF00FFFFFEFFFFFEFFFFFE17337EB21C>
+I<FFFFFE000000FFFFFE000000FFFFFE00000003FE0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000018001FC0000018001FC0000018001FC0000018001FC000003
+8001FC0000030001FC0000030001FC0000030001FC0000030001FC0000070001FC000007
+0001FC00000F0001FC00001F0001FC00003F0001FC00007F0001FC0000FE0003FC0007FE
+00FFFFFFFFFE00FFFFFFFFFE00FFFFFFFFFE0029337DB230>76 D<FFFC00000001FFF8FF
+FE00000003FFF8FFFE00000003FFF803FE00000003FE0001BF00000006FC0001BF000000
+06FC0001BF00000006FC00019F8000000CFC00019F8000000CFC00018FC0000018FC0001
+8FC0000018FC00018FC0000018FC000187E0000030FC000187E0000030FC000183F00000
+60FC000183F0000060FC000183F0000060FC000181F80000C0FC000181F80000C0FC0001
+81F80000C0FC000180FC000180FC000180FC000180FC0001807E000300FC0001807E0003
+00FC0001807E000300FC0001803F000600FC0001803F000600FC0001801F800C00FC0001
+801F800C00FC0001801F800C00FC0001800FC01800FC0001800FC01800FC0001800FC018
+00FC00018007E03000FC00018007E03000FC00018003F06000FC00018003F06000FC0001
+8003F06000FC00018001F8C000FC00018001F8C000FC00018001F8C000FC00018000FD80
+00FC00018000FD8000FC000180007F0000FC000180007F0000FC000180007F0000FC0003
+C0003E0000FC000FF0003E0001FE00FFFF001C007FFFF8FFFF001C007FFFF8FFFF001C00
+7FFFF83D337CB246>I<FFFE00001FFFF8FFFF00001FFFF8FFFF80001FFFF800FF800000
+FF0000FFC000003C0000DFE00000180000CFF00000180000CFF00000180000C7F8000018
+0000C3FC0000180000C3FC0000180000C1FE0000180000C0FF0000180000C07F80001800
+00C07F8000180000C03FC000180000C01FE000180000C01FE000180000C00FF000180000
+C007F800180000C003FC00180000C003FC00180000C001FE00180000C000FF00180000C0
+00FF00180000C0007F80180000C0003FC0180000C0001FE0180000C0001FE0180000C000
+0FF0180000C00007F8180000C00007F8180000C00003FC180000C00001FE180000C00000
+FF180000C00000FF180000C000007F980000C000003FD80000C000003FD80000C000001F
+F80000C000000FF80000C0000007F80000C0000007F80000C0000003F80000C0000001F8
+0000C0000001F80001E0000000F80007F80000007800FFFFC000003800FFFFC000003800
+FFFFC00000180035337EB23A>I<000007FC00000000007FFFC000000001FC07F0000000
+07E000FC0000000F80003E0000003F00001F8000007E00000FC00000FC000007E00001F8
+000003F00003F0000001F80003F0000001F80007E0000000FC000FE0000000FE000FC000
+00007E001FC00000007F001FC00000007F003F800000003F803F800000003F807F800000
+003FC07F800000003FC07F000000001FC07F000000001FC0FF000000001FE0FF00000000
+1FE0FF000000001FE0FF000000001FE0FF000000001FE0FF000000001FE0FF000000001F
+E0FF000000001FE0FF000000001FE0FF000000001FE0FF000000001FE07F000000001FC0
+7F800000003FC07F800000003FC07F800000003FC03F800000003F803FC00000007F803F
+C00000007F801FC00000007F001FE0000000FF000FE0000000FE0007F0000001FC0007F0
+000001FC0003F8000003F80001F8000003F00000FC000007E000007E00000FC000003F00
+001F8000001FC0007F00000007E000FC00000001FC07F0000000007FFFC00000000007FC
+00000033377CB43C>I<FFFFFFFC000000FFFFFFFF800000FFFFFFFFF0000001FE0007FC
+000000FE0001FE000000FE00007F000000FE00003F800000FE00001FC00000FE00001FE0
+0000FE00000FE00000FE00000FF00000FE00000FF00000FE00000FF00000FE00000FF000
+00FE00000FF00000FE00000FF00000FE00000FE00000FE00000FE00000FE00001FC00000
+FE00001FC00000FE00003F800000FE00007E000000FE0001FC000000FE000FF0000000FF
+FFFFC0000000FFFFFF00000000FE001FC0000000FE0007F0000000FE0003F8000000FE00
+01FC000000FE0000FC000000FE0000FE000000FE00007E000000FE00007F000000FE0000
+7F000000FE00007F000000FE00007F000000FE00007F000000FE00007F800000FE00007F
+800000FE00007F800000FE00007F800000FE00007F800000FE00007F800C00FE00007FC0
+0C00FE00007FC00C00FE00003FC01C01FF00003FC018FFFFFE001FE018FFFFFE000FE038
+FFFFFE0007F0700000000001FFE000000000003F8036357EB239>82
+D<001FE00300007FFC070001FFFF070007F01FCF000F8003FF001F0000FF003E00007F00
+3E00003F007C00001F007C00001F007800000F00F800000700F800000700F800000700F8
+00000700FC00000300FC00000300FE00000300FE000000007F000000007FC00000003FF0
+0000003FFF0000001FFFF000000FFFFF000007FFFFC00003FFFFF00000FFFFF800003FFF
+FC000003FFFE0000003FFF00000003FF00000000FF800000007F800000003F800000001F
+C00000000FC0C000000FC0C000000FC0C0000007C0C0000007C0C0000007C0E0000007C0
+E0000007C0F000000F80F000000F80F800000F00FC00001F00FE00003E00FF00007E00FF
+C000FC00F1FC03F800E0FFFFE000E01FFF8000C003FE000022377CB42B>I<7FFFFFFFFF
+FE7FFFFFFFFFFE7FFFFFFFFFFE7F8007F001FE7C0007F0003E780007F0001E700007F000
+0E700007F0000E600007F00006E00007F00007E00007F00007E00007F00007C00007F000
+03C00007F00003C00007F00003C00007F00003C00007F00003C00007F00003000007F000
+00000007F00000000007F00000000007F00000000007F00000000007F00000000007F000
+00000007F00000000007F00000000007F00000000007F00000000007F00000000007F000
+00000007F00000000007F00000000007F00000000007F00000000007F00000000007F000
+00000007F00000000007F00000000007F00000000007F00000000007F00000000007F000
+00000007F00000000007F00000000007F00000000007F0000000000FF80000001FFFFFFC
+00001FFFFFFC00001FFFFFFC0030337DB237>I<FFFFFE001FFFF8FFFFFE001FFFF8FFFF
+FE001FFFF801FF000000FF0000FE0000003C0000FE000000180000FE000000180000FE00
+0000180000FE000000180000FE000000180000FE000000180000FE000000180000FE0000
+00180000FE000000180000FE000000180000FE000000180000FE000000180000FE000000
+180000FE000000180000FE000000180000FE000000180000FE000000180000FE00000018
+0000FE000000180000FE000000180000FE000000180000FE000000180000FE0000001800
+00FE000000180000FE000000180000FE000000180000FE000000180000FE000000180000
+FE000000180000FE000000180000FE000000180000FE000000180000FE000000180000FE
+0000003800007F0000003000007F0000003000007F0000007000003F8000006000001F80
+0000E000001FC00001C000000FC00003C0000007E0000780000003F0000F00000001FC00
+1E00000000FF00FC000000003FFFF0000000000FFFC00000000001FF00000035357EB23A
+>I<7FFFFC00FFFFC07FFFFC00FFFFC07FFFFC00FFFFC001FFE0001FF800007F80000FC0
+00003F8000078000003FC000070000001FE0000E0000000FE0000C0000000FF000180000
+0007F8003800000003F8007000000003FC006000000001FE00E000000000FF01C0000000
+00FF0180000000007F8300000000003FC700000000003FC600000000001FEC0000000000
+0FFC00000000000FF8000000000007F8000000000003FC000000000003FC000000000001
+FE000000000001FF000000000003FF0000000000037F8000000000063FC0000000000E3F
+C0000000001C1FE000000000180FF0000000003807F0000000007007F8000000006003FC
+00000000C001FC00000001C001FE000000018000FF0000000300007F0000000700007F80
+00000E00003FC000000C00001FE000001C00001FE000003800000FF0000078000007F800
+00FC000007F80007FE00001FFE00FFFF8000FFFFF8FFFF8000FFFFF8FFFF8000FFFFF835
+337EB23A>88 D<FFFFF80000FFFEFFFFF80000FFFEFFFFF80000FFFE03FF8000003FE001
+FF0000001F8000FF0000000E00007F8000001C00003FC000001800003FC000003800001F
+E000003000001FE000006000000FF00000E0000007F80000C0000007F80001C0000003FC
+000180000001FE000300000001FE000700000000FF000600000000FF000C000000007F80
+1C000000003FC018000000003FC038000000001FE030000000000FF060000000000FF0E0
+0000000007F8C00000000007F9800000000003FF800000000001FF000000000001FE0000
+00000000FE000000000000FE000000000000FE000000000000FE000000000000FE000000
+000000FE000000000000FE000000000000FE000000000000FE000000000000FE00000000
+0000FE000000000000FE000000000000FE000000000000FE000000000000FE0000000000
+00FE000000000000FE000000000001FF0000000000FFFFFC00000000FFFFFC00000000FF
+FFFC000037337FB23A>I<007F80000003FFF000000F80FC00001C003E00003F003F0000
+3F801F80003F800FC0003F800FC0003F8007E0001F0007E000000007E000000007E00000
+0007E000000007E0000001FFE000001FFFE00000FF87E00003FC07E0000FF007E0001FC0
+07E0003F8007E0007F8007E0007F0007E000FF0007E0C0FE0007E0C0FE0007E0C0FE0007
+E0C0FE000FE0C0FE000FE0C0FF001FE0C07F003BE0C03F8071F1801FC1E1FF8007FFC0FF
+0000FE003C0022237DA126>97 D<03F0000000FFF0000000FFF0000000FFF000000007F0
+00000003F000000003F000000003F000000003F000000003F000000003F000000003F000
+000003F000000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F03F800003F0FFE00003F3C0F80003F7007E0003FE003F0003FC001F8003F8000FC0
+03F0000FC003F00007E003F00007F003F00007F003F00003F003F00003F803F00003F803
+F00003F803F00003F803F00003F803F00003F803F00003F803F00003F803F00003F803F0
+0003F803F00003F003F00007F003F00007E003F00007E003F0000FC003F8000FC003FC00
+1F8003EC003F0003CF007C00038381F8000301FFE00000007F000025357EB32B>I<0007
+F800003FFF0000FC07C001F000E003E003F007C007F00FC007F01F8007F03F8007F03F00
+03E07F0000007F0000007E000000FE000000FE000000FE000000FE000000FE000000FE00
+0000FE000000FE000000FE000000FE0000007F0000007F0000003F0000183F8000181F80
+00381FC000300FC0007007E000E003F001C000FC0F80003FFE000007F0001D237EA122>
+I<0000003F0000000FFF0000000FFF0000000FFF000000007F000000003F000000003F00
+0000003F000000003F000000003F000000003F000000003F000000003F000000003F0000
+00003F000000003F000000003F000000003F000000003F000007F03F00003FFC3F0000FC
+0F3F0001F003BF0007E001FF000FC000FF001F80007F001F80003F003F00003F003F0000
+3F007F00003F007E00003F00FE00003F00FE00003F00FE00003F00FE00003F00FE00003F
+00FE00003F00FE00003F00FE00003F00FE00003F00FE00003F007E00003F007F00003F00
+7F00003F003F00003F001F80007F001F80007F000FC000FF0007E001FF8003F007BFFC00
+F81E3FFC003FFC3FFC000FE03F0026357DB32B>I<000FE000007FFC0000F83F0003F00F
+8007E00FC00FC007E01F8003E01F8003F03F0003F03F0001F07F0001F87E0001F87E0001
+F8FE0001F8FE0001F8FFFFFFF8FFFFFFF8FE000000FE000000FE000000FE000000FE0000
+007E0000007F0000007F0000003F0000183F0000181F8000380F8000300FC0007007E000
+E001F003C000FC0F00003FFE000007F0001D237EA122>I<0001FC000007FF00001F0780
+003E0FC0007C1FC000FC1FC001F81FC001F81FC003F8070003F0000003F0000003F00000
+03F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00000
+FFFFF000FFFFF000FFFFF00003F0000003F0000003F0000003F0000003F0000003F00000
+03F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00000
+03F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00000
+03F0000007F800007FFFE0007FFFE0007FFFE0001A357FB417>I<0000001F00001FC07F
+8000FFF8E3C001F07FC7C007E03F03C00FC01F83800F800F80001F800FC0001F0007C000
+3F0007E0003F0007E0003F0007E0003F0007E0003F0007E0003F0007E0001F0007C0001F
+800FC0000F800F80000FC01F800007E03F000007F07C00000EFFF800000C1FC000001C00
+0000001C000000001C000000001E000000001E000000001F000000000FFFFE00000FFFFF
+C00007FFFFF00003FFFFFC0007FFFFFE001F0001FE003E00007F007C00003F007C00001F
+80F800000F80F800000F80F800000F80F800000F80F800000F80FC00001F807C00001F00
+3E00003E001F00007C000FC001F80003F007E00000FFFF8000001FFC000022337EA126>
+I<03F0000000FFF0000000FFF0000000FFF000000007F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F01FC00003F07FF00003F1
+E0FC0003F3807C0003F7007E0003FE007E0003FC003F0003FC003F0003F8003F0003F800
+3F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F
+0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F00
+03F0003F0003F0003F0003F0003F0003F0003F0003F0003F0007F8007F80FFFFC7FFFCFF
+FFC7FFFCFFFFC7FFFC26347EB32B>I<07800FC01FE01FE01FE01FE00FC0078000000000
+0000000000000000000000000000000007E0FFE0FFE0FFE00FE007E007E007E007E007E0
+07E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E0
+07E00FF0FFFFFFFFFFFF10337EB215>I<03F0000000FFF0000000FFF0000000FFF00000
+0007F000000003F000000003F000000003F000000003F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F003FFE003F003FFE003F003FFE003F001FF0003F000F80003F0
+01E00003F001C00003F003800003F00F000003F01C000003F038000003F070000003F0F0
+000003F3F8000003F7FC000003FEFC000003FC7E000003F87F000003F03F800003F01F80
+0003F00FC00003F00FE00003F007E00003F003F00003F003F80003F001F80003F000FC00
+03F000FE0007F800FF80FFFFC3FFF0FFFFC3FFF0FFFFC3FFF024347EB329>107
+D<07E0FFE0FFE0FFE00FE007E007E007E007E007E007E007E007E007E007E007E007E007
+E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007
+E007E007E007E007E007E007E007E007E007E007E007E007E00FF0FFFFFFFFFFFF10347E
+B315>I<03F01FE000FF0000FFF07FF803FFC000FFF1E07C0F03E000FFF3803E1C01F000
+07F7003F3801F80003FE003F7001F80003FC001FE000FC0003FC001FE000FC0003F8001F
+C000FC0003F8001FC000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC00
+03F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F
+8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC00
+03F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F8000FC0003F0001F
+8000FC0003F0001F8000FC0003F0001F8000FC0007F8003FC001FE00FFFFC7FFFE3FFFF0
+FFFFC7FFFE3FFFF0FFFFC7FFFE3FFFF03C217EA041>I<03F01FC000FFF07FF000FFF1E0
+FC00FFF3807C0007F7007E0003FE007E0003FC003F0003FC003F0003F8003F0003F8003F
+0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F00
+03F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003
+F0003F0003F0003F0003F0003F0003F0003F0003F0003F0007F8007F80FFFFC7FFFCFFFF
+C7FFFCFFFFC7FFFC26217EA02B>I<0007F00000003FFE000000FC1F800001F007C00003
+C001E00007C001F0000F8000F8001F00007C001F00007C003F00007E003E00003E007E00
+003F007E00003F007E00003F00FE00003F80FE00003F80FE00003F80FE00003F80FE0000
+3F80FE00003F80FE00003F80FE00003F807E00003F007E00003F007E00003F003F00007E
+003F00007E001F00007C001F8000FC000FC001F80007C001F00003F007E00000FC1F8000
+003FFE00000007F0000021237EA126>I<03F03F8000FFF0FFE000FFF3C0F800FFF7007E
+0007FE003F0003FC001F8003F8001FC003F0000FC003F0000FE003F00007F003F00007F0
+03F00007F003F00003F803F00003F803F00003F803F00003F803F00003F803F00003F803
+F00003F803F00003F803F00003F803F00007F803F00007F003F00007F003F00007E003F0
+000FE003F0000FC003F8001FC003FC003F8003FC003F0003FF00FC0003F381F80003F1FF
+E00003F07F000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000007F8000000FFFFC00000FFFFC00000
+FFFFC0000025307EA02B>I<0007F00300003FFC070000FC0F070001F8038F0007E0018F
+000FE001DF001FC000FF001F80007F003F80007F003F00003F007F00003F007F00003F00
+FF00003F00FE00003F00FE00003F00FE00003F00FE00003F00FE00003F00FE00003F00FE
+00003F00FE00003F00FE00003F007F00003F007F00003F007F00003F003F80007F001F80
+007F001FC000FF000FC001FF0007E003BF0003F0073F0000F81E3F00003FF83F00000FE0
+3F000000003F000000003F000000003F000000003F000000003F000000003F000000003F
+000000003F000000003F000000003F000000007F8000000FFFFC00000FFFFC00000FFFFC
+26307DA029>I<03E07C00FFE1FF00FFE38F80FFE71FC007EE1FC003EC1FC003EC1FC003
+FC0F8003F8000003F8000003F8000003F0000003F0000003F0000003F0000003F0000003
+F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003
+F0000003F0000003F0000003F0000007F80000FFFFE000FFFFE000FFFFE0001A217FA01E
+>I<00FF060007FFCE001F00FE003C003E0078001E0078000E00F0000E00F0000600F000
+0600F8000600F8000600FE000000FF8000007FFC00003FFFC0003FFFF0000FFFF80007FF
+FC0000FFFE00000FFF000000FF0000003F80C0001F80C0000F80E0000780E0000780E000
+0780F0000780F0000700F8000F00FC000E00FE001C00F7807800E1FFE000C07F80001923
+7EA11E>I<00300000300000300000300000300000700000700000700000F00000F00001
+F00001F00003F00007F0001FFFFEFFFFFEFFFFFE03F00003F00003F00003F00003F00003
+F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00303F00303
+F00303F00303F00303F00303F00303F00303F00701F80601F80600FC0E007E1C001FF800
+07E0182F7FAD1E>I<03F0003F00FFF00FFF00FFF00FFF00FFF00FFF0007F0007F0003F0
+003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F000
+3F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F0003F
+0003F0003F0003F0003F0003F0003F0003F0003F0003F0007F0003F0007F0003F0007F00
+03F000FF0001F000FF0001F801FF8000F803BFFC007E073FFC001FFE3FFC0007F83F0026
+227EA02B>I<FFFF00FFF0FFFF00FFF0FFFF00FFF00FF0003F8007F0001F0003F0000E00
+03F0000C0003F8001C0001F800180001F800180000FC00300000FC00300000FE00700000
+7E006000007F006000003F00C000003F00C000001F818000001F818000001FC38000000F
+C30000000FC300000007E600000007E600000007FE00000003FC00000003FC00000001F8
+00000001F800000001F800000000F000000000F00000000060000024217E9F29>I<FFFF
+1FFF81FFF0FFFF1FFF81FFF0FFFF1FFF81FFF007F801FC003F8007F001F8001E0003F000
+F8001C0003F000FC001C0001F8007C00180001F8007C00180001FC007E00380000FC00FE
+00300000FC00FE003000007E01FF006000007E019F006000007E019F806000003F030F80
+C000003F030F80C000003F030FC0C000001F8607C18000001F8607C18000001FC607E380
+00000FCC03E30000000FCC03E300000007FC03F600000007F801F600000007F801FE0000
+0003F000FC00000003F000FC00000003F000FC00000001E0007800000001E00078000000
+01E0007800000000C00030000034217F9F37>I<FFFF01FFF8FFFF01FFF8FFFF01FFF803
+FE00FF8001FC007C0000FC007800007E007000007F00E000003F81C000001F838000000F
+C300000007E600000007FE00000003FC00000001F800000000FC00000000FE00000000FF
+00000001FF000000039F800000071FC00000060FE000000C07E000001C03F000003801F8
+00007001FC0000F000FC0001F000FE000FF000FF80FFFC03FFFCFFFC03FFFCFFFC03FFFC
+26207F9F29>I<7FFF807FF87FFF807FF87FFF807FF807F8001FC003F8000F8001F80007
+0001F800060000FC000C0000FC000C0000FE001C00007E001800007E001800003F003000
+003F003000003F807000001F806000001FC0E000000FC0C000000FC0C0000007E1800000
+07E180000007F380000003F300000003FB00000001FE00000001FE00000000FC00000000
+FC00000000FC000000007800000000780000000030000000003000000000600000000060
+00000000E000000000C000000000C0000000018000007801800000FC03000000FC030000
+00FC06000000FC0E000000701C00000078380000001FF00000000FC000000025307F9F29
+>I E /Fq 1 4 df<006000007000006000006000406020E06070F861F07E67E01FFF8007
+FE0000F00007FE001FFF807E67E0F861F0E0607040602000600000600000700000600014
+157B9620>3 D E /Fr 11 66 df<003FC00000FFF00003E07C0007C03E000F801F000F00
+0F001E0007801E0007803E0007C03E0007C07C0003E07C0003E07C0003E07C0003E07C00
+03E0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC00
+03F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F07C0003E07C00
+03E07C0003E07E0007E03E0007C03E0007C03E0007C01F000F800F000F000F801F0007C0
+3E0003F0FC0000FFF000003FC0001C2D7DAB23>48 D<000C00003C00007C0003FC00FFFC
+00FC7C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C
+00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C
+00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C00007C
+0000FE007FFFFE7FFFFE172C7AAB23>I<007F800001FFF0000780FC000E003F001C001F
+8038000FC070000FC0600007E0F00007E0FC0007F0FE0007F0FE0003F0FE0003F0FE0003
+F07C0007F0000007F0000007F0000007E000000FE000000FC000001FC000001F8000003F
+0000007E0000007C000000F8000001F0000003E0000007C000000F8000001E0000003C00
+000078000000F0003000E0003001C0003003800060070000600E0000E01FFFFFE03FFFFF
+E07FFFFFC0FFFFFFC0FFFFFFC01C2C7DAB23>I<003FC00001FFF00007C0FC000E007E00
+1C003F001C001F803F001FC03F001FC03F800FC03F000FC03F000FC00C001FC000001FC0
+00001F8000001F8000003F0000003E0000007C000000F8000003F00000FFC00000FFF000
+0000FC0000003F0000001F8000001FC000000FC000000FE000000FE0000007F0000007F0
+380007F07C0007F0FE0007F0FE0007F0FE0007F0FE000FE0F8000FE060000FC070001FC0
+38001F801E003F000780FC0001FFF000007FC0001C2D7DAB23>I<00000E0000000E0000
+001E0000003E0000003E0000007E000000FE000000FE000001BE000003BE0000033E0000
+063E00000E3E00000C3E0000183E0000383E0000303E0000603E0000E03E0000C03E0001
+803E0003803E0003003E0006003E000E003E000C003E0018003E0038003E0030003E0060
+003E00E0003E00FFFFFFFCFFFFFFFC00003E0000003E0000003E0000003E0000003E0000
+003E0000003E0000003E0000003E0000007F00001FFFFC001FFFFC1E2D7EAC23>I<0C00
+01800FC01F800FFFFF000FFFFE000FFFFC000FFFF0000FFFC0000C7E00000C0000000C00
+00000C0000000C0000000C0000000C0000000C0000000C0000000C1FC0000C7FF8000DE0
+7C000F801F000F001F800E000F800C0007C0000007E0000007E0000003E0000003F00000
+03F0000003F0000003F0780003F0FC0003F0FC0003F0FC0003F0FC0003F0F80007E0E000
+07E0600007C070000FC038000F801C001F000E003E000780F80001FFE000007F80001C2D
+7DAB23>I<0003F800000FFE00003E078000F8018001F007C003E00FC007C00FC00F800F
+C00F800FC01F0007801F0000003E0000003E0000007E0000007E0000007C0000007C0FC0
+00FC3FF000FCF07C00FDC01E00FF800F00FF000F80FF0007C0FE0007E0FE0007E0FE0003
+E0FC0003F0FC0003F0FC0003F0FC0003F07C0003F07C0003F07C0003F07E0003F07E0003
+F03E0003E03E0007E01E0007E01F0007C00F000F8007801F0003C03E0001E07C00007FF0
+00001FC0001C2D7DAB23>I<300000003C0000003FFFFFF83FFFFFF83FFFFFF07FFFFFF0
+7FFFFFE0700001C06000018060000380C0000700C0000E00C0000C0000001C0000003800
+00003000000070000000E0000001C0000001C00000038000000380000007000000070000
+000F0000000E0000001E0000001E0000003E0000003E0000003E0000003C0000007C0000
+007C0000007C0000007C000000FC000000FC000000FC000000FC000000FC000000FC0000
+00FC000000FC000000FC0000007800001D2E7CAC23>I<001FC00000FFF00003E07C0007
+801E000F000F001E0007801E0007803C0003C03C0003C03C0003C03C0003C03E0003C03E
+0007C03F0007801FC00F801FE00F001FF81E000FFC3C0007FFF80003FFE00000FFE00000
+3FF80000FFFC0003C7FF000783FF801F00FFC01E003FC03C001FE07C0007E0780003F0F8
+0003F0F00001F0F00000F0F00000F0F00000F0F00000F0F80000E0780001E07C0001C03C
+0003C01E0007800F800F0007E03C0001FFF000003FC0001C2D7DAB23>I<003F800000FF
+F00003E0780007C03E000F801F001F000F003E000F803E0007807E0007C07C0007C0FC00
+07E0FC0003E0FC0003E0FC0003E0FC0003F0FC0003F0FC0003F0FC0003F0FC0003F07C00
+07F07E0007F07E0007F03E000FF01F000FF00F001FF007803BF003E0F3F000FFC3F0003F
+03E0000003E0000007E0000007E0000007C0000007C000000FC01E000F803F000F003F00
+1F003F003E003F003C003E0078001C00F0000E03E00007FF800001FE00001C2D7DAB23>
+I<000001800000000003C00000000003C00000000003C00000000007E00000000007E000
+0000000FF0000000000FF0000000000FF0000000001BF80000000019F80000000019F800
+00000030FC0000000030FC0000000070FE00000000607E00000000607E00000000C03F00
+000000C03F00000000C03F00000001801F80000001801F80000003801FC0000003000FC0
+000003000FC00000060007E00000060007E00000060007E000000C0003F000000C0003F0
+00001FFFFFF800001FFFFFF80000180001F80000300000FC0000300000FC0000300000FC
+00006000007E00006000007E0000E000007F0000C000003F0000C000003F0001C000001F
+8003C000001F8007C000001FC00FF000003FE0FFFC0003FFFFFFFC0003FFFF302F7EAE35
+>65 D E /Fs 85 125 df<000001FF000FE00000001FFFE03FFC0000007F00F8FC1E0000
+01FC003FF03F000007F0007FE07F80000FE000FFE0FF80001FC001FFC0FF80003F8001FF
+80FF80007F8001FF80FF80007F0001FF807F00007F0001FF003E0000FE0000FF00000000
+FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F
+00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000
+FE00007F00000000FE00007F00000000FE00007F00000000FE00007F000000FFFFFFFFFF
+FF8000FFFFFFFFFFFF8000FFFFFFFFFFFF800000FE00007F00000000FE00007F00000000
+FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F
+00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000
+FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F
+00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000
+FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F
+00000000FE00007F00000000FE00007F00000000FE00007F00000000FE00007F00000000
+FE00007F00000000FE00007F00000000FE00007F00000001FF0000FF8000007FFFFC3FFF
+FF80007FFFFC3FFFFF80007FFFFC3FFFFF800039407FBF35>11 D<000001FF000000001F
+FFC00000007F01F0000001FC0078000007F0001C00000FE0003E00001FC000FF00003F80
+01FF00007F8001FF00007F0001FF00007F0001FF0000FE0001FF0000FE0000FE0000FE00
+00380000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00
+00000000FE0000000000FE0000000000FE0000000000FE0000000000FE00007F00FFFFFF
+FFFF00FFFFFFFFFF00FFFFFFFFFF0000FE0001FF0000FE0000FF0000FE00007F0000FE00
+007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00
+007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00
+007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00
+007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00
+007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0001FF0000FF807FFFFC
+3FFFFE7FFFFC3FFFFE7FFFFC3FFFFE2F407FBF33>I<000001FF800000001FFFF7000000
+7F00FF000001F800FF000007F001FF00000FE001FF00001FC001FF00003F8001FF00007F
+8001FF00007F0001FF00007F0000FF0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F00FFFFFFFFFF00FFFF
+FFFFFF00FFFFFFFFFF0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE
+00007F0000FE00007F0000FE00007F0000FE00007F0001FF0000FF807FFFFC3FFFFE7FFF
+FC3FFFFE7FFFFC3FFFFE2F407FBF33>I<000001FF0000FF800000001FFFC00FFFE00000
+007F01F03F80F8000001F80078FE003C000007F0003FF8000E00000FE0007FF0001F0000
+1FC000FFE0007F80003F8001FFC000FF80007F8001FFC000FF80007F0001FF8000FF8000
+7F0001FF8000FF8000FE0001FF0000FF8000FE0000FF00007F0000FE00007F00001C0000
+FE00007F0000000000FE00007F0000000000FE00007F0000000000FE00007F0000000000
+FE00007F0000000000FE00007F0000000000FE00007F0000000000FE00007F0000000000
+FE00007F0000000000FE00007F0000000000FE00007F00003F80FFFFFFFFFFFFFFFF80FF
+FFFFFFFFFFFFFF80FFFFFFFFFFFFFFFF8000FE00007F0000FF8000FE00007F00007F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000FE00007F00003F8000
+FE00007F00003F8000FE00007F00003F8001FF0000FF80007FC07FFFFC3FFFFE1FFFFF7F
+FFFC3FFFFE1FFFFF7FFFFC3FFFFE1FFFFF48407FBF4C>I<1E000F007F803FC0FF807FC0
+FFC07FE0FFC07FE0FFE07FF0FFE07FF0FFE07FF07FE03FF01E600F300060003000600030
+006000300060003000E0007000C0006000C0006000C0006001C000E0018000C0038001C0
+03000180070003800E0007001C000E0018000C0038001C00300018001C1C7DBE2D>34
+D<0000000180000C000000000003C0001E000000000003C0001E000000000007C0003E00
+0000000007C0003E00000000000780003C00000000000780003C00000000000F80007C00
+000000000F80007C00000000000F00007800000000000F00007800000000001F0000F800
+000000001F0000F800000000001E0000F000000000001E0000F000000000003E0001F000
+000000003E0001F000000000003C0001E000000000003C0001E000000000003C0001E000
+000000007C0003E000000000007C0003E00000000000780003C00000000000780003C000
+00000000F80007C00000000000F80007C00000000000F00007800000000000F000078000
+00000001F0000F8000007FFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFF
+807FFFFFFFFFFFFFFF00000007C0003E00000000000780003C00000000000780003C0000
+0000000780003C00000000000F80007C00000000000F80007C00000000000F0000780000
+0000000F00007800000000001F0000F800000000001F0000F800000000001E0000F00000
+0000001E0000F000000000001E0000F000000000003E0001F00000007FFFFFFFFFFFFFFF
+00FFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFF807FFFFFFFFFFFFFFF000000F80007C00000
+000000F00007800000000000F00007800000000001F0000F800000000001F0000F800000
+000001E0000F000000000001E0000F000000000001E0000F000000000003E0001F000000
+000003E0001F000000000003C0001E000000000003C0001E000000000007C0003E000000
+000007C0003E00000000000780003C00000000000780003C00000000000F80007C000000
+00000F80007C00000000000F00007800000000000F00007800000000000F000078000000
+00001F0000F800000000001F0000F800000000001E0000F000000000001E0000F0000000
+00003E0001F000000000003E0001F000000000003C0001E000000000003C0001E0000000
+0000180000C00000000041517BBE4C>I<0000E000000000E000000000E000000000E000
+000007FC0000003FFF800000FFFFE00001F8E3F00003E0E0FC0007C0E03C000F80E01E00
+1F00E00F003E00E007003C00E007807C00E003807C00E003C07800E01FC0F800E03FC0F8
+00E07FC0F800E07FC0F800E07FC0F800E07FC0FC00E07FC0FC00E03F80FE00E00E00FE00
+E000007F00E000007F80E000007FC0E000003FF0E000003FFEE000001FFFE000000FFFFC
+000007FFFF000003FFFFC00001FFFFE000007FFFF800001FFFFC000003FFFC000000FFFE
+000000E7FF000000E1FF000000E0FF800000E07F800000E03F800000E01FC00000E01FC0
+3E00E00FC07F00E00FC0FF80E007C0FF80E007C0FF80E007C0FF80E007C0FF80E007C0FF
+00E007C0FC00E00780F000E00F807000E00F807800E00F007800E01F003C00E01E003C00
+E03E001E00E07C000F00E0F80007C0E1F00003F8EFE00000FFFF8000003FFE0000000FF8
+00000000E000000000E000000000E000000000E0000022497BC32D>I<00000FC0000000
+0000003FF0000000000000F878000000000001F01C000000000003E01C000000000007C0
+0E00000000000FC00E00000000000F800F00000000001F800700000000001F8007000000
+00003F000700000000003F000700000000003F000700000000003F000700000000003F00
+0700000000003F800E00000000003F800E00000000003F801C00000000003F801C000000
+00003F803800000000003F803800000000003F807000000000001FC0E000000000001FC1
+C000000000001FC1C000000000001FC38000000000001FE700007FFFFC000FEE00007FFF
+FC000FFC00007FFFFC000FF8000007FFC00007F0000001FE000007F8000001FC000007F8
+000000F0000003FC000000F0000003FC000001E0000007FE000001C000000FFE000003C0
+00001DFF00000780000038FF000007000000707F80000F000000E07F80000E000001C03F
+C0001E000003C03FE0001C000007801FE0003C00000F801FF0007800001F800FF8007000
+003F0007F800F000003F0007FC01E000007F0003FE01C000007F0001FF03C00000FF0000
+FF07800000FF0000FF87000000FF00007FCF000000FF00003FFE000000FF00001FFC0000
+38FF80000FF8000038FF80000FF80000387F800007FC0000787FC00003FE0000707FC000
+07FF0000F03FE0000F7F8000E01FE0003E3FC001E00FF000FC1FF003C007FC07F007FC1F
+8001FFFFC001FFFF00007FFF00007FFC00000FF800000FF0003E437CC047>38
+D<1E007F80FF80FFC0FFC0FFE0FFE0FFE07FE01E60006000600060006000E000C000C000
+C001C001800380030007000E001C001800380030000B1C79BE19>I<0000300000700000
+E00001C0000380000780000F00001E00003E00003C0000780000F80000F00001F00001E0
+0003E00003E00007C00007C0000FC0000F80000F80001F80001F00001F00003F00003F00
+003F00003E00007E00007E00007E00007E00007E00007E00007C0000FC0000FC0000FC00
+00FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC00
+00FC0000FC0000FC00007C00007E00007E00007E00007E00007E00007E00003E00003F00
+003F00003F00001F00001F00001F80000F80000F80000FC00007C00007C00003E00003E0
+0001E00001F00000F00000F800007800003C00003E00001E00000F000007800003800001
+C00000E0000070000030145A77C323>I<C00000E000007000003800001C00001E00000F
+000007800007C00003C00001E00001F00000F00000F800007800007C00007C00003E0000
+3E00003F00001F00001F00001F80000F80000F80000FC0000FC0000FC00007C00007E000
+07E00007E00007E00007E00007E00003E00003F00003F00003F00003F00003F00003F000
+03F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F000
+03E00007E00007E00007E00007E00007E00007E00007C0000FC0000FC0000FC0000F8000
+0F80001F80001F00001F00003F00003E00003E00007C00007C0000780000F80000F00001
+F00001E00003C00007C0000780000F00001E00001C0000380000700000E00000C0000014
+5A7BC323>I<1E007F80FF80FFC0FFC0FFE0FFE0FFE07FE01E60006000600060006000E0
+00C000C000C001C001800380030007000E001C001800380030000B1C798919>44
+D<FFFFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFFFE17067F961E>I<1E007F807F80FFC0FFC0
+FFC0FFC07F807F801E000A0A798919>I<000000018000000003C000000007C000000007
+C000000007800000000F800000000F800000000F000000001F000000001F000000001E00
+0000003E000000003E000000003C000000007C000000007C000000007800000000F80000
+0000F800000000F000000001F000000001F000000001E000000003E000000003E0000000
+03C000000007C000000007C000000007800000000F800000000F800000001F000000001F
+000000001E000000003E000000003E000000003C000000007C000000007C000000007800
+000000F800000000F800000000F000000001F000000001F000000001E000000003E00000
+0003E000000003C000000007C000000007C000000007800000000F800000000F80000000
+0F000000001F000000001F000000001E000000003E000000003E000000007C000000007C
+000000007800000000F800000000F800000000F000000001F000000001F000000001E000
+000003E000000003E000000003C000000007C000000007C000000007800000000F800000
+000F800000000F000000001F000000001F000000001E000000003E000000003E00000000
+3C000000007C000000007C000000007800000000F800000000F800000000F00000000060
+00000000225B7BC32D>I<0001FE0000000FFFC000003F03F000007C00F80000F8007C00
+01F0003E0003E0001F0007C0000F8007C0000F800FC0000FC01F800007E01F800007E01F
+800007E03F800007F03F800007F03F000003F07F000003F87F000003F87F000003F87F00
+0003F87F000003F87F000003F8FF000003FCFF000003FCFF000003FCFF000003FCFF0000
+03FCFF000003FCFF000003FCFF000003FCFF000003FCFF000003FCFF000003FCFF000003
+FCFF000003FCFF000003FCFF000003FCFF000003FCFF000003FCFF000003FCFF000003FC
+FF000003FC7F000003F87F000003F87F000003F87F000003F87F000003F83F800007F03F
+800007F03F800007F01F800007E01F800007E01F800007E00FC0000FC00FC0000FC007E0
+001F8003E0001F0001F0003E0000F8007C00007C00F800003F03F000000FFFC0000001FE
+0000263F7DBC2D>I<0001C0000003C0000007C000001FC000007FC00007FFC000FFFFC0
+00FF9FC000F81FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0
+00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0
+00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0
+00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0
+00001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC0
+00001FC000001FC000001FC000001FC000001FC000007FF000FFFFFFF8FFFFFFF8FFFFFF
+F81D3D78BC2D>I<0007FC0000003FFF800000FFFFE00003F01FF80007C007FC000F0001
+FE001E0000FF001C0000FF803C00007FC07800007FC07800003FE07000003FE0FF00003F
+E0FF80001FF0FFC0001FF0FFC0001FF0FFC0001FF0FFC0001FF0FFC0001FF07F80001FF0
+3F00001FF00C00001FF00000001FE00000003FE00000003FE00000003FC00000007FC000
+00007F80000000FF80000000FF00000001FE00000001FC00000003F800000007F0000000
+07E00000000FC00000001F800000003F000000007E000000007C00000000F800000001F0
+00000003E000000007C00000000F800000001F000070003E000070003C00007000780000
+7000F00000E001E00000E003C00000E007800000E00F000001E01FFFFFFFE01FFFFFFFE0
+3FFFFFFFE07FFFFFFFC0FFFFFFFFC0FFFFFFFFC0FFFFFFFFC0243D7CBC2D>I<0007FC00
+00003FFF800000F80FE00001E003F800078001FC000F0001FE000E0000FF001E0000FF80
+1F80007F803FC0007FC03FE0007FC03FE0007FC03FF0007FC03FE0007FC03FE0007FC01F
+E0007FC00FC0007FC00000007F80000000FF80000000FF00000000FF00000001FE000000
+01FE00000003FC00000003F800000007E00000000FC00000003F0000001FFC0000001FFF
+800000000FE000000007F800000003FC00000001FE00000000FF00000000FF800000007F
+C00000007FC00000007FE00000003FE00000003FE00000003FF00000003FF00C00003FF0
+3F00003FF07F80003FF0FFC0003FF0FFC0003FF0FFC0003FF0FFC0003FE0FFC0003FE0FF
+80007FE07F00007FC07800007FC0780000FF803C0000FF801E0001FF000F0003FE0007C0
+07FC0003F80FF00000FFFFE000003FFF80000007F80000243F7CBC2D>I<0000000E0000
+00001E000000003E000000003E000000007E000000007E00000000FE00000001FE000000
+01FE00000003FE000000077E000000067E0000000E7E0000001C7E0000001C7E00000038
+7E000000707E000000707E000000E07E000001C07E000001C07E000003807E000007007E
+000007007E00000E007E00001C007E00001C007E000038007E000070007E000070007E00
+00E0007E0000C0007E0001C0007E000380007E000300007E000700007E000E00007E000C
+00007E001C00007E003800007E003800007E007000007E00E000007E00FFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFF000000FE00000000FE00000000FE00000000FE00000000FE00000000
+FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000001FF
+000001FFFFFF0001FFFFFF0001FFFFFF283E7EBD2D>I<06000003000780001F0007F800
+FE0007FFFFFE0007FFFFFC0007FFFFF80007FFFFF00007FFFFC00007FFFF000007FFFC00
+00073FE00000070000000007000000000700000000070000000007000000000700000000
+0700000000070000000007000000000700000000070000000007000000000701FE000007
+0FFF8000073E03E000077001F80007E000FC0007C0007E000780003F000700003F800600
+001F800000001FC00000001FC00000001FE00000000FE00000000FE00000000FE0000000
+0FF00000000FF00000000FF00C00000FF07F00000FF07F80000FF0FF80000FF0FF80000F
+F0FF80000FF0FF80000FF0FF80000FE0FF00001FE0FC00001FE07000001FC07800001FC0
+3800003F803C00003F801E00007F001F0000FE000F8001FC0007C003F80003F80FE00000
+FFFFC000003FFF00000007F80000243F7CBC2D>I<00001FE0000000FFF8000003F03E00
+000FC00F00001F000780003E000780007E001FC000FC003FC001F8007FC003F8007FC003
+F0007FC007F0007FC00FE0003F800FE0001F001FE00000001FC00000001FC00000003FC0
+0000003FC00000003FC00000007F800000007F800000007F80FE00007F87FF8000FF8F07
+E000FF9C01F000FFB800FC00FFB0007E00FFF0007E00FFE0003F00FFE0003F80FFC0003F
+C0FFC0003FC0FFC0001FE0FFC0001FE0FFC0001FE0FF80001FF0FF80001FF0FF80001FF0
+FF80001FF0FF80001FF07F80001FF07F80001FF07F80001FF07F80001FF07F80001FF07F
+80001FF03F80001FF03FC0001FE03FC0001FE01FC0001FE01FC0003FC01FC0003FC00FE0
+003F800FE0003F8007E0007F0003F0007E0001F800FC0000FC01F800007E07F000003FFF
+E000000FFF80000003FC0000243F7CBC2D>I<38000000003C000000003F000000003FFF
+FFFFFC3FFFFFFFFC3FFFFFFFFC3FFFFFFFF87FFFFFFFF87FFFFFFFF07FFFFFFFE0780000
+01E070000003C0700000078070000007007000000F00E000001E00E000001C00E000003C
+00E0000078000000007000000000F000000001E000000001C000000003C0000000078000
+000007000000000F000000001E000000001E000000003C000000003C000000007C000000
+007800000000F800000000F800000001F800000001F000000003F000000003F000000003
+F000000007F000000007F000000007F00000000FF00000000FE00000000FE00000001FE0
+0000001FE00000001FE00000001FE00000001FE00000001FE00000003FE00000003FE000
+00003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000003FE00000
+003FE00000001FC00000000700000026407BBD2D>I<0003FC0000001FFF8000007C07E0
+0000F001F80001E0007C0003C0003E000780001F000F00001F000F00000F801E00000F80
+1E00000FC03E000007C03E000007C03E000007C03E000007C03F000007C03F000007C03F
+80000F803FC0000F801FE0001F801FF0001F001FFC003E000FFE007C000FFF80780007FF
+C0F00003FFF3E00001FFFF800000FFFF0000003FFF0000001FFFC000000FFFE000003FFF
+F8000078FFFC0001F07FFE0003E01FFF0007C00FFF800F8003FFC01F0001FFC03F00007F
+E03E00003FE07E00001FE07C00000FF07C000007F0F8000003F0F8000003F0F8000003F0
+F8000001F0F8000001F0F8000001F0F8000001F0FC000001E07C000003E07C000003E07E
+000003C03F000007C01F00000F801F80001F000FC0003E0007F0007C0001FC03F80000FF
+FFE000001FFF80000003FC0000243F7CBC2D>I<0003FC0000001FFF0000007E07C00000
+FC03F00001F801F80003F000FC0007E0007C000FE0007E001FC0007F001FC0003F003FC0
+003F803F80003F807F80003FC07F80003FC07F80001FC0FF80001FC0FF80001FE0FF8000
+1FE0FF80001FE0FF80001FE0FF80001FE0FF80001FF0FF80001FF0FF80001FF0FF80001F
+F0FF80001FF07F80001FF07F80003FF07F80003FF07F80003FF03FC0003FF03FC0003FF0
+1FC0007FF00FC0007FF007E000FFF007F000DFF003F001DFF000F8039FF0007E0F1FF000
+1FFE1FE00007F01FE00000001FE00000001FE00000003FC00000003FC00000003FC00000
+003FC00000003F800000007F800F80007F001FC0007F003FE000FE003FE000FE003FE001
+FC003FE001F8003FC003F0003F8007F0001E000FE0001F001FC0000FC07F000003FFFE00
+0001FFF80000003FC00000243F7CBC2D>I<1E007F807F80FFC0FFC0FFC0FFC07F807F80
+1E0000000000000000000000000000000000000000000000000000000000000000000000
+000000001E007F807F80FFC0FFC0FFC0FFC07F807F801E000A2779A619>I<1E007F807F
+80FFC0FFC0FFC0FFC07F807F801E00000000000000000000000000000000000000000000
+00000000000000000000000000000000001E007F00FF80FF80FFC0FFC0FFC0FFC07FC01E
+C000C000C000C000C001C001800180018003800300070006000E000C001C003800300030
+000A3979A619>I<7FFFFFFFFFFFFFE0FFFFFFFFFFFFFFF0FFFFFFFFFFFFFFF07FFFFFFF
+FFFFFFE00000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000007FFFFFFFFFFFFFE0FFFFFFFFFFFFFFF0FFFFFFFFFFFFFFF07FFFFFFF
+FFFFFFE03C167BA147>61 D<001FF80000FFFF0003E01FC00F0007F01E0003F83C0001FC
+780001FE780000FEFE0000FFFF0000FFFF8000FFFF8000FFFF8000FFFF8000FF7F0000FF
+3E0000FF000001FE000001FE000003FC000007F8000007F000000FC000001F8000003F00
+00003E0000007C00000078000000F8000000F0000001F0000001E0000001E0000003C000
+0003C0000003800000038000000380000003800000038000000380000003800000038000
+000380000003800000038000000300000000000000000000000000000000000000000000
+00000000000000000000000000078000001FE000001FE000003FF000003FF000003FF000
+003FF000001FE000001FE0000007800020407BBF2B>63 D<00000007000000000000000F
+800000000000000F800000000000000F800000000000001FC00000000000001FC0000000
+0000001FC00000000000003FE00000000000003FE00000000000003FE00000000000007F
+F00000000000007FF00000000000007FF0000000000000FFF8000000000000E7F8000000
+000000E7F8000000000001C7FC000000000001C3FC000000000001C3FC00000000000381
+FE00000000000381FE00000000000381FE00000000000700FF00000000000700FF000000
+00000700FF00000000000E007F80000000000E007F80000000000E007F80000000001C00
+3FC0000000001C003FC0000000001C003FC00000000038001FE00000000038001FE00000
+000038001FE00000000070000FF00000000070000FF00000000070000FF000000000E000
+07F800000000E00007F800000000E00007F800000001C00003FC00000001FFFFFFFC0000
+0001FFFFFFFC00000003FFFFFFFE00000003800001FE00000003800001FE000000070000
+00FF00000007000000FF0000000F000000FF8000000E0000007F8000000E0000007F8000
+001E0000007FC000001C0000003FC000001C0000003FC000003C0000003FE00000380000
+001FE00000380000001FE00000780000001FF00000780000000FF00000FC0000000FF000
+03FC0000001FF8000FFF0000003FFC00FFFFF0000FFFFFF8FFFFF0000FFFFFF8FFFFF000
+0FFFFFF83D417DC044>65 D<FFFFFFFFFC0000FFFFFFFFFF8000FFFFFFFFFFF00001FF80
+000FF800007F000003FE00007F000001FF00007F000000FF80007F0000007FC0007F0000
+003FE0007F0000003FE0007F0000001FF0007F0000001FF0007F0000001FF8007F000000
+1FF8007F0000001FF8007F0000000FF8007F0000001FF8007F0000001FF8007F0000001F
+F8007F0000001FF0007F0000001FF0007F0000003FE0007F0000007FE0007F0000007FC0
+007F000000FF80007F000001FF00007F000003FC00007F00000FF800007F00007FE00000
+7FFFFFFF0000007FFFFFFFE000007F000007FC00007F000001FE00007F000000FF80007F
+0000007FC0007F0000003FE0007F0000001FF0007F0000001FF8007F0000000FF8007F00
+00000FFC007F00000007FC007F00000007FC007F00000007FE007F00000007FE007F0000
+0007FE007F00000007FE007F00000007FE007F00000007FE007F00000007FE007F000000
+07FC007F0000000FFC007F0000000FFC007F0000001FF8007F0000001FF0007F0000003F
+F0007F0000007FE0007F000000FFC0007F000003FF8001FF80000FFE00FFFFFFFFFFFC00
+FFFFFFFFFFE000FFFFFFFFFF0000373E7DBD40>I<0000003FF00006000003FFFE000E00
+000FFFFF801E00003FF007E03E0000FF8000F83E0003FE00007C7E0007F800001EFE000F
+F000000FFE003FE0000007FE007FC0000003FE00FF80000003FE00FF00000001FE01FE00
+000000FE03FE00000000FE07FC000000007E07F8000000007E0FF8000000003E0FF80000
+00003E1FF0000000001E1FF0000000001E3FF0000000001E3FE0000000001E3FE0000000
+000E7FE0000000000E7FE0000000000E7FE0000000000E7FC00000000000FFC000000000
+00FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000
+FFC00000000000FFC00000000000FFC00000000000FFC00000000000FFC00000000000FF
+C000000000007FC000000000007FE000000000007FE0000000000E7FE0000000000E3FE0
+000000000E3FE0000000000E3FF0000000000E1FF0000000001E1FF0000000001C0FF800
+0000001C0FF8000000001C07F8000000003C07FC000000003803FE000000007801FE0000
+00007000FF00000000F000FF80000001E0007FC0000001C0003FE0000003C0000FF00000
+07800007F800001F000003FE00003E000000FF8000F80000003FF007F00000000FFFFFC0
+00000003FFFF00000000003FF0000037427BBF42>I<FFFFFFFFFC000000FFFFFFFFFF80
+0000FFFFFFFFFFE0000001FFC0001FF80000007F800003FE0000007F800000FF0000007F
+8000007F8000007F8000003FC000007F8000000FE000007F8000000FF000007F80000007
+F800007F80000003FC00007F80000001FC00007F80000001FE00007F80000000FF00007F
+80000000FF00007F80000000FF80007F800000007F80007F800000007FC0007F80000000
+7FC0007F800000007FC0007F800000003FE0007F800000003FE0007F800000003FE0007F
+800000003FE0007F800000003FE0007F800000003FF0007F800000003FF0007F80000000
+3FF0007F800000003FF0007F800000003FF0007F800000003FF0007F800000003FF0007F
+800000003FF0007F800000003FF0007F800000003FF0007F800000003FF0007F80000000
+3FE0007F800000003FE0007F800000003FE0007F800000003FE0007F800000003FE0007F
+800000007FC0007F800000007FC0007F800000007F80007F800000007F80007F80000000
+FF80007F80000000FF00007F80000001FE00007F80000001FE00007F80000003FC00007F
+80000003F800007F80000007F800007F8000000FF000007F8000001FE000007F8000007F
+C000007F800000FF0000007F800003FE000001FFC0001FF80000FFFFFFFFFFF00000FFFF
+FFFFFF800000FFFFFFFFFC0000003C3E7DBD45>I<FFFFFFFFFFFFE0FFFFFFFFFFFFE0FF
+FFFFFFFFFFE001FFC00001FFE0007F8000001FE0007F8000000FF0007F80000003F0007F
+80000003F0007F80000001F0007F80000000F0007F80000000F0007F80000000F0007F80
+00000070007F8000000070007F8000000070007F8000000070007F8000000038007F8000
+1C0038007F80001C0038007F80001C0038007F80001C0038007F80001C0000007F80001C
+0000007F80003C0000007F80003C0000007F80007C0000007F8000FC0000007F8003FC00
+00007FFFFFFC0000007FFFFFFC0000007FFFFFFC0000007F8003FC0000007F8000FC0000
+007F80007C0000007F80003C0000007F80003C0000007F80001C0000007F80001C000000
+7F80001C0007007F80001C0007007F80001C0007007F80001C000E007F800000000E007F
+800000000E007F800000000E007F800000000E007F800000001E007F800000001C007F80
+0000001C007F800000003C007F800000003C007F800000007C007F800000007C007F8000
+0000F8007F80000001F8007F80000003F8007F80000007F8007F8000001FF801FFC00001
+FFF8FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF0383E7DBD3E>I<FFFFFFFFFFFF
+80FFFFFFFFFFFF80FFFFFFFFFFFF8001FFC00003FF80007F8000007F80007F8000001FC0
+007F8000000FC0007F80000007C0007F80000007C0007F80000003C0007F80000003C000
+7F80000003C0007F80000001C0007F80000001C0007F80000001C0007F80000001C0007F
+80000000E0007F80000000E0007F80003800E0007F80003800E0007F80003800E0007F80
+00380000007F8000380000007F8000380000007F8000780000007F8000780000007F8000
+F80000007F8001F80000007F8007F80000007FFFFFF80000007FFFFFF80000007FFFFFF8
+0000007F8007F80000007F8001F80000007F8000F80000007F8000780000007F80007800
+00007F8000380000007F8000380000007F8000380000007F8000380000007F8000380000
+007F8000380000007F8000000000007F8000000000007F8000000000007F800000000000
+7F8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F
+8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F80
+0000000001FFE000000000FFFFFFF0000000FFFFFFF0000000FFFFFFF0000000333E7DBD
+3B>I<0000003FE0000C00000003FFFE001C0000001FFFFF803C0000007FF00FC07C0000
+00FF0001F07C000003FC000078FC000007F800003DFC00001FE000001FFC00003FC00000
+0FFC00007F80000007FC0000FF80000003FC0001FF00000003FC0001FE00000001FC0003
+FC00000001FC0007FC00000000FC0007F800000000FC000FF8000000007C000FF0000000
+007C001FF0000000003C001FF0000000003C003FE0000000003C003FE0000000003C003F
+E0000000001C007FE0000000001C007FE0000000001C007FC0000000001C007FC0000000
+000000FFC0000000000000FFC0000000000000FFC0000000000000FFC0000000000000FF
+C0000000000000FFC0000000000000FFC0000000000000FFC0000000000000FFC0000000
+000000FFC0000000000000FFC0000000000000FFC000001FFFFFF07FC000001FFFFFF07F
+C000001FFFFFF07FE00000000FFE007FE000000003FC003FE000000003FC003FE0000000
+03FC003FF000000003FC001FF000000003FC001FF000000003FC000FF800000003FC000F
+F800000003FC0007F800000003FC0007FC00000003FC0003FC00000003FC0001FE000000
+03FC0001FF00000003FC0000FF80000003FC00007FC0000007FC00003FE0000007FC0000
+1FF000000FFC000007F800001EFC000003FE00003C7C000000FF8000F83C0000007FF007
+F01C0000001FFFFFC00C00000003FFFF0000000000003FF00000003C427BBF47>I<FFFF
+FFC01FFFFFF8FFFFFFC01FFFFFF8FFFFFFC01FFFFFF801FFE000003FFC00007F8000000F
+F000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F
+8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000F
+F000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F
+8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000F
+F000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F
+8000000FF000007FFFFFFFFFF000007FFFFFFFFFF000007FFFFFFFFFF000007F8000000F
+F000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F
+8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000F
+F000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F
+8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000F
+F000007F8000000FF000007F8000000FF000007F8000000FF000007F8000000FF000007F
+8000000FF000007F8000000FF000007F8000000FF000007F8000000FF00001FFE000003F
+FC00FFFFFFC01FFFFFF8FFFFFFC01FFFFFF8FFFFFFC01FFFFFF83D3E7DBD44>I<FFFFFF
+F0FFFFFFF0FFFFFFF000FFF000003FC000003FC000003FC000003FC000003FC000003FC0
+00003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0
+00003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0
+00003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0
+00003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0
+00003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC0
+00003FC000003FC000003FC00000FFF000FFFFFFF0FFFFFFF0FFFFFFF01C3E7EBD21>I<
+001FFFFFFC001FFFFFFC001FFFFFFC000007FF00000003FE00000001FE00000001FE0000
+0001FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE000000
+01FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001
+FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE
+00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE00
+000001FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE0000
+0001FE00000001FE00000001FE00000001FE003F0001FE007F8001FE00FFC001FE00FFC0
+01FE00FFC001FE00FFC001FE00FFC003FC00FF8003FC007F0003F8007C0007F800380007
+F0003C000FE0001E001FC0000F003F800003E07E000000FFF80000003FC0000026407CBD
+2F>I<FFFFFFC0007FFFFCFFFFFFC0007FFFFCFFFFFFC0007FFFFC01FFE000000FFF8000
+7F80000007FE00007F80000007F800007F80000007E000007F80000007C000007F800000
+0F8000007F8000001F0000007F8000003E0000007F8000007C0000007F800000F8000000
+7F800001F00000007F800003E00000007F800007C00000007F80000F800000007F80001F
+000000007F80003E000000007F80007C000000007F8000F8000000007F8001F000000000
+7F8003E0000000007F800780000000007F800FC0000000007F801FC0000000007F803FE0
+000000007F807FF0000000007F80FFF0000000007F81EFF8000000007F83C7FC00000000
+7F8787FC000000007F8F03FE000000007F9E01FF000000007FBC01FF000000007FF800FF
+800000007FF0007FC00000007FE0007FC00000007FC0003FE00000007F80001FF0000000
+7F80001FF00000007F80000FF80000007F800007FC0000007F800007FC0000007F800003
+FE0000007F800001FF0000007F800001FF0000007F800000FF8000007F8000007FC00000
+7F8000007FE000007F8000003FE000007F8000001FF000007F8000000FF800007F800000
+0FF800007F80000007FC00007F80000007FE00007F80000007FF00007F80000007FF8001
+FFE000000FFFC0FFFFFFC000FFFFFFFFFFFFC000FFFFFFFFFFFFC000FFFFFF403E7DBD47
+>I<FFFFFFF8000000FFFFFFF8000000FFFFFFF800000001FFE000000000007F80000000
+00007F8000000000007F8000000000007F8000000000007F8000000000007F8000000000
+007F8000000000007F8000000000007F8000000000007F8000000000007F800000000000
+7F8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F
+8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F80
+00000000007F8000000000007F8000000000007F8000000000007F8000000000007F8000
+000000007F8000000000007F8000000000007F8000000000007F8000000000007F800000
+0000007F8000000000007F8000000000007F8000000380007F8000000380007F80000003
+80007F8000000380007F8000000380007F8000000780007F8000000700007F8000000700
+007F8000000700007F8000000700007F8000000F00007F8000000F00007F8000000F0000
+7F8000001F00007F8000001F00007F8000003F00007F8000007F00007F800000FF00007F
+800001FE00007F800007FE0001FFC0003FFE00FFFFFFFFFFFE00FFFFFFFFFFFE00FFFFFF
+FFFFFE00313E7DBD39>I<FFFFC0000000003FFFF0FFFFC0000000003FFFF0FFFFC00000
+00003FFFF001FFE0000000007FF800007FE0000000007FE0000077F000000000EFE00000
+77F000000000EFE0000077F000000000EFE0000073F800000001CFE0000073F800000001
+CFE0000071FC000000038FE0000071FC000000038FE0000071FC000000038FE0000070FE
+000000070FE0000070FE000000070FE0000070FF0000000E0FE00000707F0000000E0FE0
+0000707F0000000E0FE00000703F8000001C0FE00000703F8000001C0FE00000703F8000
+001C0FE00000701FC00000380FE00000701FC00000380FE00000700FE00000700FE00000
+700FE00000700FE00000700FE00000700FE000007007F00000E00FE000007007F00000E0
+0FE000007003F80001C00FE000007003F80001C00FE000007003F80001C00FE000007001
+FC0003800FE000007001FC0003800FE000007001FC0003800FE000007000FE0007000FE0
+00007000FE0007000FE0000070007F000E000FE0000070007F000E000FE0000070007F00
+0E000FE0000070003F801C000FE0000070003F801C000FE0000070001FC038000FE00000
+70001FC038000FE0000070001FC038000FE0000070000FE070000FE0000070000FE07000
+0FE0000070000FE0E0000FE00000700007F0E0000FE00000700007F0E0000FE000007000
+03F9C0000FE00000700003F9C0000FE00000700003F9C0000FE00000700001FF80000FE0
+0000700001FF80000FE00000700000FF00000FE00000700000FF00000FE00000F80000FF
+00000FE00001FC00007E00000FE00007FF00007E00003FF800FFFFF8003C001FFFFFF0FF
+FFF8003C001FFFFFF0FFFFF8003C001FFFFFF04C3E7DBD53>I<FFFF800000FFFFF8FFFF
+C00000FFFFF8FFFFE00000FFFFF8007FE0000007FF00007FF0000001FC00007FF8000000
+F800007FF800000070000077FC00000070000073FE00000070000073FE00000070000071
+FF00000070000070FF80000070000070FF800000700000707FC00000700000703FE00000
+700000703FE00000700000701FF00000700000700FF80000700000700FF8000070000070
+07FC00007000007003FE00007000007003FE00007000007001FF00007000007000FF8000
+7000007000FF800070000070007FC00070000070003FE00070000070003FE00070000070
+001FF00070000070000FF80070000070000FF800700000700007FC00700000700003FE00
+700000700003FE00700000700001FF00700000700000FF80700000700000FF8070000070
+00007FC07000007000003FE07000007000003FE07000007000001FF07000007000000FF8
+7000007000000FF870000070000007FC70000070000003FE70000070000003FE70000070
+000001FF70000070000000FFF0000070000000FFF00000700000007FF00000700000003F
+F00000700000003FF00000700000001FF00000700000000FF00000700000000FF0000070
+00000007F00000F800000003F00001FC00000003F00007FF00000001F000FFFFF8000000
+F000FFFFF8000000F000FFFFF800000070003D3E7DBD44>I<0000007FE0000000000007
+FFFE00000000001FC03F80000000007E0007E000000001FC0003F800000007F00000FE00
+00000FE000007F0000001FC000003F8000003F8000001FC000007F0000000FE00000FE00
+000007F00001FE00000007F80001FC00000003F80003FC00000003FC0007F800000001FE
+0007F800000001FE000FF000000000FF000FF000000000FF001FF000000000FF801FE000
+0000007F803FE0000000007FC03FE0000000007FC03FE0000000007FC07FE0000000007F
+E07FC0000000003FE07FC0000000003FE07FC0000000003FE0FFC0000000003FF0FFC000
+0000003FF0FFC0000000003FF0FFC0000000003FF0FFC0000000003FF0FFC0000000003F
+F0FFC0000000003FF0FFC0000000003FF0FFC0000000003FF0FFC0000000003FF0FFC000
+0000003FF0FFC0000000003FF07FC0000000003FE07FE0000000007FE07FE0000000007F
+E07FE0000000007FE07FE0000000007FE03FE0000000007FC03FE0000000007FC01FF000
+000000FF801FF000000000FF801FF000000000FF800FF800000001FF000FF800000001FF
+0007FC00000003FE0003FC00000003FC0003FE00000007FC0001FE00000007F80000FF00
+00000FF000007F0000000FE000003F8000001FC000001FC000003F8000000FE000007F00
+000007F00000FE00000001FC0003F8000000007F000FE0000000001FC03F800000000007
+FFFE0000000000007FE00000003C427BBF47>I<FFFFFFFFF80000FFFFFFFFFF8000FFFF
+FFFFFFE00001FFC0003FF800007F800007FC00007F800001FE00007F800000FF00007F80
+00007F80007F8000003FC0007F8000003FE0007F8000003FE0007F8000001FF0007F8000
+001FF0007F8000001FF8007F8000001FF8007F8000001FF8007F8000001FF8007F800000
+1FF8007F8000001FF8007F8000001FF8007F8000001FF8007F8000001FF0007F8000001F
+F0007F8000003FE0007F8000003FE0007F8000003FC0007F8000007F80007F800000FF00
+007F800001FE00007F800007FC00007F80003FF000007FFFFFFFC000007FFFFFFE000000
+7F8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F
+8000000000007F8000000000007F8000000000007F8000000000007F8000000000007F80
+00000000007F8000000000007F8000000000007F8000000000007F8000000000007F8000
+000000007F8000000000007F8000000000007F8000000000007F8000000000007F800000
+0000007F8000000000007F8000000000007F8000000000007F800000000001FFE0000000
+00FFFFFFC0000000FFFFFFC0000000FFFFFFC0000000353E7DBD3E>I<0000007FE00000
+00000007FFFE00000000001FC03F80000000007F000FE000000001FC0003F800000007F0
+0000FE0000000FE000007F0000001FC000003F8000003F8000001FC000007F0000000FE0
+0000FF0000000FF00001FE00000007F80001FC00000003F80003FC00000003FC0007F800
+000001FE0007F800000001FE000FF800000001FF000FF000000000FF001FF000000000FF
+801FF000000000FF803FE0000000007FC03FE0000000007FC03FE0000000007FC07FE000
+0000007FE07FE0000000007FE07FC0000000003FE07FC0000000003FE0FFC0000000003F
+F0FFC0000000003FF0FFC0000000003FF0FFC0000000003FF0FFC0000000003FF0FFC000
+0000003FF0FFC0000000003FF0FFC0000000003FF0FFC0000000003FF0FFC0000000003F
+F0FFC0000000003FF0FFC0000000003FF07FC0000000003FE07FC0000000003FE07FE000
+0000007FE07FE0000000007FE07FE0000000007FE03FE0000000007FC03FE0000000007F
+C01FF000000000FF801FF000000000FF801FF000000000FF800FF000000000FF000FF800
+000001FF0007F8000F8001FE0003FC003FE003FC0003FC00707003FC0001FE00E03807F8
+0000FF01C01C0FF000007F01800E0FE000003F8180061FC000001FC180073F8000000FE1
+80077F00000007F18003FE00000001FDC003F8000000007EE007E0000000001FF03FC000
+18000007FFFFC000180000007FE1E000180000000001E000380000000001F00038000000
+0001F800780000000001F800780000000000FC00F00000000000FF03F00000000000FFFF
+F00000000000FFFFF000000000007FFFE000000000007FFFE000000000007FFFE0000000
+00003FFFC000000000001FFF8000000000000FFF00000000000007FE00000000000001F8
+003D527BBF47>I<FFFFFFFFC0000000FFFFFFFFFC000000FFFFFFFFFF80000001FFC000
+FFE00000007F80001FF00000007F800007FC0000007F800001FE0000007F800000FF0000
+007F800000FF8000007F8000007FC000007F8000007FC000007F8000003FE000007F8000
+003FE000007F8000003FF000007F8000003FF000007F8000003FF000007F8000003FF000
+007F8000003FF000007F8000003FF000007F8000003FF000007F8000003FE000007F8000
+007FE000007F8000007FC000007F8000007F8000007F800000FF8000007F800000FF0000
+007F800001FC0000007F800007F80000007F80001FE00000007F8000FF800000007FFFFF
+FC000000007FFFFFF0000000007F8001FC000000007F80003F000000007F80001FC00000
+007F80000FE00000007F800007F00000007F800007F80000007F800003F80000007F8000
+03FC0000007F800001FC0000007F800001FE0000007F800001FE0000007F800001FE0000
+007F800001FF0000007F800001FF0000007F800001FF0000007F800001FF0000007F8000
+01FF8000007F800001FF8000007F800001FF8000007F800001FF8000007F800001FFC004
+007F800001FFC00E007F800001FFC00E007F800000FFC00E007F800000FFE00E007F8000
+007FE01E01FFE000007FE01CFFFFFFC0003FF01CFFFFFFC0001FF838FFFFFFC00007F870
+000000000001FFE00000000000003F803F407DBD43>I<0007FC000C001FFF801C007FFF
+F03C01FC03F83C03F0007E7C07C0001FFC0F80000FFC1F800007FC3F000003FC3E000001
+FC7E000000FC7E000000FC7C0000007CFC0000007CFC0000007CFC0000003CFC0000003C
+FC0000003CFE0000001CFE0000001CFF0000001CFF0000001C7F800000007FC00000007F
+E00000003FF80000003FFF8000001FFFF800000FFFFF800007FFFFF00003FFFFFC0001FF
+FFFF0000FFFFFFC0003FFFFFE00007FFFFF000007FFFF0000007FFF80000007FFC000000
+0FFC00000007FE00000003FE00000001FE00000000FF00000000FFE00000007FE0000000
+7FE00000007FE00000003FE00000003FF00000003FF00000003FF00000003FF00000003E
+F80000003EF80000007EFC0000007CFE000000FCFF000000F8FF800001F8FFC00003F0FF
+E00007E0F9FC000FC0F07F803F80F01FFFFE00E007FFF800C0007FC00028427BBF33>I<
+3FFFFFFFFFFFFF803FFFFFFFFFFFFF803FFFFFFFFFFFFF803FF0007FE001FF803F80003F
+C0003F807F00003FC0001FC07E00003FC00007C07C00003FC00007C07800003FC00003C0
+7800003FC00003C07800003FC00003C07000003FC00001C07000003FC00001C07000003F
+C00001C07000003FC00001C07000003FC00001C0E000003FC00000E0E000003FC00000E0
+E000003FC00000E0E000003FC00000E0E000003FC00000E00000003FC00000000000003F
+C00000000000003FC00000000000003FC00000000000003FC00000000000003FC0000000
+0000003FC00000000000003FC00000000000003FC00000000000003FC00000000000003F
+C00000000000003FC00000000000003FC00000000000003FC00000000000003FC0000000
+0000003FC00000000000003FC00000000000003FC00000000000003FC00000000000003F
+C00000000000003FC00000000000003FC00000000000003FC00000000000003FC0000000
+0000003FC00000000000003FC00000000000003FC00000000000003FC00000000000003F
+C00000000000003FC00000000000003FC00000000000003FC00000000000003FC0000000
+0000003FC00000000000003FC00000000000007FE0000000000000FFF00000000007FFFF
+FFFE00000007FFFFFFFE00000007FFFFFFFE00003B3D7DBC42>I<FFFFFFC000FFFFF8FF
+FFFFC000FFFFF8FFFFFFC000FFFFF801FFE0000007FF00007F80000001FC00007F800000
+00F800007F800000007000007F800000007000007F800000007000007F80000000700000
+7F800000007000007F800000007000007F800000007000007F800000007000007F800000
+007000007F800000007000007F800000007000007F800000007000007F80000000700000
+7F800000007000007F800000007000007F800000007000007F800000007000007F800000
+007000007F800000007000007F800000007000007F800000007000007F80000000700000
+7F800000007000007F800000007000007F800000007000007F800000007000007F800000
+007000007F800000007000007F800000007000007F800000007000007F80000000700000
+7F800000007000007F800000007000007F800000007000007F800000007000007F800000
+007000007F800000007000007F800000007000007F800000007000007F80000000700000
+3F80000000F000003FC0000000E000003FC0000000E000003FC0000001E000001FC00000
+01C000001FE0000001C000000FE0000003C000000FF000000780000007F0000007000000
+03F800000F00000001FC00001E00000000FE00003C000000007F0000F8000000003F8001
+F0000000000FF00FE00000000003FFFF800000000000FFFE0000000000001FF00000003D
+407DBD44>I<FFFFFF00000FFFFEFFFFFF00000FFFFEFFFFFF00000FFFFE03FFE0000001
+FFE001FF800000007F8000FF800000003F00007F800000003E00007F800000001C00007F
+C00000003C00003FC00000003800003FC00000003800003FE00000007800001FE0000000
+7000001FE00000007000000FF0000000E000000FF0000000E000000FF8000001E0000007
+F8000001C0000007F8000001C0000007FC000003C0000003FC00000380000003FC000003
+80000001FE00000700000001FE00000700000001FF00000700000000FF00000E00000000
+FF00000E00000000FF80001E000000007F80001C000000007F80001C000000007FC0003C
+000000003FC00038000000003FC00038000000001FE00070000000001FE0007000000000
+1FF000F0000000000FF000E0000000000FF000E0000000000FF801E00000000007F801C0
+0000000007F801C00000000003FC03800000000003FC03800000000003FE078000000000
+01FE07000000000001FE07000000000001FF0F000000000000FF0E000000000000FF0E00
+00000000007F9C0000000000007F9C0000000000007FDC0000000000003FF80000000000
+003FF80000000000003FF80000000000001FF00000000000001FF00000000000001FF000
+00000000000FE00000000000000FE000000000000007C000000000000007C00000000000
+0007C000000000000003800000003F407EBD44>I<FFFFFE007FFFFF8007FFFFFFFFFE00
+7FFFFF8007FFFFFFFFFE007FFFFF8007FFFF03FFC00001FFE00000FFF801FF000000FFC0
+00003FE001FF0000007F8000000F8000FF0000007F8000000F8000FF0000007FC000000F
+0000FF8000003FC000000F00007F8000003FC000000E00007F8000003FE000000E00007F
+8000003FE000000E00003FC000003FE000001C00003FC000003FE000001C00003FC00000
+7FF000001C00001FE000007FF000003800001FE000007FF000003800001FE00000E7F800
+003800000FF00000E7F800007000000FF00000E7F800007000000FF00001C3FC00007000
+000FF80001C3FC0000F0000007F80001C3FC0000E0000007F80003C3FE0000E0000007FC
+000381FE0001E0000003FC000381FE0001C0000003FC000781FF0001C0000003FC000700
+FF0001C0000001FE000700FF000380000001FE000700FF000380000001FE000E007F8003
+80000000FF000E007F800700000000FF000E007F800700000000FF001C003FC007000000
+007F801C003FC00E000000007F801C003FC00E000000007F8038001FE00E000000007FC0
+38001FE01E000000003FC038001FE01C000000003FC078001FF01C000000003FE070000F
+F03C000000001FE070000FF038000000001FE0F0000FF838000000001FE0E00007F83800
+0000000FF0E00007F870000000000FF0E00007F870000000000FF1C00003FC7000000000
+07F9C00003FCE00000000007F9C00003FCE00000000007FB800001FEE00000000003FF80
+0001FFC00000000003FF800001FFC00000000003FF000000FFC00000000003FF000000FF
+C00000000001FF000000FF800000000001FF000000FF800000000001FE0000007F800000
+000000FE0000007F000000000000FE0000007F000000000000FC0000003F000000000000
+7C0000003E0000000000007C0000003E000000000000780000001E000000000000380000
+001C00000058407EBD5D>I<7FFFFFC003FFFFE07FFFFFC003FFFFE07FFFFFC003FFFFE0
+00FFFE0000FFFC00003FF800003FE000001FF000001F8000000FF800001F0000000FF800
+001E00000007FC00001C00000003FE00003C00000003FE00007800000001FF0000700000
+0000FF8000F000000000FF8001E0000000007FC001C0000000003FC003C0000000003FE0
+0780000000001FF00700000000000FF00F00000000000FF81E000000000007FC1C000000
+000007FC3C000000000003FE78000000000001FF70000000000001FFF0000000000000FF
+E00000000000007FC00000000000007FC00000000000003FE00000000000001FF0000000
+0000001FF00000000000001FF80000000000001FFC0000000000003FFC0000000000003B
+FE00000000000071FF000000000000F1FF000000000000E0FF800000000001C07F800000
+000003C07FC00000000003803FE00000000007003FE0000000000F001FF0000000000E00
+0FF8000000001C000FF8000000003C0007FC00000000380003FE00000000780003FE0000
+0000F00001FF00000000E00000FF80000001E00000FF80000003C000007FC00000038000
+003FE00000078000003FE000000F0000001FF000001F0000000FF800003F8000000FF800
+00FFC000001FFC0007FFE000007FFF00FFFFFC0003FFFFFEFFFFFC0003FFFFFEFFFFFC00
+03FFFFFE3F3E7EBD44>I<FFFFFF800003FFFF80FFFFFF800003FFFF80FFFFFF800003FF
+FF8001FFF0000000FFF800007FE00000003FC000007FE00000001F8000003FE00000001E
+0000001FF00000001E0000001FF00000003C0000000FF80000003800000007FC00000078
+00000007FC000000F000000003FE000000E000000003FF000001E000000001FF000001C0
+00000000FF800003C000000000FF80000380000000007FC0000700000000003FE0000F00
+000000003FE0000E00000000001FF0001E00000000001FF0001C00000000000FF8003800
+0000000007FC0078000000000007FC0070000000000003FE00F0000000000003FF00E000
+0000000001FF01E0000000000000FF83C0000000000000FF83800000000000007FC78000
+00000000003FE7000000000000003FEF000000000000001FFE000000000000001FFC0000
+00000000000FFC0000000000000007F80000000000000007F80000000000000007F80000
+000000000007F80000000000000007F80000000000000007F80000000000000007F80000
+000000000007F80000000000000007F80000000000000007F80000000000000007F80000
+000000000007F80000000000000007F80000000000000007F80000000000000007F80000
+000000000007F80000000000000007F80000000000000007F80000000000000007F80000
+000000000007F80000000000000007F80000000000000007F8000000000000001FFC0000
+000000000FFFFFFC00000000000FFFFFFC00000000000FFFFFFC000000413E7FBD44>I<
+FFFCFFFCFFFCFFFCF000F000F000F000F000F000F000F000F000F000F000F000F000F000
+F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000
+F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000
+F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000
+F000F000F000F000F000F000F000F000F000F000F000F000F000F000F000FFFCFFFCFFFC
+FFFC0E5B77C319>91 D<FFFCFFFCFFFCFFFC003C003C003C003C003C003C003C003C003C
+003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C
+003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C
+003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C
+003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C003C
+003C003CFFFCFFFCFFFCFFFC0E5B7FC319>93 D<01800380030007000E001C0018003800
+30007000600060006000E000C000C000C000C000CF00FFC0FFE0FFE0FFE07FE07FE03FE0
+3FC00F000B1C7ABE19>96 D<000FF800000000FFFE00000003F01F800000078007E00000
+0F8003F000000FE001F800001FF001FC00001FF000FE00001FF000FE00001FF000FE0000
+1FF0007F00000FE0007F00000380007F00000000007F00000000007F00000000007F0000
+0000007F000000001FFF00000003FFFF0000001FF87F0000007F807F000001FC007F0000
+07F8007F00000FE0007F00001FC0007F00003F80007F00003F80007F00007F00007F0000
+7F00007F0380FE00007F0380FE00007F0380FE00007F0380FE0000FF0380FE0000FF0380
+FE0000FF03807F0001FF03807F0003BF03803F80071F87001FC00E1FCF0007F03C0FFE00
+01FFF807FC00003FC001F000292A7DA82D>I<01FC00000000FFFC00000000FFFC000000
+00FFFC0000000007FC0000000003FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC03FC000001FC1FFF800001FC7C07E00001FDE001F0
+0001FFC000FC0001FF80007E0001FF00003F0001FE00003F8001FC00001F8001FC00001F
+C001FC00000FE001FC00000FE001FC00000FF001FC00000FF001FC000007F001FC000007
+F801FC000007F801FC000007F801FC000007F801FC000007F801FC000007F801FC000007
+F801FC000007F801FC000007F801FC000007F801FC000007F001FC000007F001FC00000F
+F001FC00000FF001FC00000FE001FC00001FE001FC00001FC001FE00001F8001FE00003F
+0001FF00007F0001FF8000FE0001F3C001F80001F1E003F00001E0780FC00001C03FFF00
+00000007F800002D407EBE33>I<0001FF0000000FFFE000003F00F800007C001E0001F8
+001F0003F0007F0007F000FF800FE000FF800FC000FF801FC000FF801FC000FF803F8000
+7F003F80001C007F800000007F800000007F00000000FF00000000FF00000000FF000000
+00FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000
+FF000000007F800000007F800000007F800000003F800001C03FC00001C01FC00003C01F
+C00003800FE000078007F000070003F0000E0001F8001E0000FC007800003F01F000000F
+FFC0000001FE0000222A7DA828>I<00000001FC00000000FFFC00000000FFFC00000000
+FFFC0000000007FC0000000003FC0000000001FC0000000001FC0000000001FC00000000
+01FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC00000000
+01FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC00000000
+01FC0000000001FC000000FF01FC000007FFE1FC00001F80F9FC00007E003DFC0000FC00
+1FFC0003F80007FC0007F00007FC0007E00003FC000FC00001FC001FC00001FC003FC000
+01FC003F800001FC007F800001FC007F800001FC007F000001FC007F000001FC00FF0000
+01FC00FF000001FC00FF000001FC00FF000001FC00FF000001FC00FF000001FC00FF0000
+01FC00FF000001FC00FF000001FC00FF000001FC007F000001FC007F800001FC007F8000
+01FC003F800001FC003F800001FC001FC00001FC000FC00003FC000FE00003FC0007E000
+07FC0003F0000FFE0001F8001FFF00007C0079FFF8003F01F1FFF8000FFFC1FFF80001FE
+01FC002D407DBE33>I<0001FE0000000FFFC000003F03F00000FC01F80001F800FC0003
+F0007E0007E0003F000FE0003F800FC0001F801FC0001FC03F80000FC03F80000FC07F80
+000FC07F80000FE07F00000FE07F00000FE0FF00000FE0FF00000FE0FFFFFFFFE0FFFFFF
+FFE0FF00000000FF00000000FF00000000FF00000000FF00000000FF000000007F000000
+007F000000007F800000003F800000003F800000E01FC00000E01FC00001E00FC00001C0
+07E00003C007F000078003F800070000FC001E00007E003C00001F80F8000007FFE00000
+00FF0000232A7EA828>I<00001FC000007FF80001F83C0007E07E000FC0FF001FC1FF00
+3F81FF003F01FF007F01FF007F00FE00FE007C00FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE0000FFFFFF00FFFFFF00FFFFFF0000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000
+FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000001
+FF00007FFFFF007FFFFF007FFFFF0020407EBF1C>I<000000007C000003F801FF00001F
+FF078F80007E0FDE1F8000F803F81F8003F001F81F8003F001F81F8007E000FC06000FE0
+00FE00000FC0007E00001FC0007F00001FC0007F00001FC0007F00001FC0007F00001FC0
+007F00001FC0007F00001FC0007F00001FC0007F00000FC0007E00000FE000FE000007E0
+00FC000003F001F8000003F001F8000001F803E0000003FE0FC00000071FFF0000000703
+F80000000600000000000E00000000000E00000000000E00000000000F00000000000F00
+000000000F80000000000FC00000000007FFFFE0000007FFFFFE000003FFFFFF800001FF
+FFFFE00000FFFFFFF00003FFFFFFF8000FC0001FFC001F000001FE003E000000FE007C00
+00007E007C0000003F00F80000003F00F80000001F00F80000001F00F80000001F00F800
+00001F00FC0000003F007C0000003E007E0000007E003F000000FC001F800001F8000FC0
+0003F00003F0000FC00000FE007F0000003FFFFC00000003FFC00000293D7EA82D>I<01
+FC00000000FFFC00000000FFFC00000000FFFC0000000007FC0000000003FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC01FE000001
+FC07FFC00001FC1E07E00001FC7803F00001FCE001F80001FDC001FC0001FD8001FC0001
+FF8000FE0001FF0000FE0001FF0000FE0001FE0000FE0001FE0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0003FE0001FF00FF
+FFF87FFFFCFFFFF87FFFFCFFFFF87FFFFC2E3F7DBE33>I<01E00007F80007F8000FFC00
+0FFC000FFC000FFC0007F80007F80001E000000000000000000000000000000000000000
+00000000000000000000000000000000000001FC007FFC007FFC007FFC0007FC0003FC00
+01FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC00
+01FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC00
+01FC0001FC0001FC0001FC0001FC0001FC0003FE00FFFFF0FFFFF0FFFFF0143E7DBD1A>
+I<0000780001FE0001FE0003FF0003FF0003FF0003FF0001FE0001FE0000780000000000
+0000000000000000000000000000000000000000000000000000000000000000007F007F
+FF007FFF007FFF0001FF0000FF00007F00007F00007F00007F00007F00007F00007F0000
+7F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0000
+7F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0000
+7F00007F00007F00007F00007F00007F00007F00007F00007F00007F3E007F7F007FFF80
+7EFF80FEFF80FEFF80FCFF81F87F01F87C03F01E07C00FFF8001FC00185185BD1C>I<01
+FC00000000FFFC00000000FFFC00000000FFFC0000000007FC0000000003FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC00FFFF8001FC00FFFF8001FC00FFFF8001FC003FFC0001FC003FE00001FC003F800001
+FC003F000001FC003C000001FC0078000001FC00F0000001FC01E0000001FC07C0000001
+FC0F80000001FC1F00000001FC3E00000001FC7F00000001FCFF80000001FDFF80000001
+FFDFC0000001FF9FE0000001FF0FE0000001FE07F0000001FC07F8000001F803FC000001
+F801FC000001F801FE000001F800FF000001F8007F000001F8007F800001F8003FC00001
+F8001FC00001F8001FE00001F8000FF00001F8000FF00001F8000FF80003FC000FFE00FF
+FFF07FFFE0FFFFF07FFFE0FFFFF07FFFE02B3F7EBE30>I<01FC00FFFC00FFFC00FFFC00
+07FC0003FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC00
+01FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC00
+01FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC00
+01FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC00
+01FC0001FC0001FC0001FC0001FC0001FC0001FC0003FE00FFFFF8FFFFF8FFFFF8153F7D
+BE1A>I<01F801FE0000FF0000FFF807FFC003FFE000FFF81E07E00F03F000FFF87803F0
+3C01F80007F8E001F87000FC0003F9C001FCE000FE0001F98001FCC000FE0001FB8000FF
+C0007F0001FB0000FF80007F0001FF0000FF80007F0001FE0000FF00007F0001FE0000FF
+00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE
+00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE
+00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE
+00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE
+00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE
+00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE00007F0001FC0000FE
+00007F0003FE0001FF0000FF80FFFFF87FFFFC3FFFFEFFFFF87FFFFC3FFFFEFFFFF87FFF
+FC3FFFFE47287DA74C>I<01F801FE0000FFF807FFC000FFF81E07E000FFF87803F00007
+F8E001F80003F9C001FC0001F98001FC0001FB8000FE0001FB0000FE0001FF0000FE0001
+FE0000FE0001FE0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001
+FC0000FE0001FC0000FE0003FE0001FF00FFFFF87FFFFCFFFFF87FFFFCFFFFF87FFFFC2E
+287DA733>I<0000FF00000007FFE000001F81F800007E007E0000F8001F0001F0000F80
+03E00007C007C00003E00FC00003F01F800001F81F800001F83F800001FC3F800001FC7F
+000000FE7F000000FE7F000000FE7F000000FEFF000000FFFF000000FFFF000000FFFF00
+0000FFFF000000FFFF000000FFFF000000FFFF000000FFFF000000FF7F000000FE7F0000
+00FE7F000000FE3F800001FC3F800001FC3F800001FC1F800001F80FC00003F00FC00003
+F007E00007E003F0000FC001F8001F80007E007E00003F81FC00000FFFF0000000FF0000
+282A7EA82D>I<01FC03FC0000FFFC1FFF8000FFFC7C0FE000FFFDE003F00003FFC001FC
+0001FF8000FE0001FF00007F0001FE00003F8001FC00003F8001FC00001FC001FC00001F
+E001FC00001FE001FC00000FF001FC00000FF001FC00000FF001FC000007F801FC000007
+F801FC000007F801FC000007F801FC000007F801FC000007F801FC000007F801FC000007
+F801FC000007F801FC000007F801FC00000FF001FC00000FF001FC00000FF001FC00000F
+F001FC00001FE001FC00001FE001FC00003FC001FE00003F8001FE00007F0001FF00007F
+0001FF8000FE0001FFC001F80001FDE007F00001FC780FC00001FC3FFF000001FC07F800
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000003FE00000000FFFFF8000000FFFFF8000000FFFFF80000002D3A7EA733
+>I<0000FF001C000007FFC03C00001F80F03C00007F00387C0000FC001C7C0003F8000E
+7C0007F0000FFC0007F00007FC000FE00003FC001FE00003FC003FC00003FC003FC00001
+FC007F800001FC007F800001FC007F800001FC007F800001FC00FF000001FC00FF000001
+FC00FF000001FC00FF000001FC00FF000001FC00FF000001FC00FF000001FC00FF000001
+FC00FF000001FC00FF000001FC007F800001FC007F800001FC007F800001FC003FC00001
+FC003FC00001FC001FC00003FC000FE00003FC000FE00007FC0007F0000FFC0003F8000F
+FC0001FC003DFC00007E0079FC00003F81F1FC00000FFFC1FC000001FE01FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001
+FC0000000003FE00000000FFFFF8000000FFFFF8000000FFFFF82D3A7DA730>I<01F807
+E0FFF81FF8FFF8787CFFF8E1FE07F9C1FE03F981FE01FB81FE01FB01FE01FB00FC01FF00
+3001FE000001FE000001FE000001FC000001FC000001FC000001FC000001FC000001FC00
+0001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC00
+0001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000003FE00
+00FFFFFE00FFFFFE00FFFFFE001F287EA724>I<003FC06001FFF8E007C03FE01F000FE0
+3E0007E03C0003E07C0003E0780001E0F80001E0F80000E0F80000E0FC0000E0FE0000E0
+FF0000E0FF8000007FF800007FFFC0003FFFF8001FFFFE000FFFFF0007FFFF8001FFFFC0
+003FFFE00003FFF000001FF000000FF8E00003F8E00003F8E00001F8F00001F8F00000F8
+F00000F8F80000F8F80000F0FC0000F0FC0001F0FE0001E0FF0003C0FF800780F3E01F00
+E0FFFC00C01FE0001D2A7DA824>I<001C0000001C0000001C0000001C0000001C000000
+1C0000003C0000003C0000003C0000003C0000007C0000007C000000FC000000FC000001
+FC000003FC000007FC00001FFFFFC0FFFFFFC0FFFFFFC001FC000001FC000001FC000001
+FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001
+FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC00E001
+FC00E001FC00E001FC00E001FC00E001FC00E001FC00E001FC00E001FC00E000FC00E000
+FE01C000FE01C0007F03C0003F0380001F87000007FE000001F8001B397EB723>I<01FC
+0000FE00FFFC007FFE00FFFC007FFE00FFFC007FFE0007FC0003FE0003FC0001FE0001FC
+0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC
+0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC
+0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC
+0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0000FE0001FC0001FE0001FC
+0001FE0001FC0001FE0001FC0003FE0000FC0003FE0000FC0007FE0000FE0006FF00007E
+000EFF80003F001CFFFC001FC078FFFC0007FFE0FFFC0000FF80FE002E297DA733>I<FF
+FFE00FFFE0FFFFE00FFFE0FFFFE00FFFE007FE0003FF0003FC0000FC0003FC0000F80001
+FC0000F00001FE0000F00000FE0000E00000FE0000E00000FF0001E000007F0001C00000
+7F0001C000003F80038000003F80038000003FC0078000001FC0070000001FC007000000
+0FE00E0000000FE00E0000000FF01E00000007F01C00000007F01C00000003F838000000
+03F83800000003FC7800000001FC7000000001FC7000000001FEF000000000FEE0000000
+00FEE0000000007FC0000000007FC0000000007FC0000000003F80000000003F80000000
+001F00000000001F00000000001F00000000000E0000002B287EA630>I<FFFFC3FFFE03
+FFF8FFFFC3FFFE03FFF8FFFFC3FFFE03FFF80FFE003FE000FFC007FC001FC0003F8003F8
+001FC0003F0003FC000FC0001E0001FC000FE0001C0001FC0007E0001C0001FE0007E000
+3C0000FE000FF000380000FE000FF0003800007F000FF0007000007F001FF8007000007F
+001DF8007000003F801DF800E000003F803DFC00E000003F8038FC00E000001FC038FC01
+C000001FC078FE01C000001FC0707E03C000000FE0707F038000000FE0E03F038000000F
+F0E03F0780000007F0E03F8700000007F1C01F8700000007F9C01F8F00000003F9C01FCE
+00000003FB800FCE00000003FF800FDE00000001FF800FFC00000001FF0007FC00000000
+FF0007F800000000FF0007F800000000FE0003F8000000007E0003F0000000007E0003F0
+000000007C0001F0000000003C0001E000000000380000E000003D287EA642>I<FFFFF0
+1FFFE0FFFFF01FFFE0FFFFF01FFFE003FFC00FFF0000FF8007F800007F0007E000007F80
+07C000003FC0078000001FC00F0000000FE00E0000000FF01E00000007F83C00000003F8
+7800000001FCF000000001FEE000000000FFE0000000007FC0000000003F80000000003F
+C0000000001FC0000000001FE0000000003FF0000000003FF8000000007BF800000000F1
+FC00000001E1FE00000001C0FF00000003C07F00000007803F8000000F003FC000001E00
+1FE000003E000FE000007C0007F00000FC0007F80001FE0007FC000FFE000FFE00FFFF80
+3FFFF8FFFF803FFFF8FFFF803FFFF82D277FA630>I<FFFFE00FFFE0FFFFE00FFFE0FFFF
+E00FFFE007FE0003FF0003FC0001FC0003FC0000F80001FC0000F00001FE0000F00000FE
+0000E00000FE0000E000007F0001C000007F0001C000007F8003C000003F80038000003F
+80038000001FC0070000001FC0070000001FE00F0000000FE00E0000000FE00E00000007
+F01C00000007F01C00000007F83C00000003F83800000003F83800000001FC7000000001
+FC7000000001FEF000000000FEE000000000FEE0000000007FC0000000007FC000000000
+7FC0000000003F80000000003F80000000003F80000000001F00000000001F0000000000
+0E00000000000E00000000001E00000000001C00000000003C0000000000380000000000
+380000000000780000001800700000007E0070000000FF00E0000000FF00E0000000FF01
+C0000000FF01C0000000FE03800000007E0700000000780E000000003C3C000000001FF8
+0000000007E0000000002B3A7EA630>I<1FFFFFFF801FFFFFFF801FE000FF801F8000FF
+001F0001FE001E0003FC001C0003FC001C0007F8003C000FF0003C001FF00038001FE000
+38003FC00038007FC00038007F80003800FF00000001FE00000001FE00000003FC000000
+07F80000000FF80000000FF00000001FE00000003FC00380003FC00380007F80038000FF
+00038001FF00038001FE00038003FC00078007FC00078007F80007000FF00007001FE000
+0F001FE0000F003FC0001F007F80007F00FF8001FF00FFFFFFFF00FFFFFFFF0021277EA6
+28>I<FFFFFFFFFFF0FFFFFFFFFFF02C0280982D>I<FFFFFFFFFFFFFFFFFFFFFFC0FFFFFF
+FFFFFFFFFFFFFFFFC05A0280985B>I E /Ft 62 124 df<000000FFF8003FF00000001F
+FFFE03FFFC0000007FFFFF8FFFFE000001FFFFFFFFFFFF000007FFC03FFFF1FF80000FFE
+001FFF81FF80001FF8003FFF03FFC0003FE0007FFE03FFC0007FC0007FFE03FFC000FFC0
+007FFC03FFC000FF80007FFC03FFC001FF80007FF801FF8001FF00003FF800FF0001FF00
+003FF8007E0001FF00001FF800000001FF00000FF800000001FF00000FF800000001FF00
+000FF800000001FF00000FF800000001FF00000FF800000001FF00000FF800000001FF00
+000FF800000001FF00000FF800000001FF00000FF8000000FFFFFFFFFFFFFF0000FFFFFF
+FFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFF000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80000FFC00000001FF80
+000FFC00000001FF80000FFC0000007FFFFE03FFFFFC00007FFFFE03FFFFFC00007FFFFE
+03FFFFFC00007FFFFE03FFFFFC00007FFFFE03FFFFFC000042407EBF3D>11
+D<000000FFF8000000000FFFFF000000007FFFFF80000001FFFFFFE0000007FFC01FF000
+000FFE0007F000001FF8000FF800003FE0001FF800007FC0003FFC0000FFC0003FFC0000
+FF80003FFC0001FF80003FFC0001FF00003FFC0001FF00003FFC0001FF00001FF80001FF
+00000FF00001FF000003C00001FF000000000001FF000000000001FF000000000001FF00
+0000000001FF000000000001FF000000000001FF000003FC00FFFFFFFFFFFC00FFFFFFFF
+FFFC00FFFFFFFFFFFC00FFFFFFFFFFFC00FFFFFFFFFFFC0001FF80001FFC0001FF80000F
+FC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC
+0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC00
+01FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001
+FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF
+80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80000FFC0001FF80
+000FFC0001FF80000FFC0001FF80000FFC007FFFFE03FFFFF07FFFFE03FFFFF07FFFFE03
+FFFFF07FFFFE03FFFFF07FFFFE03FFFFF034407EBF3A>I<0FC01FE03FF07FF8FFFCFFFC
+FFFCFFFEFFFEFFFE7FFE3FFE1FFE0FDE001E001E003E003C003C007C0078007800F801F0
+01F003E007C00F801F803F001E000C000F20798D1D>44 D<FFFFFFE0FFFFFFE0FFFFFFE0
+FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE01B097F9823>I<0FC01FE03F
+F07FF8FFFCFFFCFFFCFFFCFFFCFFFC7FF83FF01FE00FC00E0E798D1D>I<0000FFE00000
+0007FFFC0000001FFFFF0000007FFFFFC00000FFE0FFE00001FF803FF00003FE000FF800
+07FC0007FC0007FC0007FC000FF80003FE001FF80003FF001FF80003FF001FF80003FF00
+3FF00001FF803FF00001FF803FF00001FF807FF00001FFC07FF00001FFC07FF00001FFC0
+7FF00001FFC07FF00001FFC0FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0
+FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0
+FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE0
+FFF00001FFE0FFF00001FFE0FFF00001FFE0FFF00001FFE07FF00001FFC07FF00001FFC0
+7FF00001FFC07FF00001FFC07FF00001FFC03FF00001FF803FF80003FF803FF80003FF80
+1FF80003FF001FF80003FF000FF80003FE000FFC0007FE0007FE000FFC0003FF001FF800
+01FF803FF00000FFE0FFE000007FFFFFC000001FFFFF00000007FFFC00000000FFE00000
+2B3D7CBB34>48 D<00000F000000003F000000007F00000001FF0000000FFF000001FFFF
+0000FFFFFF0000FFFFFF0000FFFFFF0000FFF7FF0000FE07FF00000007FF00000007FF00
+000007FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF0000
+0007FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF000000
+07FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007
+FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF
+00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF00000007FF00
+000007FF00000007FF00000007FF00000007FF00000007FF00000007FF0000FFFFFFFFF0
+FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0243C78BB34>I<0003FF800000003FFF
+F8000000FFFFFE000003FFFFFF800007FFFFFFC0000FF80FFFE0001FC003FFF0003F8000
+FFF8007FC0007FFC007FE0003FFE00FFF0003FFE00FFF8001FFF00FFF8001FFF00FFF800
+0FFF80FFF8000FFF80FFF8000FFF80FFF8000FFF807FF0000FFF803FE0000FFF801FC000
+0FFF800700000FFF800000000FFF800000001FFF000000001FFF000000001FFE00000000
+3FFE000000003FFC000000007FF8000000007FF800000000FFF000000000FFE000000001
+FFC000000003FF8000000007FE0000000007FC000000000FF8000000001FE0000000003F
+C0000000007F8000000000FF000F800001FC000F800003F8000F800007F0001F00000FE0
+001F00001F80001F00003F00001F00007E00003F0000FC00003F0001FFFFFFFF0003FFFF
+FFFE0007FFFFFFFE000FFFFFFFFE001FFFFFFFFE003FFFFFFFFE007FFFFFFFFE00FFFFFF
+FFFE00FFFFFFFFFC00FFFFFFFFFC00FFFFFFFFFC00FFFFFFFFFC00293C7BBB34>I<0001
+FFE00000000FFFFE0000003FFFFF800000FFFFFFE00001FF81FFF00003FC007FF80007F0
+003FFC0007F0003FFE000FFC001FFE000FFE001FFF001FFE001FFF001FFF001FFF001FFF
+001FFF001FFF001FFF001FFF001FFF001FFF001FFF000FFE001FFF000FFE001FFE0007FC
+003FFE0001F0003FFC000000003FFC000000007FF8000000007FF000000000FFE0000000
+01FFC00000000FFF80000007FFFE00000007FFF800000007FFFE00000007FFFFC0000000
+01FFF0000000007FF8000000003FFC000000001FFE000000000FFF000000000FFF800000
+000FFF8000000007FFC000000007FFC000000007FFE00FC00007FFE01FE00007FFE03FF0
+0007FFE07FF80007FFE0FFFC0007FFE0FFFC0007FFE0FFFC0007FFE0FFFC0007FFC0FFFC
+0007FFC0FFFC000FFFC0FFF8000FFF807FF8000FFF807FF0001FFF003FC0003FFE001FE0
+007FFC000FFE01FFF80007FFFFFFF00003FFFFFFE00000FFFFFF8000003FFFFE00000003
+FFE000002B3D7CBB34>I<00000001F80000000003F80000000007F80000000007F80000
+00000FF8000000001FF8000000003FF8000000003FF8000000007FF800000000FFF80000
+0001FFF800000003FFF800000003FFF800000007FFF80000000FFFF80000001FBFF80000
+003F3FF80000003E3FF80000007C3FF8000000FC3FF8000001F83FF8000001F03FF80000
+03E03FF8000007E03FF800000FC03FF800001F803FF800001F003FF800003E003FF80000
+7E003FF80000FC003FF80001F8003FF80001F0003FF80003E0003FF80007E0003FF8000F
+C0003FF8000F80003FF8001F00003FF8003F00003FF8007E00003FF800FC00003FF800FF
+FFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF8FFFFFFFFFFF80000007FF80000
+00007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000
+00007FF8000000007FF8000000007FF8000001FFFFFFF80001FFFFFFF80001FFFFFFF800
+01FFFFFFF80001FFFFFFF82D3C7DBB34>I<0700000038000FE00001F8000FFE003FF800
+0FFFFFFFF8000FFFFFFFF0000FFFFFFFE0000FFFFFFFC0000FFFFFFF80000FFFFFFF0000
+0FFFFFFE00000FFFFFF800000FFFFFF000000FFFFFC000000FFFFE0000000F8000000000
+0F80000000000F80000000000F80000000000F80000000000F80000000000F8000000000
+0F80000000000F80000000000F80FFC000000F87FFFC00000F9FFFFF00000FFFFFFF8000
+0FFF01FFE0000FF8007FF0000FF0003FF8000FC0001FFC000F80001FFC000700001FFE00
+0000000FFE000000000FFF000000000FFF000000000FFF000000000FFF800000000FFF80
+0700000FFF801FC0000FFF803FE0000FFF807FF0000FFF80FFF0000FFF80FFF8000FFF80
+FFF8000FFF80FFF8000FFF00FFF8000FFF00FFF0000FFF00FFF0001FFE007FE0001FFE00
+7F80001FFC003F00003FFC003F80007FF8001FE000FFF0000FFC07FFE00007FFFFFFC000
+03FFFFFF000000FFFFFC0000003FFFF000000007FF000000293D7BBB34>I<000007FF00
+0000003FFFC0000001FFFFF0000007FFFFF800000FFF03FC00003FF800FC00007FE001FE
+0000FFC003FE0001FF8007FF0003FF000FFF0003FF000FFF0007FE000FFF000FFE000FFF
+000FFE000FFF001FFC000FFF001FFC0007FE003FFC0003FC003FFC0001F8003FFC000000
+007FF8000000007FF8000000007FF8020000007FF83FFE0000FFF87FFF8000FFF9FFFFE0
+00FFFBFFFFF000FFFBE03FF800FFFF800FFC00FFFF0007FE00FFFF0007FF00FFFE0007FF
+00FFFE0003FF80FFFC0003FFC0FFFC0003FFC0FFFC0003FFC0FFFC0003FFE0FFF80003FF
+E0FFF80003FFE0FFF80003FFE0FFF80003FFE07FF80003FFE07FF80003FFE07FF80003FF
+E07FF80003FFE07FF80003FFE03FF80003FFE03FF80003FFE03FFC0003FFC01FFC0003FF
+C01FFC0003FFC00FFC0007FF800FFE0007FF0007FE0007FF0003FF000FFE0001FF801FFC
+0000FFE07FF800007FFFFFF000003FFFFFE000001FFFFF80000007FFFE00000000FFF000
+002B3D7CBB34>I<1F00000000001F80000000001FF8000000001FFFFFFFFFF01FFFFFFF
+FFF01FFFFFFFFFF01FFFFFFFFFF03FFFFFFFFFF03FFFFFFFFFE03FFFFFFFFFC03FFFFFFF
+FF803FFFFFFFFF003FFFFFFFFE003FFFFFFFFC007FFFFFFFFC007E000001F8007E000003
+F0007C000007E0007C00000FC0007C00001F80007C00001F0000F800003F0000F800007E
+0000F80000FC0000000001F80000000003F00000000003F00000000007E0000000000FE0
+000000000FC0000000001FC0000000003FC0000000003F80000000007F80000000007F80
+00000000FF8000000000FF0000000001FF0000000001FF0000000003FF0000000003FF00
+00000003FF0000000007FE0000000007FE0000000007FE000000000FFE000000000FFE00
+0000000FFE000000000FFE000000000FFE000000001FFE000000001FFE000000001FFE00
+0000001FFE000000001FFE000000001FFE000000001FFE000000001FFE000000001FFE00
+0000001FFE000000000FFC0000000007F80000000003F00000002C3F7ABD34>I<0000FF
+F000000007FFFE0000001FFFFF8000007FFFFFE00000FFC07FF00001FE001FF80003FC00
+0FFC0007F80007FE0007F80003FE000FF00003FE000FF00003FF000FF00001FF001FF000
+01FF001FF00001FF001FF80001FF001FFC0001FF001FFE0001FF001FFF0003FF001FFFC0
+03FE001FFFF003FE000FFFF807FC000FFFFE0FF8000FFFFF9FF00007FFFFFFE00003FFFF
+FFC00003FFFFFF800001FFFFFF000000FFFFFF8000007FFFFFE000001FFFFFF000003FFF
+FFF80000FFFFFFFC0001FFFFFFFE0007FE3FFFFF000FFC1FFFFF801FF807FFFF801FF001
+FFFFC03FE0007FFFC07FE0003FFFC07FC0000FFFE07FC00003FFE0FF800001FFE0FF8000
+00FFE0FF8000007FE0FF8000007FE0FF8000003FE0FF8000003FE0FF8000003FE0FFC000
+003FC07FC000003FC07FC000007F807FE000007F803FF00000FF001FF80001FF001FFE00
+07FE000FFFC03FFC0007FFFFFFF80001FFFFFFE000007FFFFFC000001FFFFE00000001FF
+F000002B3D7CBB34>I<0001FFE00000000FFFFC0000003FFFFF000000FFFFFFC00001FF
+E0FFE00003FF003FF00007FE001FF8000FFE000FFC001FFC000FFC001FFC0007FE003FFC
+0007FE007FF80007FF007FF80003FF007FF80003FF80FFF80003FF80FFF80003FF80FFF8
+0003FFC0FFF80003FFC0FFF80003FFC0FFF80003FFC0FFF80003FFC0FFF80003FFE0FFF8
+0003FFE0FFF80003FFE0FFF80003FFE07FF80007FFE07FF80007FFE07FF80007FFE07FF8
+0007FFE03FF8000FFFE01FFC000FFFE01FFC001FFFE00FFE001FFFE007FE003FFFE003FF
+80FBFFE001FFFFFBFFE0007FFFF3FFE0003FFFC3FFE0000FFF83FFC000000803FFC00000
+0003FFC000000003FFC000000007FF8003F00007FF8007F80007FF800FFC0007FF001FFE
+0007FF001FFE000FFE001FFE000FFE001FFE000FFC001FFE001FFC001FFE003FF8001FFC
+003FF0000FF800FFE0000FF001FFC00007FC0FFF800003FFFFFF000001FFFFFC000000FF
+FFF00000007FFFC00000000FFE0000002B3D7CBB34>I<0FC01FE03FF07FF8FFFCFFFCFF
+FCFFFCFFFCFFFC7FF83FF01FE00FC0000000000000000000000000000000000000000000
+0000000FC01FE03FF07FF8FFFCFFFCFFFCFFFCFFFCFFFC7FF83FF01FE00FC00E2879A71D
+>I<00000000FC0000000000000000FC0000000000000001FE0000000000000001FE0000
+000000000003FF0000000000000003FF0000000000000003FF0000000000000007FF8000
+000000000007FF800000000000000FFFC00000000000000FFFC00000000000000FFFC000
+00000000001FFFE00000000000001FFFE00000000000003FFFF00000000000003FFFF000
+00000000003FFFF00000000000007FFFF80000000000007CFFF8000000000000FCFFFC00
+0000000000F87FFC000000000000F87FFC000000000001F87FFE000000000001F03FFE00
+0000000003F03FFF000000000003E01FFF000000000007E01FFF800000000007C01FFF80
+0000000007C00FFF80000000000FC00FFFC0000000000F8007FFC0000000001F8007FFE0
+000000001F0007FFE0000000001F0003FFE0000000003F0003FFF0000000003E0001FFF0
+000000007E0001FFF8000000007C0000FFF8000000007C0000FFF800000000FC0000FFFC
+00000000F800007FFC00000001FFFFFFFFFE00000001FFFFFFFFFE00000001FFFFFFFFFE
+00000003FFFFFFFFFF00000003FFFFFFFFFF00000007E000001FFF80000007C000000FFF
+8000000FC000000FFFC000000F8000000FFFC000000F80000007FFC000001F80000007FF
+E000001F00000003FFE000003F00000003FFF000003E00000003FFF000003E00000001FF
+F000007E00000001FFF800007C00000000FFF800FFFFFC0000FFFFFFFCFFFFFC0000FFFF
+FFFCFFFFFC0000FFFFFFFCFFFFFC0000FFFFFFFCFFFFFC0000FFFFFFFC463F7CBE4F>65
+D<FFFFFFFFFFF80000FFFFFFFFFFFF8000FFFFFFFFFFFFF000FFFFFFFFFFFFFC00FFFFFF
+FFFFFFFE00003FFC00003FFF00003FFC00000FFF80003FFC000007FFC0003FFC000003FF
+E0003FFC000001FFE0003FFC000001FFF0003FFC000001FFF0003FFC000000FFF8003FFC
+000000FFF8003FFC000000FFF8003FFC000000FFF8003FFC000000FFF8003FFC000000FF
+F8003FFC000000FFF8003FFC000000FFF0003FFC000001FFF0003FFC000001FFF0003FFC
+000003FFE0003FFC000003FFC0003FFC000007FF80003FFC00000FFF00003FFC00003FFE
+00003FFC0001FFF800003FFFFFFFFFE000003FFFFFFFFF8000003FFFFFFFFFF800003FFF
+FFFFFFFE00003FFC00000FFF80003FFC000003FFC0003FFC000001FFE0003FFC000000FF
+F0003FFC000000FFF8003FFC0000007FFC003FFC0000007FFC003FFC0000003FFE003FFC
+0000003FFE003FFC0000003FFF003FFC0000003FFF003FFC0000003FFF003FFC0000001F
+FF003FFC0000003FFF003FFC0000003FFF003FFC0000003FFF003FFC0000003FFF003FFC
+0000003FFE003FFC0000007FFE003FFC0000007FFE003FFC000000FFFC003FFC000001FF
+F8003FFC000003FFF8003FFC000007FFF0003FFC00003FFFE0FFFFFFFFFFFFFFC0FFFFFF
+FFFFFFFF00FFFFFFFFFFFFFC00FFFFFFFFFFFFF000FFFFFFFFFFFF0000403E7DBD4A>I<
+00000007FFC0000E000000FFFFFC001E000007FFFFFF003E00003FFFFFFFC07E0000FFFF
+FFFFE1FE0003FFFF803FFBFE0007FFF80003FFFE000FFFC00000FFFE003FFF0000007FFE
+007FFE0000001FFE00FFF80000000FFE01FFF000000007FE03FFE000000007FE03FFC000
+000003FE07FFC000000001FE0FFF8000000001FE0FFF8000000000FE1FFF0000000000FE
+1FFF00000000007E3FFF00000000007E3FFE00000000007E3FFE00000000003E7FFE0000
+0000003E7FFE00000000003E7FFE00000000003E7FFC000000000000FFFC000000000000
+FFFC000000000000FFFC000000000000FFFC000000000000FFFC000000000000FFFC0000
+00000000FFFC000000000000FFFC000000000000FFFC000000000000FFFC000000000000
+FFFC000000000000FFFC0000000000007FFC0000000000007FFE0000000000007FFE0000
+0000003E7FFE00000000003E3FFE00000000003E3FFE00000000003E3FFF00000000003E
+1FFF00000000007E1FFF00000000007C0FFF80000000007C0FFF8000000000FC07FFC000
+000000F803FFE000000001F803FFE000000001F001FFF000000003F000FFF800000007E0
+007FFE0000000FC0003FFF0000003F80000FFFC00000FF000007FFF80003FE000003FFFF
+801FFC000000FFFFFFFFF80000003FFFFFFFE000000007FFFFFF8000000000FFFFFC0000
+00000007FFC000003F407ABE4C>I<FFFFFFFFFFF8000000FFFFFFFFFFFF800000FFFFFF
+FFFFFFF00000FFFFFFFFFFFFFC0000FFFFFFFFFFFFFF0000003FFC00007FFFC000003FFC
+000007FFE000003FFC000001FFF000003FFC0000007FF800003FFC0000003FFC00003FFC
+0000001FFE00003FFC0000000FFF00003FFC00000007FF80003FFC00000007FF80003FFC
+00000003FFC0003FFC00000003FFC0003FFC00000001FFE0003FFC00000001FFE0003FFC
+00000001FFF0003FFC00000000FFF0003FFC00000000FFF0003FFC00000000FFF8003FFC
+00000000FFF8003FFC00000000FFF8003FFC00000000FFF8003FFC00000000FFFC003FFC
+00000000FFFC003FFC00000000FFFC003FFC00000000FFFC003FFC00000000FFFC003FFC
+000000007FFC003FFC000000007FFC003FFC000000007FFC003FFC00000000FFFC003FFC
+00000000FFFC003FFC00000000FFFC003FFC00000000FFFC003FFC00000000FFFC003FFC
+00000000FFF8003FFC00000000FFF8003FFC00000000FFF8003FFC00000000FFF8003FFC
+00000000FFF0003FFC00000000FFF0003FFC00000001FFF0003FFC00000001FFE0003FFC
+00000001FFE0003FFC00000003FFC0003FFC00000003FFC0003FFC00000007FF80003FFC
+0000000FFF00003FFC0000001FFF00003FFC0000003FFE00003FFC0000007FFC00003FFC
+000001FFF800003FFC000007FFE000003FFC00007FFFC000FFFFFFFFFFFFFF8000FFFFFF
+FFFFFFFE0000FFFFFFFFFFFFF80000FFFFFFFFFFFFC00000FFFFFFFFFFF8000000463E7D
+BD50>I<FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFF00
+FFFFFFFFFFFFFF80003FFE00003FFF80003FFE000007FF80003FFE000001FF80003FFE00
+0000FF80003FFE0000003F80003FFE0000003F80003FFE0000001F80003FFE0000000FC0
+003FFE0000000FC0003FFE0000000FC0003FFE00000007C0003FFE0007C007C0003FFE00
+07C007C0003FFE0007C007C0003FFE0007C003E0003FFE0007C003E0003FFE0007C003E0
+003FFE000FC003E0003FFE000FC00000003FFE001FC00000003FFE003FC00000003FFE00
+FFC00000003FFFFFFFC00000003FFFFFFFC00000003FFFFFFFC00000003FFFFFFFC00000
+003FFFFFFFC00000003FFE00FFC00000003FFE003FC00000003FFE001FC00000003FFE00
+0FC0007C003FFE000FC0007C003FFE0007C0007C003FFE0007C000F8003FFE0007C000F8
+003FFE0007C000F8003FFE0007C000F8003FFE0007C000F8003FFE00000001F8003FFE00
+000001F8003FFE00000001F0003FFE00000003F0003FFE00000003F0003FFE00000007F0
+003FFE00000007F0003FFE0000000FF0003FFE0000001FE0003FFE0000003FE0003FFE00
+0000FFE0003FFE000003FFE0003FFE00003FFFE0FFFFFFFFFFFFFFE0FFFFFFFFFFFFFFE0
+FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC03E3D7DBC45>I<FFFFFFFFFF
+FFFE00FFFFFFFFFFFFFE00FFFFFFFFFFFFFE00FFFFFFFFFFFFFE00FFFFFFFFFFFFFF0000
+3FFE00007FFF00003FFE00000FFF00003FFE000003FF00003FFE000000FF00003FFE0000
+007F00003FFE0000007F00003FFE0000003F00003FFE0000001F80003FFE0000001F8000
+3FFE0000001F80003FFE0000000F80003FFE0000000F80003FFE0007C00F80003FFE0007
+C00F80003FFE0007C007C0003FFE0007C007C0003FFE0007C007C0003FFE0007C007C000
+3FFE000FC00000003FFE000FC00000003FFE001FC00000003FFE003FC00000003FFE00FF
+C00000003FFFFFFFC00000003FFFFFFFC00000003FFFFFFFC00000003FFFFFFFC0000000
+3FFFFFFFC00000003FFE00FFC00000003FFE003FC00000003FFE001FC00000003FFE000F
+C00000003FFE000FC00000003FFE0007C00000003FFE0007C00000003FFE0007C0000000
+3FFE0007C00000003FFE0007C00000003FFE0007C00000003FFE0000000000003FFE0000
+000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000000000
+3FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000
+000000003FFE0000000000FFFFFFFFE0000000FFFFFFFFE0000000FFFFFFFFE0000000FF
+FFFFFFE0000000FFFFFFFFE00000003A3D7DBC42>I<00000007FFC0000E00000000FFFF
+FC001E00000007FFFFFF003E0000003FFFFFFFC07E000000FFFFFFFFE1FE000003FFFF80
+3FFBFE000007FFF80003FFFE00000FFFC00000FFFE00003FFF0000007FFE00007FFE0000
+001FFE0000FFF80000000FFE0001FFF000000007FE0003FFE000000007FE0003FFC00000
+0003FE0007FFC000000001FE000FFF8000000001FE000FFF8000000000FE001FFF000000
+0000FE001FFF00000000007E003FFF00000000007E003FFE00000000007E003FFE000000
+00003E007FFE00000000003E007FFE00000000003E007FFE00000000003E007FFC000000
+00000000FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC000000
+00000000FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC000000
+00000000FFFC00000000000000FFFC00000000000000FFFC00000000000000FFFC000007
+FFFFFFFC7FFC000007FFFFFFFC7FFE000007FFFFFFFC7FFE000007FFFFFFFC7FFE000007
+FFFFFFFC3FFE000000003FFE003FFE000000003FFE003FFF000000003FFE001FFF000000
+003FFE001FFF000000003FFE000FFF800000003FFE000FFF800000003FFE0007FFC00000
+003FFE0003FFE00000003FFE0003FFE00000003FFE0001FFF00000003FFE0000FFF80000
+003FFE00007FFE0000007FFE00003FFF8000007FFE00000FFFE00000FFFE000007FFF800
+03FFFE000003FFFF801FFFFE000000FFFFFFFFF3FE0000003FFFFFFFC0FE00000007FFFF
+FF803E00000000FFFFFE000E0000000007FFE000000046407ABE52>I<FFFFFFFF803FFF
+FFFFE0FFFFFFFF803FFFFFFFE0FFFFFFFF803FFFFFFFE0FFFFFFFF803FFFFFFFE0FFFFFF
+FF803FFFFFFFE0003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF80
+00003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000
+000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF800000
+3FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000F
+FF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE
+0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF80
+00003FFE0000000FFF8000003FFFFFFFFFFFFF8000003FFFFFFFFFFFFF8000003FFFFFFF
+FFFFFF8000003FFFFFFFFFFFFF8000003FFFFFFFFFFFFF8000003FFE0000000FFF800000
+3FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000F
+FF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE
+0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF80
+00003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000
+000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF800000
+3FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000FFF8000003FFE0000000F
+FF8000003FFE0000000FFF8000003FFE0000000FFF8000FFFFFFFF803FFFFFFFE0FFFFFF
+FF803FFFFFFFE0FFFFFFFF803FFFFFFFE0FFFFFFFF803FFFFFFFE0FFFFFFFF803FFFFFFF
+E04B3E7DBD52>I<FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF80003FFE
+0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE00
+00003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000
+003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE000000
+3FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003F
+FE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE
+0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE00
+00003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000003FFE0000
+003FFE0000FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF80FFFFFFFF80213E7DBD28>
+I<FFFFFFFF8000FFFFFF00FFFFFFFF8000FFFFFF00FFFFFFFF8000FFFFFF00FFFFFFFF80
+00FFFFFF00FFFFFFFF8000FFFFFF00003FFE00000001FC0000003FFE00000007F8000000
+3FFE0000000FF00000003FFE0000001FE00000003FFE0000003F800000003FFE0000007F
+000000003FFE000000FE000000003FFE000003FC000000003FFE000007F8000000003FFE
+00000FF0000000003FFE00001FC0000000003FFE00003F80000000003FFE00007F000000
+00003FFE0001FE00000000003FFE0003FC00000000003FFE0007F800000000003FFE000F
+E000000000003FFE001FC000000000003FFE003F8000000000003FFE00FF800000000000
+3FFE01FFC000000000003FFE03FFE000000000003FFE07FFE000000000003FFE0FFFF000
+000000003FFE1FFFF800000000003FFE7FFFFC00000000003FFEFFFFFC00000000003FFF
+FE7FFE00000000003FFFF83FFF00000000003FFFF03FFF80000000003FFFE01FFF800000
+00003FFFC00FFFC0000000003FFF8007FFE0000000003FFF0007FFF0000000003FFE0003
+FFF0000000003FFE0001FFF8000000003FFE0000FFFC000000003FFE0000FFFE00000000
+3FFE00007FFF000000003FFE00003FFF000000003FFE00001FFF800000003FFE00001FFF
+C00000003FFE00000FFFE00000003FFE000007FFE00000003FFE000003FFF00000003FFE
+000003FFF80000003FFE000001FFFC0000003FFE000000FFFC0000003FFE0000007FFE00
+00003FFE0000007FFF0000003FFE0000003FFF8000003FFE0000001FFF8000FFFFFFFF80
+07FFFFFFC0FFFFFFFF8007FFFFFFC0FFFFFFFF8007FFFFFFC0FFFFFFFF8007FFFFFFC0FF
+FFFFFF8007FFFFFFC04A3E7DBD52>75 D<FFFFFFFFE00000FFFFFFFFE00000FFFFFFFFE0
+0000FFFFFFFFE00000FFFFFFFFE00000003FFE00000000003FFE00000000003FFE000000
+00003FFE00000000003FFE00000000003FFE00000000003FFE00000000003FFE00000000
+003FFE00000000003FFE00000000003FFE00000000003FFE00000000003FFE0000000000
+3FFE00000000003FFE00000000003FFE00000000003FFE00000000003FFE00000000003F
+FE00000000003FFE00000000003FFE00000000003FFE00000000003FFE00000000003FFE
+00000000003FFE00000000003FFE00000000003FFE00000000003FFE00000000003FFE00
+000000003FFE00000000003FFE00000000003FFE0000003E003FFE0000003E003FFE0000
+003E003FFE0000003E003FFE0000007E003FFE0000007C003FFE0000007C003FFE000000
+7C003FFE0000007C003FFE000000FC003FFE000000FC003FFE000001FC003FFE000001FC
+003FFE000003F8003FFE000003F8003FFE000007F8003FFE00000FF8003FFE00001FF800
+3FFE00007FF8003FFE0001FFF8003FFE000FFFF8FFFFFFFFFFFFF8FFFFFFFFFFFFF0FFFF
+FFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF0373E7DBD3F>I<FFFFFF00000000001FFF
+FFC0FFFFFF80000000003FFFFFC0FFFFFF80000000003FFFFFC0FFFFFFC0000000007FFF
+FFC0FFFFFFC0000000007FFFFFC0003FFFC0000000007FFF0000003FFFE000000000F7FF
+0000003FFFE000000000F7FF0000003F7FF000000001E7FF0000003F7FF000000001E7FF
+0000003F3FF800000003C7FF0000003F3FF800000003C7FF0000003F3FF800000003C7FF
+0000003F1FFC0000000787FF0000003F1FFC0000000787FF0000003F0FFE0000000F07FF
+0000003F0FFE0000000F07FF0000003F07FF0000001E07FF0000003F07FF0000001E07FF
+0000003F07FF0000001E07FF0000003F03FF8000003C07FF0000003F03FF8000003C07FF
+0000003F01FFC000007807FF0000003F01FFC000007807FF0000003F00FFE00000F007FF
+0000003F00FFE00000F007FF0000003F007FF00001E007FF0000003F007FF00001E007FF
+0000003F007FF00001E007FF0000003F003FF80003C007FF0000003F003FF80003C007FF
+0000003F001FFC00078007FF0000003F001FFC00078007FF0000003F000FFE000F0007FF
+0000003F000FFE000F0007FF0000003F000FFE000F0007FF0000003F0007FF001E0007FF
+0000003F0007FF001E0007FF0000003F0003FF803C0007FF0000003F0003FF803C0007FF
+0000003F0001FFC0780007FF0000003F0001FFC0780007FF0000003F0000FFE0F00007FF
+0000003F0000FFE0F00007FF0000003F0000FFE0F00007FF0000003F00007FF1E00007FF
+0000003F00007FF1E00007FF0000003F00003FFBC00007FF0000003F00003FFBC00007FF
+0000003F00001FFF800007FF0000003F00001FFF800007FF0000003F00001FFF800007FF
+0000003F00000FFF000007FF0000003F00000FFF000007FF0000003F000007FE000007FF
+0000003F000007FE000007FF0000003F000003FC000007FF0000FFFFFFC003FC001FFFFF
+FFC0FFFFFFC003FC001FFFFFFFC0FFFFFFC001F8001FFFFFFFC0FFFFFFC001F8001FFFFF
+FFC0FFFFFFC000F0001FFFFFFFC05A3E7CBD63>I<FFFFFF0000007FFFFFE0FFFFFF0000
+007FFFFFE0FFFFFF8000007FFFFFE0FFFFFFC000007FFFFFE0FFFFFFE000007FFFFFE000
+3FFFF00000001F8000003FFFF80000001F8000003FFFF80000001F8000003FFFFC000000
+1F8000003FFFFE0000001F8000003F7FFF0000001F8000003F3FFF8000001F8000003F1F
+FFC000001F8000003F0FFFC000001F8000003F0FFFE000001F8000003F07FFF000001F80
+00003F03FFF800001F8000003F01FFFC00001F8000003F00FFFE00001F8000003F007FFE
+00001F8000003F007FFF00001F8000003F003FFF80001F8000003F001FFFC0001F800000
+3F000FFFE0001F8000003F0007FFF0001F8000003F0003FFF0001F8000003F0003FFF800
+1F8000003F0001FFFC001F8000003F0000FFFE001F8000003F00007FFF001F8000003F00
+003FFF801F8000003F00003FFF801F8000003F00001FFFC01F8000003F00000FFFE01F80
+00003F000007FFF01F8000003F000003FFF81F8000003F000001FFFC1F8000003F000001
+FFFC1F8000003F000000FFFE1F8000003F0000007FFF1F8000003F0000003FFF9F800000
+3F0000001FFFDF8000003F0000000FFFDF8000003F0000000FFFFF8000003F00000007FF
+FF8000003F00000003FFFF8000003F00000001FFFF8000003F00000000FFFF8000003F00
+0000007FFF8000003F000000007FFF8000003F000000003FFF8000003F000000001FFF80
+00003F000000000FFF8000003F0000000007FF8000003F0000000003FF8000003F000000
+0003FF8000003F0000000001FF8000FFFFFFC0000000FF8000FFFFFFC00000007F8000FF
+FFFFC00000003F8000FFFFFFC00000001F8000FFFFFFC00000001F80004B3E7DBD52>I<
+0000003FFF00000000000003FFFFF000000000001FFFFFFE00000000007FFFFFFF800000
+0001FFF807FFE000000007FFC000FFF80000000FFF00003FFC0000003FFC00000FFF0000
+007FF8000007FF800000FFF0000003FFC00001FFE0000001FFE00001FFC0000000FFE000
+03FFC0000000FFF00007FF800000007FF80007FF800000007FF8000FFF000000003FFC00
+1FFF000000003FFE001FFF000000003FFE001FFE000000001FFE003FFE000000001FFF00
+3FFE000000001FFF003FFE000000001FFF007FFC000000000FFF807FFC000000000FFF80
+7FFC000000000FFF807FFC000000000FFF80FFFC000000000FFFC0FFFC000000000FFFC0
+FFFC000000000FFFC0FFFC000000000FFFC0FFFC000000000FFFC0FFFC000000000FFFC0
+FFFC000000000FFFC0FFFC000000000FFFC0FFFC000000000FFFC0FFFC000000000FFFC0
+FFFC000000000FFFC0FFFC000000000FFFC0FFFC000000000FFFC07FFC000000000FFF80
+7FFE000000001FFF807FFE000000001FFF807FFE000000001FFF803FFE000000001FFF00
+3FFE000000001FFF003FFF000000003FFF001FFF000000003FFE001FFF000000003FFE00
+0FFF800000007FFC000FFF800000007FFC0007FFC0000000FFF80003FFE0000001FFF000
+03FFE0000001FFF00001FFF0000003FFE00000FFF8000007FFC000007FFC00000FFF8000
+003FFF00003FFF0000001FFFC000FFFE00000007FFF807FFF800000001FFFFFFFFE00000
+0000FFFFFFFFC0000000001FFFFFFE000000000003FFFFF00000000000003FFF00000000
+42407ABE4F>I<FFFFFFFFFFF00000FFFFFFFFFFFF0000FFFFFFFFFFFFC000FFFFFFFFFF
+FFF000FFFFFFFFFFFFFC00003FFC0000FFFE00003FFC00001FFF00003FFC00000FFF8000
+3FFC000007FFC0003FFC000003FFE0003FFC000003FFE0003FFC000001FFF0003FFC0000
+01FFF0003FFC000001FFF0003FFC000001FFF8003FFC000001FFF8003FFC000001FFF800
+3FFC000001FFF8003FFC000001FFF8003FFC000001FFF8003FFC000001FFF8003FFC0000
+01FFF8003FFC000001FFF0003FFC000001FFF0003FFC000001FFF0003FFC000003FFE000
+3FFC000003FFC0003FFC000007FFC0003FFC00000FFF80003FFC00003FFF00003FFC0000
+FFFE00003FFFFFFFFFF800003FFFFFFFFFF000003FFFFFFFFF8000003FFFFFFFFC000000
+3FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000
+000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000000000
+3FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000
+000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000000000
+3FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000FFFFFFFF80
+000000FFFFFFFF80000000FFFFFFFF80000000FFFFFFFF80000000FFFFFFFF800000003D
+3E7DBD47>I<FFFFFFFFFF8000000000FFFFFFFFFFFC00000000FFFFFFFFFFFF80000000
+FFFFFFFFFFFFF0000000FFFFFFFFFFFFF8000000003FFC0001FFFE000000003FFC00003F
+FF000000003FFC00000FFF800000003FFC000007FFC00000003FFC000003FFE00000003F
+FC000003FFE00000003FFC000003FFF00000003FFC000001FFF00000003FFC000001FFF8
+0000003FFC000001FFF80000003FFC000001FFF80000003FFC000001FFF80000003FFC00
+0001FFF80000003FFC000001FFF80000003FFC000001FFF80000003FFC000001FFF00000
+003FFC000001FFF00000003FFC000003FFF00000003FFC000003FFE00000003FFC000003
+FFC00000003FFC000007FF800000003FFC00000FFF000000003FFC00003FFE000000003F
+FC0001FFFC000000003FFFFFFFFFF0000000003FFFFFFFFFC0000000003FFFFFFFFE0000
+0000003FFFFFFFFF80000000003FFC000FFFC0000000003FFC0001FFF0000000003FFC00
+00FFF8000000003FFC00007FFC000000003FFC00007FFC000000003FFC00003FFE000000
+003FFC00003FFE000000003FFC00001FFF000000003FFC00001FFF000000003FFC00001F
+FF000000003FFC00001FFF000000003FFC00001FFF000000003FFC00001FFF000000003F
+FC00001FFF800000003FFC00001FFF800000003FFC00001FFF800000003FFC00001FFF80
+0000003FFC00001FFF800000003FFC00001FFF800000003FFC00001FFF8007C0003FFC00
+001FFFC007C0003FFC00001FFFC007C0003FFC00000FFFC00FC0003FFC00000FFFE00F80
+FFFFFFFF0007FFF01F80FFFFFFFF0003FFFC3F00FFFFFFFF0001FFFFFF00FFFFFFFF0000
+7FFFFE00FFFFFFFF00001FFFF80000000000000001FFE0004A3F7DBD4E>82
+D<0003FFC001C0001FFFF803C0007FFFFE07C001FFFFFF8FC003FFFFFFDFC007FF00FFFF
+C00FF8000FFFC01FF00003FFC01FE00001FFC03FC000007FC07FC000007FC07F8000003F
+C07F8000001FC0FF8000001FC0FF8000000FC0FF8000000FC0FFC000000FC0FFC0000007
+C0FFC0000007C0FFE0000007C0FFF0000007C0FFFC00000000FFFF800000007FFFF80000
+007FFFFFC000003FFFFFFC00003FFFFFFF80001FFFFFFFE0001FFFFFFFF8000FFFFFFFFC
+0007FFFFFFFE0003FFFFFFFF0001FFFFFFFF80007FFFFFFFC0003FFFFFFFC00007FFFFFF
+E000007FFFFFE0000007FFFFF00000003FFFF000000003FFF000000000FFF8000000007F
+F8000000003FF8780000003FF8F80000001FF8F80000001FF8F80000000FF8F80000000F
+F8FC0000000FF8FC0000000FF8FC0000000FF0FE0000000FF0FE0000001FF0FF0000001F
+E0FF8000003FE0FFE000003FC0FFF800007F80FFFE0001FF80FFFFE007FF00FEFFFFFFFE
+00FC7FFFFFF800F81FFFFFF000F003FFFFC000E0003FFE00002D407ABE3A>I<3FFFFFFF
+FFFFFFFC3FFFFFFFFFFFFFFC3FFFFFFFFFFFFFFC3FFFFFFFFFFFFFFC3FFFFFFFFFFFFFFC
+3FFE003FFE003FFC7FF0003FFE000FFE7FC0003FFE0003FE7F80003FFE0001FE7F00003F
+FE0000FE7F00003FFE00007E7E00003FFE00007E7E00003FFE00007E7C00003FFE00003E
+7C00003FFE00003E7C00003FFE00003E7C00003FFE00003EFC00003FFE00003FF800003F
+FE00001FF800003FFE00001FF800003FFE00001FF800003FFE00001FF800003FFE00001F
+0000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003F
+FE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000
+0000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003F
+FE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000
+0000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003F
+FE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003FFE000000
+0000003FFE0000000000003FFE0000000000003FFE0000000000003FFE0000000000003F
+FE0000000000003FFE000000000FFFFFFFFFF800000FFFFFFFFFF800000FFFFFFFFFF800
+000FFFFFFFFFF800000FFFFFFFFFF800403D7CBC49>I<FFFFFFFF8000FFFFFF80FFFFFF
+FF8000FFFFFF80FFFFFFFF8000FFFFFF80FFFFFFFF8000FFFFFF80FFFFFFFF8000FFFFFF
+80003FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE0000
+00003E0000003FFE000000003E0000003FFE000000003E0000003FFE000000003E000000
+3FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE00000000
+3E0000003FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE
+000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE000000003E00
+00003FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE0000
+00003E0000003FFE000000003E0000003FFE000000003E0000003FFE000000003E000000
+3FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE00000000
+3E0000003FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE
+000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE000000003E00
+00003FFE000000003E0000003FFE000000003E0000003FFE000000003E0000003FFE0000
+00003E0000003FFE000000007E0000001FFE000000007C0000001FFF000000007C000000
+1FFF000000007C0000000FFF00000000FC0000000FFF00000000F800000007FF80000001
+F800000007FF80000003F000000003FFC0000007E000000001FFE000000FE000000000FF
+F800003FC0000000007FFE0000FF80000000003FFFC00FFF00000000000FFFFFFFFC0000
+00000003FFFFFFF8000000000000FFFFFFE00000000000001FFFFF8000000000000001FF
+F800000000493F7DBD50>I<FFFFFFFC00000FFFFFC0FFFFFFFC00000FFFFFC0FFFFFFFC
+00000FFFFFC0FFFFFFFC00000FFFFFC0FFFFFFFC00000FFFFFC0007FFE000000001F8000
+003FFE000000001F0000003FFF000000001F0000003FFF000000003F0000001FFF000000
+003E0000001FFF800000007E0000000FFF800000007C0000000FFFC0000000FC00000007
+FFC0000000F800000007FFE0000000F800000007FFE0000001F800000003FFF0000001F0
+00000003FFF0000003F000000001FFF0000003E000000001FFF8000007E000000000FFF8
+000007C000000000FFFC00000FC0000000007FFC00000F80000000007FFE00000F800000
+00007FFE00001F80000000003FFE00001F00000000003FFF00003F00000000001FFF0000
+3E00000000001FFF80007E00000000000FFF80007C00000000000FFFC0007C0000000000
+0FFFC000FC000000000007FFE000F8000000000007FFE001F8000000000003FFE001F000
+0000000003FFF003F0000000000001FFF003E0000000000001FFF807E0000000000000FF
+F807C0000000000000FFFC07C0000000000000FFFC0FC00000000000007FFC0F80000000
+0000007FFE1F800000000000003FFE1F000000000000003FFF3F000000000000001FFF3E
+000000000000001FFFBE000000000000001FFFFE000000000000000FFFFC000000000000
+000FFFFC0000000000000007FFF80000000000000007FFF80000000000000003FFF00000
+000000000003FFF00000000000000001FFE00000000000000001FFE00000000000000001
+FFE00000000000000000FFC00000000000000000FFC000000000000000007F8000000000
+000000007F8000000000000000003F0000000000000000003F00000000004A3F7EBD4F>
+I<FFFFFFFC03FFFFFFF000FFFFFEFFFFFFFC03FFFFFFF000FFFFFEFFFFFFFC03FFFFFFF0
+00FFFFFEFFFFFFFC03FFFFFFF000FFFFFEFFFFFFFC03FFFFFFF000FFFFFE00FFFC000003
+FFF00000007E00007FFC000001FFF00000007C00007FFC000001FFF80000007C00007FFE
+000000FFF8000000FC00003FFE000000FFF8000000F800003FFE000000FFFC000000F800
+001FFF0000007FFC000001F000001FFF0000007FFC000001F000001FFF800000FFFE0000
+03F000000FFF800000FFFE000003E000000FFF800001FFFF000003E000000FFFC00001FF
+FF000007E0000007FFC00001FFFF000007C0000007FFC00003FFFF800007C0000007FFE0
+0003EFFF80000FC0000003FFE00003EFFF80000F80000003FFF00007EFFFC0001F800000
+01FFF00007C7FFC0001F00000001FFF0000FC7FFE0001F00000001FFF8000F83FFE0003F
+00000000FFF8000F83FFE0003E00000000FFF8001F83FFF0003E00000000FFFC001F01FF
+F0007E000000007FFC001F01FFF0007C000000007FFE003F01FFF800FC000000003FFE00
+3E00FFF800F8000000003FFE007E00FFFC00F8000000003FFF007C007FFC01F800000000
+1FFF007C007FFC01F0000000001FFF00FC007FFE01F0000000001FFF80F8003FFE03F000
+0000000FFF80F8003FFE03E0000000000FFFC1F8003FFF07E00000000007FFC1F0001FFF
+07C00000000007FFC3F0001FFF87C00000000007FFE3E0000FFF8FC00000000003FFE3E0
+000FFF8F800000000003FFE7E0000FFFCF800000000003FFF7C00007FFDF800000000001
+FFF7C00007FFDF000000000001FFFFC00007FFFF000000000000FFFF800003FFFE000000
+000000FFFF800003FFFE000000000000FFFF000001FFFE0000000000007FFF000001FFFC
+0000000000007FFF000001FFFC0000000000007FFE000000FFFC0000000000003FFE0000
+00FFF80000000000003FFE000000FFF80000000000001FFC0000007FF00000000000001F
+FC0000007FF00000000000001FF80000003FF00000000000000FF80000003FE000000000
+00000FF80000003FE00000000000000FF00000001FE000000000000007F00000001FC000
+000000000007F00000001FC000000000000003E00000000F80000000673F7EBD6C>I<7F
+FFFFFF003FFFFFF07FFFFFFF003FFFFFF07FFFFFFF003FFFFFF07FFFFFFF003FFFFFF07F
+FFFFFF003FFFFFF0001FFFC000003F0000000FFFE000007E0000000FFFE00000FE000000
+07FFF00000FC00000003FFF80001F800000001FFF80003F000000001FFFC0007F0000000
+00FFFE0007E0000000007FFF000FC0000000007FFF001F80000000003FFF803F80000000
+001FFFC03F00000000000FFFC07E00000000000FFFE0FC000000000007FFF1FC00000000
+0003FFF9F8000000000001FFFBF0000000000001FFFFE0000000000000FFFFE000000000
+00007FFFC00000000000007FFF800000000000003FFF800000000000001FFFC000000000
+00000FFFC00000000000000FFFE000000000000007FFF000000000000003FFF000000000
+000003FFF800000000000007FFFC0000000000000FFFFE0000000000001FFFFE00000000
+00001FFFFF0000000000003F3FFF8000000000007E1FFF800000000000FE1FFFC0000000
+0000FC0FFFE00000000001F807FFF00000000003F003FFF00000000007F003FFF8000000
+0007E001FFFC000000000FC000FFFC000000001F8000FFFE000000003F80007FFF000000
+003F00003FFF800000007E00001FFF80000000FC00001FFFC0000001FC00000FFFE00000
+01F8000007FFF0000003F0000007FFF0000007E0000003FFF800000FE0000001FFFC0000
+0FC0000000FFFC00FFFFFFC0007FFFFFFFFFFFFFC0007FFFFFFFFFFFFFC0007FFFFFFFFF
+FFFFC0007FFFFFFFFFFFFFC0007FFFFFFF483E7DBD4F>I<FFFFFFFE00000FFFFFC0FFFF
+FFFE00000FFFFFC0FFFFFFFE00000FFFFFC0FFFFFFFE00000FFFFFC0FFFFFFFE00000FFF
+FFC0007FFF000000001F8000003FFF800000003F0000001FFFC00000007E0000001FFFC0
+0000007E0000000FFFE0000000FC00000007FFF0000001F800000007FFF8000001F80000
+0003FFF8000003F000000001FFFC000007E000000001FFFE000007E000000000FFFE0000
+0FC0000000007FFF00001F80000000003FFF80001F80000000003FFF80003F0000000000
+1FFFC0007E00000000000FFFE0007E00000000000FFFE000FC000000000007FFF001F800
+0000000003FFF801F8000000000003FFF803F0000000000001FFFC07E0000000000000FF
+FE07E0000000000000FFFF0FC00000000000007FFF1F800000000000003FFF9F80000000
+0000003FFFFF000000000000001FFFFE000000000000000FFFFE000000000000000FFFFC
+0000000000000007FFF80000000000000003FFF80000000000000001FFF0000000000000
+0001FFE00000000000000001FFE00000000000000001FFE00000000000000001FFE00000
+000000000001FFE00000000000000001FFE00000000000000001FFE00000000000000001
+FFE00000000000000001FFE00000000000000001FFE00000000000000001FFE000000000
+00000001FFE00000000000000001FFE00000000000000001FFE00000000000000001FFE0
+0000000000000001FFE00000000000000001FFE00000000000000001FFE0000000000000
+0001FFE00000000000000001FFE000000000000007FFFFFFF8000000000007FFFFFFF800
+0000000007FFFFFFF8000000000007FFFFFFF8000000000007FFFFFFF80000004A3E7EBD
+4F>I<0007FFC00000003FFFF8000001FFFFFF000003FFFFFF800007FE03FFC0000FF800
+FFE0000FFC003FF0001FFE003FF8001FFE001FFC001FFE001FFC001FFE001FFC001FFE00
+0FFE001FFE000FFE000FFC000FFE0007F8000FFE0001E0000FFE000000000FFE00000000
+3FFE000000FFFFFE00000FFFFFFE00007FFFFFFE0001FFFE0FFE0003FFE00FFE000FFF80
+0FFE001FFE000FFE003FFC000FFE003FF8000FFE007FF0000FFE00FFF0000FFE00FFE000
+0FFE00FFE0000FFE00FFE0000FFE00FFE0000FFE00FFE0001FFE00FFF0001FFE007FF000
+3FFE007FF8007BFF803FFC00FBFFFE1FFF07F3FFFE0FFFFFE1FFFE03FFFF80FFFE00FFFF
+003FFE001FF80000002F2B7DA933>97 D<00FF0000000000FFFF0000000000FFFF000000
+0000FFFF0000000000FFFF0000000000FFFF000000000007FF000000000003FF00000000
+0003FF000000000003FF000000000003FF000000000003FF000000000003FF0000000000
+03FF000000000003FF000000000003FF000000000003FF000000000003FF000000000003
+FF000000000003FF000000000003FF000000000003FF000000000003FF00FFE0000003FF
+07FFFC000003FF1FFFFF800003FF7FFFFFC00003FFFF81FFF00003FFFC003FF80003FFF0
+001FFC0003FFE0000FFE0003FFC00007FE0003FF800007FF0003FF800003FF8003FF8000
+03FF8003FF800003FFC003FF800001FFC003FF800001FFC003FF800001FFC003FF800001
+FFE003FF800001FFE003FF800001FFE003FF800001FFE003FF800001FFE003FF800001FF
+E003FF800001FFE003FF800001FFE003FF800001FFE003FF800001FFE003FF800001FFC0
+03FF800001FFC003FF800003FFC003FF800003FF8003FF800003FF8003FF800003FF0003
+FF800007FF0003FFC00007FE0003FFE0000FFC0003FFF0001FF80003FFFC007FF00003FC
+FF01FFE00003F87FFFFFC00003F01FFFFF000003E007FFFC0000000001FFC0000033407D
+BE3A>I<00007FF0000007FFFF00001FFFFFC0007FFFFFE000FFF01FF001FF800FF803FF
+001FF807FE003FFC0FFE003FFC1FFC003FFC1FFC003FFC3FF8003FFC3FF8003FFC7FF800
+1FF87FF0000FF07FF00003C0FFF0000000FFF0000000FFF0000000FFF0000000FFF00000
+00FFF0000000FFF0000000FFF0000000FFF0000000FFF0000000FFF00000007FF0000000
+7FF80000007FF80000007FF80000003FF800003E3FFC00003E1FFC00007E0FFE00007C07
+FF0000FC07FF8001F803FFC003F000FFF81FE0007FFFFFC0001FFFFF800007FFFE000000
+7FF000272B7DA92E>I<0000000007F80000000007FFF80000000007FFF80000000007FF
+F80000000007FFF80000000007FFF800000000003FF800000000001FF800000000001FF8
+00000000001FF800000000001FF800000000001FF800000000001FF800000000001FF800
+000000001FF800000000001FF800000000001FF800000000001FF800000000001FF80000
+0000001FF800000000001FF800000000001FF80000007FF01FF8000007FFFE1FF800001F
+FFFF9FF800007FFFFFDFF80000FFF01FFFF80001FFC003FFF80003FF0001FFF80007FE00
+007FF8000FFC00007FF8001FFC00003FF8001FF800003FF8003FF800003FF8003FF80000
+3FF8007FF800003FF8007FF000003FF8007FF000003FF800FFF000003FF800FFF000003F
+F800FFF000003FF800FFF000003FF800FFF000003FF800FFF000003FF800FFF000003FF8
+00FFF000003FF800FFF000003FF800FFF000003FF8007FF000003FF8007FF000003FF800
+7FF000003FF8007FF800003FF8003FF800003FF8003FF800003FF8001FFC00007FF8000F
+FC00007FF8000FFE0000FFF80007FF0003FFFC0003FF8007FFFFE001FFF03FFFFFE0007F
+FFFFBFFFE0003FFFFF3FFFE00007FFFC3FFFE00000FFE03FE00033407DBE3A>I<0000FF
+F000000007FFFE0000001FFFFF8000007FFFFFC00000FFE07FE00001FF801FF00003FF00
+0FF80007FE0007FC000FFC0003FE001FFC0003FE001FF80001FE003FF80001FF003FF800
+01FF007FF00001FF007FF00000FF807FF00000FF80FFF00000FF80FFF00000FF80FFFFFF
+FFFF80FFFFFFFFFF80FFFFFFFFFF80FFFFFFFFFF80FFF000000000FFF000000000FFF000
+000000FFF000000000FFF0000000007FF0000000007FF0000000007FF8000000003FF800
+0000003FF800000F801FFC00000F801FFC00001F800FFE00001F0007FF00003F0003FF80
+007E0001FFE001FC0000FFF80FF800003FFFFFF000001FFFFFC0000003FFFF000000007F
+F80000292B7DA930>I<000007FE0000007FFF800001FFFFC00007FFFFE0000FFE3FF000
+1FF03FF0003FE07FF8007FC07FF800FFC07FF800FF807FF800FF807FF801FF003FF001FF
+001FE001FF000FC001FF00000001FF00000001FF00000001FF00000001FF00000001FF00
+000001FF00000001FF00000001FF00000001FF000000FFFFFFE000FFFFFFE000FFFFFFE0
+00FFFFFFE000FFFFFFE00001FF80000001FF80000001FF80000001FF80000001FF800000
+01FF80000001FF80000001FF80000001FF80000001FF80000001FF80000001FF80000001
+FF80000001FF80000001FF80000001FF80000001FF80000001FF80000001FF80000001FF
+80000001FF80000001FF80000001FF80000001FF80000001FF80000001FF80000001FF80
+000001FF80000001FF80000001FF8000007FFFFF80007FFFFF80007FFFFF80007FFFFF80
+007FFFFF800025407DBF20>I<0003FF8007F0003FFFF83FF8007FFFFCFFFC01FFFFFFFF
+FE03FF83FFF9FE07FC007FC3FE0FF8003FE1FE1FF8003FF1FC1FF0001FF0F81FF0001FF0
+003FF0001FF8003FF0001FF8003FF0001FF8003FF0001FF8003FF0001FF8003FF0001FF8
+003FF0001FF8001FF0001FF0001FF0001FF0001FF8003FF0000FF8003FE00007FC007FC0
+0003FF83FF800003FFFFFF000007FFFFFC000007BFFFF800000F03FF8000000F00000000
+000F00000000001F80000000001F80000000001FC0000000001FF0000000000FFFFFFF00
+000FFFFFFFF0000FFFFFFFFC0007FFFFFFFF0007FFFFFFFF8003FFFFFFFFC001FFFFFFFF
+E007FFFFFFFFE01FFFFFFFFFF03FE00003FFF07FC000003FF07F8000001FF8FF8000000F
+F8FF00000007F8FF00000007F8FF00000007F8FF00000007F8FF00000007F87F8000000F
+F07FC000001FF03FC000001FE03FF000007FE01FFC0001FFC007FF800FFF0003FFFFFFFE
+0000FFFFFFF800003FFFFFE0000001FFFC00002F3D7DA834>I<00FF0000000000FFFF00
+00000000FFFF0000000000FFFF0000000000FFFF0000000000FFFF000000000007FF0000
+00000003FF000000000003FF000000000003FF000000000003FF000000000003FF000000
+000003FF000000000003FF000000000003FF000000000003FF000000000003FF00000000
+0003FF000000000003FF000000000003FF000000000003FF000000000003FF0000000000
+03FF001FF8000003FF00FFFE000003FF03FFFF800003FF07FFFFC00003FF0FE0FFE00003
+FF1F007FE00003FF3C007FF00003FF78007FF00003FFF0003FF80003FFE0003FF80003FF
+E0003FF80003FFC0003FF80003FFC0003FF80003FFC0003FF80003FF80003FF80003FF80
+003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF8000
+3FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003F
+F80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF8
+0003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF800
+FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE033
+3F7CBE3A>I<01F80003FC0007FE000FFF001FFF801FFF801FFF801FFF801FFF801FFF80
+0FFF0007FE0003FC0001F800000000000000000000000000000000000000000000000000
+00000000FF00FFFF00FFFF00FFFF00FFFF00FFFF0007FF0003FF0003FF0003FF0003FF00
+03FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF00
+03FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF00
+03FF00FFFFF8FFFFF8FFFFF8FFFFF8FFFFF815407CBF1D>I<00FF00FFFF00FFFF00FFFF
+00FFFF00FFFF0007FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF
+0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF
+0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF
+0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF0003FF
+0003FF0003FF0003FF0003FF0003FF0003FF00FFFFFCFFFFFCFFFFFCFFFFFCFFFFFC163F
+7CBE1D>108 D<00FF001FF80000FFC00000FFFF00FFFF0007FFF80000FFFF03FFFFC01F
+FFFE0000FFFF07FFFFE03FFFFF0000FFFF0FE0FFF07F07FF8000FFFF1F003FF0F801FF80
+0007FF3E003FF9F001FFC00003FF78003FFBC001FFC00003FFF0001FFF8000FFE00003FF
+F0001FFF8000FFE00003FFE0001FFF0000FFE00003FFC0001FFE0000FFE00003FFC0001F
+FE0000FFE00003FFC0001FFE0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000
+FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE000
+03FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80
+001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC
+0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FF
+E00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003
+FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF80001FFC0000FFE00003FF8000
+1FFC0000FFE000FFFFFE07FFFFF03FFFFF80FFFFFE07FFFFF03FFFFF80FFFFFE07FFFFF0
+3FFFFF80FFFFFE07FFFFF03FFFFF80FFFFFE07FFFFF03FFFFF8051297CA858>I<00FF00
+1FF80000FFFF00FFFE0000FFFF03FFFF8000FFFF07FFFFC000FFFF0FE0FFE000FFFF1F00
+7FE00007FF3C007FF00003FF78007FF00003FFF0003FF80003FFE0003FF80003FFE0003F
+F80003FFC0003FF80003FFC0003FF80003FFC0003FF80003FF80003FF80003FF80003FF8
+0003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF800
+03FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003
+FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF
+80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF800FFFFFE
+0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE0FFFFFE033297CA8
+3A>I<00007FF000000003FFFE0000001FFFFFC000007FFFFFF00000FFE03FF80001FF80
+0FFC0003FE0003FE0007FC0001FF000FFC0001FF801FF80000FFC01FF80000FFC03FF800
+00FFE03FF000007FE07FF000007FF07FF000007FF07FF000007FF07FF000007FF0FFF000
+007FF8FFF000007FF8FFF000007FF8FFF000007FF8FFF000007FF8FFF000007FF8FFF000
+007FF8FFF000007FF8FFF000007FF8FFF000007FF87FF000007FF07FF000007FF07FF000
+007FF07FF000007FF03FF80000FFE03FF80000FFE01FF80000FFC00FFC0001FF800FFC00
+01FF8007FE0003FF0003FF800FFE0001FFE03FFC00007FFFFFF000001FFFFFC0000007FF
+FF000000007FF000002D2B7DA934>I<00FF00FFE00000FFFF07FFFC0000FFFF1FFFFF80
+00FFFF7FFFFFC000FFFFFF81FFF000FFFFFC007FF80003FFF0003FFC0003FFE0001FFE00
+03FFC0000FFE0003FF800007FF0003FF800007FF8003FF800007FF8003FF800003FFC003
+FF800003FFC003FF800003FFC003FF800001FFC003FF800001FFE003FF800001FFE003FF
+800001FFE003FF800001FFE003FF800001FFE003FF800001FFE003FF800001FFE003FF80
+0001FFE003FF800001FFE003FF800001FFE003FF800003FFC003FF800003FFC003FF8000
+03FFC003FF800003FF8003FF800007FF8003FF800007FF0003FF80000FFF0003FFC0000F
+FE0003FFE0001FFC0003FFF0003FF80003FFFC00FFF00003FFFF03FFE00003FFFFFFFFC0
+0003FF9FFFFF000003FF87FFFC000003FF81FFC0000003FF800000000003FF8000000000
+03FF800000000003FF800000000003FF800000000003FF800000000003FF800000000003
+FF800000000003FF800000000003FF800000000003FF800000000003FF8000000000FFFF
+FE00000000FFFFFE00000000FFFFFE00000000FFFFFE00000000FFFFFE00000000333B7D
+A83A>I<01FE01FE00FFFE07FF80FFFE0FFFE0FFFE1FFFF0FFFE3F1FF0FFFE7C3FF807FE
+F83FF803FEF03FF803FFE03FF803FFE03FF803FFC01FF003FFC00FE003FF8007C003FF80
+000003FF80000003FF80000003FF00000003FF00000003FF00000003FF00000003FF0000
+0003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF000000
+03FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003
+FF000000FFFFFF0000FFFFFF0000FFFFFF0000FFFFFF0000FFFFFF000025297DA82B>
+114 D<003FFC1E0001FFFFBE0007FFFFFE000FFFFFFE001FF00FFE003F8001FE007F0000
+FE007E00007E007E00007E00FE00003E00FE00003E00FF00003E00FF80003E00FFC00000
+00FFF8000000FFFFE000007FFFFF00007FFFFFC0003FFFFFF0001FFFFFF8000FFFFFFC00
+07FFFFFE0003FFFFFF0000FFFFFF80001FFFFF800000FFFF80000007FFC0000000FFC078
+00007FC0F800003FC0F800001FC0FC00001FC0FC00001FC0FE00001FC0FE00001F80FF00
+003F80FF80003F00FFE000FF00FFF803FE00FFFFFFFC00FFFFFFF000F87FFFC000E00FFE
+0000222B7DA929>I<0007C0000007C0000007C0000007C0000007C000000FC000000FC0
+00000FC000000FC000001FC000001FC000001FC000003FC000007FC000007FC00000FFC0
+0001FFC00007FFC0001FFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFE01FFC00001FFC0
+0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0
+0001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC00001FFC0
+1F01FFC01F01FFC01F01FFC01F01FFC01F01FFC01F01FFC01F01FFC01F01FFC01F00FFE0
+3E00FFE03E007FE07E007FF8FC003FFFF8001FFFF00007FFE00000FF80203B7EB929>I<
+00FF80000FF800FFFF800FFFF800FFFF800FFFF800FFFF800FFFF800FFFF800FFFF800FF
+FF800FFFF80007FF80007FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF
+80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80
+003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF8000
+3FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003F
+F80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80003FF80007FF8
+0003FF80007FF80003FF80007FF80003FF8000FFF80001FF8001FFF80001FF8003FFFC00
+00FFC007DFFFE000FFF01F9FFFE0007FFFFF1FFFE0003FFFFE1FFFE0000FFFF81FFFE000
+01FFE01FE000332A7CA83A>I<FFFFFC003FFFC0FFFFFC003FFFC0FFFFFC003FFFC0FFFF
+FC003FFFC0FFFFFC003FFFC001FFC00003E00001FFE00007E00001FFE00007E00000FFE0
+0007C00000FFF0000FC000007FF0000F8000007FF8001F8000003FF8001F0000003FFC00
+3F0000001FFC003E0000001FFE007E0000000FFE007C0000000FFF00FC0000000FFF00FC
+00000007FF00F800000007FF81F800000003FF81F000000003FFC3F000000001FFC3E000
+000001FFE7E000000000FFE7C000000000FFFFC0000000007FFF80000000007FFF800000
+00007FFF80000000003FFF00000000003FFF00000000001FFE00000000001FFE00000000
+000FFC00000000000FFC000000000007F8000000000007F8000000000003F00000000000
+03F000000032287EA737>I<FFFFFC3FFFFC03FFFEFFFFFC3FFFFC03FFFEFFFFFC3FFFFC
+03FFFEFFFFFC3FFFFC03FFFEFFFFFC3FFFFC03FFFE03FF8000FFC0000F8003FFC000FFC0
+001F8001FFC0007FC0001F0001FFE000FFE0003F0000FFE000FFE0003E0000FFE000FFF0
+003E0000FFF001FFF0007E00007FF001FFF0007C00007FF803FFF800FC00003FF803EFF8
+00F800003FF803EFFC00F800003FFC07EFFC01F800001FFC07C7FC01F000001FFE0FC7FE
+03F000000FFE0F83FE03E000000FFE0F83FF03E000000FFF1F83FF07E0000007FF1F01FF
+07C0000007FFBF01FF8FC0000003FFBE00FF8F80000003FFBE00FFCF80000003FFFE00FF
+DF80000001FFFC007FDF00000001FFFC007FFF00000000FFF8003FFE00000000FFF8003F
+FE00000000FFF8003FFE000000007FF0001FFC000000007FF0001FFC000000003FE0000F
+F8000000003FE0000FF8000000003FE0000FF8000000001FC00007F0000000001FC00007
+F0000000000F800003E0000047287EA74C>I<FFFFFC03FFFF80FFFFFC03FFFF80FFFFFC
+03FFFF80FFFFFC03FFFF80FFFFFC03FFFF8000FFE0007F000000FFF000FE0000007FF800
+FC0000003FFC01F80000001FFE03F00000000FFE07F000000007FF0FE000000007FF9FC0
+00000003FFFF8000000001FFFF0000000000FFFE00000000007FFC00000000007FFC0000
+0000003FFC00000000001FFE00000000000FFE00000000000FFF00000000001FFF800000
+00003FFFC0000000007FFFE000000000FEFFF000000001FC7FF000000003F83FF8000000
+03F03FFC00000007E01FFE0000000FC00FFF0000001FC007FF0000003F8003FF8000007F
+0003FFC00000FE0001FFE000FFFFC007FFFFC0FFFFC007FFFFC0FFFFC007FFFFC0FFFFC0
+07FFFFC0FFFFC007FFFFC032287EA737>I<FFFFFC003FFFC0FFFFFC003FFFC0FFFFFC00
+3FFFC0FFFFFC003FFFC0FFFFFC003FFFC001FFC00003E00001FFE00007E00001FFE00007
+E00000FFE00007C00000FFF0000FC000007FF0000F8000007FF8001F8000003FF8001F00
+00003FFC003F0000001FFC003E0000001FFE007E0000000FFE007C0000000FFF00FC0000
+000FFF00FC00000007FF00F800000007FF81F800000003FF81F000000003FFC3F0000000
+01FFC3E000000001FFE7E000000000FFE7C000000000FFFFC0000000007FFF8000000000
+7FFF80000000007FFF80000000003FFF00000000003FFF00000000001FFE00000000001F
+FE00000000000FFC00000000000FFC000000000007F8000000000007F8000000000003F0
+000000000003F0000000000003F0000000000003E0000000000007E0000000000007C000
+00000E000FC00000003F800F800000007FC01F80000000FFE01F00000000FFE03F000000
+00FFE03E00000000FFE07E00000000FFE0FC00000000FFC1F8000000007FC3F000000000
+7E0FE0000000003FFFC0000000001FFF80000000000FFE000000000003F8000000000032
+3B7EA737>I<FFFFFFFFFFFFE0FFFFFFFFFFFFE0FFFFFFFFFFFFE0FFFFFFFFFFFFE03304
+809A34>123 D E /Fu 44 122 df<00000000FFFC0000000000001FFFFF800000000001
+FFFFFFE00000000007FFFFFFF0000000001FFFC00FF8000000007FFE0003FC00000000FF
+F00000FE00000001FFE00003FF00000003FF800007FF00000007FF00000FFF8000000FFE
+00001FFF8000000FFE00001FFF8000001FFC00001FFF8000001FFC00003FFFC000003FFC
+00001FFF8000003FF800001FFF8000003FF800001FFF8000003FF800001FFF8000003FF8
+00000FFF0000003FF8000007FE0000003FF8000001F80000003FF8000000000000003FF8
+000000000000003FF8000000000000003FF8000000000000003FF8000000000000003FF8
+000000000000003FF8000000000000003FF8000000000000003FF8000000000000003FF8
+0003FFFFC000FFFFFFFFFFFFFFC000FFFFFFFFFFFFFFC000FFFFFFFFFFFFFFC000FFFFFF
+FFFFFFFFC000FFFFFFFFFFFFFFC000003FFC000007FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC000003FFC
+000003FFC0003FFFFFFC03FFFFFFC03FFFFFFC03FFFFFFC03FFFFFFC03FFFFFFC03FFFFF
+FC03FFFFFFC03FFFFFFC03FFFFFFC042547DD34B>12 D<FFFFFFFFF0FFFFFFFFF0FFFFFF
+FFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFF
+F0FFFFFFFFF0240B7F9F2D>45 D<000000780000000000FC0000000003FC0000000007FC
+000000001FFC00000000FFFC0000000FFFFC000007FFFFFC0000FFFFFFFC0000FFFFFFFC
+0000FFFF7FFC0000FFF07FFC0000F8007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC000000007FFC
+000000007FFC000000007FFC000000007FFC00007FFFFFFFFFFE7FFFFFFFFFFE7FFFFFFF
+FFFE7FFFFFFFFFFE7FFFFFFFFFFE2F4E76CD43>49 D<00003FFE0000000003FFFFE00000
+000FFFFFFC0000003FFFFFFF000000FFFFFFFFC00001FFC07FFFE00003FE000FFFF80007
+F80003FFFC000FE00001FFFE001FC00000FFFF003F8000007FFF003FF000007FFF807FF8
+00003FFFC07FFC00003FFFC0FFFE00001FFFE0FFFF00001FFFE0FFFF00001FFFE0FFFF00
+000FFFF0FFFF00000FFFF0FFFF00000FFFF0FFFF00000FFFF0FFFF00000FFFF07FFE0000
+0FFFF07FFE00000FFFF03FFC00000FFFF00FF000000FFFF003C000000FFFF0000000000F
+FFE0000000001FFFE0000000001FFFE0000000001FFFC0000000003FFFC0000000003FFF
+80000000003FFF80000000007FFF00000000007FFE0000000000FFFC0000000001FFF800
+00000001FFF00000000003FFE00000000003FFC00000000007FF80000000000FFF000000
+00001FFE00000000001FFC00000000003FF800000000007FE00000000000FFC000000000
+01FF800000000003FE000000000007FC000000000007F800000000000FF00001F000001F
+E00001F000003F800001F000007F000001F00000FE000003E00001FC000003E00003F800
+0003E00007F0000003E0000FE0000003E0001F80000007E0003F00000007E0003E000000
+0FE0007FFFFFFFFFE000FFFFFFFFFFC001FFFFFFFFFFC003FFFFFFFFFFC007FFFFFFFFFF
+C00FFFFFFFFFFFC01FFFFFFFFFFFC03FFFFFFFFFFFC07FFFFFFFFFFFC0FFFFFFFFFFFFC0
+FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80FFFFFFFFFFFF80344E79CD43>I<00
+000FFFC000000000FFFFFC00000007FFFFFF8000001FFFFFFFE000003FF807FFF00000FF
+8001FFFC0001FE00007FFE0003F800003FFF0003F000003FFF8007FC00001FFF800FFF00
+001FFFC00FFF80001FFFC01FFFC0001FFFE01FFFC0001FFFE01FFFC0001FFFE01FFFC000
+1FFFE01FFFE0001FFFE01FFFC0001FFFE01FFFC0001FFFE01FFFC0001FFFE00FFFC0001F
+FFC007FF80001FFFC003FF00003FFFC001FC00003FFF80000000003FFF80000000007FFF
+00000000007FFE00000000007FFE0000000000FFFC0000000001FFF80000000003FFF000
+00000007FFC0000000000FFF8000000000FFFE00000000FFFFF800000000FFFFE0000000
+00FFFFFC00000000FFFFFF800000000007FFE00000000001FFF800000000007FFE000000
+00003FFF00000000001FFF80000000000FFFC0000000000FFFE00000000007FFF0000000
+0007FFF00000000007FFF80000000007FFF80000000003FFFC0000000003FFFC00000000
+03FFFE0000000003FFFE03E0000003FFFE0FF8000003FFFE1FFC000003FFFE3FFE000003
+FFFE7FFF000003FFFEFFFF800003FFFEFFFF800003FFFEFFFF800003FFFEFFFF800003FF
+FCFFFF800003FFFCFFFF800007FFFCFFFF800007FFF8FFFF000007FFF87FFF000007FFF0
+7FFE00000FFFF03FFC00000FFFE03FF000001FFFC01FE000003FFF800FF800007FFF0007
+FF0000FFFE0003FFF007FFFC0000FFFFFFFFF000007FFFFFFFE000001FFFFFFF80000003
+FFFFFC000000001FFF800000374F7ACD43>I<00000000007C00000000000000FE000000
+00000000FE00000000000001FE00000000000003FE00000000000007FE0000000000000F
+FE0000000000000FFE0000000000001FFE0000000000003FFE0000000000007FFE000000
+0000007FFE000000000000FFFE000000000001FFFE000000000003FFFE000000000003FF
+FE000000000007FFFE00000000000FFFFE00000000001FBFFE00000000003F3FFE000000
+00003E3FFE00000000007C3FFE0000000000FC3FFE0000000001F83FFE0000000001F03F
+FE0000000003E03FFE0000000007E03FFE000000000FC03FFE000000000F803FFE000000
+001F003FFE000000003F003FFE000000007E003FFE000000007C003FFE00000000F8003F
+FE00000001F8003FFE00000003F0003FFE00000007E0003FFE00000007C0003FFE000000
+0F80003FFE0000001F80003FFE0000003F00003FFE0000003E00003FFE0000007C00003F
+FE000000FC00003FFE000001F800003FFE000001F000003FFE000003E000003FFE000007
+E000003FFE00000FC000003FFE00001F8000003FFE00001F0000003FFE00003E0000003F
+FE00007E0000003FFE0000FC0000003FFE0000FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC0FF
+FFFFFFFFFFFFC0FFFFFFFFFFFFFFC0FFFFFFFFFFFFFFC0000000007FFE0000000000007F
+FE0000000000007FFE0000000000007FFE0000000000007FFE0000000000007FFE000000
+0000007FFE0000000000007FFE0000000000007FFE0000000000007FFE0000000000007F
+FE0000000000007FFE0000000000007FFE0000000000007FFE0000000000007FFE000000
+000FFFFFFFFFC000000FFFFFFFFFC000000FFFFFFFFFC000000FFFFFFFFFC000000FFFFF
+FFFFC03A4F7CCE43>I<03800000000E0007E00000007E0007FE000003FE0007FFF0007F
+FE0007FFFFFFFFFC0007FFFFFFFFF80007FFFFFFFFF00007FFFFFFFFE00007FFFFFFFFC0
+0007FFFFFFFF800007FFFFFFFF000007FFFFFFFE000007FFFFFFFC000007FFFFFFF00000
+07FFFFFFC0000007FFFFFF00000007FFFFF800000007E1FF0000000007E0000000000007
+E0000000000007E0000000000007E0000000000007E0000000000007E0000000000007E0
+000000000007E0000000000007E0000000000007E0000000000007E0000000000007E00F
+FF00000007E07FFFF0000007E3FFFFFE000007E7FFFFFF800007FFF807FFC00007FFC001
+FFE00007FE0000FFF80007FC00007FFC0007F800003FFC0007F000003FFE0007E000001F
+FF0003C000001FFF80000000001FFF80000000001FFFC0000000000FFFC0000000000FFF
+E0000000000FFFE0000000000FFFE0000000000FFFE0000000000FFFF0000000000FFFF0
+000000000FFFF00FE000000FFFF01FF000000FFFF03FF800000FFFF07FFC00000FFFF0FF
+FE00000FFFF0FFFE00000FFFF0FFFE00000FFFF0FFFE00000FFFF0FFFE00000FFFE0FFFE
+00000FFFE0FFFE00000FFFE0FFFC00000FFFE07FF800001FFFC07FF000001FFFC07FE000
+001FFF803E0000003FFF803F0000003FFF001F8000007FFE001FC000007FFC000FE00000
+FFF80007F80001FFF00003FE0007FFE00001FFC03FFFC00000FFFFFFFF8000003FFFFFFE
+0000001FFFFFF800000003FFFFC0000000007FF8000000344F79CD43>I<00000000001F
+00000000000000000000003F80000000000000000000007FC0000000000000000000007F
+C000000000000000000000FFE000000000000000000000FFE000000000000000000000FF
+E000000000000000000001FFF000000000000000000001FFF000000000000000000003FF
+F800000000000000000003FFF800000000000000000003FFF800000000000000000007FF
+FC00000000000000000007FFFC00000000000000000007FFFC0000000000000000000FFF
+FE0000000000000000000FFFFE0000000000000000001FFFFF0000000000000000001FFF
+FF0000000000000000001FFFFF0000000000000000003FFFFF8000000000000000003F7F
+FF8000000000000000007F7FFFC000000000000000007E7FFFC000000000000000007E3F
+FFC00000000000000000FE3FFFE00000000000000000FC1FFFE00000000000000001FC1F
+FFF00000000000000001F81FFFF00000000000000001F80FFFF00000000000000003F80F
+FFF80000000000000003F007FFF80000000000000007F007FFFC0000000000000007E007
+FFFC0000000000000007E003FFFC000000000000000FE003FFFE000000000000000FC001
+FFFE000000000000001FC001FFFF000000000000001F8001FFFF000000000000001F8000
+FFFF000000000000003F8000FFFF800000000000003F00007FFF800000000000007F0000
+7FFFC00000000000007E00007FFFC00000000000007E00003FFFC0000000000000FE0000
+3FFFE0000000000000FC00001FFFE0000000000001FC00001FFFF0000000000001F80000
+1FFFF0000000000001F800000FFFF0000000000003F800000FFFF8000000000003F00000
+07FFF8000000000007F0000007FFFC000000000007E0000007FFFC000000000007E00000
+03FFFC00000000000FFFFFFFFFFFFE00000000000FFFFFFFFFFFFE00000000001FFFFFFF
+FFFFFF00000000001FFFFFFFFFFFFF00000000001FFFFFFFFFFFFF00000000003F800000
+00FFFF80000000003F000000007FFF80000000007F000000007FFFC0000000007F000000
+007FFFC0000000007E000000003FFFC000000000FE000000003FFFE000000000FC000000
+001FFFE000000001FC000000001FFFF000000001FC000000001FFFF000000001F8000000
+000FFFF000000003F8000000000FFFF800000003F00000000007FFF800000007F0000000
+0007FFFC00000007F00000000007FFFC00000007E00000000003FFFC0000000FE0000000
+0003FFFE0000000FC00000000003FFFE0000001FC00000000001FFFF000000FFFC000000
+0001FFFF0000FFFFFFF800000FFFFFFFFFE0FFFFFFF800000FFFFFFFFFE0FFFFFFF80000
+0FFFFFFFFFE0FFFFFFF800000FFFFFFFFFE0FFFFFFF800000FFFFFFFFFE05B547BD366>
+65 D<FFFFFFFFFFFFFFC0000000FFFFFFFFFFFFFFFE000000FFFFFFFFFFFFFFFFC00000
+FFFFFFFFFFFFFFFFF00000FFFFFFFFFFFFFFFFFC00000007FFF0000003FFFF00000007FF
+F00000007FFF80000007FFF00000003FFFC0000007FFF00000000FFFE0000007FFF00000
+0007FFF0000007FFF000000007FFF8000007FFF000000003FFF8000007FFF000000003FF
+FC000007FFF000000001FFFC000007FFF000000001FFFE000007FFF000000000FFFE0000
+07FFF000000000FFFE000007FFF000000000FFFF000007FFF000000000FFFF000007FFF0
+00000000FFFF000007FFF000000000FFFF000007FFF000000000FFFF000007FFF0000000
+00FFFF000007FFF000000000FFFF000007FFF000000000FFFF000007FFF000000001FFFE
+000007FFF000000001FFFE000007FFF000000001FFFC000007FFF000000003FFFC000007
+FFF000000003FFF8000007FFF000000007FFF8000007FFF000000007FFF0000007FFF000
+00000FFFE0000007FFF00000001FFFC0000007FFF00000007FFF00000007FFF0000001FF
+FE00000007FFF0000007FFF800000007FFFFFFFFFFFFE000000007FFFFFFFFFFFF000000
+0007FFFFFFFFFFFF8000000007FFFFFFFFFFFFF000000007FFF0000003FFFE00000007FF
+F00000003FFF80000007FFF00000000FFFE0000007FFF000000007FFF0000007FFF00000
+0001FFF8000007FFF000000001FFFC000007FFF000000000FFFE000007FFF0000000007F
+FF000007FFF0000000007FFF800007FFF0000000003FFFC00007FFF0000000003FFFC000
+07FFF0000000001FFFE00007FFF0000000001FFFE00007FFF0000000001FFFE00007FFF0
+000000001FFFF00007FFF0000000001FFFF00007FFF0000000001FFFF00007FFF0000000
+000FFFF00007FFF0000000000FFFF00007FFF0000000000FFFF00007FFF0000000001FFF
+F00007FFF0000000001FFFF00007FFF0000000001FFFF00007FFF0000000001FFFE00007
+FFF0000000001FFFE00007FFF0000000003FFFE00007FFF0000000003FFFC00007FFF000
+0000003FFFC00007FFF0000000007FFF800007FFF000000000FFFF800007FFF000000000
+FFFF000007FFF000000001FFFE000007FFF000000007FFFE000007FFF00000000FFFFC00
+0007FFF00000003FFFF0000007FFF0000001FFFFE000FFFFFFFFFFFFFFFFFF8000FFFFFF
+FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFF80000FFFFFFFFFFFFFFFFC00000FFFFFFFFFFFF
+FFF800000054527CD160>I<0000000001FFFC000001C0000000007FFFFFC00003C00000
+0007FFFFFFF80007C00000003FFFFFFFFE001FC0000000FFFFFFFFFF803FC0000003FFFF
+E003FFC07FC000000FFFFC00003FF0FFC000003FFFE000000FF9FFC000007FFF80000003
+FFFFC00001FFFE00000000FFFFC00003FFF8000000007FFFC00007FFF0000000003FFFC0
+000FFFE0000000001FFFC0001FFFC0000000000FFFC0003FFF800000000007FFC0007FFF
+000000000003FFC000FFFE000000000001FFC000FFFE000000000001FFC001FFFC000000
+000000FFC003FFF8000000000000FFC003FFF80000000000007FC007FFF0000000000000
+7FC00FFFF00000000000003FC00FFFF00000000000003FC01FFFE00000000000001FC01F
+FFE00000000000001FC01FFFE00000000000001FC03FFFC00000000000001FC03FFFC000
+00000000000FC03FFFC00000000000000FC07FFFC00000000000000FC07FFFC000000000
+00000FC07FFFC000000000000000007FFF8000000000000000007FFF8000000000000000
+00FFFF800000000000000000FFFF800000000000000000FFFF800000000000000000FFFF
+800000000000000000FFFF800000000000000000FFFF800000000000000000FFFF800000
+000000000000FFFF800000000000000000FFFF800000000000000000FFFF800000000000
+000000FFFF800000000000000000FFFF800000000000000000FFFF800000000000000000
+FFFF8000000000000000007FFF8000000000000000007FFF8000000000000000007FFFC0
+00000000000000007FFFC000000000000000007FFFC000000000000007C03FFFC0000000
+00000007C03FFFC000000000000007C03FFFC000000000000007C01FFFE0000000000000
+07C01FFFE000000000000007C01FFFE00000000000000FC00FFFF00000000000000F800F
+FFF00000000000000F8007FFF00000000000001F8003FFF80000000000001F8003FFF800
+00000000001F0001FFFC0000000000003F0000FFFE0000000000007E0000FFFE00000000
+00007E00007FFF000000000000FC00003FFF800000000001F800001FFFC00000000003F8
+00000FFFE00000000007F0000007FFF0000000000FE0000003FFFC000000001FC0000001
+FFFE000000007F800000007FFF80000000FF000000003FFFE0000007FE000000000FFFFE
+00001FF80000000003FFFFE001FFF00000000000FFFFFFFFFFC000000000003FFFFFFFFF
+00000000000007FFFFFFFC000000000000007FFFFFE00000000000000001FFFC00000000
+525479D261>I<FFFFFFFFFFFFFF8000000000FFFFFFFFFFFFFFFC00000000FFFFFFFFFF
+FFFFFF80000000FFFFFFFFFFFFFFFFF0000000FFFFFFFFFFFFFFFFFC0000000007FFF000
+000FFFFF0000000007FFF0000000FFFFC000000007FFF00000001FFFE000000007FFF000
+000007FFF800000007FFF000000001FFFC00000007FFF000000000FFFE00000007FFF000
+0000007FFF00000007FFF0000000003FFF80000007FFF0000000001FFFC0000007FFF000
+0000000FFFC0000007FFF00000000007FFE0000007FFF00000000003FFF0000007FFF000
+00000003FFF8000007FFF00000000001FFF8000007FFF00000000001FFFC000007FFF000
+00000000FFFC000007FFF00000000000FFFE000007FFF00000000000FFFE000007FFF000
+000000007FFF000007FFF000000000007FFF000007FFF000000000007FFF000007FFF000
+000000007FFF800007FFF000000000003FFF800007FFF000000000003FFF800007FFF000
+000000003FFFC00007FFF000000000003FFFC00007FFF000000000003FFFC00007FFF000
+000000003FFFC00007FFF000000000003FFFC00007FFF000000000003FFFE00007FFF000
+000000003FFFE00007FFF000000000003FFFE00007FFF000000000001FFFE00007FFF000
+000000001FFFE00007FFF000000000001FFFE00007FFF000000000001FFFE00007FFF000
+000000001FFFE00007FFF000000000001FFFE00007FFF000000000001FFFE00007FFF000
+000000001FFFE00007FFF000000000001FFFE00007FFF000000000003FFFE00007FFF000
+000000003FFFE00007FFF000000000003FFFE00007FFF000000000003FFFC00007FFF000
+000000003FFFC00007FFF000000000003FFFC00007FFF000000000003FFFC00007FFF000
+000000003FFFC00007FFF000000000003FFF800007FFF000000000003FFF800007FFF000
+000000007FFF800007FFF000000000007FFF000007FFF000000000007FFF000007FFF000
+000000007FFF000007FFF00000000000FFFE000007FFF00000000000FFFE000007FFF000
+00000000FFFC000007FFF00000000001FFFC000007FFF00000000001FFF8000007FFF000
+00000003FFF0000007FFF00000000007FFF0000007FFF00000000007FFE0000007FFF000
+0000000FFFC0000007FFF0000000001FFF80000007FFF0000000003FFF00000007FFF000
+000000FFFE00000007FFF000000001FFFC00000007FFF000000007FFF800000007FFF000
+00001FFFF000000007FFF0000000FFFFC000000007FFF000000FFFFF000000FFFFFFFFFF
+FFFFFFFE000000FFFFFFFFFFFFFFFFF0000000FFFFFFFFFFFFFFFFC0000000FFFFFFFFFF
+FFFFFC00000000FFFFFFFFFFFFFF80000000005B527CD167>I<FFFFFFFFFFFFFFFFFF80
+FFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFFFF80FFFFFFFFFFFF
+FFFFFF800007FFF8000001FFFFC00007FFF80000001FFFC00007FFF800000007FFC00007
+FFF800000001FFC00007FFF800000000FFC00007FFF8000000007FC00007FFF800000000
+3FC00007FFF8000000001FC00007FFF8000000001FC00007FFF8000000000FE00007FFF8
+000000000FE00007FFF80000000007E00007FFF80000000007E00007FFF80000000007E0
+0007FFF80000000003E00007FFF80000000003E00007FFF80000000003E00007FFF80000
+F80003E00007FFF80000F80003F00007FFF80000F80001F00007FFF80000F80001F00007
+FFF80000F80001F00007FFF80000F80001F00007FFF80000F80000000007FFF80001F800
+00000007FFF80001F80000000007FFF80001F80000000007FFF80003F80000000007FFF8
+0007F80000000007FFF8000FF80000000007FFF8007FF80000000007FFFFFFFFF8000000
+0007FFFFFFFFF80000000007FFFFFFFFF80000000007FFFFFFFFF80000000007FFFFFFFF
+F80000000007FFF8007FF80000000007FFF8000FF80000000007FFF80007F80000000007
+FFF80003F80000000007FFF80001F80000000007FFF80001F80000000007FFF80001F800
+00000007FFF80000F80000000007FFF80000F800003E0007FFF80000F800003E0007FFF8
+0000F800003E0007FFF80000F800007C0007FFF80000F800007C0007FFF80000F800007C
+0007FFF800000000007C0007FFF800000000007C0007FFF80000000000FC0007FFF80000
+000000FC0007FFF80000000000F80007FFF80000000000F80007FFF80000000001F80007
+FFF80000000001F80007FFF80000000001F80007FFF80000000003F80007FFF800000000
+03F00007FFF80000000007F00007FFF8000000000FF00007FFF8000000000FF00007FFF8
+000000001FF00007FFF8000000003FF00007FFF8000000007FE00007FFF800000001FFE0
+0007FFF800000007FFE00007FFF80000001FFFE00007FFF8000003FFFFE0FFFFFFFFFFFF
+FFFFFFE0FFFFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFC0FFFF
+FFFFFFFFFFFFFFC04F517CD058>I<FFFFFFFFFFFFFFFFFE00FFFFFFFFFFFFFFFFFE00FF
+FFFFFFFFFFFFFFFE00FFFFFFFFFFFFFFFFFE00FFFFFFFFFFFFFFFFFE000007FFF8000007
+FFFF000007FFF80000007FFF000007FFF80000001FFF000007FFF800000007FF000007FF
+F800000003FF000007FFF800000001FF000007FFF800000000FF000007FFF8000000007F
+000007FFF8000000003F000007FFF8000000003F800007FFF8000000003F800007FFF800
+0000001F800007FFF8000000001F800007FFF8000000001F800007FFF8000000000F8000
+07FFF8000000000F800007FFF8000000000F800007FFF8000000000F800007FFF8000000
+000FC00007FFF80000F80007C00007FFF80000F80007C00007FFF80000F80007C00007FF
+F80000F80007C00007FFF80000F80000000007FFF80000F80000000007FFF80000F80000
+000007FFF80001F80000000007FFF80001F80000000007FFF80001F80000000007FFF800
+03F80000000007FFF80007F80000000007FFF8000FF80000000007FFF8007FF800000000
+07FFFFFFFFF80000000007FFFFFFFFF80000000007FFFFFFFFF80000000007FFFFFFFFF8
+0000000007FFFFFFFFF80000000007FFF8007FF80000000007FFF8000FF80000000007FF
+F80007F80000000007FFF80003F80000000007FFF80001F80000000007FFF80001F80000
+000007FFF80001F80000000007FFF80000F80000000007FFF80000F80000000007FFF800
+00F80000000007FFF80000F80000000007FFF80000F80000000007FFF80000F800000000
+07FFF80000F80000000007FFF80000000000000007FFF80000000000000007FFF8000000
+0000000007FFF80000000000000007FFF80000000000000007FFF80000000000000007FF
+F80000000000000007FFF80000000000000007FFF80000000000000007FFF80000000000
+000007FFF80000000000000007FFF80000000000000007FFF80000000000000007FFF800
+00000000000007FFF80000000000000007FFF80000000000000007FFF800000000000000
+07FFF80000000000000007FFF8000000000000FFFFFFFFFFF800000000FFFFFFFFFFF800
+000000FFFFFFFFFFF800000000FFFFFFFFFFF800000000FFFFFFFFFFF8000000004A517C
+D055>I<0000000001FFFC000001C000000000007FFFFFC00003C00000000007FFFFFFF8
+0007C0000000003FFFFFFFFE001FC000000000FFFFFFFFFF803FC000000003FFFFE003FF
+C07FC00000000FFFFC00003FF0FFC00000003FFFE000000FF9FFC00000007FFF80000003
+FFFFC0000001FFFE00000000FFFFC0000003FFF8000000007FFFC0000007FFF000000000
+3FFFC000000FFFE0000000001FFFC000001FFFC0000000000FFFC000003FFF8000000000
+07FFC000007FFF000000000003FFC00000FFFE000000000001FFC00000FFFE0000000000
+01FFC00001FFFC000000000000FFC00003FFF8000000000000FFC00003FFF80000000000
+007FC00007FFF00000000000007FC0000FFFF00000000000003FC0000FFFF00000000000
+003FC0001FFFE00000000000001FC0001FFFE00000000000001FC0001FFFE00000000000
+001FC0003FFFC00000000000001FC0003FFFC00000000000000FC0003FFFC00000000000
+000FC0007FFFC00000000000000FC0007FFFC00000000000000FC0007FFFC00000000000
+000000007FFF800000000000000000007FFF80000000000000000000FFFF800000000000
+00000000FFFF80000000000000000000FFFF80000000000000000000FFFF800000000000
+00000000FFFF80000000000000000000FFFF80000000000000000000FFFF800000000000
+00000000FFFF80000000000000000000FFFF80000000000000000000FFFF800000000000
+00000000FFFF80000000000000000000FFFF80000000000000000000FFFF800000000000
+00000000FFFF800000000000000000007FFF800000007FFFFFFFFFE07FFF800000007FFF
+FFFFFFE07FFFC00000007FFFFFFFFFE07FFFC00000007FFFFFFFFFE07FFFC00000007FFF
+FFFFFFE03FFFC000000000003FFFC0003FFFC000000000003FFFC0003FFFC00000000000
+3FFFC0001FFFE000000000003FFFC0001FFFE000000000003FFFC0001FFFE00000000000
+3FFFC0000FFFF000000000003FFFC0000FFFF000000000003FFFC00007FFF00000000000
+3FFFC00003FFF800000000003FFFC00003FFF800000000003FFFC00001FFFC0000000000
+3FFFC00000FFFE00000000003FFFC00000FFFE00000000003FFFC000007FFF0000000000
+3FFFC000003FFF80000000003FFFC000001FFFC0000000003FFFC000000FFFE000000000
+7FFFC0000007FFF0000000007FFFC0000003FFFC00000000FFFFC0000001FFFF00000000
+FFFFC00000007FFF80000001FFFFC00000003FFFF0000007FBFFC00000000FFFFE00001F
+F1FFC000000003FFFFF001FFE0FFC000000000FFFFFFFFFFC07FC0000000003FFFFFFFFF
+001FC00000000007FFFFFFFC0007C000000000007FFFFFE00001C0000000000001FFFE00
+000000005B5479D26A>I<FFFFFFFFFFC003FFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFF
+FFFFFFFFC003FFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFF00
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFFFFFFFFFFFFFFFE00000
+07FFFFFFFFFFFFFFFFE0000007FFFFFFFFFFFFFFFFE0000007FFFFFFFFFFFFFFFFE00000
+07FFFFFFFFFFFFFFFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE00000
+07FFF8000000001FFFE0000007FFF8000000001FFFE0000007FFF8000000001FFFE000FF
+FFFFFFFFC003FFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFFFF
+FFFFFFFFC003FFFFFFFFFFFFFFFFFFFFC003FFFFFFFFFF60527CD169>I<FFFFFFFFFFC0
+FFFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC00007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF800000007FFF800000007FFF80000
+0007FFF800000007FFF800000007FFF800000007FFF80000FFFFFFFFFFC0FFFFFFFFFFC0
+FFFFFFFFFFC0FFFFFFFFFFC0FFFFFFFFFFC02A527CD132>I<FFFFFFFFFFC00000FFFFFF
+F8FFFFFFFFFFC00000FFFFFFF8FFFFFFFFFFC00000FFFFFFF8FFFFFFFFFFC00000FFFFFF
+F8FFFFFFFFFFC00000FFFFFFF80007FFF80000000003FFF8000007FFF800000000007F80
+000007FFF80000000000FF00000007FFF80000000001FE00000007FFF80000000003F800
+000007FFF8000000000FF000000007FFF8000000001FE000000007FFF8000000003FC000
+000007FFF8000000007F8000000007FFF800000000FF0000000007FFF800000001FC0000
+000007FFF800000007F80000000007FFF80000000FF00000000007FFF80000001FE00000
+000007FFF80000003FC00000000007FFF80000007F800000000007FFF8000000FE000000
+000007FFF8000003FC000000000007FFF8000007F8000000000007FFF800000FF0000000
+000007FFF800001FE0000000000007FFF800003FC0000000000007FFF800007F80000000
+000007FFF80001FE00000000000007FFF80003FC00000000000007FFF80007F800000000
+000007FFF8000FF000000000000007FFF8001FF800000000000007FFF8003FF800000000
+000007FFF8007FFC00000000000007FFF801FFFE00000000000007FFF803FFFF00000000
+000007FFF807FFFF00000000000007FFF80FFFFF80000000000007FFF81FFFFFC0000000
+000007FFF83FFFFFE0000000000007FFF8FF7FFFE0000000000007FFF9FE3FFFF0000000
+000007FFFBFC3FFFF8000000000007FFFFF81FFFFC000000000007FFFFF00FFFFC000000
+000007FFFFC007FFFE000000000007FFFF8007FFFF000000000007FFFF0003FFFF000000
+000007FFFE0001FFFF800000000007FFFC0000FFFFC00000000007FFF80000FFFFE00000
+000007FFF800007FFFE00000000007FFF800003FFFF00000000007FFF800001FFFF80000
+000007FFF800001FFFFC0000000007FFF800000FFFFC0000000007FFF8000007FFFE0000
+000007FFF8000003FFFF0000000007FFF8000003FFFF8000000007FFF8000001FFFF8000
+000007FFF8000000FFFFC000000007FFF8000000FFFFE000000007FFF80000007FFFF000
+000007FFF80000003FFFF000000007FFF80000001FFFF800000007FFF80000001FFFFC00
+000007FFF80000000FFFFE00000007FFF800000007FFFE00000007FFF800000003FFFF00
+000007FFF800000003FFFF80000007FFF800000001FFFF80000007FFF800000000FFFFC0
+000007FFF8000000007FFFE0000007FFF8000000007FFFF0000007FFF8000000003FFFF0
+000007FFF800000000FFFFFC00FFFFFFFFFFC0003FFFFFFFFEFFFFFFFFFFC0003FFFFFFF
+FEFFFFFFFFFFC0003FFFFFFFFEFFFFFFFFFFC0003FFFFFFFFEFFFFFFFFFFC0003FFFFFFF
+FE5F527CD169>75 D<FFFFFFFFFFF8000000FFFFFFFFFFF8000000FFFFFFFFFFF8000000
+FFFFFFFFFFF8000000FFFFFFFFFFF80000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF80000000000
+0007FFF800000000000007FFF800000000000007FFF800000000000007FFF8000000007C
+0007FFF8000000007C0007FFF8000000007C0007FFF8000000007C0007FFF800000000FC
+0007FFF800000000F80007FFF800000000F80007FFF800000000F80007FFF800000000F8
+0007FFF800000000F80007FFF800000001F80007FFF800000001F80007FFF800000001F8
+0007FFF800000003F80007FFF800000003F80007FFF800000007F80007FFF800000007F0
+0007FFF80000000FF00007FFF80000000FF00007FFF80000001FF00007FFF80000003FF0
+0007FFF80000007FF00007FFF8000000FFF00007FFF8000003FFF00007FFF8000007FFF0
+0007FFF800003FFFF00007FFF80001FFFFF0FFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFE0
+FFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFE046527CD151>I<FFFF
+FFFC000000000000003FFFFFFEFFFFFFFE000000000000007FFFFFFEFFFFFFFE00000000
+0000007FFFFFFEFFFFFFFF00000000000000FFFFFFFEFFFFFFFF00000000000000FFFFFF
+FE0007FFFF00000000000000FFFFC0000007FFFF80000000000001EFFFC0000007FFFF80
+000000000001EFFFC0000007EFFFC0000000000003CFFFC0000007EFFFC0000000000003
+CFFFC0000007E7FFE00000000000078FFFC0000007E7FFE00000000000078FFFC0000007
+E3FFF000000000000F0FFFC0000007E3FFF000000000000F0FFFC0000007E1FFF8000000
+00001E0FFFC0000007E1FFF800000000001E0FFFC0000007E1FFF800000000001E0FFFC0
+000007E0FFFC00000000003C0FFFC0000007E0FFFC00000000003C0FFFC0000007E07FFE
+0000000000780FFFC0000007E07FFE0000000000780FFFC0000007E03FFF0000000000F0
+0FFFC0000007E03FFF0000000000F00FFFC0000007E01FFF8000000001E00FFFC0000007
+E01FFF8000000001E00FFFC0000007E00FFFC000000003C00FFFC0000007E00FFFC00000
+0003C00FFFC0000007E00FFFC000000003C00FFFC0000007E007FFE000000007800FFFC0
+000007E007FFE000000007800FFFC0000007E003FFF00000000F000FFFC0000007E003FF
+F00000000F000FFFC0000007E001FFF80000001E000FFFC0000007E001FFF80000001E00
+0FFFC0000007E000FFFC0000003C000FFFC0000007E000FFFC0000003C000FFFC0000007
+E000FFFC0000003C000FFFC0000007E0007FFE00000078000FFFC0000007E0007FFE0000
+0078000FFFC0000007E0003FFF000000F0000FFFC0000007E0003FFF000000F0000FFFC0
+000007E0001FFF800001E0000FFFC0000007E0001FFF800001E0000FFFC0000007E0000F
+FFC00003C0000FFFC0000007E0000FFFC00003C0000FFFC0000007E00007FFE000078000
+0FFFC0000007E00007FFE0000780000FFFC0000007E00007FFE0000780000FFFC0000007
+E00003FFF0000F00000FFFC0000007E00003FFF0000F00000FFFC0000007E00001FFF800
+1E00000FFFC0000007E00001FFF8001E00000FFFC0000007E00000FFFC003C00000FFFC0
+000007E00000FFFC003C00000FFFC0000007E000007FFE007800000FFFC0000007E00000
+7FFE007800000FFFC0000007E000007FFE007800000FFFC0000007E000003FFF00F00000
+0FFFC0000007E000003FFF00F000000FFFC0000007E000001FFF81E000000FFFC0000007
+E000001FFF81E000000FFFC0000007E000000FFFC3C000000FFFC0000007E000000FFFC3
+C000000FFFC0000007E0000007FFE78000000FFFC0000007E0000007FFE78000000FFFC0
+000007E0000003FFFF0000000FFFC0000007E0000003FFFF0000000FFFC0000007E00000
+03FFFF0000000FFFC0000007E0000001FFFE0000000FFFC0000007E0000001FFFE000000
+0FFFC0000007E0000000FFFC0000000FFFC0000007E0000000FFFC0000000FFFC0000007
+E00000007FF80000000FFFC0000007E00000007FF80000000FFFC0000007E00000003FF0
+0000000FFFC0000007E00000003FF00000000FFFC000003FFC0000001FE00000000FFFC0
+00FFFFFFFF00001FE00001FFFFFFFFFEFFFFFFFF00001FE00001FFFFFFFFFEFFFFFFFF00
+000FC00001FFFFFFFFFEFFFFFFFF00000FC00001FFFFFFFFFEFFFFFFFF000007800001FF
+FFFFFFFE77527CD180>I<FFFFFFFFFFFFF00000000000FFFFFFFFFFFFFF8000000000FF
+FFFFFFFFFFFFF800000000FFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFC000000000
+07FFF00000FFFFF00000000007FFF000000FFFF80000000007FFF0000001FFFE00000000
+07FFF0000000FFFF0000000007FFF00000007FFF8000000007FFF00000003FFFC0000000
+07FFF00000001FFFC000000007FFF00000000FFFE000000007FFF00000000FFFF0000000
+07FFF00000000FFFF000000007FFF000000007FFF800000007FFF000000007FFF8000000
+07FFF000000007FFF800000007FFF000000007FFFC00000007FFF000000007FFFC000000
+07FFF000000007FFFC00000007FFF000000007FFFC00000007FFF000000007FFFC000000
+07FFF000000007FFFC00000007FFF000000007FFFC00000007FFF000000007FFFC000000
+07FFF000000007FFF800000007FFF000000007FFF800000007FFF00000000FFFF8000000
+07FFF00000000FFFF000000007FFF00000000FFFE000000007FFF00000000FFFE0000000
+07FFF00000001FFFC000000007FFF00000003FFF8000000007FFF00000007FFF00000000
+07FFF0000000FFFE0000000007FFF0000003FFFC0000000007FFF000000FFFF000000000
+07FFF00000FFFFC00000000007FFFFFFFFFFFF000000000007FFFFFFFFFFF80000000000
+07FFFFFFFFFFE0000000000007FFFFFFFFFFF8000000000007FFF00003FFFE0000000000
+07FFF000007FFF800000000007FFF000003FFFC00000000007FFF000001FFFE000000000
+07FFF000000FFFF00000000007FFF0000007FFF80000000007FFF0000003FFFC00000000
+07FFF0000003FFFE0000000007FFF0000001FFFE0000000007FFF0000001FFFE00000000
+07FFF0000001FFFF0000000007FFF0000000FFFF0000000007FFF0000000FFFF00000000
+07FFF0000000FFFF0000000007FFF0000000FFFF0000000007FFF0000000FFFF00000000
+07FFF0000000FFFF0000000007FFF0000000FFFF0000000007FFF0000000FFFF80000000
+07FFF0000000FFFF8000000007FFF0000000FFFF8000000007FFF0000000FFFF80000000
+07FFF0000000FFFF8000000007FFF0000000FFFF8000000007FFF0000000FFFF80000000
+07FFF0000000FFFF80001C0007FFF0000000FFFFC0003E0007FFF0000000FFFFC0003E00
+07FFF0000000FFFFC0003E0007FFF00000007FFFC0003E0007FFF00000007FFFE0007E00
+07FFF00000003FFFE0007C0007FFF00000003FFFF000FC0007FFF00000001FFFF001FCFF
+FFFFFFFF80000FFFF803F8FFFFFFFFFF800003FFFE07F0FFFFFFFFFF800001FFFFFFE0FF
+FFFFFFFF8000007FFFFFC0FFFFFFFFFF8000000FFFFF000000000000000000007FFC005F
+537CD164>82 D<00000FFF800007000000FFFFF8000F000007FFFFFF001F00001FFFFFFF
+C03F00003FFFFFFFF07F0000FFFC00FFF8FF0001FFE0000FFDFF0003FF800001FFFF0007
+FE0000007FFF000FFC0000003FFF000FF80000000FFF001FF800000007FF001FF0000000
+03FF003FF000000003FF003FE000000001FF007FE000000000FF007FE000000000FF007F
+E0000000007F00FFE0000000007F00FFE0000000003F00FFE0000000003F00FFF0000000
+003F00FFF0000000003F00FFF8000000001F00FFF8000000001F00FFFC000000001F00FF
+FE000000001F00FFFF000000000000FFFFC000000000007FFFF000000000007FFFFF0000
+0000007FFFFFF8000000003FFFFFFF800000003FFFFFFFFC0000001FFFFFFFFFC000001F
+FFFFFFFFF000000FFFFFFFFFFC000007FFFFFFFFFF000003FFFFFFFFFFC00001FFFFFFFF
+FFE00000FFFFFFFFFFF000007FFFFFFFFFF800003FFFFFFFFFFC00000FFFFFFFFFFE0000
+03FFFFFFFFFE000000FFFFFFFFFF0000001FFFFFFFFF80000000FFFFFFFF800000000FFF
+FFFFC0000000007FFFFFC00000000007FFFFE00000000000FFFFE000000000003FFFE000
+000000000FFFF0000000000007FFF0000000000003FFF0000000000003FFF07800000000
+01FFF0F80000000000FFF0F80000000000FFF0F80000000000FFF0F800000000007FF0F8
+00000000007FF0FC00000000007FF0FC00000000007FF0FC00000000007FE0FE00000000
+007FE0FE00000000007FE0FF0000000000FFC0FF0000000000FFC0FF8000000000FFC0FF
+C000000001FF80FFE000000001FF00FFF000000003FF00FFFC00000007FE00FFFF000000
+0FFC00FFFFC000001FF800FFFFF800007FF000FF1FFFC003FFE000FE0FFFFFFFFFC000FC
+03FFFFFFFF0000F8007FFFFFFC0000F0000FFFFFF00000E000007FFF0000003C5479D24B
+>I<3FFFFFFFFFFFFFFFFFFF803FFFFFFFFFFFFFFFFFFF803FFFFFFFFFFFFFFFFFFF803F
+FFFFFFFFFFFFFFFFFF803FFFFFFFFFFFFFFFFFFF803FFFC0003FFFC0007FFF803FFE0000
+3FFFC00007FF807FF800003FFFC00001FFC07FE000003FFFC00000FFC07FC000003FFFC0
+00007FC07F8000003FFFC000003FC07F0000003FFFC000001FC07F0000003FFFC000001F
+C07E0000003FFFC000000FC07E0000003FFFC000000FC07E0000003FFFC000000FC07C00
+00003FFFC0000007C07C0000003FFFC0000007C07C0000003FFFC0000007C07C0000003F
+FFC0000007C07C0000003FFFC0000007C0FC0000003FFFC0000007E0F80000003FFFC000
+0003E0F80000003FFFC0000003E0F80000003FFFC0000003E0F80000003FFFC0000003E0
+F80000003FFFC0000003E0F80000003FFFC0000003E0000000003FFFC000000000000000
+003FFFC000000000000000003FFFC000000000000000003FFFC000000000000000003FFF
+C000000000000000003FFFC000000000000000003FFFC000000000000000003FFFC00000
+0000000000003FFFC000000000000000003FFFC000000000000000003FFFC00000000000
+0000003FFFC000000000000000003FFFC000000000000000003FFFC00000000000000000
+3FFFC000000000000000003FFFC000000000000000003FFFC000000000000000003FFFC0
+00000000000000003FFFC000000000000000003FFFC000000000000000003FFFC0000000
+00000000003FFFC000000000000000003FFFC000000000000000003FFFC0000000000000
+00003FFFC000000000000000003FFFC000000000000000003FFFC000000000000000003F
+FFC000000000000000003FFFC000000000000000003FFFC000000000000000003FFFC000
+000000000000003FFFC000000000000000003FFFC000000000000000003FFFC000000000
+000000003FFFC000000000000000003FFFC000000000000000003FFFC000000000000000
+003FFFC000000000000000003FFFC000000000000000003FFFC000000000000000003FFF
+C000000000000000003FFFC000000000000000003FFFC000000000000000003FFFC00000
+0000000000003FFFC000000000000000003FFFC000000000000000003FFFC00000000000
+0000003FFFC0000000000000FFFFFFFFFFFFF000000000FFFFFFFFFFFFF000000000FFFF
+FFFFFFFFF000000000FFFFFFFFFFFFF000000000FFFFFFFFFFFFF0000053517BD05E>I<
+3FFFFFFFFF8003FFFFFFFF003FFFFFFFFF8003FFFFFFFF003FFFFFFFFF8003FFFFFFFF00
+3FFFFFFFFF8003FFFFFFFF003FFFFFFFFF8003FFFFFFFF000007FFFE00000007FFF80000
+0003FFFF000000007F8000000001FFFF800000007F0000000001FFFFC0000000FE000000
+0000FFFFC0000001FE00000000007FFFE0000001FC00000000007FFFF0000003F8000000
+00003FFFF0000007F800000000001FFFF800000FF000000000000FFFFC00000FE0000000
+00000FFFFC00001FC0000000000007FFFE00003FC0000000000003FFFF00007F80000000
+000003FFFF80007F00000000000001FFFF8000FE00000000000000FFFFC001FE00000000
+000000FFFFE003FC000000000000007FFFE003F8000000000000003FFFF007F000000000
+0000001FFFF80FF0000000000000001FFFFC1FE0000000000000000FFFFC1FC000000000
+00000007FFFE3F800000000000000007FFFF7F800000000000000003FFFFFF0000000000
+00000001FFFFFE000000000000000000FFFFFC000000000000000000FFFFFC0000000000
+000000007FFFF80000000000000000003FFFF00000000000000000003FFFF80000000000
+000000001FFFF80000000000000000000FFFFC00000000000000000007FFFE0000000000
+0000000007FFFE00000000000000000003FFFF00000000000000000001FFFF8000000000
+0000000001FFFFC0000000000000000003FFFFC0000000000000000007FFFFE000000000
+0000000007FFFFF000000000000000000FFFFFF000000000000000001FFFFFF800000000
+000000003FCFFFFC00000000000000003F8FFFFE00000000000000007F07FFFE00000000
+00000000FF03FFFF0000000000000001FE03FFFF8000000000000001FC01FFFF80000000
+00000003F800FFFFC000000000000007F8007FFFE00000000000000FF0007FFFF0000000
+0000000FE0003FFFF00000000000001FC0001FFFF80000000000003FC0001FFFFC000000
+0000003F80000FFFFC0000000000007F000007FFFE000000000000FF000003FFFF000000
+000001FE000003FFFF000000000001FC000001FFFF800000000003F8000000FFFFC00000
+000007F8000000FFFFE0000000000FF00000007FFFE0000000000FE00000003FFFF00000
+00001FC00000003FFFF8000000003FC00000001FFFF8000000007F800000000FFFFC0000
+00007F0000000007FFFE00000000FE0000000007FFFF00000001FE0000000003FFFF0000
+0003FE0000000001FFFF8000003FFFC000000001FFFFC000FFFFFFFF800003FFFFFFFFF8
+FFFFFFFF800003FFFFFFFFF8FFFFFFFF800003FFFFFFFFF8FFFFFFFF800003FFFFFFFFF8
+FFFFFFFF800003FFFFFFFFF85D527CD166>88 D<00007FFF000000000007FFFFF0000000
+003FFFFFFE00000000FFFFFFFF80000001FFE00FFFC0000003FE0001FFF0000007FF0000
+FFF8000007FF80003FFC00000FFF80003FFE00000FFFC0001FFE00000FFFC0001FFF0000
+0FFFC0000FFF80000FFFC0000FFF80000FFFC0000FFF800007FF800007FFC00007FF8000
+07FFC00003FF000007FFC00001FE000007FFC0000000000007FFC0000000000007FFC000
+0000000007FFC0000000000007FFC0000000000007FFC0000000000007FFC0000000007F
+FFFFC00000000FFFFFFFC0000000FFFFFFFFC0000007FFFF87FFC000003FFFF007FFC000
+007FFF8007FFC00001FFFC0007FFC00003FFF00007FFC00007FFE00007FFC0000FFFC000
+07FFC0001FFF800007FFC0003FFF000007FFC0007FFF000007FFC0007FFE000007FFC000
+7FFE000007FFC000FFFC000007FFC000FFFC000007FFC000FFFC000007FFC000FFFC0000
+07FFC000FFFC00000FFFC000FFFC00000FFFC000FFFE00001FFFC0007FFE00001DFFC000
+7FFE00003DFFC0003FFF000079FFE0001FFF8000F1FFF8000FFFC003E1FFFFE007FFF81F
+C0FFFFF003FFFFFF807FFFF000FFFFFF001FFFF0001FFFFC0007FFE00001FFE000000000
+3C387CB641>97 D<003FF0000000000000FFFFF0000000000000FFFFF0000000000000FF
+FFF0000000000000FFFFF0000000000000FFFFF000000000000003FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF001FFE000000000FFF00FFFFE00000000
+FFF03FFFFFC0000000FFF0FFFFFFF0000000FFF3FF01FFF8000000FFF7F8003FFE000000
+FFFFE0000FFF000000FFFF800007FF800000FFFF000003FFC00000FFFE000001FFE00000
+FFFC000001FFF00000FFF8000000FFF80000FFF8000000FFF80000FFF80000007FFC0000
+FFF80000007FFC0000FFF80000007FFE0000FFF80000007FFE0000FFF80000007FFF0000
+FFF80000003FFF0000FFF80000003FFF0000FFF80000003FFF0000FFF80000003FFF8000
+FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000
+FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000
+FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF0000
+FFF80000003FFF0000FFF80000003FFF0000FFF80000003FFF0000FFF80000007FFE0000
+FFF80000007FFE0000FFF80000007FFE0000FFF80000007FFC0000FFF8000000FFFC0000
+FFF8000000FFF80000FFFC000001FFF00000FFFC000001FFF00000FFFE000003FFE00000
+FFFF000007FFC00000FFFF80000FFF800000FFCFC0001FFF000000FF87F0007FFC000000
+FF03FE03FFF8000000FE00FFFFFFE0000000FC007FFFFF80000000F8001FFFFC00000000
+000003FFC000000041547BD24B>I<000001FFF8000000001FFFFF80000000FFFFFFF000
+0003FFFFFFFC00000FFFC00FFE00001FFE0001FF00007FFC0003FF8000FFF00007FF8001
+FFF00007FFC003FFE0000FFFC003FFC0000FFFC007FFC0000FFFC00FFF80000FFFC00FFF
+80000FFFC01FFF800007FF801FFF000007FF803FFF000003FF003FFF000001FE007FFF00
+000000007FFE00000000007FFE00000000007FFE0000000000FFFE0000000000FFFE0000
+000000FFFE0000000000FFFE0000000000FFFE0000000000FFFE0000000000FFFE000000
+0000FFFE0000000000FFFE0000000000FFFE0000000000FFFE0000000000FFFE00000000
+00FFFE00000000007FFE00000000007FFF00000000007FFF00000000003FFF0000000000
+3FFF00000000003FFF00000003E01FFF80000003E01FFF80000007E00FFFC0000007C007
+FFC0000007C007FFE000000FC003FFE000001F8001FFF000003F0000FFF800007E00007F
+FE0000FC00003FFF0003F800000FFFE01FF0000003FFFFFFE0000000FFFFFF800000003F
+FFFE0000000001FFE0000033387CB63C>I<000000000001FF80000000000007FFFF8000
+0000000007FFFF80000000000007FFFF80000000000007FFFF80000000000007FFFF8000
+00000000001FFF8000000000000007FF8000000000000007FF8000000000000007FF8000
+000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF8000
+000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF8000
+000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF8000
+000000000007FF8000000000000007FF8000000000000007FF8000000000000007FF8000
+000000000007FF8000000000000007FF8000000000000007FF8000000001FFE007FF8000
+00001FFFFC07FF80000000FFFFFF07FF80000003FFFFFFC7FF8000000FFFE03FE7FF8000
+001FFF0007F7FF8000007FFC0001FFFF800000FFF80000FFFF800001FFF000003FFF8000
+03FFE000001FFF800007FFC000001FFF800007FFC000000FFF80000FFF8000000FFF8000
+1FFF8000000FFF80001FFF0000000FFF80003FFF0000000FFF80003FFF0000000FFF8000
+3FFF0000000FFF80007FFE0000000FFF80007FFE0000000FFF80007FFE0000000FFF8000
+7FFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000
+FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000
+FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000FFFE0000000FFF8000
+FFFE0000000FFF80007FFE0000000FFF80007FFE0000000FFF80007FFE0000000FFF8000
+3FFF0000000FFF80003FFF0000000FFF80003FFF0000000FFF80001FFF0000000FFF8000
+1FFF0000000FFF80000FFF8000000FFF80000FFF8000001FFF800007FFC000003FFF8000
+03FFC000003FFF800001FFE000007FFF800000FFF00001FFFF8000007FF80003FFFFE000
+003FFE000FEFFFFF80000FFFC07FCFFFFF800007FFFFFF8FFFFF800001FFFFFE0FFFFF80
+00003FFFF80FFFFF80000003FFC00FFE000041547CD24B>I<000003FFC0000000003FFF
+FC00000001FFFFFF00000007FFFFFFC000000FFF81FFE000003FFC007FF800007FF8003F
+FC0000FFF0001FFE0001FFE0000FFE0003FFC00007FF0007FFC00007FF800FFF800003FF
+800FFF800003FFC01FFF800001FFC01FFF000001FFC03FFF000001FFE03FFF000001FFE0
+7FFF000000FFE07FFE000000FFE07FFE000000FFF07FFE000000FFF0FFFE000000FFF0FF
+FE000000FFF0FFFE000000FFF0FFFE000000FFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFF
+FFFFFFFFF0FFFFFFFFFFFFE0FFFE0000000000FFFE0000000000FFFE0000000000FFFE00
+00000000FFFE0000000000FFFE00000000007FFE00000000007FFE00000000007FFF0000
+0000003FFF00000000003FFF00000000003FFF00000000E01FFF00000001F01FFF800000
+03F00FFF80000003F007FFC0000007E007FFC0000007E003FFE000000FC001FFF000001F
+C000FFF800003F80007FFC0000FF00001FFE0003FE00000FFFC03FF8000003FFFFFFF000
+0000FFFFFFC00000001FFFFE0000000001FFF0000034387CB63D>I<0000003FFC000000
+03FFFF0000000FFFFFC000003FFFFFE00000FFF81FF00001FFC03FF80003FF807FF80007
+FF00FFFC000FFE00FFFC001FFC00FFFC001FFC00FFFC003FF800FFFC003FF800FFFC003F
+F8007FF8007FF0007FF8007FF0003FF0007FF0000FC0007FF0000000007FF0000000007F
+F0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000007F
+F0000000007FF0000000007FF0000000007FF0000000007FF0000000007FF0000000FFFF
+FFFFE000FFFFFFFFE000FFFFFFFFE000FFFFFFFFE000FFFFFFFFE000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF8000000007F
+F8000000007FF8000000007FF8000000007FF8000000007FF8000000007FF80000007FFF
+FFFE00007FFFFFFE00007FFFFFFE00007FFFFFFE00007FFFFFFE00002E547CD329>I<00
+003FFF0000FF000003FFFFF007FFC0000FFFFFFC1FFFE0003FFFFFFF7FFFE0007FFC0FFF
+FF9FF000FFE001FFF83FF001FFC000FFE03FF003FF80007FF01FF007FF00003FF81FE00F
+FF00003FFC0FC00FFF00003FFC07801FFE00001FFE00001FFE00001FFE00003FFE00001F
+FF00003FFE00001FFF00003FFE00001FFF00003FFE00001FFF00003FFE00001FFF00003F
+FE00001FFF00003FFE00001FFF00003FFE00001FFF00003FFE00001FFF00001FFE00001F
+FE00001FFE00001FFE00000FFF00003FFC00000FFF00003FFC000007FF00003FF8000003
+FF80007FF0000001FFC000FFE0000000FFE001FFC0000000FFFC0FFF80000001FFFFFFFF
+00000003EFFFFFFC00000003C3FFFFF000000007C03FFF0000000007C000000000000007
+C00000000000000FC00000000000000FC00000000000000FC00000000000000FE0000000
+0000000FE00000000000000FF80000000000000FFE0000000000000FFFFFFFFF00000007
+FFFFFFFFF8000007FFFFFFFFFF000007FFFFFFFFFFC00003FFFFFFFFFFE00001FFFFFFFF
+FFF00000FFFFFFFFFFF800007FFFFFFFFFFC00007FFFFFFFFFFE0001FFFFFFFFFFFF0007
+FFFFFFFFFFFF000FFE000003FFFF801FF80000003FFF803FF000000007FF807FE0000000
+03FFC07FE000000001FFC0FFC000000001FFC0FFC000000000FFC0FFC000000000FFC0FF
+C000000000FFC0FFC000000000FFC0FFC000000000FFC0FFE000000001FFC07FE0000000
+01FF807FF000000003FF803FF000000003FF001FF800000007FE000FFE0000001FFC0007
+FF8000007FF80003FFE00001FFF00001FFFE001FFFE000007FFFFFFFFF8000000FFFFFFF
+FC00000001FFFFFFE0000000000FFFFC0000003C4F7CB543>I<003FF0000000000000FF
+FFF0000000000000FFFFF0000000000000FFFFF0000000000000FFFFF0000000000000FF
+FFF000000000000003FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF000000000000000FFF000000000000000FFF000000000000000FFF000000000000000
+FFF0001FFC00000000FFF000FFFFC0000000FFF003FFFFF0000000FFF00FFFFFF8000000
+FFF01FE07FFC000000FFF03F001FFE000000FFF07C001FFF000000FFF0F0000FFF000000
+FFF1E0000FFF800000FFF3C0000FFF800000FFF7800007FF800000FFF7800007FFC00000
+FFFF000007FFC00000FFFE000007FFC00000FFFE000007FFC00000FFFC000007FFC00000
+FFFC000007FFC00000FFFC000007FFC00000FFFC000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000
+FFF8000007FFC000FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FF
+FFFFF807FFFFFFC0FFFFFFF807FFFFFFC042537BD24B>I<007F000000FF800003FFE000
+07FFF00007FFF0000FFFF8000FFFF8000FFFF8000FFFF8000FFFF8000FFFF8000FFFF800
+07FFF00007FFF00003FFE00000FF8000007F000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+003FF000FFFFF000FFFFF000FFFFF000FFFFF000FFFFF00001FFF00000FFF00000FFF000
+00FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF000
+00FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF000
+00FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF000
+00FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF000
+00FFF00000FFF00000FFF00000FFF000FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0FFFFFFE0
+1B547BD325>I<003FF000FFFFF000FFFFF000FFFFF000FFFFF000FFFFF00001FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000
+FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF00000FFF000FFFFFFF0FF
+FFFFF0FFFFFFF0FFFFFFF0FFFFFFF01C537BD225>108 D<003FF0001FFC000000FFE000
+00FFFFF000FFFFC00007FFFE0000FFFFF003FFFFF0001FFFFF8000FFFFF00FFFFFF8007F
+FFFFC000FFFFF01FE07FFC00FF03FFE000FFFFF03F001FFE01F800FFF00003FFF07C001F
+FF03E000FFF80000FFF0F0000FFF0780007FF80000FFF1E0000FFF8F00007FFC0000FFF3
+C0000FFF9E00007FFC0000FFF7800007FFBC00003FFC0000FFF7800007FFFC00003FFE00
+00FFFF000007FFF800003FFE0000FFFE000007FFF000003FFE0000FFFE000007FFF00000
+3FFE0000FFFC000007FFE000003FFE0000FFFC000007FFE000003FFE0000FFFC000007FF
+E000003FFE0000FFFC000007FFE000003FFE0000FFF8000007FFC000003FFE0000FFF800
+0007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000
+FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003F
+FE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC0
+00003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF80000
+07FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FF
+F8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE
+0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000
+003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007
+FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8
+000007FFC000003FFE0000FFF8000007FFC000003FFE0000FFF8000007FFC000003FFE00
+00FFF8000007FFC000003FFE00FFFFFFF807FFFFFFC03FFFFFFEFFFFFFF807FFFFFFC03F
+FFFFFEFFFFFFF807FFFFFFC03FFFFFFEFFFFFFF807FFFFFFC03FFFFFFEFFFFFFF807FFFF
+FFC03FFFFFFE67367BB570>I<003FF0001FFC000000FFFFF000FFFFC00000FFFFF003FF
+FFF00000FFFFF00FFFFFF80000FFFFF01FE07FFC0000FFFFF03F001FFE000003FFF07C00
+1FFF000000FFF0F0000FFF000000FFF1E0000FFF800000FFF3C0000FFF800000FFF78000
+07FF800000FFF7800007FFC00000FFFF000007FFC00000FFFE000007FFC00000FFFE0000
+07FFC00000FFFC000007FFC00000FFFC000007FFC00000FFFC000007FFC00000FFFC0000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF80000
+07FFC00000FFF8000007FFC00000FFF8000007FFC000FFFFFFF807FFFFFFC0FFFFFFF807
+FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC0FFFFFFF807FFFFFFC042367BB54B
+>I<000001FFE000000000001FFFFE0000000000FFFFFFC000000003FFFFFFF00000000F
+FF807FFC0000001FFC000FFE0000007FF80007FF800000FFF00003FFC00001FFE00001FF
+E00003FFC00000FFF00003FF8000007FF00007FF8000007FF8000FFF0000003FFC000FFF
+0000003FFC001FFF0000003FFE001FFF0000003FFE003FFE0000001FFF003FFE0000001F
+FF003FFE0000001FFF007FFE0000001FFF807FFE0000001FFF807FFE0000001FFF807FFE
+0000001FFF80FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001F
+FFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE
+0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC0FFFE0000001FFFC07FFE0000001F
+FF807FFE0000001FFF807FFE0000001FFF803FFE0000001FFF003FFF0000003FFF003FFF
+0000003FFF001FFF0000003FFE001FFF0000003FFE000FFF0000003FFC000FFF8000007F
+FC0007FF8000007FF80003FFC00000FFF00001FFE00001FFE00000FFF00003FFC000007F
+F80007FF8000003FFE001FFF0000000FFF807FFC00000007FFFFFFF800000000FFFFFFC0
+000000003FFFFF000000000001FFE00000003A387CB643>I<003FF001FFE0000000FFFF
+F00FFFFE000000FFFFF03FFFFFC00000FFFFF0FFFFFFF00000FFFFF3FF01FFF80000FFFF
+F7F8007FFE000003FFFFE0001FFF000000FFFF80000FFF800000FFFF000007FFC00000FF
+FE000007FFE00000FFFC000003FFF00000FFF8000001FFF80000FFF8000001FFF80000FF
+F8000000FFFC0000FFF8000000FFFC0000FFF8000000FFFE0000FFF80000007FFE0000FF
+F80000007FFF0000FFF80000007FFF0000FFF80000007FFF0000FFF80000007FFF0000FF
+F80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FF
+F80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FF
+F80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FFF80000003FFF8000FF
+F80000003FFF0000FFF80000007FFF0000FFF80000007FFF0000FFF80000007FFF0000FF
+F80000007FFE0000FFF8000000FFFE0000FFF8000000FFFE0000FFF8000000FFFC0000FF
+F8000001FFFC0000FFF8000001FFF80000FFFC000003FFF00000FFFC000003FFF00000FF
+FE000007FFE00000FFFF00000FFFC00000FFFF80001FFF800000FFFFC0003FFF000000FF
+FFF000FFFC000000FFFBFE07FFF8000000FFF8FFFFFFE0000000FFF87FFFFF80000000FF
+F81FFFFC00000000FFF803FFC000000000FFF800000000000000FFF800000000000000FF
+F800000000000000FFF800000000000000FFF800000000000000FFF800000000000000FF
+F800000000000000FFF800000000000000FFF800000000000000FFF800000000000000FF
+F800000000000000FFF800000000000000FFF800000000000000FFF800000000000000FF
+F800000000000000FFF800000000000000FFF8000000000000FFFFFFF80000000000FFFF
+FFF80000000000FFFFFFF80000000000FFFFFFF80000000000FFFFFFF80000000000414D
+7BB54B>I<007FE003FE00FFFFE00FFF80FFFFE03FFFE0FFFFE07FFFF0FFFFE0FE1FF8FF
+FFE1F83FFC03FFE3E03FFE00FFE3C07FFE00FFE7807FFE00FFEF807FFE00FFEF007FFE00
+FFEE007FFE00FFFE003FFC00FFFC003FFC00FFFC001FF800FFFC000FF000FFF800000000
+FFF800000000FFF800000000FFF800000000FFF800000000FFF000000000FFF000000000
+FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000
+FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000
+FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000
+FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000FFF000000000
+FFF000000000FFF0000000FFFFFFFC0000FFFFFFFC0000FFFFFFFC0000FFFFFFFC0000FF
+FFFFFC00002F367CB537>114 D<0003FFF00F00003FFFFE1F0000FFFFFFFF0003FFFFFF
+FF0007FF003FFF000FF80007FF001FE00001FF003FC00000FF003F8000007F007F800000
+7F007F0000003F007F0000003F00FF0000001F00FF0000001F00FF8000001F00FF800000
+1F00FFC000001F00FFF000000000FFFC00000000FFFFC00000007FFFFF0000007FFFFFF8
+00003FFFFFFF00003FFFFFFFC0001FFFFFFFF0000FFFFFFFF80007FFFFFFFC0003FFFFFF
+FE0000FFFFFFFF00003FFFFFFF80000FFFFFFFC00000FFFFFFC0000007FFFFE00000003F
+FFE000000007FFF000000001FFF0780000007FF0F80000003FF0F80000001FF0FC000000
+1FF0FC0000000FF0FC0000000FF0FE0000000FF0FE0000000FE0FF0000000FE0FF800000
+1FE0FF8000001FC0FFC000001FC0FFE000003F80FFF800007F00FFFE0001FE00FFFFC00F
+FC00FF7FFFFFF800FC1FFFFFE000F807FFFF8000F000FFF800002C387CB635>I<00003E
+00000000003E00000000003E00000000003E00000000003E00000000003E00000000007E
+00000000007E00000000007E00000000007E0000000000FE0000000000FE0000000001FE
+0000000001FE0000000001FE0000000003FE0000000007FE0000000007FE000000000FFE
+000000001FFE000000003FFE00000000FFFE00000001FFFE0000000FFFFFFFFF00FFFFFF
+FFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFFFFFFF00003FFE000000003FFE000000003FFE
+000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE
+000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE
+000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE
+000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE000000003FFE
+000000003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE
+0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0003FFE0007C0001FFE
+000F80001FFF000F80001FFF000F80000FFF001F00000FFF801F000007FFC03E000003FF
+F0FC000001FFFFF80000007FFFF00000001FFFE000000003FF80002A4D7ECB34>I<003F
+F8000001FFC000FFFFF80007FFFFC000FFFFF80007FFFFC000FFFFF80007FFFFC000FFFF
+F80007FFFFC000FFFFF80007FFFFC00003FFF800001FFFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FF
+F8000007FFC00000FFF8000007FFC00000FFF8000007FFC00000FFF800000FFFC00000FF
+F800000FFFC00000FFF800000FFFC00000FFF800001FFFC00000FFF800001FFFC000007F
+F800003FFFC000007FF800003BFFC000007FF800007BFFC000003FFC0000F3FFC000003F
+FC0001E3FFF000001FFE0007C3FFFFC0000FFFC03F83FFFFC00007FFFFFF03FFFFC00001
+FFFFFE03FFFFC000007FFFF803FFFFC0000007FFE003FF000042377BB54B>I<FFFFFFE0
+7FFFFFC003FFFFC0FFFFFFE07FFFFFC003FFFFC0FFFFFFE07FFFFFC003FFFFC0FFFFFFE0
+7FFFFFC003FFFFC0FFFFFFE07FFFFFC003FFFFC001FFF00000FFF000001FF80001FFF800
+007FF0000007E00000FFF800007FF8000007C00000FFF800007FF8000007C00000FFFC00
+003FF800000FC000007FFC00003FFC00000F8000007FFC00003FFC00000F8000007FFE00
+003FFC00001F8000003FFE00007FFE00001F0000003FFF00007FFE00003F0000001FFF00
+007FFF00003E0000001FFF0000FFFF00003E0000001FFF8000FFFF00007E0000000FFF80
+01FFFF80007C0000000FFFC001F3FF8000FC00000007FFC001F3FFC000F800000007FFC0
+03F3FFC000F800000007FFE003E1FFC001F800000003FFE007E1FFE001F000000003FFF0
+07C0FFE001F000000001FFF007C0FFF003E000000001FFF00FC0FFF003E000000001FFF8
+0F807FF007E000000000FFF80F807FF807C000000000FFF81F003FF807C000000000FFFC
+1F003FF80FC0000000007FFC3F003FFC0F80000000007FFE3E001FFC1F80000000003FFE
+3E001FFE1F00000000003FFE7E001FFE1F00000000003FFF7C000FFE3F00000000001FFF
+FC000FFF3E00000000001FFFF80007FF7E00000000000FFFF80007FFFC00000000000FFF
+F80007FFFC00000000000FFFF00003FFFC000000000007FFF00003FFF8000000000007FF
+E00001FFF8000000000003FFE00001FFF0000000000003FFE00001FFF0000000000003FF
+C00000FFF0000000000001FFC00000FFE0000000000001FF8000007FE0000000000001FF
+8000007FE0000000000000FF8000007FC0000000000000FF0000003FC00000000000007F
+0000003F800000000000007F0000003F800000000000003E0000001F000000005A367DB4
+61>119 D<7FFFFFF0007FFFFE007FFFFFF0007FFFFE007FFFFFF0007FFFFE007FFFFFF0
+007FFFFE007FFFFFF0007FFFFE00007FFE00000FFF0000003FFF000007F80000001FFF80
+0007F00000000FFFC0000FE000000007FFC0001FC000000007FFE0003F8000000003FFF0
+003F0000000001FFF8007E0000000000FFFC00FC00000000007FFE01FC00000000007FFE
+03F800000000003FFF07F000000000001FFF8FE000000000000FFFCFC0000000000007FF
+FF80000000000003FFFF00000000000003FFFF00000000000001FFFE00000000000000FF
+FC000000000000007FFE000000000000003FFF000000000000003FFF000000000000001F
+FF800000000000001FFFC00000000000003FFFE00000000000007FFFF0000000000000FF
+FFF0000000000001FDFFF8000000000001F8FFFC000000000003F07FFE000000000007E0
+3FFF00000000000FE01FFF00000000001FC01FFF80000000003F800FFFC0000000007F00
+07FFE000000000FE0003FFF000000000FC0001FFF800000001F80001FFF800000003F000
+00FFFC00000007F000007FFE0000000FE000003FFF0000001FC000001FFF800000FFF000
+001FFF8000FFFFFE0001FFFFFFC0FFFFFE0001FFFFFFC0FFFFFE0001FFFFFFC0FFFFFE00
+01FFFFFFC0FFFFFE0001FFFFFFC042357EB447>I<FFFFFFF00007FFFFFFFFFFF00007FF
+FFFFFFFFF00007FFFFFFFFFFF00007FFFFFFFFFFF00007FFFF00FFF80000007FE000FFFC
+0000003F0000FFFC0000003F00007FFE0000003E00007FFE0000007E00003FFE0000007C
+00003FFF000000FC00001FFF000000F800001FFF800001F800000FFF800001F000000FFF
+C00003F0000007FFC00003E0000007FFE00003E0000007FFE00007E0000003FFF00007C0
+000003FFF0000FC0000001FFF8000F80000001FFF8001F80000000FFF8001F00000000FF
+FC003F000000007FFC003E000000007FFE007E000000003FFE007C000000003FFF00FC00
+0000003FFF00FC000000001FFF80F8000000001FFF81F8000000000FFFC1F0000000000F
+FFC3F00000000007FFC3E00000000007FFE7E00000000003FFE7C00000000003FFFFC000
+00000001FFFF800000000001FFFF800000000000FFFF000000000000FFFF000000000000
+FFFF0000000000007FFE0000000000007FFE0000000000003FFC0000000000003FFC0000
+000000001FF80000000000001FF80000000000000FF00000000000000FF0000000000000
+07E000000000000007E000000000000007E000000000000007C00000000000000FC00000
+000000000F800000000000001F800000000000001F000000000000003F000000001FC000
+3E000000003FE0007E000000007FF0007C00000000FFF800FC00000000FFF800F8000000
+00FFF801F800000000FFF801F000000000FFF803F000000000FFF807E0000000007FF00F
+C0000000007FE01F80000000003FC07F00000000003F81FE00000000001FFFFC00000000
+000FFFF0000000000003FFE0000000000000FF000000000000404D7DB447>I
+E /Fv 8 121 df<FFFFFCFFFFFCFFFFFCFFFFFCFFFFFC16057E941F>45
+D<0000000E000000000000000E000000000000000E000000000000001F00000000000000
+1F000000000000003F800000000000003F800000000000003F800000000000007FC00000
+000000007FC00000000000007FC0000000000000DFE0000000000000DFE0000000000001
+DFF00000000000018FF00000000000018FF00000000000030FF800000000000307F80000
+0000000307F800000000000607FC00000000000603FC00000000000E03FE00000000000C
+01FE00000000000C01FE00000000001C01FF00000000001800FF00000000001800FF0000
+0000003000FF800000000030007F800000000030007F800000000060003FC00000000060
+003FC000000000E0003FE000000000C0001FE000000000C0001FE00000000180001FF000
+00000180000FF00000000180000FF000000003FFFFFFF800000003FFFFFFF800000007FF
+FFFFFC00000006000003FC00000006000003FC0000000C000003FE0000000C000001FE00
+00000C000001FE00000018000001FF00000018000000FF00000018000000FF0000003000
+00007F800000300000007F800000700000007FC00000600000003FC00000E00000003FC0
+0000F00000003FE00003F00000003FE0000FFC0000007FF800FFFF80000FFFFFE0FFFF80
+000FFFFFE0FFFF80000FFFFFE03B3C7CBB44>65 D<FFFFFFFFFFFFC0FFFFFFFFFFFFC0FF
+FFFFFFFFFFC000FFC00000FFC0007F8000001FC0007F80000007E0007F80000003E0007F
+80000001E0007F80000001E0007F80000000E0007F80000000E0007F8000000060007F80
+00000060007F8000000060007F8000000070007F8000000030007F8000180030007F8000
+180030007F8000180030007F8000180000007F8000180000007F8000180000007F800038
+0000007F8000380000007F8000780000007F8003F80000007FFFFFF80000007FFFFFF800
+00007FFFFFF80000007F8003F80000007F8000780000007F8000380000007F8000380000
+007F8000180000007F8000180000007F8000180006007F8000180006007F800018000600
+7F800018000E007F800000000C007F800000000C007F800000000C007F800000000C007F
+800000001C007F800000001C007F800000001C007F8000000038007F8000000038007F80
+00000078007F80000000F8007F80000001F8007F80000003F8007F8000000FF800FFC000
+007FF0FFFFFFFFFFFFF0FFFFFFFFFFFFF0FFFFFFFFFFFFF037397DB83E>69
+D<FFFFFFFFE0FFFFFFFFE007F8000FE003F00003E003F00000F003F000007003F0000070
+03F000003003F000003003F000003003F000003003F000001803F000001803F000C01803
+F000C00003F000C00003F000C00003F001C00003F001C00003F007C00003FFFFC00003FF
+FFC00003F007C00003F001C00003F001C00003F000C00003F000C00003F000C00603F000
+C00603F000000603F000000603F000000C03F000000C03F000000C03F000000C03F00000
+1C03F000001C03F000003C03F000007C03F00000F807F80007F8FFFFFFFFF8FFFFFFFFF8
+272B7CAA2E>101 D<FFFFFFE000FFFFFFFC0007F800FE0003F0001F8003F0000FC003F0
+0007E003F00007F003F00003F003F00003F003F00003F803F00003F803F00003F803F000
+03F803F00003F803F00003F003F00003F003F00007F003F00007E003F0000FC003F0001F
+8003F000FE0003FFFFFC0003FFFFE00003F000000003F000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F000000007F8000000FFFF
+C00000FFFFC00000252B7CAA2E>112 D<FFFFFF800000FFFFFFF0000007F800FE000003
+F0003F000003F0000FC00003F00007E00003F00007E00003F00003F00003F00003F80003
+F00003F80003F00003F80003F00003F80003F00003F80003F00003F80003F00003F00003
+F00007E00003F00007E00003F0000FC00003F0003F000003F000FE000003FFFFF0000003
+FFFFE0000003F001F8000003F0007E000003F0003F000003F0001F800003F0001F800003
+F0000FC00003F0000FC00003F0000FC00003F0000FC00003F0000FC00003F0000FE00003
+F0000FE00003F0000FE00003F0000FE00003F0000FE01803F0000FF01803F00007F01803
+F00007F03807F80003F830FFFFC001F870FFFFC0007FE0000000001F802D2C7CAA32>
+114 D<007F006001FFE0E00780F9E00E001FE01C0007E0380003E0780003E0700001E0F0
+0000E0F00000E0F00000E0F0000060F8000060F8000060FC000000FE0000007F0000007F
+C000003FFE00003FFFE0001FFFF80007FFFE0003FFFF0000FFFF80000FFFC00000FFC000
+000FE0000007E0000003F0000001F0000001F0C00001F0C00000F0C00000F0C00000F0E0
+0000F0E00000E0F00001E0F00001E0F80003C0FC000780FF000F00F3E01E00E0FFF800C0
+1FE0001C2D7BAB26>I<7FFF800FFFC07FFF800FFFC007FF0003FE0003FE0001F80001FE
+0001F00000FE0001C000007F0003C000003F00038000003F80070000001FC0060000000F
+E00C0000000FE01C00000007F03800000003F83000000001F86000000001FCE000000000
+FEC0000000007F80000000007F80000000003F80000000001FC0000000000FC000000000
+1FE0000000003FF00000000033F00000000063F800000000E1FC00000000C0FE00000001
+807E00000003807F00000007003F80000006001F8000000C001FC000001C000FE0000038
+0007F00000300003F00000700003F80000F00001FC0001F00001FE0007F00001FF001FF8
+0003FF80FFFC0007FFF8FFFC0007FFF82D2B7DAA33>120 D E /Fw
+1 66 df<00000E00000000000E00000000001F00000000001F00000000001F0000000000
+3F80000000003F80000000003F80000000006FC0000000006FC000000000EFE000000000
+C7E000000000C7E00000000183F00000000183F00000000183F00000000301F800000003
+01F80000000601FC0000000600FC0000000600FC0000000C007E0000000C007E0000001C
+007F00000018003F00000018003F00000030003F8000003FFFFF8000003FFFFF80000060
+000FC0000060000FC00000E0000FE00000C00007E00000C00007E00001800003F0000180
+0003F00003800003F80003800001F80007800001F8001FC00003FC00FFF8003FFFE0FFF8
+003FFFE02B2A7EA931>65 D E /Fx 31 122 df<00000FF8000000007FFE00000001F807
+80000007E001C000001F8000E000003F0007E000007E000FF000007E000FF00000FC000F
+F00000FC000FF00001F8000FF00001F80007E00001F80001800001F80000000001F80000
+000001F80000000001F80000000001F80000000001F80000000001F80000000001F80000
+000001F80000000001F80003F000FFFFFFFFF000FFFFFFFFF000FFFFFFFFF00001F8000F
+F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003
+F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003
+F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003
+F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003F00001F80003
+F00001F80003F00001F80003F00001F80003F00001F80003F00003FC0007F8007FFFE0FF
+FFC07FFFE0FFFFC07FFFE0FFFFC02A3B7FBA2E>12 D<FFFFFCFFFFFCFFFFFCFFFFFCFFFF
+FC16057F941C>45 D<1C007F00FF80FF80FF80FF80FF807F001C000909798817>I<FFFF
+FFFFC00000FFFFFFFFF80000FFFFFFFFFE000001FF8001FF800000FF00003FE00000FF00
+000FF00000FF000003F80000FF000001FC0000FF000000FE0000FF0000007F0000FF0000
+007F0000FF0000003F8000FF0000003FC000FF0000001FC000FF0000001FE000FF000000
+0FE000FF0000000FF000FF0000000FF000FF0000000FF000FF00000007F800FF00000007
+F800FF00000007F800FF00000007F800FF00000007FC00FF00000007FC00FF00000007FC
+00FF00000007FC00FF00000007FC00FF00000007FC00FF00000007FC00FF00000007FC00
+FF00000007FC00FF00000007FC00FF00000007FC00FF00000007FC00FF00000007F800FF
+00000007F800FF00000007F800FF00000007F800FF0000000FF000FF0000000FF000FF00
+00000FE000FF0000000FE000FF0000001FE000FF0000001FC000FF0000003F8000FF0000
+003F8000FF0000007F0000FF000000FE0000FF000001FC0000FF000003F80000FF00000F
+F00000FF00003FE00001FF8000FF8000FFFFFFFFFF0000FFFFFFFFF80000FFFFFFFFC000
+0036397DB83F>68 D<FFFFFFFFFFFC00FFFFFFFFFFFC00FFFFFFFFFFFC0001FF80000FFC
+0000FF000001FC0000FF0000007E0000FF0000003E0000FF0000001E0000FF0000000E00
+00FF0000000E0000FF0000000E0000FF000000060000FF000000060000FF000000060000
+FF000000070000FF000000030000FF0000C0030000FF0000C0030000FF0000C0030000FF
+0000C0000000FF0000C0000000FF0000C0000000FF0001C0000000FF0001C0000000FF00
+03C0000000FF000FC0000000FFFFFFC0000000FFFFFFC0000000FFFFFFC0000000FF000F
+C0000000FF0003C0000000FF0001C0000000FF0001C0000000FF0000C0000000FF0000C0
+000000FF0000C0006000FF0000C0006000FF0000C0006000FF0000C000E000FF00000000
+C000FF00000000C000FF00000000C000FF00000000C000FF00000001C000FF00000001C0
+00FF00000001C000FF000000038000FF000000038000FF000000078000FF000000078000
+FF0000000F8000FF0000003F8000FF0000007F8001FF800007FF00FFFFFFFFFFFF00FFFF
+FFFFFFFF00FFFFFFFFFFFF0033397DB839>I<FFFFFFE00000FFFFFFE00000FFFFFFE000
+0001FFC000000000FF0000000000FF0000000000FF0000000000FF0000000000FF000000
+0000FF0000000000FF0000000000FF0000000000FF0000000000FF0000000000FF000000
+0000FF0000000000FF0000000000FF0000000000FF0000000000FF0000000000FF000000
+0000FF0000000000FF0000000000FF0000000000FF0000000000FF0000000000FF000000
+0000FF0000000000FF0000000000FF0000000000FF0000000000FF0000000000FF000000
+0000FF0000000000FF0000000000FF0000001800FF0000001800FF0000001800FF000000
+1800FF0000001800FF0000003800FF0000003000FF0000003000FF0000003000FF000000
+7000FF0000007000FF0000007000FF000000F000FF000000F000FF000001F000FF000003
+F000FF00000FF000FF00001FE001FF8000FFE0FFFFFFFFFFE0FFFFFFFFFFE0FFFFFFFFFF
+E02D397DB834>76 D<000FF800C0003FFE01C000FFFF81C003F807E3C007E000F7C00FC0
+007FC01F80003FC03F00001FC03E00000FC07E000007C07E000007C07C000003C0FC0000
+03C0FC000001C0FC000001C0FC000001C0FE000000C0FE000000C0FE000000C0FF000000
+C0FF800000007FC00000007FE00000007FF80000003FFF8000001FFFF800001FFFFF8000
+0FFFFFE00007FFFFF80003FFFFFE0000FFFFFF00003FFFFF800007FFFFC000007FFFC000
+0007FFE00000007FE00000003FF00000001FF00000000FF000000007F800000007F8C000
+0003F8C0000003F8C0000001F8C0000001F8C0000001F8E0000001F8E0000001F8E00000
+01F0F0000001F0F0000003F0F8000003E0FC000007E0FE000007C0FF00000FC0FF80001F
+80FBF0003F00F0FE00FE00E03FFFF800E00FFFE000C001FF0000253D7CBA2E>83
+D<3FFFFFFFFFFFE03FFFFFFFFFFFE03FFFFFFFFFFFE03FC003FF001FE03E0001FE0003E0
+7C0001FE0001F0780001FE0000F0700001FE000070700001FE000070700001FE00007060
+0001FE000030600001FE000030600001FE000030600001FE000030E00001FE000038C000
+01FE000018C00001FE000018C00001FE000018C00001FE000018000001FE000000000001
+FE000000000001FE000000000001FE000000000001FE000000000001FE000000000001FE
+000000000001FE000000000001FE000000000001FE000000000001FE000000000001FE00
+0000000001FE000000000001FE000000000001FE000000000001FE000000000001FE0000
+00000001FE000000000001FE000000000001FE000000000001FE000000000001FE000000
+000001FE000000000001FE000000000001FE000000000001FE000000000001FE00000000
+0001FE000000000001FE000000000001FE000000000001FE000000000001FE0000000000
+01FE000000000001FE000000000007FF800000001FFFFFFFE000001FFFFFFFE000001FFF
+FFFFE00035397DB83C>I<7FFFFF003FFFFC007FFFFF003FFFFC007FFFFF003FFFFC0000
+FFF80007FF8000007FE00003FC0000003FE00001F00000001FF00001E00000001FF00001
+C00000000FF800018000000007FC00038000000007FC00070000000003FE000600000000
+03FE000E0000000001FF001C0000000000FF80180000000000FF803800000000007FC030
+00000000003FE06000000000003FE0E000000000001FF0C000000000000FF18000000000
+000FFB80000000000007FF00000000000007FE00000000000003FE00000000000001FF00
+000000000001FF00000000000000FF800000000000007FC00000000000007FC000000000
+0000FFE0000000000000DFE00000000000019FF00000000000038FF80000000000030FF8
+00000000000607FC00000000000E03FE00000000000C03FE00000000001801FF00000000
+003800FF00000000003000FF800000000060007FC000000000E0007FC000000000C0003F
+E00000000180001FF00000000380001FF00000000300000FF800000006000007FC000000
+0E000007FC0000000C000003FE0000001C000001FE0000003C000001FF000000FE000001
+FF800007FF800007FFE000FFFFE0003FFFFF80FFFFE0003FFFFF80FFFFE0003FFFFF8039
+397EB83E>88 D<001FE0000000FFFC000003E03F000007000F80000F8007E0001FC003F0
+001FE003F0001FE001F8001FE001F8001FE000FC000FC000FC00078000FC00000000FC00
+000000FC00000000FC00000000FC0000007FFC000007FFFC00003FE0FC0000FE00FC0003
+F800FC000FF000FC001FC000FC003FC000FC007F8000FC007F0000FC007F0000FC0CFE00
+00FC0CFE0000FC0CFE0000FC0CFE0001FC0CFE0001FC0CFF0003FC0C7F00077C0C7F8006
+3E183FC01E3E180FE0781FF003FFF00FE0007F8007C026277DA52A>97
+D<03F0000000FFF0000000FFF0000000FFF00000000FF000000003F000000003F0000000
+03F000000003F000000003F000000003F000000003F000000003F000000003F000000003
+F000000003F000000003F000000003F000000003F000000003F000000003F000000003F0
+1FE00003F07FF80003F1E03E0003F3801F8003F7000FC003FE0007E003FC0003F003F800
+01F803F00001F803F00000FC03F00000FC03F00000FE03F00000FE03F000007E03F00000
+7F03F000007F03F000007F03F000007F03F000007F03F000007F03F000007F03F000007F
+03F000007F03F000007F03F000007E03F00000FE03F00000FE03F00000FC03F00001FC03
+F80001F803F80003F003FC0003F003EE0007E003C6000FC003C7801F000381E07E000300
+FFF80000001FC000283B7EB92E>I<0003FC00001FFF80007E03E001F8007003F000F807
+E001FC0FC003FC0FC003FC1F8003FC3F8003FC3F0001F87F0000F07F0000007F0000007E
+000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE
+000000FE0000007E0000007F0000007F0000003F0000063F8000061F80000E1FC0000C0F
+C0001C07E0003803F0007001F800E0007C07C0001FFF000007F8001F277DA525>I<0000
+000FC0000003FFC0000003FFC0000003FFC00000003FC00000000FC00000000FC0000000
+0FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000F
+C00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00003F80FC0
+001FFF0FC0007E078FC000F801EFC003F0007FC007E0003FC00FC0001FC00FC0001FC01F
+80000FC03F80000FC03F00000FC07F00000FC07F00000FC07E00000FC0FE00000FC0FE00
+000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE00000FC0FE0000
+0FC0FE00000FC07E00000FC07F00000FC07F00000FC03F00000FC03F00000FC01F80001F
+C01F80001FC00FC0003FC007E0007FC003F000EFF001F801CFFF007C078FFF001FFE0FFF
+0007F80FC0283B7DB92E>I<0007F800001FFF00007C0FC001F803E003F001F007E001F8
+0FC000F81F80007C1F80007C3F00007E3F00003E7F00003E7F00003F7E00003FFE00003F
+FE00003FFE00003FFFFFFFFFFFFFFFFFFE000000FE000000FE000000FE000000FE000000
+7E0000007E0000007F0000007F0000003F0000033F8000031F8000070FC0000607C0000E
+07E0001C01F0003800F80070007E03E0001FFF800003FC0020277EA525>I<00007E0000
+03FF80000FC1E0001F87E0003F0FF0007E0FF0007E0FF000FC0FF000FC0FF001F803C001
+F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001
+F8000001F8000001F8000001F80000FFFFFC00FFFFFC00FFFFFC0001F8000001F8000001
+F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001
+F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001
+F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000003
+FC00007FFFF8007FFFF8007FFFF8001C3B7FBA19>I<00000003F0000FF00FF8003FFC3C
+3C00F81F707C01F00FE07C03E007C07C07C003E0100FC003F0000FC003F0001F8001F800
+1F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8001F8000F
+C003F0000FC003F00007C003E00003E007C00003F00F800003F81F0000073FFC0000060F
+F000000E000000000E000000000E000000000E000000000F000000000F000000000FC000
+000007FFFFC00007FFFFF80003FFFFFE0001FFFFFF8003FFFFFFC00F80007FE01F00000F
+F03E000003F07C000001F07C000001F8F8000000F8F8000000F8F8000000F8F8000000F8
+F8000000F8FC000001F87C000001F03E000003E03F000007E00F80000F8007E0003F0001
+FC01FC00007FFFF0000007FF000026387EA52A>I<03F000000000FFF000000000FFF000
+000000FFF0000000000FF00000000003F00000000003F00000000003F00000000003F000
+00000003F00000000003F00000000003F00000000003F00000000003F00000000003F000
+00000003F00000000003F00000000003F00000000003F00000000003F00000000003F000
+00000003F00FF0000003F03FFC000003F0F03F000003F1C01F800003F3800FC00003F700
+0FC00003FE000FC00003FC0007E00003FC0007E00003F80007E00003F80007E00003F800
+07E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F000
+07E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F000
+07E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F000
+07E00003F00007E00003F00007E00003F00007E00007F8000FF000FFFFC1FFFF80FFFFC1
+FFFF80FFFFC1FFFF80293A7EB92E>I<0380000FE0001FF0001FF0001FF0001FF0001FF0
+000FE0000380000000000000000000000000000000000000000000000000000000000000
+0003F000FFF000FFF000FFF00007F00003F00003F00003F00003F00003F00003F00003F0
+0003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F0
+0003F00003F00003F00003F00003F00003F00003F00003F00003F00007F800FFFFC0FFFF
+C0FFFFC012387EB717>I<03F000FFF000FFF000FFF0000FF00003F00003F00003F00003
+F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003
+F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003
+F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003F00003
+F00003F00003F00003F00003F00003F00003F00003F00003F00003F00007F800FFFFC0FF
+FFC0FFFFC0123A7EB917>108 D<03F00FF0001FE000FFF03FFC007FF800FFF0F03F01E0
+7E00FFF1C01F83803F000FF3800FC7001F8003F7000FCE001F8003FE000FDC001F8003FC
+0007F8000FC003FC0007F8000FC003F80007F0000FC003F80007F0000FC003F80007F000
+0FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F0
+0007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E000
+0FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F0
+0007E0000FC003F00007E0000FC003F00007E0000FC003F00007E0000FC003F00007E000
+0FC003F00007E0000FC003F00007E0000FC003F00007E0000FC007F8000FF0001FE0FFFF
+C1FFFF83FFFFFFFFC1FFFF83FFFFFFFFC1FFFF83FFFF40257EA445>I<03F00FF00000FF
+F03FFC0000FFF0F03F0000FFF1C01F80000FF3800FC00003F7000FC00003FE000FC00003
+FC0007E00003FC0007E00003F80007E00003F80007E00003F80007E00003F00007E00003
+F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003
+F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003
+F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003
+F00007E00003F00007E00007F8000FF000FFFFC1FFFF80FFFFC1FFFF80FFFFC1FFFF8029
+257EA42E>I<0003FE0000000FFF8000003E03E00000F800F80001F0007C0003E0003E00
+07C0001F000F80000F801F80000FC01F000007C03F000007E03F000007E07E000003F07E
+000003F07E000003F07E000003F0FE000003F8FE000003F8FE000003F8FE000003F8FE00
+0003F8FE000003F8FE000003F8FE000003F8FE000003F87E000003F07E000003F07F0000
+07F03F000007E03F000007E01F80000FC00F80000F800FC0001F8007E0003F0003F0007E
+0000F800F800007E03F000001FFFC0000003FE000025277EA52A>I<03F01FE000FFF07F
+F800FFF1E07E00FFF3801F8007F7000FC003FE0007E003FC0003F003F80003F803F00001
+F803F00001FC03F00000FC03F00000FE03F00000FE03F00000FE03F000007F03F000007F
+03F000007F03F000007F03F000007F03F000007F03F000007F03F000007F03F000007F03
+F000007F03F00000FE03F00000FE03F00000FE03F00001FC03F00001FC03F80003F803F8
+0003F003FC0007F003FE000FE003F6000FC003F7803F0003F1E07E0003F0FFF80003F01F
+C00003F000000003F000000003F000000003F000000003F000000003F000000003F00000
+0003F000000003F000000003F000000003F000000007F8000000FFFFC00000FFFFC00000
+FFFFC0000028357EA42E>I<07E01F00FFE07FC0FFE1E3E0FFE387F00FE707F003E607F0
+03EE07F003EC03E003FC008003F8000003F8000003F8000003F8000003F0000003F00000
+03F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00000
+03F0000003F0000003F0000003F0000003F0000003F0000003F0000003F0000003F00000
+07F80000FFFFF000FFFFF000FFFFF0001C257EA421>114 D<00FF030003FFE7000F80FF
+001E003F003C001F0078000F0070000700F0000700F0000700F0000300F8000300F80003
+00FC000300FF0000007FE000007FFF00003FFFE0001FFFF8000FFFFC0003FFFE0000FFFF
+000007FF8000007F8000001F80C0000FC0C00007C0C00007C0E00003C0E00003C0E00003
+C0F00003C0F0000380F8000780FC000780FC000F00FF001E00F3C07C00E1FFF000C03F80
+001A277DA521>I<00180000001800000018000000180000001800000038000000380000
+0038000000780000007800000078000000F8000001F8000003F8000007F800001FFFFF00
+FFFFFF00FFFFFF0001F8000001F8000001F8000001F8000001F8000001F8000001F80000
+01F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F80000
+01F8000001F8000001F800C001F800C001F800C001F800C001F800C001F800C001F800C0
+01F800C001F800C000FC01C000FC0180007C0380007E0300003F0700000FFE000001F800
+1A347FB220>I<03F00007E000FFF001FFE000FFF001FFE000FFF001FFE0000FF0001FE0
+0003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E0
+0003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E0
+0003F00007E00003F00007E00003F00007E00003F00007E00003F00007E00003F00007E0
+0003F00007E00003F00007E00003F00007E00003F00007E00003F0000FE00003F0000FE0
+0003F0000FE00003F0001FE00001F0001FE00001F8003FE00000F80077F80000FC00E7FF
+80003F03C7FF80001FFF87FF800003FC07E00029267EA42E>I<FFFF803FFEFFFF803FFE
+FFFF803FFE0FF8000FF007F00007E003F00003C003F800038001F800030001F800030000
+FC00060000FC00060000FE000E00007E000C00007E000C00003F001800003F001800003F
+803800001F803000001F803000000FC06000000FC06000000FE060000007E0C0000007E0
+C0000003F180000003F180000003F180000001FB00000001FB00000001FF00000000FE00
+000000FE000000007C000000007C000000007C00000000380000000038000027257EA32C
+>I<FFFF1FFFE03FFEFFFF1FFFE03FFEFFFF1FFFE03FFE0FF800FF000FF807F0007E0003
+E007F0007E0003C003F0003E00018003F0003E00018001F8003F00030001F8003F000300
+01F8003F00030000FC003F80060000FC006F80060000FC006F800600007E00EFC00C0000
+7E00C7C00C00007E00C7C00C00003F01C7E01800003F0183E01800003F8183F03800001F
+8383F03000001F8301F03000001FC301F87000000FC600F86000000FC600F860000007E6
+00FCC0000007EC007CC0000007EC007CC0000003FC007F80000003F8003F80000003F800
+3F80000001F8003F00000001F0001F00000001F0001F00000000F0001E00000000E0000E
+0000000060000C000037257EA33C>I<FFFF807FFF00FFFF807FFF00FFFF807FFF0003FE
+003FF00001FE001F800000FE001F0000007E001C0000003F00180000001F80300000001F
+C0700000000FC0E000000007E0C000000007F18000000003FB8000000001FF0000000000
+FE0000000000FE00000000007F00000000003F00000000007F80000000007FC000000000
+CFC000000001C7E00000000383F00000000703F80000000601F80000000C00FC0000001C
+007E00000038007F00000078003F000000F0001F800001F8001FC0000FF8003FF000FFFE
+00FFFF80FFFE00FFFF80FFFE00FFFF8029247FA32C>I<FFFF803FFEFFFF803FFEFFFF80
+3FFE0FF8000FF007F00007C003F000038001F800038001F800030001FC00030000FC0006
+0000FC000600007E000C00007E000C00007F000C00003F001800003F001800001F803000
+001F803000001FC07000000FC06000000FC060000007E0C0000007E0C0000007F1C00000
+03F180000003F180000001FB00000001FB00000001FF00000000FE00000000FE00000000
+7C000000007C000000007C00000000380000000038000000003000000000300000000070
+0000000060000000006000000000C000000000C000007C01C00000FE01800000FE038000
+00FE03000000FE06000000FC0E000000701C00000038380000001FF00000000FC0000000
+27357EA32C>I E /Fy 4 89 df<000007F80000003FFF000000FFFFC00003F01FE00007
+800FF0000E0003F8001C0003FC00380001FE00700001FE00600000FE00E00000FF00FC00
+00FF01FE0000FF01FF0000FF01FF0000FF01FF0000FF01FF0000FF01FE0001FE01FC0001
+FE00780001FE00000001FE00000003FC00000003FC00000007F80000000FF00000000FF0
+0000001FE00000003FC00000003F800000007F00000000FE00000001FC00000003F80000
+0007E00000000FC00000001F800000003F000000007C00000000F800000001F000000003
+E000000007800060000F000060001E000060003C0000C000700000C000E00000C001C000
+01C0038000038007FFFFFF800FFFFFFF803FFFFFFF007FFFFFFF00FFFFFFFF00FFFFFFFE
+00FFFFFFFE0028387CB72A>50 D<007FFFFFF00000007FFFFFF00000007FFFFFF0000000
+00FFC000000000007F8000000000007F800000000000FF800000000000FF000000000000
+FF000000000000FF000000000000FF000000000000FF000000000001FF000000000001FE
+000000000001FE000000000001FE000000000001FE000000000001FE000000000003FE00
+0000000003FC000000000003FC000000000003FC000000000003FC000000000003FC0000
+00000007FC000000000007F8000000000007F8000000000007F8000000000007F8000000
+000007F800000000000FF800000000000FF000000000000FF000000000000FF000000000
+000FF000000000000FF000000180001FF000000300001FE000000300001FE00000030000
+1FE000000700001FE000000600001FE000000600003FE000000E00003FC000000C00003F
+C000000C00003FC000001C00003FC000003C00003FC000003800007FC000007800007F80
+0000F800007F800001F800007F800007F000007F80001FF00001FF8000FFF000FFFFFFFF
+FFF000FFFFFFFFFFE000FFFFFFFFFFE00031397DB834>76 D<07FFFFFFFFFFFC07FFFFFF
+FFFFFC07FFFFFFFFFFFC07F8007FE003FC0FC0003FC000FC0F80003FC0003C0E00007FC0
+003C1E00007F80001C1C00007F80001C1C00007F80001C1800007F80001C3800007F8000
+0C300000FF80000C300000FF00000C300000FF00000C600000FF00000C600000FF000018
+600000FF000018C00001FF000018000001FE000000000001FE000000000001FE00000000
+0001FE000000000001FE000000000003FE000000000003FC000000000003FC0000000000
+03FC000000000003FC000000000003FC000000000007FC000000000007F8000000000007
+F8000000000007F8000000000007F8000000000007F800000000000FF800000000000FF0
+00000000000FF000000000000FF000000000000FF000000000000FF000000000001FF000
+000000001FE000000000001FE000000000001FE000000000001FE000000000001FE00000
+0000003FE000000000003FC000000000003FC000000000003FC000000000007FC0000000
+0000FFE000000003FFFFFFF8000007FFFFFFF8000007FFFFFFF80000363977B83C>84
+D<001FFFFFC00FFFFE003FFFFFC01FFFFE003FFFFF801FFFFE00007FFC0003FFC000003F
+F00001FC0000003FF00000F80000001FF00000E00000000FF00001C00000000FF8000180
+0000000FF800030000000007FC00070000000007FC000E0000000003FE000C0000000003
+FE00180000000001FF00300000000001FF00600000000000FF80E00000000000FF81C000
+000000007FC18000000000007FC30000000000003FE60000000000003FEE000000000000
+1FFC0000000000001FF80000000000001FF00000000000000FF80000000000000FF80000
+0000000007FC00000000000007FC00000000000003FE00000000000007FE000000000000
+0DFF00000000000019FF00000000000038FF80000000000070FF800000000000607FC000
+00000000C07FC00000000001803FC00000000003003FE00000000007003FE0000000000E
+001FF0000000000C001FF00000000018000FF80000000030000FF800000000700007FC00
+000000E00007FC00000001C00003FE00000001800003FE00000003000001FF0000000700
+0001FF0000000E000000FF8000003E000000FF8000007F000001FFC00003FF800003FFE0
+00FFFFF0003FFFFF80FFFFF0003FFFFF80FFFFF0003FFFFF803F397EB83E>88
+D E /Fz 7 117 df<00000003E00000000000000007F00000000000000007F000000000
+0000000FF8000000000000000FF8000000000000000FF8000000000000001FFC00000000
+0000001FFC000000000000003FFE000000000000003FFE000000000000003FFE00000000
+0000007FFF000000000000007FFF00000000000000FFFF80000000000000FFFF80000000
+000000FFFF80000000000001FFFFC0000000000001F3FFC0000000000003F3FFE0000000
+000003E1FFE0000000000003E1FFE0000000000007E1FFF0000000000007C0FFF0000000
+00000FC0FFF800000000000F807FF800000000000F807FF800000000001F807FFC000000
+00001F003FFC00000000003F003FFE00000000003E001FFE00000000003E001FFE000000
+00007E001FFF00000000007C000FFF0000000000FC000FFF8000000000F80007FF800000
+0000F80007FF8000000001F80007FFC000000001F00003FFC000000003FFFFFFFFE00000
+0003FFFFFFFFE000000003FFFFFFFFE000000007FFFFFFFFF000000007C00000FFF00000
+000FC00000FFF80000000F8000007FF80000000F8000007FF80000001F8000007FFC0000
+001F0000003FFC0000003F0000003FFE0000003E0000001FFE0000003E0000001FFE0000
+007E0000001FFF0000007C0000000FFF000000FE0000000FFF8000FFFFF80007FFFFFF80
+FFFFF80007FFFFFF80FFFFF80007FFFFFF80FFFFF80007FFFFFF80413A7DB948>65
+D<003FFE00000003FFFFE000000FFFFFF800001FF00FFE00003FF003FF00003FF801FF80
+003FF800FFC0003FF800FFC0003FF8007FE0003FF8007FE0001FF0007FE0000FE0007FE0
+000380007FE0000000007FE0000000007FE00000003FFFE000000FFFFFE000007FFFFFE0
+0001FFF87FE00007FF807FE0000FFE007FE0003FF8007FE0003FF0007FE0007FE0007FE0
+00FFE0007FE000FFC0007FE000FFC0007FE000FFC0007FE000FFC0007FE000FFC000FFE0
+00FFE001FFE0007FE001FFE0003FF007FFF8001FFC1FBFFFC00FFFFE1FFFC003FFF80FFF
+C0003FE003FFC02A257DA42E>97 D<00FF00000000FFFF00000000FFFF00000000FFFF00
+000000FFFF0000000007FF0000000003FF0000000003FF0000000003FF0000000003FF00
+00000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF00
+00000003FF0000000003FF0000000003FF0000000003FF0000000003FF0000000003FF01
+FF800003FF0FFFF00003FF3FFFFC0003FFFE03FF0003FFF000FF8003FFE0007FC003FF80
+003FE003FF00003FF003FF00001FF803FF00001FF803FF00001FFC03FF00000FFC03FF00
+000FFC03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00
+000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFE03FF00000FFC03FF00
+000FFC03FF00000FFC03FF00001FF803FF00001FF803FF00001FF003FF80003FF003FFC0
+007FE003FFE0007FC003FDF001FF8003F8FC07FE0003F03FFFF80003E00FFFE00003C003
+FF00002F3A7EB935>I<0001FFC000000FFFFC00007FFFFF0000FF80FF8003FE00FFC007
+FC01FFC00FF801FFC01FF801FFC01FF001FFC03FF001FFC03FF000FF807FE0007F007FE0
+001C007FE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE0000000FFE000
+0000FFE0000000FFE0000000FFE00000007FE00000007FE00000007FF00000003FF00000
+003FF00001E01FF80001E01FF80003E00FFC0007C007FE00078003FF001F8000FFC07E00
+007FFFFC00000FFFF0000001FF800023257DA42A>I<00FE03F000FFFE0FFE00FFFE3FFF
+00FFFE7C7F80FFFEF8FFC007FEF0FFC003FFE0FFC003FFC0FFC003FFC0FFC003FF807F80
+03FF803F0003FF800C0003FF80000003FF00000003FF00000003FF00000003FF00000003
+FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF
+00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00000003FF00
+000003FF000000FFFFFE0000FFFFFE0000FFFFFE0000FFFFFE000022257EA427>114
+D<003FF03803FFFEF80FFFFFF81FC00FF83F0003F87E0001F87C0000F8FC0000F8FC0000
+78FE000078FF000078FF800000FFFC0000FFFFE0007FFFFC007FFFFF803FFFFFC01FFFFF
+F00FFFFFF803FFFFF800FFFFFC001FFFFC00007FFE000007FEF00001FEF00000FEF80000
+FEF800007EFC00007EFC00007CFE0000FCFF0000F8FF8001F8FFF007F0FFFFFFC0F8FFFF
+00E01FF8001F257DA426>I<000F0000000F0000000F0000000F0000000F0000001F0000
+001F0000001F0000001F0000003F0000003F0000007F000000FF000000FF000001FF0000
+07FF00001FFFFFE0FFFFFFE0FFFFFFE0FFFFFFE003FF000003FF000003FF000003FF0000
+03FF000003FF000003FF000003FF000003FF000003FF000003FF000003FF000003FF0000
+03FF000003FF000003FF000003FF000003FF000003FF007803FF007803FF007803FF0078
+03FF007803FF007803FF007803FF007803FF00F801FF80F001FF81F000FFC3E0003FFFC0
+001FFF800003FE001D357EB425>I E /FA 17 120 df<1F003F807FC0FFE0FFE0FFE0FF
+E0FFE07FC03F801F000B0B6C8A33>46 D<000007F8000000003FFF00000000FFFF800000
+03FFFFE000000FFFFFF000001FFFFFF800003FFC0FF800007FE003FC0000FF8001FC0001
+FF0000FE0003FC00007E0003F8007E7F0007F801FFBF0007F007FFFF000FE00FFFFF800F
+C01FFFFF801FC03FFFFF801F803FC3FF803F807F81FF803F007F00FFC03F00FE007FC07F
+00FC003FC07E01FC003FC07E01F8001FC07E01F8001FC0FE01F8001FC0FC03F8001FC0FC
+03F0000FC0FC03F0000FC0FC03F0000FC0FC03F0000FC0FC03F0000FC0FC03F0000FC0FC
+03F0000FC0FC03F0000FC0FC03F0000FC0FC03F8001FC0FE01F8001F807E01F8001F807E
+01F8001F807E01FC003F807F00FC003F003F00FE007F003F007F00FE003F807F81FE001F
+803FC3FC001FC03FFFFC000FC01FFFF8000FE00FFFF00007F007FFE00007F801FF800003
+F8007E000003FC00000F8001FF00001FC000FF80003FC0007FE000FFC0003FFC07FF8000
+1FFFFFFF00000FFFFFFE000003FFFFF8000000FFFFF00000003FFF8000000007FC00002A
+3F7CBD33>64 D<001FFC00000000FFFF80000003FFFFE0000007FFFFF000000FFFFFFC00
+001FFFFFFE00001FF007FF00001FE001FF00001FE000FF80001FE0003F80000FC0003FC0
+000780001FC0000000001FE0000000000FE0000000000FE0000000000FE0000000000FE0
+000000000FE00000000FFFE0000001FFFFE000001FFFFFE000007FFFFFE00001FFFFFFE0
+0007FFFF0FE0000FFFC00FE0001FFC000FE0003FF0000FE0007FC0000FE0007F80000FE0
+00FF00000FE000FE00000FE000FE00000FE000FE00000FE000FE00000FE000FE00000FE0
+00FF00001FE0007F00001FE0007F80007FE0003FE000FFF0003FF807FFFFF01FFFFFFFFF
+F80FFFFFFFFFF807FFFFF3FFF803FFFFC1FFF800FFFF003FF0001FF00000002D2E7BAC33
+>97 D<0000FFF0000007FFFE00001FFFFF80003FFFFFC0007FFFFFE001FFFFFFF003FFC0
+1FF003FE000FF007FC000FF00FF8000FF01FF00007E01FE00003C03FC00000003F800000
+003F800000007F800000007F000000007F00000000FF00000000FE00000000FE00000000
+FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FF
+000000007F000000007F000000007F800000003F800001F03FC00003F81FE00003F81FF0
+0007F80FF80007F007FC000FF007FF001FE003FFE07FE001FFFFFFC000FFFFFF80003FFF
+FF00001FFFFC000007FFF8000000FFC000252E79AC33>99 D<0000FF80000007FFF00000
+1FFFFC00003FFFFE0000FFFFFF0001FFFFFF8003FF80FFC007FE003FE007F8000FF00FF0
+0007F01FE00007F81FC00003F83FC00003FC3F800001FC7F800001FC7F000001FC7F0000
+01FE7F000000FEFF000000FEFE000000FEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFF
+FEFFFFFFFFFEFFFFFFFFFCFE00000000FF000000007F000000007F000000007F00000000
+3F800000003F8000007C1FC00000FE1FE00000FE0FF00000FE0FF80001FE07FC0003FC03
+FF000FFC01FFC03FF800FFFFFFF0007FFFFFE0003FFFFFC0000FFFFF000003FFFC000000
+7FE000272E7BAC33>101 D<0001FE001FE0000FFFC0FFF0003FFFF3FFF8007FFFFFFFFC
+00FFFFFFFFFC01FFFFFFFFFC03FF03FFE1FC07FC00FF80F807F8007F80600FF0003FC000
+0FE0001FC0000FE0001FC0001FE0001FE0001FC0000FE0001FC0000FE0001FC0000FE000
+1FC0000FE0001FC0000FE0001FC0000FE0001FE0001FE0000FE0001FC0000FE0001FC000
+0FF0003FC00007F8007F800007FC00FF800003FF03FF000003FFFFFE000007FFFFFC0000
+07FFFFF8000007FFFFF000000FCFFFC000000F81FE0000000F80000000000F8000000000
+0FC0000000000FC00000000007E00000000007F00000000007FFFFFC000003FFFFFFC000
+01FFFFFFF00007FFFFFFFC000FFFFFFFFF001FFFFFFFFF801FE00007FF803FC000007FC0
+3F0000001FE07F0000000FE07E00000007E0FE00000007F0FC00000003F0FC00000003F0
+FC00000003F0FC00000003F0FC00000003F0FE00000007F07E00000007E07F0000000FE0
+3F8000001FC03FE000007FC01FF80001FF800FFF801FFF0007FFFFFFFE0003FFFFFFFC00
+00FFFFFFF000003FFFFFC000000FFFFF00000000FFF000002E447DAB33>103
+D<0000E000000003F800000003F800000007FC00000007FC00000007FC00000003F80000
+0003F800000000E000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000003FFFF800007FFFFC00007FFF
+FC00007FFFFC00007FFFFC00003FFFFC00000001FC00000001FC00000001FC00000001FC
+00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00
+000001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC0000
+0001FC00000001FC00000001FC00000001FC00000001FC00000001FC00000001FC000000
+01FC00000001FC00000001FC00000001FC00000001FC00000001FC00007FFFFFFFC0FFFF
+FFFFE0FFFFFFFFF0FFFFFFFFF0FFFFFFFFE07FFFFFFFC0243E78BD33>105
+D<7FF800000000FFFC00000000FFFC00000000FFFC00000000FFFC000000007FFC000000
+0000FC0000000000FC0000000000FC0000000000FC0000000000FC0000000000FC000000
+0000FC0000000000FC0000000000FC0000000000FC0000000000FC0000000000FC000000
+0000FC01FFFFC000FC03FFFFE000FC07FFFFF000FC07FFFFF000FC03FFFFE000FC01FFFF
+C000FC000FF00000FC001FE00000FC003FC00000FC007F800000FC00FF000000FC01FE00
+0000FC03FC000000FC07F8000000FC0FF0000000FC1FE0000000FC3FC0000000FC7F8000
+0000FCFFC0000000FDFFE0000000FFFFE0000000FFFFF0000000FFF3F8000000FFE3FC00
+0000FFC1FC000000FF80FE000000FF007F000000FE007F000000FC003F800000FC001FC0
+0000FC001FE00000FC000FE00000FC0007F00000FC0003F80000FC0003FC0000FC0001FC
+0000FC0000FE007FFFF80FFFF0FFFFFC1FFFF8FFFFFC1FFFFCFFFFFC1FFFFCFFFFFC1FFF
+F87FFFF80FFFF02E3D7EBC33>107 D<3FFFFC00007FFFFE0000FFFFFE0000FFFFFE0000
+7FFFFE00003FFFFE00000000FE00000000FE00000000FE00000000FE00000000FE000000
+00FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000
+FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE
+00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE0000
+0000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE000000
+00FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000
+FE00003FFFFFFFF87FFFFFFFFCFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC3FFFFFFFF8273D7A
+BC33>I<0000FC007E00007FC3FF01FF8000FFEFFF87FFC000FFFFFFCFFFE000FFFFFFDF
+FFE000FFFFFFFFFFF0007FFF0FFF87F00007FE07FF03F00007FC07FE03F80007F803FC01
+F80007F803FC01F80007F003F801F80007F003F801F80007F003F801F80007F003F801F8
+0007E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F800
+07E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F80007
+E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F80007E0
+03F001F80007E003F001F80007E003F001F80007E003F001F80007E003F001F80007E003
+F001F80007E003F001F80007E003F001F8007FFE0FFF07FF80FFFF1FFF8FFFC0FFFF1FFF
+8FFFC0FFFF1FFF8FFFC0FFFF1FFF8FFFC07FFE0FFF07FF80322C80AB33>I<000001FF00
+003FFC07FFC0007FFE1FFFF000FFFE7FFFF800FFFEFFFFF8007FFFFFFFFC003FFFFF07FE
+0000FFF801FE0000FFF000FE0000FFE000FF0000FFC0007F0000FF80007F0000FF80007F
+0000FF00007F0000FF00007F0000FF00007F0000FE00007F0000FE00007F0000FE00007F
+0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F
+0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F
+0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F0000FE00007F
+0000FE00007F003FFFF80FFFFC7FFFFC1FFFFEFFFFFE3FFFFFFFFFFE3FFFFF7FFFFC1FFF
+FE3FFFF80FFFFC302C7FAB33>I<0001FE0000000FFFC000003FFFF000007FFFF80000FF
+FFFC0001FFFFFE0003FF03FF0007FC00FF800FF8007FC00FF0003FC01FE0001FE01FC000
+0FE03F800007F03F800007F07F800007F87F000003F87F000003F87F000003F8FE000001
+FCFE000001FCFE000001FCFE000001FCFE000001FCFE000001FCFE000001FCFE000001FC
+FE000001FCFE000001FCFF000003FC7F000003F87F000003F87F800007F83F800007F03F
+C0000FF03FC0000FF01FE0001FE01FF0003FE00FF8007FC007FC00FF8003FF03FF0001FF
+FFFE0000FFFFFC00007FFFF800003FFFF000000FFFC0000001FE0000262E7AAC33>I<00
+0001FE00003FFC0FFFC0007FFE1FFFF000FFFE7FFFF800FFFEFFFFFE007FFFFFFFFF003F
+FFFE07FF0000FFF800FF8000FFE0007FC000FFC0003FE000FF80001FE000FF80000FF000
+FF00000FF000FF000007F000FE000007F800FE000003F800FE000003F800FE000003FC00
+FE000001FC00FE000001FC00FE000001FC00FE000001FC00FE000001FC00FE000001FC00
+FE000001FC00FE000001FC00FE000001FC00FE000003FC00FE000003F800FE000003F800
+FF000007F800FF000007F000FF80000FF000FF80000FE000FFC0001FE000FFC0003FC000
+FFE0007FC000FFF801FF8000FFFE07FF0000FFFFFFFE0000FEFFFFFC0000FE7FFFF80000
+FE3FFFE00000FE0FFF800000FE03FE000000FE0000000000FE0000000000FE0000000000
+FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000
+FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE000000003F
+FFF80000007FFFFC000000FFFFFE000000FFFFFE0000007FFFFC0000003FFFF80000002E
+427FAB33>I<001FFE0F0000FFFF8F8003FFFFFF800FFFFFFF801FFFFFFF803FFFFFFF80
+3FF007FF807F8001FF807F0000FF80FE00007F80FC00007F80FC00003F80FC00003F80FC
+00003F80FE00003F807F00001F007FC00000003FF80000003FFFC000001FFFFF00000FFF
+FFE00003FFFFF80000FFFFFC00001FFFFF000000FFFF80000007FFC00000007FC0000000
+1FE07C00000FE0FE000007F0FE000003F0FE000003F0FF000003F0FF000003F0FF800003
+F0FF800007F0FFC00007E0FFE0000FE0FFF0003FC0FFFE01FFC0FFFFFFFF80FFFFFFFF00
+FDFFFFFE00FCFFFFF800F83FFFE0007807FF0000242E79AC33>115
+D<0003C00000000007E0000000000FE0000000000FE0000000000FE0000000000FE00000
+00000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00000
+003FFFFFFFFC007FFFFFFFFE00FFFFFFFFFE00FFFFFFFFFE00FFFFFFFFFE007FFFFFFFFC
+00000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00000
+00000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00000
+00000FE0000000000FE0000000000FE0000000000FE0000000000FE0000000000FE00000
+00000FE0000000000FE0000000000FE0000000000FE0001F00000FE0003F80000FE0003F
+80000FE0003F80000FE0003F80000FE0003F80000FE0007F80000FF0007F000007F000FF
+000007F801FF000007FE07FE000003FFFFFC000001FFFFF8000000FFFFF00000007FFFE0
+0000001FFF8000000007FC000029387EB633>I<3FFFC00FFFF07FFFE01FFFF8FFFFF03F
+FFFCFFFFF03FFFFC7FFFE01FFFF83FFFC00FFFF001F800007E0001FC0000FE0000FC0000
+FC0000FC0000FC0000FE0001FC00007E0001F800007E0001F800007F0003F800003F0003
+F000003F0003F000003F8007F000001F8007E000001F8007E000001FC00FE000000FC00F
+C000000FC00FC000000FC00FC0000007E01F80000007E01F80000007E01F80000007F03F
+80000003F03F00000003F03F00000003F87F00000001F87E00000001F87E00000001FCFE
+00000000FCFC00000000FCFC00000000FFFC000000007FF8000000007FF8000000007FF8
+000000003FF0000000003FF0000000001FE0000000000FC000002E2B7EAA33>118
+D<7FFF8007FFF8FFFFC00FFFFCFFFFE01FFFFCFFFFE01FFFFCFFFFC00FFFFC7FFF8007FF
+F80FC000000FC00FE000001FC007E000001F8007E000001F8007E000001F8007E000001F
+8007E000001F8007F000003F8003F000003F0003F000003F0003F000003F0003F00FC03F
+0003F01FE03F0003F01FE03F0001F83FF07E0001F83FF07E0001F83FF07E0001F87FF87E
+0001F87CF87E0001F87CF87E0000F87CF87C0000FCFCFCFC0000FCFCFCFC0000FCFCFCFC
+0000FCF87CFC0000FCF87CFC00007CF87CF800007DF87EF800007DF03EF800007DF03EF8
+00007FF03FF800007FF03FF800003FE01FF000003FE01FF000003FE01FF000003FC00FF0
+00000F8007C0002E2B7EAA33>I E /FB 1 4 df<000C0000001E0000001E0000001E0000
+001E0000001E0000601E0180781E0780FC0C0FC07F0C3F803F8C7F0007CCF80001FFE000
+007F8000001E0000007F800001FFE00007CCF8003F8C7F007F0C3F80FC0C0FC0781E0780
+601E0180001E0000001E0000001E0000001E0000001E0000000C00001A1D7C9E23>3
+D E /FC 29 122 df<1E007F807F80FFC0FFC0FFC0FFC07F807F801E000A0A78891B>46
+D<000030000000F0000001F0000003F000001FF00000FFF000FFFFF000FFE7F000FF07F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0
+000007F0000007F0000007F0000007F0000007F0000007F0000007F000000FF800001FFC
+007FFFFFFF7FFFFFFF7FFFFFFF204278C131>49 D<1C00000000001C00000000001F8000
+0000001FFFFFFFFFC01FFFFFFFFFC01FFFFFFFFFC03FFFFFFFFF803FFFFFFFFF803FFFFF
+FFFF003FFFFFFFFE00380000000C00300000001C00700000003800600000003000600000
+00700060000000E00060000000C000C0000001C000C00000038000C00000070000000000
+0600000000000E00000000001C0000000000180000000000380000000000700000000000
+600000000000E00000000001C00000000001C00000000003800000000007800000000007
+00000000000F00000000000F00000000001F00000000001E00000000003E00000000003E
+00000000007E00000000007C00000000007C0000000000FC0000000000FC0000000001FC
+0000000001FC0000000001FC0000000003F80000000003F80000000003F80000000003F8
+0000000007F80000000007F80000000007F80000000007F80000000007F80000000007F8
+000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8
+000000000FF8000000000FF8000000000FF8000000000FF80000000007F00000000001C0
+0000002A457BC231>55 D<0000FF00000007FFE000001FFFF800007F80FC0000FC007E00
+01F8003F0003F0001F8007E0000FC00FE00007E01FC00007E01FC00003F03F800003F03F
+800003F87F800001F87F000001FC7F000001FCFF000001FCFF000001FCFF000001FEFF00
+0000FEFF000000FEFF000000FEFF000000FEFF000000FEFF000000FFFF000000FFFF0000
+00FFFF000000FF7F000001FF7F000001FF7F000001FF3F800001FF3F800003FF1F800003
+FF1FC00003FF0FC00007FF07E00006FF07E0000EFF03F0001CFF01F80038FF007C0070FF
+003F01E0FF000FFF80FE0001FE00FE00000000FE00000001FE00000001FC00000001FC00
+000001FC00000001FC00000003F800000003F800000003F00F800007F01FC00007E03FE0
+000FE03FE0000FC03FE0001F803FE0001F803FC0003F003F80007E001E0000FC001C0001
+F8000F0003F00007E01FE00003FFFF800000FFFE0000001FF0000028447CC131>57
+D<1E007F807F80FFC0FFC0FFC0FFC07F807F801E00000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000001E007F807F
+80FFC0FFC0FFC0FFC07F807F801E000A2B78AA1B>I<00000000C00000000000000001E0
+0000000000000001E00000000000000001E00000000000000003F00000000000000003F0
+0000000000000003F00000000000000007F80000000000000007F80000000000000007F8
+000000000000000FFC000000000000000FFC000000000000000FFC0000000000000019FE
+0000000000000019FE0000000000000019FE0000000000000030FF0000000000000030FF
+0000000000000070FF80000000000000607F80000000000000607F80000000000000E07F
+C0000000000000C03FC0000000000000C03FC0000000000001C03FE0000000000001801F
+E0000000000001801FE0000000000003001FF0000000000003000FF0000000000003000F
+F0000000000006000FF80000000000060007F80000000000060007F800000000000C0003
+FC00000000000C0003FC00000000000C0003FC0000000000180001FE0000000000180001
+FE0000000000180001FE0000000000300000FF0000000000300000FF0000000000700000
+FF80000000006000007F80000000006000007F8000000000E000007FC000000000FFFFFF
+FFC000000000FFFFFFFFC000000001FFFFFFFFE0000000018000001FE000000001800000
+1FE0000000030000001FF0000000030000000FF0000000030000000FF000000006000000
+0FF80000000600000007F80000000600000007F80000000C00000003FC0000000C000000
+03FC0000000C00000003FC0000001800000001FE0000001800000001FE00000018000000
+01FE0000003000000000FF0000003000000000FF0000007800000000FF800000F8000000
+00FF800001FC00000000FFC0000FFF00000003FFE000FFFFE000007FFFFFC0FFFFE00000
+7FFFFFC0FFFFE000007FFFFFC042477DC649>65 D<0000000FFE000060000000FFFFC000
+E0000003FFFFF000E000000FFC01FC01E000003FC0003E01E00000FF00000F83E00003FC
+000003C7E00007F8000001E7E0000FF0000000FFE0001FE00000007FE0003FC00000003F
+E0007F800000001FE000FF000000000FE001FE000000000FE001FC0000000007E003FC00
+00000007E007F80000000003E007F80000000003E00FF00000000001E00FF00000000001
+E01FE00000000000E01FE00000000000E03FE00000000000E03FE00000000000E03FC000
+00000000607FC00000000000607FC00000000000607FC00000000000607FC00000000000
+00FF80000000000000FF80000000000000FF80000000000000FF80000000000000FF8000
+0000000000FF80000000000000FF80000000000000FF80000000000000FF800000000000
+00FF80000000000000FF80000000000000FF80000000000000FF80000000000000FF8000
+00000000007FC00000000000007FC00000000000007FC00000000000607FC00000000000
+603FC00000000000603FE00000000000603FE00000000000601FE00000000000E01FF000
+00000000E00FF00000000000C00FF00000000000C007F80000000001C007F80000000001
+8003FC00000000038001FC00000000038001FE00000000070000FF000000000600007F80
+0000000E00003FC00000001C00001FE00000003800000FF000000078000007F8000000F0
+000003FC000001E0000000FF000007800000003FC0001F000000000FFC00FC0000000003
+FFFFF00000000000FFFFC000000000000FFE0000003B487BC546>67
+D<FFFFFFFFFFFFF800FFFFFFFFFFFFF800FFFFFFFFFFFFF80001FFC000007FF800007F80
+000007FC00007F80000001FC00007F80000000FC00007F800000007C00007F800000003C
+00007F800000001C00007F800000001C00007F800000000E00007F800000000E00007F80
+0000000E00007F800000000600007F800000000600007F800000000600007F8000000006
+00007F800000000700007F800006000300007F800006000300007F800006000300007F80
+0006000000007F800006000000007F800006000000007F800006000000007F80000E0000
+00007F80000E000000007F80001E000000007F80003E000000007F8000FE000000007FFF
+FFFE000000007FFFFFFE000000007FFFFFFE000000007F8000FE000000007F80003E0000
+00007F80001E000000007F80000E000000007F80000E000000007F800006000000007F80
+0006000000007F800006000000007F8000060000C0007F8000060000C0007F8000060000
+C0007F800006000180007F800000000180007F800000000180007F800000000180007F80
+0000000180007F800000000380007F800000000380007F800000000300007F8000000003
+00007F800000000700007F800000000700007F800000000F00007F800000000F00007F80
+0000001E00007F800000001E00007F800000003E00007F800000007E00007F80000001FE
+00007F80000007FE0001FFC000007FFE00FFFFFFFFFFFFFC00FFFFFFFFFFFFFC00FFFFFF
+FFFFFFFC003A447CC342>69 D<000FFFFFFE000FFFFFFE000FFFFFFE000003FF80000001
+FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF
+00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00
+000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF0000
+0000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF000000
+00FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000
+FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF
+00000000FF00000000FF00000000FF00000000FF003F0000FF007F8000FF00FFC000FF00
+FFC000FF00FFC000FF00FFC000FF00FFC001FE00FF8001FE00FF0001FE006C0003FC0070
+0003F800380007F8001C0007F0000E000FE00007001F800003E07F000000FFFC0000001F
+E0000027467BC332>74 D<FFFFFFFFFC0000FFFFFFFFFFC000FFFFFFFFFFF80001FFC000
+0FFC00007F800001FF00007F8000007F80007F8000001FE0007F8000000FE0007F800000
+07F0007F80000007F8007F80000003FC007F80000003FC007F80000003FE007F80000001
+FE007F80000001FE007F80000001FF007F80000001FF007F80000001FF007F80000001FF
+007F80000001FF007F80000001FF007F80000001FF007F80000001FE007F80000001FE00
+7F80000003FE007F80000003FC007F80000003FC007F80000007F8007F80000007F0007F
+8000000FE0007F8000001FC0007F8000007F80007F800001FE00007F80000FFC00007FFF
+FFFFF000007FFFFFFF8000007F8000000000007F8000000000007F8000000000007F8000
+000000007F8000000000007F8000000000007F8000000000007F8000000000007F800000
+0000007F8000000000007F8000000000007F8000000000007F8000000000007F80000000
+00007F8000000000007F8000000000007F8000000000007F8000000000007F8000000000
+007F8000000000007F8000000000007F8000000000007F8000000000007F800000000000
+7F8000000000007F8000000000007F8000000000007F800000000001FFE000000000FFFF
+FFC0000000FFFFFFC0000000FFFFFFC000000038447CC342>80 D<FFFFFFFFE000000000
+FFFFFFFFFF00000000FFFFFFFFFFC000000001FFC0003FF8000000007F800003FC000000
+007F800000FF000000007F8000007F800000007F8000003FC00000007F8000001FE00000
+007F8000000FF00000007F80000007F80000007F80000007F80000007F80000007FC0000
+007F80000003FC0000007F80000003FE0000007F80000003FE0000007F80000003FE0000
+007F80000003FE0000007F80000003FE0000007F80000003FE0000007F80000003FE0000
+007F80000003FC0000007F80000003FC0000007F80000007FC0000007F80000007F80000
+007F8000000FF00000007F8000000FF00000007F8000001FE00000007F8000003FC00000
+007F8000007F000000007F800001FE000000007F800007F8000000007F80003FE0000000
+007FFFFFFF00000000007FFFFFFC00000000007F80007F80000000007F80000FE0000000
+007F800007F0000000007F800003FC000000007F800001FE000000007F800000FE000000
+007F800000FF000000007F8000007F800000007F8000007F800000007F8000003FC00000
+007F8000003FC00000007F8000003FC00000007F8000003FC00000007F8000003FC00000
+007F8000003FC00000007F8000003FC00000007F8000003FE00000007F8000003FE00000
+007F8000003FE00000007F8000003FE00000007F8000003FE00000007F8000003FE00000
+007F8000003FE00000007F8000003FE00060007F8000003FF00060007F8000001FF00060
+007F8000001FF00060007F8000001FF000E0007F8000000FF800C001FFE0000007F801C0
+FFFFFFC00007F80180FFFFFFC00001FC0380FFFFFFC00000FE07000000000000003FFE00
+00000000000007F80043467CC348>82 D<FFFFFFC0000FFFFFFFFFFFC0000FFFFFFFFFFF
+C0000FFFFF01FFE0000000FFF0007F800000001F80007F800000000F00007F800000000F
+00007F800000000600007F800000000600007F800000000600007F800000000600007F80
+0000000600007F800000000600007F800000000600007F800000000600007F8000000006
+00007F800000000600007F800000000600007F800000000600007F800000000600007F80
+0000000600007F800000000600007F800000000600007F800000000600007F8000000006
+00007F800000000600007F800000000600007F800000000600007F800000000600007F80
+0000000600007F800000000600007F800000000600007F800000000600007F8000000006
+00007F800000000600007F800000000600007F800000000600007F800000000600007F80
+0000000600007F800000000600007F800000000600007F800000000600007F8000000006
+00007F800000000600007F800000000600007F800000000600007F800000000600007F80
+0000000600007F800000000600007F800000000600007F800000000E00003FC00000000C
+00003FC00000000C00003FC00000001C00001FC00000001C00001FE00000001800000FE0
+0000003800000FE000000030000007F000000070000007F0000000E0000003F8000001E0
+000001FC000001C0000000FE000007800000007F00000F000000003F80001E000000001F
+E0007C0000000007FC03F00000000001FFFFE000000000007FFF80000000000007FC0000
+0040467CC349>85 D<FFFFFF0007FFFFF8000FFFFEFFFFFF0007FFFFF8000FFFFEFFFFFF
+0007FFFFF8000FFFFE03FFE000001FFF000000FFF001FF8000000FFC0000003FC001FF00
+000007F80000001F0000FF00000007F80000000F0000FF00000007F80000000E00007F80
+000003FC0000000E00007F80000003FC0000000C00007F80000003FC0000000C00003FC0
+000003FE0000001800003FC0000003FE0000001800003FC0000003FE0000001800003FE0
+000006FF0000003800001FE0000006FF0000003000001FE0000006FF0000003000001FF0
+00000EFF8000007000000FF000000C7F8000006000000FF000000C7F8000006000000FF8
+00001C7FC0000060000007F80000183FC00000C0000007F80000183FC00000C0000007F8
+0000183FE00000C0000003FC0000301FE0000180000003FC0000301FE0000180000003FC
+0000301FE0000180000001FE0000600FF0000300000001FE0000600FF0000300000001FE
+0000600FF0000300000000FF0000C007F8000600000000FF0000C007F8000600000000FF
+0000C007F8000600000000FF8001C007FC000E000000007F80018003FC000C000000007F
+80018003FC000C000000007FC0038003FE000C000000003FC0030001FE0018000000003F
+C0030001FE0018000000003FE0030001FF0018000000001FE0060000FF0030000000001F
+E0060000FF0030000000001FE0060000FF0030000000000FF00C00007F8060000000000F
+F00C00007F8060000000000FF00C00007F80600000000007F81800003FC0C00000000007
+F81800003FC0C00000000007F81800003FC0C00000000007FC3000001FE1C00000000003
+FC3000001FE1800000000003FC3000001FE1800000000003FE7000001FF3800000000001
+FE6000000FF3000000000001FE6000000FF3000000000001FFE000000FFB000000000000
+FFC0000007FE000000000000FFC0000007FE000000000000FFC0000007FE000000000000
+7F80000003FC0000000000007F80000003FC0000000000007F80000003FC000000000000
+3F00000001F80000000000003F00000001F80000000000003F00000001F8000000000000
+1E00000000F00000000000001E00000000F00000000000001E00000000F0000000000000
+1E00000000F00000000000000C00000000600000005F467EC364>87
+D<0007FC000000003FFF80000000F80FE0000003C003F00000070001F800000E0000FC00
+000FC0007E00001FE0007F00001FF0003F80001FF0003F80001FF0003F80001FF0001FC0
+001FF0001FC0000FE0001FC0000380001FC0000000001FC0000000001FC0000000001FC0
+000000001FC00000000FFFC0000001FFFFC000000FFE1FC000003FC01FC00000FF001FC0
+0003FC001FC00007F8001FC0000FF0001FC0001FE0001FC0003FC0001FC0007FC0001FC0
+007F80001FC0007F80001FC060FF00001FC060FF00001FC060FF00001FC060FF00003FC0
+60FF00003FC060FF00003FC060FF80007FC0607F8000EFC0607FC000C7E0C03FC001C7E0
+C01FE00783F1C007F81E03FF8001FFFC01FF00001FE0007C002B2E7CAC31>97
+D<00007F80000003FFF000000FC07C00003F000F0000FC00038001F80001C003F8000FC0
+07F0001FE007E0003FE00FE0003FE01FC0003FE01FC0003FE03F80003FE03F80001FC07F
+800007007F800000007F800000007F00000000FF00000000FF00000000FF00000000FF00
+000000FF00000000FF00000000FF00000000FF00000000FF00000000FF00000000FF0000
+00007F000000007F800000007F800000003F800000003F800000303FC00000301FC00000
+700FE00000600FE00000E007F00000C003F80001C001F800038000FC000700003F001E00
+001FC078000007FFF0000000FF8000242E7DAC2B>99 D<0001FE00000007FFC000001F03
+F000007E00FC0000FC007E0001F8003F0003F0003F0007E0001F800FE0001FC00FC0000F
+C01FC0000FC03F80000FE03F800007E03F800007E07F800007F07F000007F07F000007F0
+FF000007F0FF000007F0FF000007F0FFFFFFFFF0FFFFFFFFF0FF00000000FF00000000FF
+00000000FF00000000FF00000000FF000000007F000000007F000000007F800000007F80
+0000003F800000003F800000301FC00000301FC00000700FC00000600FE00000E007F000
+00C003F00001C001F800038000FC000700003E001E00001F80F8000003FFE0000000FF00
+00242E7DAC2B>101 D<00000FE00000007FF8000001F81E000003F03F00000FE07F8000
+1FC0FF80001F80FF80003F80FF80007F00FF80007F00FF80007F007F0000FE001C0000FE
+00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE0000
+00FFFFFF8000FFFFFF8000FFFFFF800000FE00000000FE00000000FE00000000FE000000
+00FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000
+FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE
+00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00
+000000FE00000000FE00000000FE00000000FE00000000FE00000000FE00000000FE0000
+0000FE00000000FE00000000FE00000001FF8000007FFFFF00007FFFFF00007FFFFF0000
+21467EC51E>I<01FC00000000FFFC00000000FFFC00000000FFFC0000000007FC000000
+0003FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC0000000001FC0000000001FC0000000001FC000000
+0001FC0000000001FC0000000001FC01FE000001FC07FFC00001FC1E07F00001FC3801F8
+0001FC7001FC0001FCE000FC0001FDC000FE0001FD8000FE0001FF80007F0001FF00007F
+0001FF00007F0001FE00007F0001FE00007F0001FE00007F0001FC00007F0001FC00007F
+0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F
+0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F
+0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F
+0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F
+0003FE0000FF80FFFFF83FFFFEFFFFF83FFFFEFFFFF83FFFFE2F457DC436>104
+D<01E00007F80007F8000FFC000FFC000FFC000FFC0007F80007F80001E0000000000000
+0000000000000000000000000000000000000000000000000000000000000000000001FC
+00FFFC00FFFC00FFFC0007FC0003FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC
+0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC
+0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC
+0001FC0001FC0001FC0003FE00FFFFF8FFFFF8FFFFF815437DC21C>I<01FC00FFFC00FF
+FC00FFFC0007FC0003FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001
+FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001
+FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001
+FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001
+FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001FC0001
+FC0001FC0001FC0003FE00FFFFF8FFFFF8FFFFF815457DC41C>108
+D<01FC00FF00001FE00000FFFC07FFE000FFFC0000FFFC0F03F801E07F0000FFFC3C01FC
+07803F800007FC7000FE0E001FC00003FCE0007E1C000FC00001FDC0007F38000FE00001
+FD80007F30000FE00001FF80003FF00007F00001FF00003FE00007F00001FF00003FE000
+07F00001FE00003FC00007F00001FE00003FC00007F00001FE00003FC00007F00001FC00
+003F800007F00001FC00003F800007F00001FC00003F800007F00001FC00003F800007F0
+0001FC00003F800007F00001FC00003F800007F00001FC00003F800007F00001FC00003F
+800007F00001FC00003F800007F00001FC00003F800007F00001FC00003F800007F00001
+FC00003F800007F00001FC00003F800007F00001FC00003F800007F00001FC00003F8000
+07F00001FC00003F800007F00001FC00003F800007F00001FC00003F800007F00001FC00
+003F800007F00001FC00003F800007F00001FC00003F800007F00001FC00003F800007F0
+0001FC00003F800007F00001FC00003F800007F00001FC00003F800007F00001FC00003F
+800007F00003FE00007FC0000FF800FFFFF81FFFFF03FFFFE0FFFFF81FFFFF03FFFFE0FF
+FFF81FFFFF03FFFFE04B2C7DAB52>I<01FC01FE0000FFFC07FFC000FFFC1E07F000FFFC
+3801F80007FC7001FC0003FCE000FC0001FDC000FE0001FD8000FE0001FF80007F0001FF
+00007F0001FF00007F0001FE00007F0001FE00007F0001FE00007F0001FC00007F0001FC
+00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC
+00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC
+00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC
+00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC
+00007F0003FE0000FF80FFFFF83FFFFEFFFFF83FFFFEFFFFF83FFFFE2F2C7DAB36>I<00
+007F8000000003FFF00000000FC0FC0000003E001F0000007C000F800000F80007C00001
+F00003E00003E00001F00007C00000F8000FC00000FC000FC00000FC001F8000007E003F
+8000007F003F8000007F003F0000003F007F0000003F807F0000003F807F0000003F807F
+0000003F80FF0000003FC0FF0000003FC0FF0000003FC0FF0000003FC0FF0000003FC0FF
+0000003FC0FF0000003FC0FF0000003FC0FF0000003FC0FF0000003FC07F0000003F807F
+0000003F807F8000007F803F8000007F003F8000007F001F8000007E001FC00000FE000F
+C00000FC000FE00001FC0007E00001F80003F00003F00001F80007E00000FC000FC00000
+3E001F0000001FC0FE00000007FFF8000000007F8000002A2E7DAC31>I<03F803F0FFF8
+1FFCFFF83C3EFFF8707F07F8E0FF03F9C0FF01F980FF01FB80FF01FB007E01FB003C01FF
+000001FE000001FE000001FE000001FE000001FC000001FC000001FC000001FC000001FC
+000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC
+000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC000001FC
+000001FC000001FC000003FF0000FFFFFE00FFFFFE00FFFFFE00202C7DAB26>114
+D<003FE01801FFFC3807E01F780F0003F81E0001F83C0000F87C00007878000078F80000
+38F8000038F8000018F8000018FC000018FC000018FE000018FF8000007FC000007FFC00
+003FFFE0001FFFFC000FFFFF0007FFFFC003FFFFE000FFFFF0001FFFF80000FFF800000F
+FC000003FCC00001FEC00000FEC000007EE000007EE000003EE000003EF000003EF00000
+3EF000003EF800003CFC00007CFC000078FE0000F8FF0001F0F38003E0F1F00F80E07FFE
+00C00FF0001F2E7DAC26>I<0006000000060000000600000006000000060000000E0000
+000E0000000E0000000E0000001E0000001E0000001E0000003E0000007E0000007E0000
+00FE000001FE000007FE00001FFFFFF0FFFFFFF0FFFFFFF000FE000000FE000000FE0000
+00FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE0000
+00FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE0000
+00FE000000FE000C00FE000C00FE000C00FE000C00FE000C00FE000C00FE000C00FE000C
+00FE000C00FE000C007E001C007F0018007F0018003F0038001F8030001FC0700007E0E0
+0001FFC000007F001E3E7EBC26>I<01FC00007F00FFFC003FFF00FFFC003FFF00FFFC00
+3FFF0007FC0001FF0003FC0000FF0001FC00007F0001FC00007F0001FC00007F0001FC00
+007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00
+007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00
+007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC00
+007F0001FC00007F0001FC00007F0001FC00007F0001FC00007F0001FC0000FF0001FC00
+00FF0001FC0000FF0001FC0001FF0001FC0001FF0000FC0001FF0000FE0003FF00007E00
+077F80007F000E7FC0003F001C7FFE000FC0787FFE0003FFF07FFE00007F807F002F2D7D
+AB36>I<FFFFF001FFFCFFFFF001FFFCFFFFF001FFFC07FF00007FE003FE00001F8001FE
+00001F0001FE00000E0000FE00000E0000FE00000C00007F00001800007F00001800007F
+80001800003F80003000003F80003000003FC0007000001FC0006000001FE0006000000F
+E000C000000FE000C000000FF001C0000007F00180000007F00180000003F80300000003
+F80300000003FC0700000001FC0600000001FC0600000000FE0C00000000FE0C00000000
+FF0C000000007F18000000007F18000000007FB8000000003FB0000000003FF000000000
+1FE0000000001FE0000000001FE0000000000FC0000000000FC000000000078000000000
+078000000000078000000000030000002E2C7EAA33>I<FFFFF001FFFCFFFFF001FFFCFF
+FFF001FFFC07FF00007FE003FE00001F8001FE00001F0001FE00000E0000FE00000C0000
+FF00001C00007F00001800007F00001800007F80003800003F80003000003F8000300000
+1FC0006000001FC0006000001FE000E000000FE000C000000FE000C0000007F001800000
+07F00180000007F80380000003F80300000003F80300000001FC0600000001FC06000000
+01FE0E00000000FE0C00000000FE0C000000007F18000000007F18000000007FB8000000
+003FB0000000003FB0000000001FE0000000001FE0000000001FE0000000000FC0000000
+000FC0000000000780000000000780000000000780000000000300000000000300000000
+000600000000000600000000000600000000000C00000000000C00000000001800000000
+00180000003C00180000007E0030000000FF0030000000FF0060000000FF0060000000FF
+00C0000000FE01C00000007C03800000007007000000003C1E000000000FFC0000000003
+F0000000002E3F7EAA33>121 D E /FD 13 118 df<FFFFFFFFF0FFFFFFFFF0FFFFFFFF
+F0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0FFFFFFFFF0240780A12B>45
+D<00000000000F00000000000000000000000F00000000000000000000000F0000000000
+0000000000001F80000000000000000000001F80000000000000000000003FC000000000
+0000000000003FC0000000000000000000003FC0000000000000000000007FE000000000
+0000000000007FE0000000000000000000007FE000000000000000000000FFF000000000
+000000000000FFF000000000000000000000FFF000000000000000000001FFF800000000
+000000000001DFF800000000000000000001DFF8000000000000000000039FFC00000000
+0000000000038FFC000000000000000000038FFC000000000000000000070FFE00000000
+00000000000707FE0000000000000000000F07FF0000000000000000000E03FF00000000
+00000000000E03FF0000000000000000001E03FF8000000000000000001C01FF80000000
+00000000001C01FF8000000000000000003C01FFC000000000000000003800FFC0000000
+00000000003800FFC000000000000000007000FFE0000000000000000070007FE0000000
+000000000070007FE00000000000000000E0007FF00000000000000000E0003FF0000000
+0000000000E0003FF00000000000000001C0003FF80000000000000001C0001FF8000000
+0000000003C0001FFC000000000000000380000FFC000000000000000380000FFC000000
+000000000780000FFE0000000000000007000007FE0000000000000007000007FE000000
+000000000F000007FF000000000000000E000003FF000000000000000E000003FF000000
+000000001C000003FF800000000000001C000001FF800000000000001C000001FF800000
+0000000038000001FFC000000000000038000000FFC000000000000038000000FFC00000
+0000000070000000FFE0000000000000700000007FE0000000000000F00000007FF00000
+00000000E00000003FF0000000000000E00000003FF0000000000001E00000003FF80000
+00000001C00000001FF8000000000001C00000001FF8000000000003C00000001FFC0000
+00000003FFFFFFFFFFFC000000000003FFFFFFFFFFFC000000000007FFFFFFFFFFFE0000
+00000007FFFFFFFFFFFE0000000000070000000007FE00000000000E0000000007FF0000
+0000000E0000000003FF00000000000E0000000003FF00000000001C0000000003FF8000
+0000001C0000000001FF80000000003C0000000001FFC000000000380000000000FFC000
+000000380000000000FFC000000000780000000000FFE0000000007000000000007FE000
+0000007000000000007FE000000000F000000000007FF000000000E000000000003FF000
+000000E000000000003FF000000001C000000000003FF800000001C000000000001FF800
+000001C000000000001FF8000000038000000000001FFC000000038000000000000FFC00
+0000038000000000000FFC000000070000000000000FFE0000000700000000000007FE00
+00000F00000000000007FF0000000F00000000000003FF0000001F00000000000003FF00
+00003F80000000000003FF8000007FC0000000000003FF800001FFE0000000000007FFC0
+000FFFF800000000001FFFF000FFFFFF0000000007FFFFFFF0FFFFFF0000000007FFFFFF
+F0FFFFFF0000000007FFFFFFF0FFFFFF0000000007FFFFFFF05C657DE463>65
+D<FFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFFFFFFF80FFFFFFFFFF
+FFFFFFFF8000FFFC00000001FFFF80003FF8000000001FFFC0001FF80000000003FFC000
+1FF80000000000FFC0001FF800000000007FC0001FF800000000003FC0001FF800000000
+001FC0001FF800000000000FC0001FF8000000000007C0001FF8000000000007C0001FF8
+000000000003C0001FF8000000000003C0001FF8000000000003E0001FF8000000000001
+E0001FF8000000000001E0001FF8000000000001E0001FF8000000000001E0001FF80000
+00000000E0001FF8000000000000E0001FF8000000000000E0001FF8000000000000E000
+1FF8000000000000E0001FF8000000000000E0001FF800000000000070001FF800000070
+000070001FF800000070000070001FF800000070000070001FF800000070000070001FF8
+00000070000000001FF800000070000000001FF800000070000000001FF8000000700000
+00001FF8000000F0000000001FF8000000F0000000001FF8000000F0000000001FF80000
+00F0000000001FF8000001F0000000001FF8000003F0000000001FF8000007F000000000
+1FF800000FF0000000001FF800007FF0000000001FFFFFFFFFF0000000001FFFFFFFFFF0
+000000001FFFFFFFFFF0000000001FFFFFFFFFF0000000001FF800007FF0000000001FF8
+00000FF0000000001FF8000007F0000000001FF8000003F0000000001FF8000001F00000
+00001FF8000000F0000000001FF8000000F0000000001FF8000000F0000000001FF80000
+00F0000000001FF800000070000000001FF800000070000000001FF80000007000000000
+1FF80000007000000E001FF80000007000000E001FF80000007000000E001FF800000070
+00000E001FF80000007000001C001FF80000000000001C001FF80000000000001C001FF8
+0000000000001C001FF80000000000001C001FF80000000000001C001FF8000000000000
+3C001FF800000000000038001FF800000000000038001FF800000000000038001FF80000
+0000000078001FF800000000000078001FF800000000000078001FF80000000000007800
+1FF8000000000000F0001FF8000000000000F0001FF8000000000000F0001FF800000000
+0001F0001FF8000000000001F0001FF8000000000003F0001FF8000000000007F0001FF8
+000000000007F0001FF800000000000FE0001FF800000000001FE0001FF800000000007F
+E0001FF80000000000FFE0001FF80000000003FFE0003FF8000000001FFFE000FFFC0000
+0003FFFFE0FFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFC0FFFFFFFFFFFFFFFFFFC0FF
+FFFFFFFFFFFFFFFFC04F6279E15A>69 D<FFFFFFFFE000000000FFFFFFFFE000000000FF
+FFFFFFE000000000FFFFFFFFE00000000000FFFF800000000000003FFC00000000000000
+1FFC000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000000000
+1FF8000000000000001FF8000000000000001FF8000000000000001FF800000000001C00
+1FF800000000001C001FF800000000001C001FF800000000001C001FF800000000001C00
+1FF800000000001C001FF800000000003C001FF8000000000038001FF800000000003800
+1FF8000000000038001FF8000000000038001FF8000000000038001FF800000000003800
+1FF8000000000078001FF8000000000078001FF8000000000078001FF800000000007800
+1FF80000000000F8001FF80000000000F8001FF80000000000F0001FF80000000001F000
+1FF80000000001F0001FF80000000003F0001FF80000000007F0001FF80000000007F000
+1FF8000000000FF0001FF8000000001FF0001FF8000000003FF0001FF8000000007FF000
+1FF800000001FFF0001FF800000007FFF0003FF80000003FFFE000FFFC000003FFFFE0FF
+FFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFE0FFFFFFFFFFFFFFFFE046
+6279E153>76 D<3FFFFFFFFFFFFFFFFFFFF83FFFFFFFFFFFFFFFFFFFF83FFFFFFFFFFFFF
+FFFFFFF83FFFFFFFFFFFFFFFFFFFF83FFFC00003FFC00003FFF83FFC000001FF8000007F
+F83FF0000001FF8000000FF83FC0000001FF80000007F87F80000001FF80000003FC7F00
+000001FF80000001FC7E00000001FF80000000FC7C00000001FF800000007C7C00000001
+FF800000007C7C00000001FF800000007C7800000001FF800000003C7800000001FF8000
+00003C7800000001FF800000003C7800000001FF800000003C7000000001FF800000001C
+7000000001FF800000001C7000000001FF800000001C7000000001FF800000001C700000
+0001FF800000001C7000000001FF800000001CF000000001FF800000001EE000000001FF
+800000000EE000000001FF800000000EE000000001FF800000000EE000000001FF800000
+000EE000000001FF800000000EE000000001FF800000000EE000000001FF800000000E00
+00000001FF80000000000000000001FF80000000000000000001FF800000000000000000
+01FF80000000000000000001FF80000000000000000001FF80000000000000000001FF80
+000000000000000001FF80000000000000000001FF80000000000000000001FF80000000
+000000000001FF80000000000000000001FF80000000000000000001FF80000000000000
+000001FF80000000000000000001FF80000000000000000001FF80000000000000000001
+FF80000000000000000001FF80000000000000000001FF80000000000000000001FF8000
+0000000000000001FF80000000000000000001FF80000000000000000001FF8000000000
+0000000001FF80000000000000000001FF80000000000000000001FF8000000000000000
+0001FF80000000000000000001FF80000000000000000001FF80000000000000000001FF
+80000000000000000001FF80000000000000000001FF80000000000000000001FF800000
+00000000000001FF80000000000000000001FF80000000000000000001FF800000000000
+00000001FF80000000000000000001FF80000000000000000001FF800000000000000000
+01FF80000000000000000001FF80000000000000000001FF80000000000000000001FF80
+000000000000000001FF80000000000000000001FF80000000000000000001FF80000000
+000000000001FF80000000000000000001FF80000000000000000001FF80000000000000
+000001FF80000000000000000001FF80000000000000000001FF80000000000000000001
+FF80000000000000000001FF80000000000000000001FF80000000000000000001FF8000
+0000000000000001FF80000000000000000001FF80000000000000000001FF8000000000
+0000000003FFC0000000000000000003FFC000000000000000001FFFF800000000000001
+FFFFFFFFFF800000000001FFFFFFFFFF800000000001FFFFFFFFFF800000000001FFFFFF
+FFFF80000057627CE160>84 D<3FFFFFFF80000003FFFFFF803FFFFFFF80000003FFFFFF
+803FFFFFFF80000003FFFFFF803FFFFFFF80000003FFFFFF80003FFFFC000000007FFFE0
+00000FFFF0000000003FFF00000007FFE0000000001FFC00000003FFC0000000000FF000
+000001FFE0000000000FE000000000FFE0000000000FC000000000FFF0000000000F8000
+0000007FF0000000000F00000000003FF8000000001E00000000003FFC000000001C0000
+0000001FFC000000003C00000000000FFE000000007800000000000FFF00000000700000
+00000007FF00000000F0000000000003FF80000001E0000000000003FFC0000001C00000
+00000001FFC000000380000000000000FFE000000780000000000000FFF000000F000000
+000000007FF800000E000000000000003FF800001E000000000000003FFC00003C000000
+000000001FFE000038000000000000000FFE000078000000000000000FFF0000F0000000
+0000000007FF8000E00000000000000003FF8001E00000000000000003FFC003C0000000
+0000000001FFE003800000000000000000FFE007800000000000000000FFF00F00000000
+00000000007FF80E0000000000000000003FF81E0000000000000000003FFC3C00000000
+00000000001FFE380000000000000000000FFE780000000000000000000FFFF000000000
+000000000007FFE000000000000000000003FFC000000000000000000003FFC000000000
+000000000001FFE000000000000000000000FFE000000000000000000000FFF000000000
+0000000000007FF8000000000000000000003FF8000000000000000000003FFC00000000
+0000000000007FFE000000000000000000007FFE00000000000000000000F7FF00000000
+000000000001E7FF80000000000000000001C3FF80000000000000000003C1FFC0000000
+00000000000781FFE000000000000000000700FFE000000000000000000F007FF0000000
+00000000001E007FF800000000000000001C003FF800000000000000003C001FFC000000
+000000000078001FFE000000000000000070000FFE0000000000000000E00007FF000000
+0000000001E00007FF8000000000000003C00003FF8000000000000003800001FFC00000
+0000000007800001FFE00000000000000F000000FFE00000000000000E0000007FF00000
+000000001E0000007FF80000000000003C0000003FF8000000000000380000001FFC0000
+00000000780000001FFE000000000000F00000000FFE000000000000E000000007FF0000
+00000001E000000007FF800000000003C000000003FFC000000000038000000001FFC000
+000000078000000001FFE0000000000F0000000000FFF0000000000E00000000007FF000
+0000001E00000000007FF8000000003C00000000003FFC000000007800000000001FFC00
+0000007800000000001FFE00000000F800000000000FFF00000001F0000000000007FF00
+000003F0000000000007FF8000000FF8000000000007FFC000001FF8000000000007FFE0
+00007FFC00000000000FFFF00007FFFF00000000003FFFFC00FFFFFFC000000001FFFFFF
+FCFFFFFFC000000001FFFFFFFCFFFFFFC000000001FFFFFFFCFFFFFFC000000001FFFFFF
+FC5E627EE163>88 D<00003FF0000000000003FFFE00000000000FFFFF80000000003FC0
+3FE0000000007E0007F800000000F80003FC00000001E00001FE00000003C00000FF0000
+00078000007F8000000F0000003FC000000F8000003FC000000FF000001FE000001FF800
+001FE000001FFC00000FF000001FFC00000FF000001FFC00000FF000001FFC000007F800
+001FFC000007F800001FFC000007F800000FF8000007F8000003E0000007F80000000000
+0007F800000000000007F800000000000007F800000000000007F800000000000007F800
+000000000007F80000000000007FF800000000007FFFF8000000000FFFFFF8000000007F
+F807F800000001FF8007F800000007FC0007F80000001FF00007F80000007FC00007F800
+0000FF800007F8000003FE000007F8000007FC000007F800000FFC000007F800000FF800
+0007F800001FF0000007F800003FE0000007F800003FE0000007F800007FC0000007F800
+E07FC0000007F800E07FC0000007F800E0FFC0000007F800E0FF80000007F800E0FF8000
+0007F800E0FF8000000FF800E0FF8000000FF800E0FF8000000FF800E0FF8000001FF800
+E0FFC000001BF800E07FC000003BF800E07FC0000073F800E07FE0000071FC01C03FF000
+00E1FC01C01FF00001C1FC01C00FFC000780FE038007FE000F00FF070001FF807E007FFF
+00007FFFF8003FFE00001FFFE0001FF8000001FF000007E0003B417ABF42>97
+D<000003FE00000000001FFFE000000000FFFFF800000001FE03FE00000007F0007F8000
+000FE0003FC000003FC0001FE000007F00000FF00000FF000007F80000FE000003F80001
+FC000003FC0003F8000001FC0007F8000001FE0007F0000000FE000FF0000000FF000FF0
+0000007F001FE00000007F001FE00000007F803FE00000007F803FC00000003F803FC000
+00003F807FC00000003FC07FC00000003FC07FC00000003FC07F800000003FC07F800000
+003FC0FF800000003FC0FFFFFFFFFFFFC0FFFFFFFFFFFFC0FFFFFFFFFFFFC0FF80000000
+0000FF800000000000FF800000000000FF800000000000FF800000000000FF8000000000
+00FF800000000000FF800000000000FF8000000000007F8000000000007FC00000000000
+7FC000000000007FC000000000003FC000000000003FC000000000003FE000000000001F
+E000000000001FE000000001C00FF000000001C00FF000000003C007F8000000038007F8
+000000038003FC000000078001FC0000000F0001FE0000000E0000FF0000001E00007F80
+00003C00003FC000007800001FE00000F0000007F00003E0000003FC0007C0000000FF80
+3F000000003FFFFC000000000FFFF00000000001FF80000032417CBF3A>101
+D<0000000000003F80000003FC0001FFE000003FFFC007FFF00000FFFFF01FC1F80003FC
+03FC3E03F80007F000FE7803F8000FE0007FE003F8001FC0003FC003F8003F80001FC001
+F0007F00000FE0000000FE000007F0000000FE000007F0000001FC000003F8000001FC00
+0003F8000003FC000003FC000003FC000003FC000003F8000001FC000007F8000001FE00
+0007F8000001FE000007F8000001FE000007F8000001FE000007F8000001FE000007F800
+0001FE000007F8000001FE000007F8000001FE000007F8000001FE000007F8000001FE00
+0003F8000001FC000003FC000003FC000003FC000003FC000001FC000003F8000001FC00
+0003F8000000FE000007F0000000FE000007F00000007F00000FE00000003F80001FC000
+00001FC0003F800000003FE0007F0000000037F000FE0000000073FC03FC0000000060FF
+FFF000000000E03FFFC000000000E003FC0000000001C000000000000001C00000000000
+0001C000000000000001C000000000000001C000000000000001E000000000000001E000
+000000000001F000000000000001F000000000000001F800000000000000FC0000000000
+0000FF00000000000000FFFFFFFE000000007FFFFFFFF00000003FFFFFFFFE0000001FFF
+FFFFFF8000000FFFFFFFFFE000000FFFFFFFFFF000003FFFFFFFFFFC0000FE000001FFFE
+0003F80000001FFE0007E000000003FF000FC000000000FF801F80000000007F803F8000
+0000003FC03F00000000001FC07E00000000001FC07E00000000000FE0FE00000000000F
+E0FC000000000007E0FC000000000007E0FC000000000007E0FC000000000007E0FC0000
+00000007E0FC000000000007E0FE00000000000FE07E00000000000FC07E00000000000F
+C07F00000000001FC03F80000000003F801FC0000000007F000FC0000000007E0007F000
+000001FC0003F800000003F80001FC00000007F000007F0000001FC000003FE00000FF80
+00000FFE000FFE00000001FFFFFFF0000000003FFFFF800000000001FFF00000003D5E7D
+BF42>103 D<000000FF8000000000000FFFF800000000003FFFFE0000000000FF007F80
+00000003FC001FE000000007F00007F00000000FC00001F80000003F800000FE0000007F
+0000007F0000007E0000003F000000FC0000001F800001F80000000FC00003F80000000F
+E00003F000000007E00007F000000007F0000FE000000003F8000FE000000003F8001FE0
+00000003FC001FC000000001FC001FC000000001FC003FC000000001FE003FC000000001
+FE003FC000000001FE007F8000000000FF007F8000000000FF007F8000000000FF007F80
+00000000FF00FF8000000000FF80FF8000000000FF80FF8000000000FF80FF8000000000
+FF80FF8000000000FF80FF8000000000FF80FF8000000000FF80FF8000000000FF80FF80
+00000000FF80FF8000000000FF80FF8000000000FF80FF8000000000FF807F8000000000
+FF007F8000000000FF007FC000000001FF007FC000000001FF003FC000000001FE003FC0
+00000001FE003FC000000001FE001FE000000003FC001FE000000003FC001FE000000003
+FC000FF000000007F80007F000000007F00007F000000007F00003F80000000FE00001FC
+0000001FC00001FC0000001FC00000FE0000003F8000007F0000007F0000003F800000FE
+0000001FC00001FC0000000FF00007F800000003FC001FE000000000FF007F8000000000
+7FFFFF00000000000FFFF8000000000001FFC000000039417CBF42>111
+D<00078003F80007FF800FFF00FFFF803FFFC0FFFF807C0FE0FFFF81F01FE0FFFF81E03F
+F001FF83803FF0007F87003FF0007F8F003FF0003F8E003FF0003F9C001FE0003F9C000F
+C0003F98000300003FB8000000003FB8000000003FB0000000003FF0000000003FF00000
+00003FE0000000003FE0000000003FE0000000003FE0000000003FE0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC00000
+00003FC0000000003FC0000000003FC0000000007FE000000000FFF8000000FFFFFFFC00
+00FFFFFFFC0000FFFFFFFC0000FFFFFFFC00002C3F7CBE33>114
+D<0000380000000000380000000000380000000000380000000000380000000000380000
+000000380000000000780000000000780000000000780000000000780000000000F80000
+000000F80000000000F80000000001F80000000001F80000000001F80000000003F80000
+000003F80000000007F8000000000FF8000000001FF8000000001FF8000000007FF80000
+0000FFF800000003FFF80000000FFFFFFFFF00FFFFFFFFFF00FFFFFFFFFF00FFFFFFFFFF
+000007F80000000007F80000000007F80000000007F80000000007F80000000007F80000
+000007F80000000007F80000000007F80000000007F80000000007F80000000007F80000
+000007F80000000007F80000000007F80000000007F80000000007F80000000007F80000
+000007F80000000007F80000000007F80000000007F80000000007F80000000007F80000
+000007F80000000007F80000000007F80000000007F80000000007F80000000007F80000
+000007F80000000007F80000000007F80000E00007F80000E00007F80000E00007F80000
+E00007F80000E00007F80000E00007F80000E00007F80000E00007F80000E00007F80000
+E00007F80000E00007F80000E00007F80000E00007F80000E00003FC0001C00003FC0001
+C00003FC0001C00003FC0003C00001FE0003800001FE0007800000FF00070000007F800F
+0000003FC01E0000001FF07C0000000FFFF800000003FFE0000000007F80002B597FD733
+>116 D<0003C00000000F000007FFC000001FFF0000FFFFC00003FFFF0000FFFFC00003
+FFFF0000FFFFC00003FFFF0000FFFFC00003FFFF000001FFC0000007FF0000007FC00000
+01FF0000007FC0000001FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000000FF0000003FC0000000FF0000003FC00000
+00FF0000003FC0000000FF0000003FC0000001FF0000003FC0000001FF0000003FC00000
+01FF0000003FC0000003FF0000003FC0000003FF0000003FC0000003FF0000003FC00000
+07FF0000001FC0000006FF0000001FE000000EFF0000001FE000001CFF0000000FE00000
+1CFF0000000FF0000038FF80000007F0000070FF80000003F80001E0FFE0000001FE0003
+C0FFFFC00000FFC01F80FFFFC000003FFFFE00FFFFC000000FFFF800FFFFC0000000FFC0
+00FF800042407DBE49>I E /FE 5 89 df<000000000FFE000000000000007FFFE00000
+00000003FFFFFC00000000000FFFFFFF00000000003FE00FFF80000000007F0001FFE000
+000000FC0000FFF000000003F000007FF800000007E000003FFC0000000F8000001FFE00
+00001F0000000FFE0000003E0000000FFF0000003C00000007FF0000007C00000007FF80
+0000F800000007FF800000F000000003FFC00001F000000003FFC00003E000000003FFC0
+0003C000000003FFC00007C000000003FFC000078000000003FFE00007FC00000001FFE0
+000FFE00000001FFE0000FFF00000003FFE0000FFF00000003FFE0000FFF00000003FFE0
+001FFF00000003FFC0001FFF00000003FFC0001FFF00000003FFC0001FFF00000003FFC0
+000FFE00000007FFC0000FFC00000007FF800007F800000007FF800001C00000000FFF80
+0000000000000FFF000000000000000FFF000000000000001FFE000000000000001FFE00
+0000000000003FFC000000000000003FFC000000000000007FF800000000000000FFF000
+000000000000FFF000000000000001FFE000000000000003FFC000000000000003FF8000
+000000000007FF000000000000000FFE000000000000000FFC000000000000001FF80000
+00000000003FF0000000000000007FE000000000000000FFC000000000000001FF800000
+0000000003FF0000000000000007FC000000000000000FF8000000000000001FF0000000
+000000001FE0000000000000003F80000000000000007F0000000000000001FE00000000
+00000003FC0000000000000007F0000000000000000FE0000000000000001FC000000000
+0000003F80000000000000007F0000000000000000FC0000000000000001F80000000000
+000003F0000000E000000007E0000000E00000000FC0000001C00000001F80000001C000
+00003E00000001C00000007C0000000380000000F80000000380000001F0000000038000
+0003E00000000700000007C0000000070000000F000000000F0000001E000000000E0000
+003C000000001E00000078000000007E000000FFFFFFFFFFFC000001FFFFFFFFFFFC0000
+03FFFFFFFFFFFC000007FFFFFFFFFFF800000FFFFFFFFFFFF800001FFFFFFFFFFFF80000
+3FFFFFFFFFFFF000007FFFFFFFFFFFF00000FFFFFFFFFFFFF00000FFFFFFFFFFFFE00000
+FFFFFFFFFFFFE00000435F79DE46>50 D<0003C0000FF0003FF8007FFC007FFC00FFFC00
+FFFC00FFFC00FFFC00FFF800FFF8007FF0003FE0000F8000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000003C0000FF0003FF8007FFC007FFC00FFFC00FF
+FC00FFFC00FFFC00FFF800FFF8007FF0003FE0000F8000163E73BD27>58
+D<0000FFFFFFFFFFC00000000000FFFFFFFFFFC00000000001FFFFFFFFFFC00000000001
+FFFFFFFFFFC00000000000007FFFF800000000000000001FFFC000000000000000000FFF
+8000000000000000000FFF0000000000000000000FFF0000000000000000000FFF000000
+0000000000000FFF0000000000000000001FFF0000000000000000001FFE000000000000
+0000001FFE0000000000000000001FFE0000000000000000001FFE000000000000000000
+1FFE0000000000000000003FFE0000000000000000003FFC0000000000000000003FFC00
+00000000000000003FFC0000000000000000003FFC0000000000000000003FFC00000000
+00000000007FFC0000000000000000007FF80000000000000000007FF800000000000000
+00007FF80000000000000000007FF80000000000000000007FF8000000000000000000FF
+F8000000000000000000FFF0000000000000000000FFF0000000000000000000FFF00000
+00000000000000FFF0000000000000000000FFF0000000000000000001FFF00000000000
+00000001FFE0000000000000000001FFE0000000000000000001FFE00000000000000000
+01FFE0000000000000000001FFE0000000000000000003FFE0000000000000000003FFC0
+000000000000000003FFC0000000000000000003FFC0000000000000000003FFC0000000
+000000000003FFC0000000000000000007FFC0000000000000000007FF80000000000000
+000007FF80000000000000000007FF80000000000000000007FF80000000000000000007
+FF8000000000000000000FFF8000000000000000000FFF0000000000000000000FFF0000
+000000000000000FFF0000000000000000000FFF0000000000000000000FFF0000000000
+000000001FFF0000000000000000001FFE0000000000000000001FFE0000000000038000
+001FFE0000000000038000001FFE0000000000038000001FFE0000000000070000003FFE
+0000000000070000003FFC0000000000070000003FFC00000000000E0000003FFC000000
+00000E0000003FFC00000000000E0000003FFC00000000001E0000007FFC00000000001C
+0000007FF800000000001C0000007FF800000000003C0000007FF8000000000038000000
+7FF80000000000780000007FF8000000000078000000FFF8000000000078000000FFF000
+00000000F0000000FFF00000000001F0000000FFF00000000001F0000000FFF000000000
+03F0000000FFF00000000003E0000001FFF00000000007E0000001FFE0000000000FE000
+0001FFE0000000001FC0000001FFE0000000003FC0000001FFE0000000007FC0000001FF
+E000000000FFC0000003FFE000000003FF80000003FFC00000000FFF80000007FFC00000
+003FFF80000007FFE0000001FFFF8000003FFFF000001FFFFF0000FFFFFFFFFFFFFFFFFF
+0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFE0000FFFFFFFFFFFFFFFFFE000051
+627AE158>76 D<00FFFFFFFFFFFFFFFFFFFFF000FFFFFFFFFFFFFFFFFFFFF000FFFFFFFF
+FFFFFFFFFFFFF001FFFFFFFFFFFFFFFFFFFFF001FFFE00003FFF80000FFFF001FFE00000
+1FFF000000FFF003FF0000001FFE0000003FF003FE0000001FFE0000001FF003F8000000
+1FFE0000000FF003F00000001FFE00000007E007E00000003FFE00000003E007C0000000
+3FFC00000003E007C00000003FFC00000003E007800000003FFC00000001E00F80000000
+3FFC00000001E00F000000003FFC00000001E00F000000007FFC00000001E00E00000000
+7FF800000001E01E000000007FF800000001E01C000000007FF800000001E01C00000000
+7FF800000001E01C000000007FF800000001E03800000000FFF800000001E03800000000
+FFF000000001C03800000000FFF000000001C03800000000FFF000000001C07000000000
+FFF000000001C07000000000FFF000000001C07000000001FFF000000001C0E000000001
+FFE000000001C0E000000001FFE000000001C0E000000001FFE000000001C00000000001
+FFE000000000000000000001FFE000000000000000000003FFE000000000000000000003
+FFC000000000000000000003FFC000000000000000000003FFC000000000000000000003
+FFC000000000000000000003FFC000000000000000000007FFC000000000000000000007
+FF8000000000000000000007FF8000000000000000000007FF8000000000000000000007
+FF8000000000000000000007FF800000000000000000000FFF800000000000000000000F
+FF000000000000000000000FFF000000000000000000000FFF000000000000000000000F
+FF000000000000000000000FFF000000000000000000001FFF000000000000000000001F
+FE000000000000000000001FFE000000000000000000001FFE000000000000000000001F
+FE000000000000000000001FFE000000000000000000003FFE000000000000000000003F
+FC000000000000000000003FFC000000000000000000003FFC000000000000000000003F
+FC000000000000000000003FFC000000000000000000007FFC000000000000000000007F
+F8000000000000000000007FF8000000000000000000007FF8000000000000000000007F
+F8000000000000000000007FF800000000000000000000FFF800000000000000000000FF
+F000000000000000000000FFF000000000000000000000FFF000000000000000000000FF
+F000000000000000000000FFF000000000000000000001FFF000000000000000000001FF
+E000000000000000000001FFE000000000000000000001FFE000000000000000000001FF
+E000000000000000000001FFE000000000000000000003FFE000000000000000000003FF
+C000000000000000000003FFC000000000000000000003FFC000000000000000000003FF
+C000000000000000000003FFC000000000000000000007FFC000000000000000000007FF
+C00000000000000000000FFFC00000000000000000001FFFE0000000000000000001FFFF
+FC000000000000003FFFFFFFFFFFF000000000007FFFFFFFFFFFE000000000007FFFFFFF
+FFFFE000000000007FFFFFFFFFFFE0000000005C6170E065>84 D<00003FFFFFFFFE0000
+07FFFFFFF000003FFFFFFFFE000007FFFFFFF000003FFFFFFFFE000007FFFFFFF000003F
+FFFFFFFC00000FFFFFFFF00000003FFFFFE0000001FFFFFC0000000007FFFF000000007F
+FFC00000000003FFFE000000003FFE000000000001FFFC000000001FFC000000000001FF
+F8000000001FF0000000000000FFF8000000001FE0000000000000FFFC000000001F8000
+00000000007FFC000000001F000000000000007FFE000000003E000000000000003FFE00
+0000003C000000000000003FFF000000007C000000000000001FFF00000000F800000000
+0000001FFF80000001F0000000000000000FFF80000003E0000000000000000FFFC00000
+07C00000000000000007FFC0000007800000000000000007FFE000000F80000000000000
+0003FFE000001F000000000000000003FFF000003E000000000000000001FFF000007C00
+0000000000000001FFF80000F8000000000000000000FFF80000F0000000000000000000
+FFFC0001F00000000000000000007FFC0003E00000000000000000007FFE0007C0000000
+0000000000003FFE000F800000000000000000003FFF001F000000000000000000001FFF
+001E000000000000000000001FFF803E000000000000000000000FFF807C000000000000
+000000000FFFC0F80000000000000000000007FFC1F00000000000000000000007FFE3E0
+0000000000000000000003FFE3C00000000000000000000003FFF7800000000000000000
+000001FFFF800000000000000000000001FFFF000000000000000000000000FFFE000000
+000000000000000000FFFC0000000000000000000000007FFC0000000000000000000000
+007FFE0000000000000000000000003FFE0000000000000000000000003FFF0000000000
+000000000000001FFF0000000000000000000000001FFF8000000000000000000000001F
+FF8000000000000000000000001FFFC000000000000000000000003FFFC0000000000000
+00000000007FFFE00000000000000000000000FBFFE00000000000000000000001F3FFF0
+0000000000000000000003E1FFF00000000000000000000003C1FFF80000000000000000
+000007C0FFF8000000000000000000000F80FFFC000000000000000000001F007FFC0000
+00000000000000003E007FFE000000000000000000007C007FFE00000000000000000000
+78003FFF00000000000000000000F8003FFF00000000000000000001F0001FFF80000000
+000000000003E0001FFF80000000000000000007C0000FFFC000000000000000000F8000
+0FFFC000000000000000000F000007FFE000000000000000001F000007FFE00000000000
+0000003E000003FFE000000000000000007C000003FFF00000000000000000F8000001FF
+F00000000000000001F0000001FFF80000000000000001E0000000FFF800000000000000
+03C0000000FFFC0000000000000007C00000007FFC000000000000000F800000007FFE00
+0000000000001F000000003FFE000000000000003E000000003FFF000000000000007C00
+0000001FFF0000000000000078000000001FFF80000000000000F8000000000FFF800000
+00000001F0000000000FFFC0000000000003E00000000007FFC0000000000007C0000000
+0007FFE000000000000FC00000000003FFE000000000001FC00000000003FFF000000000
+003F800000000001FFF000000000007FC00000000001FFF80000000001FFC00000000003
+FFFC0000000007FFE00000000003FFFC000000001FFFE0000000000FFFFE00000001FFFF
+F8000000003FFFFFC000007FFFFFFF00000003FFFFFFFFC0007FFFFFFF00000003FFFFFF
+FFC000FFFFFFFF00000003FFFFFFFFC000FFFFFFFF00000007FFFFFFFFC0006C627DE169
+>88 D E end
+%%EndProlog
+%%BeginSetup
+%%Feature: *Resolution 600dpi
+TeXDict begin
+%%PaperSize: A4
+
+%%EndSetup
+%%Page: 1 1
+1 0 bop 922 937 a FE(L)-12 b(TX2X:)46 b FD(A)e(L)1643
+907 y FC(A)1696 937 y FD(T)1770 968 y(E)1843 937 y(X)g(to)f(X)g
+(Auto-tagger)1607 1190 y FC(P)m(eter)34 b(R.)e(Wilson)1287
+1306 y(Catholic)f(Univ)m(ersit)m(y)j(of)e(America)2614
+1270 y FB(\003)1277 1422 y FC(Email:)41 b FA(pwilson@cme.nist.gov)1665
+1625 y FC(Jan)m(uary)33 b(1997)1767 2060 y Fz(Abstract)502
+2211 y Fy(L)-7 b(TX2X)24 b Fx(is)g(a)f(table-driv)n(en)g(program)f
+(that)i(will)g(replace)f(L)2358 2194 y Fw(A)2395 2211
+y Fx(T)2441 2229 y(E)2487 2211 y(X)h(commands)f(b)n(y)h(user)f
+(de\014ned)377 2311 y(text.)57 b(This)34 b(rep)r(ort)g(describ)r(es)f
+(the)i(b)r(eta)f(v)n(ersion)f(of)h(the)g(system.)57 b
+Fy(L)-7 b(TX2X)34 b Fx(supp)r(orts)g(b)r(oth)g(a)377
+2411 y(declaritiv)n(e)i(command)h(st)n(yle)g(and)g(an)g(in)n(terpreted)
+f(pro)r(cedural)g(language)g(ten)n(tativ)n(ely)g(called)377
+2510 y Fv(Express-A)p Fx(.)24 b(Details)f(are)g(giv)n(en)f(of)i(the)g
+(program)d(functionalit)n(y)i(including)h(examples.)35
+b(System)377 2610 y(installation)27 b(instructions)g(are)g(pro)n
+(vided.)150 2896 y Fu(Con)l(ten)l(ts)150 3100 y Ft(1)84
+b(In)m(tro)s(duction)2836 b(1)286 3213 y Fs(1.1)94 b(Ov)m(erview)83
+b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)184 b(2)150 3417 y Ft(2)84 b(The)35 b(command)f(table)g
+(\014le)2327 b(6)286 3530 y Fs(2.1)94 b(Sp)s(ecial)29
+b(prin)m(t)g(c)m(haracters)j(in)d(tags)68 b(.)46 b(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)184 b(7)286 3643 y(2.2)94 b(L)519 3626 y Fr(A)558
+3643 y Fs(T)609 3662 y(E)660 3643 y(X)30 b(command)g(t)m(yp)s(es)63
+b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)184
+b(8)495 3756 y(2.2.1)106 b(Built)29 b(in)g(command)i(t)m(yp)s(es)51
+b(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)184 b(8)495 3868 y(2.2.2)106
+b(Optional)29 b(command)h(t)m(yp)s(es)81 b(.)45 b(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+184 b(9)286 3981 y(2.3)94 b(Command)30 b(action)h(tags)76
+b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(10)286 4094 y(2.4)94 b(Argumen)m(t)31 b(actions)f(.)46
+b(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(12)495 4207 y(2.4.1)106 b(Prin)m(t)30 b(options)63
+b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(12)786 4320 y(2.4.1.1)118 b(Argumen)m(t)31 b(pro)s(cessing)84
+b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)138 b(12)786 4433 y(2.4.1.2)118 b(General)30
+b(prin)m(ting)54 b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(14)786
+4546 y(2.4.1.3)118 b(Read)31 b(actions)57 b(.)46 b(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)138 b(15)495 4659 y(2.4.2)106 b(Prin)m(t)30 b(switc)m(hing)49
+b(.)d(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(17)495 4772 y(2.4.3)106 b(Notes)32 b(on)e(the)h(use)f(of)g(bu\013ers)
+g(and)f(\014les)83 b(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)138 b(18)495 4885 y(2.4.4)106
+b(User)31 b(sp)s(eci\014ed)d(mo)s(des)44 b(.)h(.)h(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)138 b(18)286 4998 y(2.5)94 b(Sectioning)30 b(command)g(t)m(yp)s
+(es)e(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)
+h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(24)286
+5110 y(2.6)94 b(List)30 b(en)m(vironmen)m(t)g(t)m(yp)s(es)j(.)46
+b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(25)p
+150 5190 1440 4 v 252 5243 a Fq(\003)288 5275 y Fp(This)18
+b(w)n(ork)g(w)n(as)g(p)r(erformed)g(while)g(a)g(Guest)f(Researc)n(her)h
+(at)g(the)f(National)h(Institute)f(of)h(Standards)f(and)g(T)-6
+b(ec)n(hnology)1937 5531 y Fs(i)p eop
+%%Page: 2 2
+2 1 bop 286 573 a Fs(2.7)94 b(Character)31 b(t)m(yp)s(es)i(.)45
+b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f
+(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(27)286 686 y(2.8)94 b(V)-8 b(erbatim)31 b(lik)m(e)e(t)m(yp)s(es)k(.)
+46 b(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(27)286 799 y(2.9)94 b(Odd)29 b(command)i(t)m(yp)s(es)53
+b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(29)286 912 y(2.10)49 b(Other)30 b(command)g(t)m(yp)s(es)63
+b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(30)286 1024 y(2.11)49 b(Picture)30 b(t)m(yp)s(es)67
+b(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h
+(.)138 b(30)286 1137 y(2.12)49 b(Sp)s(ecial)29 b(command)h(t)m(yp)s(es)
+86 b(.)46 b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(33)286 1250 y(2.13)49 b(File)30 b(inclusion)64 b(.)46
+b(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(33)286 1363 y(2.14)49 b(In)m(terpreter)31 b(commands)69
+b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(35)150 1567 y Ft(3)84 b(The)35 b(L)-9 b(TX2X)35 b(program)2386
+b(36)286 1680 y Fs(3.1)94 b(Running)28 b(L)-8 b(TX2X)72
+b(.)46 b(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(36)495 1793 y(3.1.1)106 b(Directory)31 b(searc)m(hing)d(.)46
+b(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(39)286 1906
+y(3.2)94 b(System)31 b(comp)s(onen)m(ts)93 b(.)45 b(.)h(.)g(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(39)495 2019 y(3.2.1)106
+b(The)30 b(lexer)70 b(.)46 b(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)138 b(40)495 2132 y(3.2.2)106 b(The)30
+b(parser)87 b(.)46 b(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h
+(.)138 b(40)495 2245 y(3.2.3)106 b(The)30 b(supp)s(ort)f(libraries)d(.)
+45 b(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(42)495 2357
+y(3.2.4)106 b(The)30 b(user-de\014ned)f(library)52 b(.)46
+b(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g
+(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(42)495 2470 y(3.2.5)106
+b(The)30 b Fo(Express-A)f Fs(in)m(terpreter)43 b(.)j(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(42)150 2674 y Ft(4)84 b(The)35 b Fo(Express-A)f Ft(programming)g
+(language)1592 b(42)286 2787 y Fs(4.1)94 b(Basic)31 b(elemen)m(ts)85
+b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(43)286 2900 y(4.2)94 b(Data)32 b(t)m(yp)s(es)90 b(.)46
+b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+138 b(44)286 3013 y(4.3)94 b(Statemen)m(ts)85 b(.)46
+b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+138 b(45)286 3126 y(4.4)94 b(Expressions)59 b(.)46 b(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(48)495 3239 y(4.4.1)106 b(Arithmetic)30 b(op)s(erators)37
+b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(48)495
+3352 y(4.4.2)106 b(Relational)30 b(op)s(erators)64 b(.)45
+b(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f
+(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(49)495 3465
+y(4.4.3)106 b(Logical)31 b(op)s(erators)43 b(.)j(.)g(.)f(.)h(.)g(.)f(.)
+h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)138 b(49)495 3577 y(4.4.4)106 b(Miscellaneous)44
+b(.)h(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g
+(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(50)286 3690 y(4.5)94 b(Built)30 b(in)f(pro)s(cedures)g(and)g
+(functions)40 b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(52)495
+3803 y(4.5.1)106 b(Pro)s(cedures)78 b(.)46 b(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g
+(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(52)495 3916 y(4.5.2)106
+b(F)-8 b(unctions)61 b(.)46 b(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)138 b(53)286 4029 y(4.6)94 b(Source)31
+b(lev)m(el)f(debugger)90 b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)138 b(56)286 4142 y(4.7)94 b(Example)30 b Fo(Express-A)f
+Fs(co)s(de)34 b(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(57)150 4346 y Ft(5)84 b(Sp)s(ecifying)36 b(a)f Fn(SPECIAL)p
+1218 4346 29 4 v 67 w Ft(command)1925 b(64)286 4459 y
+Fs(5.1)94 b(Example)37 b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(66)495 4572
+y(5.1.1)106 b(Grammar)31 b(metho)s(d)e(implemen)m(tation)71
+b(.)46 b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)138 b(68)495 4685 y(5.1.2)106 b(Co)s(de)30 b(metho)s(d)g
+(implemen)m(tation)39 b(.)46 b(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(71)286
+4797 y(5.2)94 b(Notes)c(.)46 b(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(77)495
+4910 y(5.2.1)106 b(An)30 b(up)s(dated)f(metho)s(d)66
+b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(78)150
+5114 y Ft(A)57 b(Example)34 b(command)g(table)g(\014le)h(for)g(de-T)
+1983 5134 y(E)2038 5114 y(Xing)1389 b(79)1925 5531 y
+Fs(ii)p eop
+%%Page: 3 3
+3 2 bop 150 573 a Ft(B)62 b(LaT)-9 b(eX)35 b(to)g(HTML)f(translation)
+2046 b(84)150 777 y(C)60 b(Kno)m(wn)35 b(limitations)2513
+b(88)150 980 y(D)56 b(Command)33 b(table)i(summary)2169
+b(89)286 1093 y Fs(D.1)70 b(Sp)s(ecial)29 b(prin)m(t)g(c)m(haracters)84
+b(.)46 b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)
+h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(89)286
+1206 y(D.2)70 b Fo(Express-A)30 b Fs(co)s(de)g(initialization)90
+b(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(90)286 1319 y(D.3)70
+b(Commen)m(ts)31 b(and)f(\014le)f(inclusion)35 b(.)45
+b(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f
+(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(90)286 1432
+y(D.4)70 b(Command)30 b(t)m(yp)s(es)88 b(.)46 b(.)g(.)f(.)h(.)g(.)g(.)f
+(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(90)495 1545 y(D.4.1)82
+b(Built)29 b(in)g(command)i(t)m(yp)s(es)51 b(.)46 b(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)138 b(91)495 1658 y(D.4.2)82 b(Optional)29 b(command)h(t)m(yp)s(es)
+81 b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(92)286 1771 y(D.5)70
+b(T)-8 b(ag)32 b(sp)s(eci\014cation)d(commands)45 b(.)g(.)h(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)138 b(94)495 1884 y(D.5.1)82 b(Argumen)m(ts)h(.)46
+b(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g
+(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(94)495 1997 y(D.5.2)82 b(T)-8 b(ag)32 b(actions)60
+b(.)46 b(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(94)495 2110 y(D.5.3)82 b(Prin)m(t)30 b(con)m(trol)77
+b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(95)495 2223 y(D.5.4)82 b(Sectioning)37 b(.)46 b(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(96)150 2426
+y Ft(E)67 b(System)34 b(installation)2485 b(97)286 2539
+y Fs(E.1)77 b(Command)30 b(table)g(prin)m(ting)36 b(.)46
+b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(99)286
+2652 y(E.2)77 b(A)31 b Fn(make)e Fs(\014le)89 b(.)46
+b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+93 b(100)286 2765 y(E.3)77 b(Limits)29 b(and)h(errors)47
+b(.)f(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f
+(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)93
+b(106)286 2878 y(E.4)77 b(Av)-5 b(ailabilit)m(y)64 b(.)46
+b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+93 b(107)495 2991 y(E.4.1)c(Cop)m(yrigh)m(t)50 b(.)c(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)93 b(107)495 3104
+y(E.4.2)c(Disclaimer)27 b(.)46 b(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)
+h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)93 b(107)150 3308 y Ft(F)70 b(A)35
+b(grammar)e(for)i(the)g(command)f(table)1698 b(108)286
+3421 y Fs(F.1)80 b(Notation)35 b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)93 b(108)286
+3533 y(F.2)80 b(Grammar)70 b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)93 b(109)150 3737
+y Ft(G)54 b(A)35 b(grammar)e(for)i Fo(Express-A)2110
+b Ft(115)150 3941 y(References)2953 b(123)150 4227 y
+Fu(List)45 b(of)h(T)-11 b(ables)286 4430 y Fs(1)164 b(A)31
+b(simple)d(table)j(t)m(yp)s(eset)g(b)m(y)f(L)1571 4414
+y Fr(A)1610 4430 y Fs(T)1661 4450 y(E)1711 4430 y(X.)66
+b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(20)286 4543 y(2)164
+b(A)31 b(simple)d(table)j(t)m(yp)s(eset)g(after)g(translation)e(to)i
+(HTML.)71 b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+138 b(21)286 4656 y(3)164 b(The)30 b(NOT)g(logical)g(op)s(erator)51
+b(.)46 b(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(50)286
+4769 y(4)164 b(The)30 b(AND,)i(OR)e(and)f(X)m(OR)i(logical)f(op)s
+(erators)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)138 b(50)286 4882 y(5)164 b(Sp)s(ecial)29
+b(prin)m(t)g(c)m(haracter)j(commands.)67 b(.)46 b(.)g(.)f(.)h(.)g(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(90)286 4995 y(6)164 b(Built)30 b(in)f(command)h(t)m(yp)s(e)g(k)m(eyw)
+m(ords.)g(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(91)286 5108
+y(7)164 b(General)31 b(command)f(t)m(yp)s(e)g(k)m(eyw)m(ords.)e(.)45
+b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f
+(.)h(.)g(.)g(.)f(.)h(.)138 b(92)286 5221 y(8)164 b(Sp)s(eci\014c)29
+b(command)h(t)m(yp)s(e)h(k)m(eyw)m(ords.)36 b(.)45 b(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h
+(.)138 b(93)1912 5531 y(iii)p eop
+%%Page: 4 4
+4 3 bop 286 573 a Fs(9)164 b(Sp)s(ecial)29 b(command)h(t)m(yp)s(e)h(k)m
+(eyw)m(ords.)56 b(.)45 b(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)
+g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(93)286
+686 y(10)119 b(Argumen)m(t)31 b(commands.)75 b(.)46 b(.)g(.)g(.)f(.)h
+(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)
+g(.)f(.)h(.)g(.)g(.)f(.)h(.)138 b(94)286 799 y(11)119
+b(T)-8 b(ag)32 b(commands.)43 b(.)i(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)138 b(94)286 912 y(12)119 b(T)-8
+b(ag)32 b(actions.)43 b(.)j(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g
+(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)
+f(.)h(.)g(.)g(.)f(.)h(.)138 b(95)286 1024 y(13)119 b(Prin)m(t)30
+b(con)m(trol)h(commands.)i(.)46 b(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h
+(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)
+h(.)138 b(95)286 1137 y(14)119 b(Prin)m(t)30 b(con)m(trol)h(v)-5
+b(alues.)71 b(.)45 b(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)
+g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(96)286 1250 y(15)119 b(Sectioning)30 b(lev)m(el)g(v)-5
+b(alues.)37 b(.)46 b(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)
+f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)g(.)f(.)h(.)g(.)g(.)f(.)h(.)138
+b(96)1913 5531 y(iv)p eop
+%%Page: 1 5
+1 4 bop 150 573 a Fu(1)135 b(In)l(tro)t(duction)150 776
+y Fs(L)174 759 y Fr(A)213 776 y Fs(T)264 795 y(E)314
+776 y(X)23 b([1)q(],)i(whic)m(h)d(is)g(built)e(on)j(top)g(of)h(T)1518
+795 y(E)1568 776 y(X)f([2],)i(is)d(a)i(do)s(cumen)m(t)e(tagging)i
+(system)f(that)h(is)e(v)m(ery)h(p)s(opular)150 889 y(in)32
+b(the)i(academic)g(and)f(scien)m(ti\014c)f(publishing)d(comm)m(unities)
+k(b)s(ecause)g(of)h(the)f(high)g(qualit)m(y)f(t)m(yp)s(eset)150
+1002 y(material)e(that)h(the)f(system)h(outputs)f(for)g(normal)f(text)j
+(and)d(esp)s(ecially)g(for)h(mathematics.)291 1115 y(In)j(particular,)g
+(man)m(y)g(of)h(the)g(do)s(cumen)m(ts)f(forming)f(the)i(In)m
+(ternational)e(Standard)h(ISO)65 b(10303,)150 1227 y(commonly)27
+b(referred)f(to)j(as)e(STEP)f([3)q(],)i(ha)m(v)m(e)h(b)s(een)e(written)
+f(using)g(L)2543 1211 y Fr(A)2582 1227 y Fs(T)2633 1247
+y(E)2683 1227 y(X)i(as)f(the)h(do)s(cumen)m(t)f(tagging)150
+1340 y(language.)38 b(Lately)21 b(there)g(ha)m(v)m(e)g(b)s(een)f(mo)m
+(v)m(es)i(to)m(w)m(ards)g(con)m(v)m(erting)f(the)g(STEP)e(do)s(cumen)m
+(ts)i(to)g(em)m(b)s(o)s(dy)150 1453 y(SGML)h([4])g(rather)g(than)g(L)
+1044 1437 y Fr(A)1083 1453 y Fs(T)1134 1473 y(E)1184
+1453 y(X)g(markup.)37 b(This)20 b(has)h(led)g(to)i(an)e(in)m(terest)h
+(in)f(the)h(automatic)h(con)m(v)m(ersion)150 1566 y(from)38
+b(L)397 1549 y Fr(A)436 1566 y Fs(T)487 1586 y(E)537
+1566 y(X)h(to)g(SGML)g(do)s(cumen)m(ts.)64 b(The)38 b
+Fy(L)-7 b(TX2X)39 b Fs(system)f(is)g(an)g(initial)e(attempt)k(to)f(pro)
+m(vide)f(a)150 1679 y(generic)30 b(capabilit)m(y)g(for)g(con)m(v)m
+(erting)h(L)1483 1662 y Fr(A)1522 1679 y Fs(T)1573 1699
+y(E)1623 1679 y(X)g(tags)g(in)m(to)f(other)h(kinds)d(of)j(tags.)291
+1792 y(The)c Fy(L)-7 b(TX2X)28 b Fs(system)f(describ)s(ed)f(b)s(elo)m
+(w)h(is)f(in)h(a)h(b)s(eta)f(release)h(state.)41 b(That)28
+b(is,)f(there)h(is)f(probably)150 1905 y(some)j(more)g(w)m(ork)g(to)g
+(b)s(e)g(done)f(on)h(it)f(but)g(exp)s(erience)g(from)h(use)f(is)g
+(needed)g(to)i(determine)e(desirable)150 2018 y(additional)g
+(functionalit)m(y)-8 b(.)43 b(Ho)m(w)m(ev)m(er,)35 b(the)c(co)s(de)h
+(has)f(b)s(een)g(stable)g(for)h(some)g(time.)43 b(Bug)32
+b(rep)s(orts)f(or)150 2131 y(suggested)38 b(enhancemen)m(ts)g(\(esp)s
+(ecially)d(if)h(the)i(suggestions)f(are)h(accompanied)f(b)m(y)g(w)m
+(orking)f(co)s(de\))150 2244 y(are)31 b(encouraged,)g(as)g(are)f
+(constructiv)m(e)h(commen)m(ts)h(ab)s(out)e(this)f(do)s(cumen)m(t.)291
+2357 y(Essen)m(tially)-8 b(,)28 b Fy(L)-7 b(TX2X)27 b
+Fs(reads)h(a)g(\014le)f(con)m(taining)h(L)1979 2340 y
+Fr(A)2018 2357 y Fs(T)2069 2376 y(E)2119 2357 y(X)g(markup,)f(replaces)
+h(the)g(L)3094 2340 y Fr(A)3133 2357 y Fs(T)3184 2376
+y(E)3234 2357 y(X)g(commands)150 2469 y(b)m(y)45 b(user-de\014ned)f
+(text,)50 b(and)45 b(writes)f(the)i(result)e(out)h(to)i(another)e
+(\014le.)85 b(The)44 b(program)h(op)s(erates)150 2582
+y(from)38 b(a)i(command)e(table)h(that)g(sp)s(eci\014es)f(the)h
+(replacemen)m(t)g(text.)67 b(In)38 b(general,)j(no)e(programming)150
+2695 y(kno)m(wledge)24 b(or)h(skills)d(are)i(required)f(to)i(write)f(a)
+g(command)g(table,)i(whic)m(h)d Fy(L)-7 b(TX2X)25 b Fs(will)c(then)j
+(in)m(terpret.)150 2808 y(Some)30 b(kno)m(wledge)f(of)h(L)957
+2791 y Fr(A)996 2808 y Fs(T)1047 2828 y(E)1098 2808 y(X)f(is)g
+(required,)f(but)h(no)h(more)g(than)f(is)g(necessary)h(for)g(authoring)
+e(a)i(L)3541 2791 y Fr(A)3580 2808 y Fs(T)3631 2828 y(E)3682
+2808 y(X)150 2921 y(do)s(cumen)m(t.)291 3034 y Fy(L)-7
+b(TX2X)30 b Fs(has)h(pro)m(v)m(ed)f(capable)h(of)f(p)s(erforming)e(suc)
+m(h)i(functions)f(as:)286 3221 y Fm(\017)46 b Fs(Con)m(v)m(ersion)33
+b(of)h(do)s(cumen)m(ts)f(mark)m(ed)g(up)g(according)g(to)h(a)g(sp)s
+(eci\014c)e(L)2822 3205 y Fr(A)2861 3221 y Fs(T)2912
+3241 y(E)2963 3221 y(X)h(do)s(cumen)m(tclass)g(to)377
+3334 y(do)s(cumen)m(ts)d(tagged)i(according)f(to)g(a)f(sp)s(eci\014c)g
+(SGML)g(DTD.)286 3522 y Fm(\017)46 b Fs(Remo)m(v)-5 b(al)31
+b(of)g(L)875 3505 y Fr(A)914 3522 y Fs(T)965 3541 y(E)1015
+3522 y(X)g(commands)f(to)h(pro)s(duce)e(deT)-8 b(eXed)31
+b(source.)286 3709 y Fm(\017)46 b Fs(Con)m(v)m(ersion)24
+b(of)f(simple)f(L)1236 3693 y Fr(A)1275 3709 y Fs(T)1326
+3729 y(E)1376 3709 y(X)i(do)s(cumen)m(ts)g(to)g(HTML)g([5])g(tagged)i
+(do)s(cumen)m(ts)d(for)h(publication)377 3822 y(on)31
+b(the)f(W)-8 b(orld)30 b(Wide)g(W)-8 b(eb.)291 4010 y(The)28
+b(remainder)f(of)i(this)f(in)m(tro)s(duction)e(giv)m(es)j(an)g(o)m(v)m
+(erview)g(of)g(the)g Fy(L)-7 b(TX2X)28 b Fs(program.)40
+b(The)28 b(com-)150 4122 y(mand)h(table)h(is)f(describ)s(ed)f(in)g
+(more)i(detail)f(in)g(section)h(2)g(and)g(information)e(on)i(running)d
+(the)j Fy(L)-7 b(TX2X)150 4235 y Fs(program)27 b(is)f(pro)m(vided)g(in)
+g(section)i(3.)40 b(Section)27 b(4)g(giv)m(es)h(an)f(o)m(v)m(erview)h
+(of)f(the)h Fo(Express-A)e Fs(language.)3710 4202 y Fr(1)150
+4348 y Fs(Although)c(the)h(functionalit)m(y)e(a)m(v)-5
+b(ailable)22 b(through)f(the)i(command)g(table)f(facilit)m(y)g(is)f
+(suitable)g(for)i(man)m(y)150 4461 y(tasks,)33 b(esp)s(ecially)e(since)
+h(an)g(in)m(terpreter)f(for)h(the)h Fo(Express-A)e Fs(general)h
+(programming)f(language)i(is)150 4574 y(included)24 b(within)h
+Fy(L)-7 b(TX2X)p Fs(,)27 b(section)g(5)g(giv)m(es)h(details)e(on)g(ho)m
+(w)h(the)h(system)f(can)g(b)s(e)f(extended)h(for)g(cases)150
+4687 y(where)j(this)f(pro)m(v)m(es)i(to)g(b)s(e)f(inadequate.)291
+4800 y(The)j(rep)s(ort)g(ends)g(with)f(sev)m(eral)i(app)s(endices.)49
+b(An)33 b(example)g(command)g(table)h(for)f(deT)-8 b(eXing)34
+b(a)150 4913 y(do)s(cumen)m(t)i(is)f(repro)s(duced)f(in)g(A)i(and)g
+(some)g(of)g(the)g(issues)e(in)h(con)m(v)m(erting)i(from)e(L)3115
+4896 y Fr(A)3154 4913 y Fs(T)3205 4932 y(E)3255 4913
+y(X)h(to)h(HTML)150 5026 y(are)31 b(discussed)e(in)g(B.)42
+b(The)30 b(kno)m(wn)h(limitations)d(of)j Fy(L)-7 b(TX2X)30
+b Fs(are)h(listed)f(in)f(C)h(and)g(a)h(summary)f(of)h(the)p
+150 5105 1440 4 v 254 5158 a Fl(1)288 5190 y Fp(The)36
+b(o)n(v)n(erview)f(is)h(necessarily)g(rather)f(brief)h(as)g(I)e(am)h
+(shortly)g(mo)n(ving)f(to)h(a)h(new)f(place)h(of)g(emplo)n(ymen)n(t)c
+(and)150 5282 y Fk(Express-A)26 b Fp(is)g(the)f(latest)i(addition)f(to)
+f(the)h(system.)1927 5531 y Fs(1)p eop
+%%Page: 2 6
+2 5 bop 150 573 a Fs(command)38 b(table)h(facilities)e(are)i(giv)m(en)g
+(in)e(D.)66 b(App)s(endix)36 b(E)j(pro)m(vides)f(instructions)e(on)j
+(installing)150 686 y(the)h Fy(L)-7 b(TX2X)41 b Fs(program,)h(together)
+g(with)d(cop)m(yrigh)m(t)h(and)g(w)m(arran)m(t)m(y)h(information.)69
+b(Finally)-8 b(,)41 b(F)g(and)150 799 y(Gpro)m(vide)30
+b(grammars)g(for)g(the)h(command)f(tableand)g Fo(Express-A)p
+Fs(,)f(resp)s(ectiv)m(ely)-8 b(.)150 1042 y Fj(1.1)112
+b(Ov)m(erview)150 1214 y Fs(The)40 b(in)m(ten)m(t)h(of)g(Leslie)f(Lamp)
+s(ort,)j(the)e(author)g(of)g(L)2024 1197 y Fr(A)2063
+1214 y Fs(T)2114 1233 y(E)2164 1214 y(X,)j(w)m(as)d(to)g(pro)m(vide)f
+(a)h(do)s(cumen)m(t)g(tagging)150 1327 y(system)33 b(that)h(enabled)e
+(the)i(capture)f(of)g(the)h(logical)e(structure)h(of)g(a)h(do)s(cumen)m
+(t.)49 b(This)31 b(system)i(uses)150 1440 y(Donald)21
+b(Kn)m(uth's)g(T)847 1459 y(E)897 1440 y(X)h(system)g(as)f(its)h(t)m
+(yp)s(esetting)g(engine)f([2],)j(and)d(th)m(us)h(has)f(an)h(inheren)m
+(t)e(capabilit)m(y)150 1552 y(for)30 b(high)f(qualit)m(y)h(t)m(yp)s
+(esetting.)291 1665 y(All)43 b(L)478 1649 y Fr(A)517
+1665 y Fs(T)568 1685 y(E)618 1665 y(X)h(commands)f(are)h(distinguished)
+c(b)m(y)k(starting)f(with)g(a)h(bac)m(kslash)g(\()p Fn(\\)p
+Fs(\).)81 b(Generally)150 1778 y(sp)s(eaking,)38 b(the)f(name)g(of)g(a)
+h(command)f(is)f(a)h(string)f(of)i(alphab)s(etic)d(c)m(haracters)k
+(\(e.g.)62 b Fn(\\acommand)p Fs(\).)150 1891 y(Commands)33
+b(ma)m(y)h(tak)m(e)i(argumen)m(ts.)52 b(Required)32 b(argumen)m(ts)i
+(are)h(enclosed)e(in)g(curly)g(braces)h(\(i.e.)51 b Fn({)150
+2004 y Fs(and)36 b Fn(})p Fs(\).)60 b(Optional)35 b(argumen)m(ts)i(are)
+g(enclosed)g(in)e(square)i(brac)m(k)m(ets)h(\(i.e.)60
+b Fn([)37 b Fs(and)f Fn(])p Fs(\).)60 b(The)36 b(general)150
+2117 y(syn)m(tax)j(for)g(a)f(command)h(is)e(the)i(command)g(name)f
+(\(preceded)h(b)m(y)f(a)h(bac)m(kslash\))g(follo)m(w)m(ed)f(b)m(y)h
+(the)150 2230 y(argumen)m(t)31 b(list)e(with)g(a)i(maxim)m(um)1387
+2197 y Fr(2)1455 2230 y Fs(of)g(nine)e(argumen)m(ts.)291
+2343 y(The)i Fy(L)-7 b(TX2X)30 b Fs(program)h(reads)g(a)g(L)1484
+2326 y Fr(A)1523 2343 y Fs(T)1574 2362 y(E)1625 2343
+y(X)g(do)s(cumen)m(t)f(\014le)g(and)h(outputs)f(a)i(transformation)e
+(of)h(this)150 2456 y(\014le.)55 b(By)35 b(default)g(it)g(outputs)g
+(the)g(normal)f(text)j(while)c(for)i(eac)m(h)i(L)2529
+2439 y Fr(A)2568 2456 y Fs(T)2619 2475 y(E)2669 2456
+y(X)f(command)f(and)f(argumen)m(t)150 2569 y(p)s(erforms)e(some)i
+(user-sp)s(eci\014ed)e(actions;)j(t)m(ypically)e(these)h(actions)g(in)m
+(v)m(olv)m(e)f(the)h(output)f(of)h(sp)s(eci\014c)150
+2682 y(text)23 b(corresp)s(onding)e(to)i(the)f(particular)f(command.)38
+b(The)21 b(actions)i(are)g(sp)s(eci\014ed)d(in)h(a)i
+Fi(c)-5 b(ommand)27 b(table)150 2794 y Fs(\014le,)k(written)f(b)m(y)h
+(the)g(user,)g(whic)m(h)f(is)g(read)h(in)m(to)h(the)f
+Fy(L)-7 b(TX2X)31 b Fs(system)g(b)s(efore)g(do)s(cumen)m(t)g(pro)s
+(cessing)150 2907 y(is)26 b(b)s(egun.)38 b(A)26 b(command)h(table)f
+(consists)g(of)h(a)f(listing)f(of)h(the)h(L)2318 2891
+y Fr(A)2357 2907 y Fs(T)2408 2927 y(E)2458 2907 y(X)g(commands)f(of)h
+(in)m(terest)f(together)150 3020 y(with)h(the)i(desired)e(actiond)i
+(for)f(eac)m(h)i(of)f(these)g(commands)f(and)g(their)g(argumen)m(ts.)40
+b(Di\013eren)m(t)30 b(e\013ects)150 3133 y(ma)m(y)22
+b(b)s(e)e(easily)h(obtained)f(b)m(y)i(c)m(hanging)f(the)g(command)g
+(table)g(\014le.)37 b(F)-8 b(or)22 b(example,)h(a)f(simple)d(command)
+150 3246 y(table)j(\014le)g(ma)m(y)h(b)s(e)e(written)h(that)h(will)c
+(delete)k(all)e(the)i(L)2021 3229 y Fr(A)2060 3246 y
+Fs(T)2111 3266 y(E)2161 3246 y(X)f(commands)g(from)g(a)h(do)s(cumen)m
+(t,)h(resulting)150 3359 y(in)j(a)i(plain)e(ASCI)s(I)g(\014le)g(with)h
+(no)g(em)m(b)s(edded)g(markup.)2069 3326 y Fr(3)2147
+3359 y Fs(A)h(more)f(complex)h(command)f(table)g(ma)m(y)i(b)s(e)150
+3472 y(written)f(that)i(will)d(replace)i(L)1169 3455
+y Fr(A)1208 3472 y Fs(T)1259 3492 y(E)1310 3472 y(X)g(tags)i(with)d
+(appropriate)g(SGML)h(tags.)291 3585 y(In)k(some)h(circles)f(it)g(is)f
+(traditional)g(to)i(in)m(tro)s(duce)f(a)h(programming)e(language)i(b)m
+(y)g(pro)m(viding)d(an)150 3698 y(example)i(program)h(that)g(prin)m(ts)
+f(`Hello)g(w)m(orld'.)53 b(In)34 b(con)m(trast,)k(the)c(follo)m(wing)g
+(command)g(table)h(\014le)150 3811 y(called)h Fn(bye.ct)p
+Fs(,)i(when)e(used)g(in)g(conjunction)h(with)f(a)h(t)m(ypical)g(v)-5
+b(anilla)35 b(L)2758 3794 y Fr(A)2797 3811 y Fs(T)2848
+3830 y(E)2898 3811 y(X)j(\014le,)g(will)d(transform)150
+3924 y(the)c(L)331 3907 y Fr(A)370 3924 y Fs(T)421 3943
+y(E)471 3924 y(X)f(\014le)g(to)h(a)g(\014le)e(that)i(consists)f(only)f
+(of)i(the)g(w)m(ords)e(`Go)s(o)s(db)m(y)m(e)j(do)s(cumen)m(t'.)150
+4123 y Fh(C=)348 b(bye.ct)128 b("Goodbye)40 b(document")g(for)j(ltx2x)
+150 4322 y(TYPE=)f(COMMAND)150 4422 y(NAME=)g(\\documentclass)237
+4521 y(START_TAG=)e("Goodbye)g(document")237 4621 y(PC_AT_END=)g
+(NO_PRINT)150 4721 y(END_TYPE)150 4920 y(C=)j(just)f(in)g(case)g(a)i
+(LaTeX)d(v2.09)h(document)150 5019 y(TYPE=)g(COMMAND)p
+150 5081 1440 4 v 254 5135 a Fl(2)288 5166 y Fp(Under)25
+b(v)n(ery)g(un)n(usual)g(circumstances)g(this)h(limit)g(ma)n(y)e(b)r(e)
+i(exceeded.)254 5226 y Fl(3)288 5258 y Fp(T)-6 b(o)26
+b(a\016cionados,)i(this)e(pro)r(cess)g(is)h(kno)n(wn)e(as)h(de-T)1814
+5274 y(E)1857 5258 y(Xing.)1927 5531 y Fs(2)p eop
+%%Page: 3 7
+3 6 bop 150 573 a Fh(NAME=)42 b(\\documentstyle)237 672
+y(START_TAG=)e("Goodbye)g(document")237 772 y(PC_AT_END=)g(NO_PRINT)150
+872 y(END_TYPE)150 1071 y(C=)j(just)f(in)g(case)g(there)g(is)h(no)f
+(\\documentclass/st)o(yle)37 b(command)150 1171 y(TYPE=)42
+b(BEGIN_DOCUMENT)237 1270 y(START_TAG=)e("Goodbye)g(document")237
+1370 y(PC_AT_END=)g(NO_PRINT)150 1469 y(END_TYPE)150
+1669 y(TYPE=)i(OTHER_COMMAND)237 1768 y(PRINT_CONTROL=)c(NO_PRINT)150
+1868 y(END_TYPE)150 2067 y(TYPE=)k(OTHER_BEGIN)237 2167
+y(PRINT_CONTROL=)c(NO_PRINT)150 2267 y(END_TYPE)150 2466
+y(TYPE=)k(OTHER_END)237 2565 y(PRINT_CONTROL=)c(NO_PRINT)150
+2665 y(END_TYPE)150 2864 y(END_CTFILE=)83 b(end)42 b(of)h(bye.ct)291
+3077 y Fs(Essen)m(tially)25 b(the)h(command)g(table)g(instructs)f
+Fy(L)-7 b(TX2X)26 b Fs(what)g(to)g(prin)m(t)f(for)h(eac)m(h)h(L)3106
+3060 y Fr(A)3145 3077 y Fs(T)3196 3096 y(E)3247 3077
+y(X)f(command.)150 3190 y(A)35 b(command)g(table)g(\014le)f(consists)h
+(of)g(a)g(series)g(of)g(commands,)h(one)f(p)s(er)f(line)g(and)g(in)m
+(tro)s(duced)g(b)m(y)h(a)150 3303 y(k)m(eyw)m(ord)40
+b(suc)m(h)g(as)g Fh(TYPE=)p Fs(.)67 b(Keyw)m(ords)40
+b(are)g(case)h(insensitiv)m(e)d(but)h(b)m(y)h(con)m(v)m(en)m(tion)h
+(are)f(written)f(in)150 3416 y(upp)s(er)28 b(case.)42
+b(Commen)m(ts)31 b(in)e(a)h(command)h(table)f(are)h(in)m(tro)s(duced)d
+(b)m(y)j(the)f(k)m(eyw)m(ord)h Fh(C=)p Fs(.)291 3528
+y(The)37 b(main)g(b)s(o)s(dy)f(of)i(a)g(command)f(table)h(consists)f
+(of)h(the)g(sp)s(eci\014cation)e(of)i(L)3084 3512 y Fr(A)3123
+3528 y Fs(T)3174 3548 y(E)3225 3528 y(X)f(commands)150
+3641 y(of)f(in)m(terest)g(and)f(the)h(actions)g(to)g(b)s(e)f(tak)m(en)i
+(for)f(these.)57 b(Eac)m(h)36 b(sp)s(eci\014cation)f(commences)h(with)f
+(the)150 3754 y(k)m(eyw)m(ord)30 b Fh(TYPE=)e Fs(and)h(is)f(completed)i
+(b)m(y)f(the)h(k)m(eyw)m(ord)g Fh(END)p 2232 3754 27
+4 v 30 w(TYPE)p Fs(,)f(the)g(relev)-5 b(an)m(t)30 b(actions)g(b)s(eing)
+e(listed)150 3867 y(b)s(et)m(w)m(een)j(these)g(t)m(w)m(o)h(k)m(eyw)m
+(ords.)291 3980 y Fy(L)-7 b(TX2X)25 b Fs(treats)h(some)f(L)1086
+3963 y Fr(A)1125 3980 y Fs(T)1176 4000 y(E)1226 3980
+y(X)g(commands)g(sp)s(ecially;)f(among)i(these)f(are)g
+Fn(\\begin{document})c Fs(and)150 4093 y Fn(\\end{document})p
+Fs(.)34 b(In)20 b(a)h(command)g(table)f(these)i(are)f(sp)s(eci\014ed)e
+(b)m(y)i(the)g(t)m(yp)s(es)f Fh(TYPE=)42 b(BEGIN)p 3377
+4093 V 29 w(DOCUMENT)150 4206 y Fs(and)35 b Fh(TYPE=)42
+b(END)p 731 4206 V 30 w(DOCUMENT)p Fs(.)33 b(The)i(actions)h(at)h
+Fn(\\begin{document})32 b Fs(are)k(\014rstly)f(to)h(prin)m(t)f(the)h
+(string)150 4319 y(`Go)s(o)s(db)m(y)m(e)28 b(do)s(cumen)m(t')f(\(sp)s
+(eci\014ed)f(in)g(the)h(line)e Fh(START)p 2043 4319 V
+30 w(TAG=)41 b("Goodbye)g(document")p Fs(\))23 b(and)k(secondly)f(to)
+150 4432 y(stop)k(prin)m(ting)f(an)m(y)h(output)g(\(sp)s(eci\014ed)f
+(in)g(the)i(line)e Fh(PC)p 2093 4432 V 30 w(AT)p 2211
+4432 V 31 w(END=)42 b(NO)p 2548 4432 V 30 w(PRINT)p Fs(\).)291
+4545 y(By)21 b(not)f(sp)s(ecifying)e(the)j Fh(END)p 1271
+4545 V 30 w(DOCUMENT)c Fs(en)m(try)-8 b(,)23 b(the)e(default)e(action)i
+(is)e(used)g(for)h(the)h Fn(\\end{document})150 4658
+y Fs(command.)291 4770 y(The)36 b(command)f(table)h(en)m(tries)g(for)g
+(the)g(commands)f Fn(\\documentclass)d Fs(and)k Fn(\\documentstyle)150
+4883 y Fs(sp)s(ecify)e(that,)j(if)d(either)g(of)i(these)f(is)f(in)g
+(the)h(source)g(do)s(cumen)m(t,)i(then)d(it)h(is)f(to)i(b)s(e)e
+(replaced)h(b)m(y)g(the)150 4996 y(text)c(string)g Fh("Goodbye)40
+b(document")p Fs(,)27 b(and)j(then)g(all)f(further)g(prin)m(ting)f(is)i
+(to)h(b)s(e)f(switc)m(hed)f(o\013.)291 5109 y(The)38
+b(other)h(three)g(en)m(tries)g(in)e(the)i(command)g(table)g(sp)s(ecify)
+e(the)i(actions)g(for)g(an)m(y)g(other)g(kind)150 5222
+y(of)45 b(L)292 5205 y Fr(A)331 5222 y Fs(T)382 5242
+y(E)432 5222 y(X)h(command.)84 b(The)44 b(k)m(eyw)m(ord)i
+Fh(OTHER)p 1839 5222 V 29 w(BEGIN)d Fs(signi\014es)g(a)i(L)2594
+5205 y Fr(A)2633 5222 y Fs(T)2684 5242 y(E)2734 5222
+y(X)g(command)g(of)g(the)g(form)1927 5531 y(3)p eop
+%%Page: 4 8
+4 7 bop 150 573 a Fn(\\begin{name})31 b Fs(and)i Fh(OTHER)p
+1162 573 27 4 v 29 w(END)g Fs(signi\014es)f(a)i(command)g(of)g(the)h
+(form)e Fn(\\end{name})p Fs(.)49 b(The)33 b(k)m(eyw)m(ord)150
+686 y Fh(OTHER)p 375 686 V 29 w(COMMAND)38 b Fs(signi\014es)h(an)m(y)i
+(other)g(kind)e(of)i(L)1878 669 y Fr(A)1917 686 y Fs(T)1968
+705 y(E)2019 686 y(X)g(command)f(\(e.g.,)46 b Fn(\\acommand)f(...)i
+Fs(\).)72 b(The)150 799 y(actions)35 b(declared)g(for)g(these)h(are)f
+(all)g Fh(PRINT)p 1722 799 V 29 w(CONTROL=)40 b(NO)p
+2231 799 V 31 w(PRINT)33 b Fs(whic)m(h)h(sh)m(uts)g(o\013)i(an)m(y)g
+(prin)m(ting)d(of)150 912 y(the)h(command)g(or)g(its)f(argumen)m(ts.)52
+b(In)33 b(the)h(command)f(table)h Fn(bye.ct)e Fs(these)j(are)f(only)f
+(included)e(to)150 1024 y(prev)m(en)m(t)g(prin)m(ting)d(b)s(efore)i
+(the)h Fn(\\begin{document})p Fs(.)291 1137 y(T)-8 b(o)33
+b(run)d Fy(L)-7 b(TX2X)32 b Fs(with)e(the)j(ab)s(o)m(v)m(e)g(command)e
+(table,)i(t)m(yp)s(e)f(the)g(follo)m(wing)e(\(where)i
+Fn(>)g Fs(is)f(assumed)150 1250 y(to)g(b)s(e)f(the)g(system)h
+(prompt\):)150 1430 y Fn(>)47 b(ltx2x)g(-f)g(bye.ct)f(input.tex)f
+(output.tex)150 1609 y Fs(where)30 b Fn(bye.ct)f Fs(is)h(the)h(name)f
+(of)h(the)g(command)g(table,)g(and)f Fn(input.tex)e Fs(and)i
+Fn(output.tex)e Fs(are)j(the)150 1722 y(names)f(of)h(the)f(input)f(L)
+955 1705 y Fr(A)994 1722 y Fs(T)1045 1741 y(E)1095 1722
+y(X)i(\014le)e(and)h(the)g(resulting)f(pro)s(cessed)h(\014le)f(resp)s
+(ectiv)m(ely)-8 b(.)291 1835 y(As)28 b(an)g(example)g(of)g(a)g(more)g
+(useful)f(command)h(table)f(\014le,)h(the)g(follo)m(wing)f(one)h
+(called)f Fn(decomm.ct)150 1948 y Fs(will)h(remo)m(v)m(e)k(all)d(L)783
+1931 y Fr(A)822 1948 y Fs(T)873 1967 y(E)923 1948 y(X)i(commen)m(ts)g
+(from)f(a)h(t)m(ypical)f(L)2062 1931 y Fr(A)2101 1948
+y Fs(T)2152 1967 y(E)2202 1948 y(X)g(source)h(\014le.)150
+2137 y Fh(C=)86 b(decomm.ct)e(Command)40 b(table)i(file)g(for)g(ltx2x)g
+(to)h(de-comment)c(LaTeX)j(source)150 2336 y(C=)h(----------------)o
+(--)o(--)o(---)o(--)o(---)o(--)o(---)o(--)o(-)37 b(set)43
+b(newline)d(characters)150 2436 y(ESCAPE_CHAR=)f(?)150
+2535 y(NEWLINE_CHAR=)f(N)150 2735 y(C=)130 b(----------------)o(--)o
+(---)o(--)o(---)o(--)o(---)o(--)o(--)37 b(built)42 b(in)g(commands)150
+2834 y(TYPE=)g(BEGIN_DOCUMENT)237 2934 y(START_TAG=)e("\\begin{documen)
+o(t}")150 3033 y(END_TYPE)150 3233 y(TYPE=)i(END_DOCUMENT)237
+3332 y(START_TAG=)e("\\end{document})o(")150 3432 y(END_TYPE)150
+3631 y(TYPE=)i(BEGIN_VERB)237 3731 y(START_TAG=)e("\\verb|")150
+3830 y(END_TYPE)150 4030 y(TYPE=)i(END_VERB)237 4129
+y(START_TAG=)e("|")150 4229 y(END_TYPE)150 4428 y(TYPE=)i
+(BEGIN_VERBATIM)237 4528 y(START_TAG=)e("\\begin{verbati)o(m}")150
+4627 y(END_TYPE)150 4817 y(TYPE=)i(END_VERBATIM)237 4916
+y(START_TAG=)e("\\end{verbatim})o(")150 5016 y(END_TYPE)150
+5182 y(TYPE=)i(LBRACE)237 5282 y(START_TAG=)e("{")1927
+5531 y Fs(4)p eop
+%%Page: 5 9
+5 8 bop 150 573 a Fh(END_TYPE)150 772 y(TYPE=)42 b(RBRACE)237
+872 y(START_TAG=)e("}")150 971 y(END_TYPE)150 1171 y(TYPE=)i(PARAGRAPH)
+237 1270 y(START_TAG=)e("?N?N)172 b(")150 1370 y(END_TYPE)150
+1569 y(C=)43 b(----------------)o(--)o(-)37 b(define)42
+b('\\item')e(tags)i(within)f(lists)150 1768 y(TYPE=)h(BEGIN_LIST_ENV)
+150 1868 y(NAME=)g(itemize)237 1968 y(START_TAG=)e("\\begin{itemize)o
+(}")237 2067 y(START_ITEM=)f("\\item)i(")150 2167 y(END_TYPE)150
+2366 y(TYPE=)h(BEGIN_LIST_ENV)150 2466 y(NAME=)g(enumerate)237
+2565 y(START_TAG=)e("\\begin{enumera)o(te})o(")237 2665
+y(START_ITEM=)f("\\item)i(")150 2765 y(END_TYPE)150 2964
+y(TYPE=)h(BEGIN_LIST_ENV)150 3064 y(NAME=)g(description)237
+3163 y(START_TAG=)e("\\begin{descrip)o(tio)o(n})o(")237
+3263 y(START_ITEM=)f("\\item")237 3362 y(START_ITEM_PARAM=)e("[")237
+3462 y(END_ITEM_PARAM=)h("])k(")150 3562 y(END_TYPE)150
+3761 y(TYPE=)g(END_LIST_ENV)237 3861 y(NAME=)g(itemize)150
+3960 y(END_TYPE)150 4159 y(TYPE=)g(END_LIST_ENV)237 4259
+y(NAME=)g(enumerate)150 4359 y(END_TYPE)150 4558 y(TYPE=)g
+(END_LIST_ENV)237 4658 y(NAME=)g(description)150 4757
+y(END_TYPE)150 4956 y(C=)174 b(---------------)o(--)o(---)o(-)37
+b(pass)42 b(through)f(all)h(other)g(LaTeX)f(commands)150
+5156 y(TYPE=)h(OTHER_COMMAND)150 5255 y(END_TYPE)1927
+5531 y Fs(5)p eop
+%%Page: 6 10
+6 9 bop 150 672 a Fh(TYPE=)42 b(OTHER_BEGIN)150 772 y(END_TYPE)150
+971 y(TYPE=)g(OTHER_END)150 1071 y(END_TYPE)150 1270
+y(END_CTFILE=)d(end)j(of)h(file)f(decomm.ct)291 1458
+y Fs(In)20 b(the)g(ab)s(o)m(v)m(e)i(command)e(table)g(\014le,)h(the)g
+(\014rst)e(pair)g(of)i(commands)f(\()p Fh(ESCAPE)p 2912
+1458 27 4 v 29 w(CHAR=)e Fs(and)i Fh(NEWLINE)p 3654 1458
+V 28 w(CHAR=)p Fs(\))150 1571 y(de\014ne)25 b(the)h(c)m(haracter)i
+(pair)c(that)j(are)f(to)h(b)s(e)e(used)g(to)h(signify)e(a)j(`newline')d
+(within)f(a)j(tag.)41 b(An)25 b(example)150 1684 y(of)31
+b(their)e(use)h(is)f(later)i(in)e(the)h(\014le)g(in)f(the)i
+Fh(PARAGRAPH)26 b Fs(command)k(t)m(yp)s(e.)291 1797 y(As)23
+b(indicated)f(ab)s(o)m(v)m(e,)k Fy(L)-7 b(TX2X)23 b Fs(treats)h(some)f
+(L)1871 1780 y Fr(A)1910 1797 y Fs(T)1961 1816 y(E)2012
+1797 y(X)g(commands)f(sp)s(ecially)-8 b(.)37 b(These)23
+b(are)g(listed)f(next)150 1910 y(in)i(the)h(command)f(table.)39
+b(The)24 b(sp)s(ecial)g(L)1567 1893 y Fr(A)1606 1910
+y Fs(T)1657 1929 y(E)1707 1910 y(X)h(commands)g(are)g(the)g(b)s(egin)f
+(and)g(end)g(of)h(the)g Fn(document)150 2022 y Fs(and)31
+b Fn(verbatim)e Fs(en)m(vironmen)m(ts,)i(together)h(with)e(the)i
+Fn(\\verb)d Fs(command,)j(left)f(and)f(righ)m(t)h(braces,)h(the)150
+2135 y Fn(\\ )f Fs(command,)h(and)g(the)f Fy(L)-7 b(TX2X)40
+b Fh(PARAGRAPH)28 b Fs(sp)s(eci\014cation.)44 b(There)32
+b(are)g(default)f(actions)h(for)f(these,)150 2248 y(but)h(apart)g(from)
+g(the)h Fn(\\ )f Fs(command)g(the)g(defaults)g(are)h(not)f(appropriate)
+g(in)f(this)g(case.)48 b(Ab)s(o)m(v)m(e,)34 b(the)150
+2361 y(actions)29 b(are)h(to)g(replace)f(the)g(L)1204
+2344 y Fr(A)1243 2361 y Fs(T)1294 2381 y(E)1345 2361
+y(X)g(command)g(b)m(y)g(the)g(string)f(forming)g(the)i(L)2907
+2344 y Fr(A)2946 2361 y Fs(T)2997 2381 y(E)3047 2361
+y(X)f(command.)40 b(The)150 2474 y(exception)e(is)f(that)i(paragraphs)f
+(\(the)g Fh(PARAGRAPH)d Fs(sp)s(eci\014cation\))i(should)f(start)j
+(with)d(at)j(least)g(one)150 2587 y(blank)29 b(line)g(and)g(b)s(e)h
+(inden)m(ted)f(some)i(spaces.)291 2700 y(The)38 b(L)510
+2683 y Fr(A)549 2700 y Fs(T)600 2719 y(E)651 2700 y(X)h
+Fn(\\item)e Fs(command)i(is)e(used)h(within)f(lists.)64
+b Fy(L)-7 b(TX2X)39 b Fs(has)f(to)i(b)s(e)e(told)g(ho)m(w)h(to)h(treat)
+150 2813 y(the)34 b Fn(\\item)f Fs(command)h(within)d(eac)m(h)36
+b(kind)c(of)i(list.)51 b(This)32 b(has)i(b)s(een)f(done)h(ab)s(o)m(v)m
+(e)h(for)f(the)h Fn(itemize)p Fs(,)150 2926 y Fn(enumerate)28
+b Fs(and)i Fn(description)d Fs(en)m(vironmen)m(ts.)291
+3039 y(The)j(\014nal)e(instructions)g(in)h(the)h(command)f(table)h
+(\014le)f(tell)g Fy(L)-7 b(TX2X)30 b Fs(to)h(pass)e(through)h(the)g
+(text)h(of)150 3152 y(all)g(other)i(commands)f(and)f(their)g(argumen)m
+(ts.)47 b(The)32 b(end)f(of)i(the)f(command)g(table)g(\014le)g(is)f
+(either)h(the)150 3264 y(ph)m(ysical)21 b(end)g(of)i(the)f(\014le)f(or)
+h(the)h(command)f Fh(END)p 1831 3264 V 30 w(CTFILE=)p
+Fs(,)f(whic)m(hev)m(er)h(comes)h(\014rst.)37 b(The)22
+b Fh(END)p 3420 3264 V 30 w(CTFILE=)150 3377 y Fs(command)30
+b(acts)i(lik)m(e)d(the)i Fh(C=)e Fs(command)h(in)f(that)i(arbitrary)f
+(text)h(can)g(b)s(e)e(put)h(after)h(the)f(command.)291
+3490 y(T)-8 b(o)36 b(use)e(the)i Fn(decomm.ct)c Fs(command)j(table)g
+(to)g(de-commen)m(t)i(a)e(L)2605 3474 y Fr(A)2644 3490
+y Fs(T)2695 3510 y(E)2745 3490 y(X)h(\014le,)f(t)m(yp)s(e)g(the)g
+(follo)m(wing)150 3603 y(\(where)30 b Fn(>)g Fs(is)g(assumed)f(to)i(b)s
+(e)f(the)h(system)f(prompt\):)150 3791 y Fn(>)47 b(ltx2x)g(-f)g
+(decomm.ct)e(input.tex)h(output.tex)150 3978 y Fs(where)26
+b Fn(input.tex)e Fs(and)i Fn(output.tex)e Fs(are)j(the)g(names)g(of)g
+(the)f(input)f(L)2633 3962 y Fr(A)2672 3978 y Fs(T)2723
+3998 y(E)2773 3978 y(X)i(\014le)f(for)g(de-commen)m(ting)150
+4091 y(and)k(the)g(resulting)f(de-commen)m(ted)i(v)m(ersion)f(resp)s
+(ectiv)m(ely)-8 b(.)150 4378 y Fu(2)135 b(The)44 b(command)h(table)h
+(\014le)150 4581 y Fs(By)36 b(default,)h Fy(L)-7 b(TX2X)36
+b Fs(do)s(es)f(not)h(output)g(an)m(y)g(L)1825 4564 y
+Fr(A)1864 4581 y Fs(T)1915 4600 y(E)1966 4581 y(X)g(commen)m(ts.)58
+b(Otherwise,)36 b(whenev)m(er)g(it)f(comes)150 4694 y(across)c(a)f(L)
+518 4677 y Fr(A)557 4694 y Fs(T)608 4713 y(E)659 4694
+y(X)g(command)g(it)g(lo)s(oks)f(at)i(the)f(data)h(in)e(the)i(command)e
+(table)i(\014le)e(to)i(determine)e(what)150 4807 y(actions)k(it)g
+(should)e(tak)m(e.)50 b(The)32 b(t)m(w)m(o)j(most)e(t)m(ypical)f
+(actions)i(are)f(either)f(to)i(prin)m(t)e(out)h(the)g(command)150
+4919 y(as)e(read)f(in,)f(or)i(to)g(replace)f(the)h(command)f(b)m(y)g
+(some)h(\(p)s(ossibly)d(empt)m(y\))j(text.)291 5032 y(Eac)m(h)j(line)d
+(in)g(a)i(command)g(table)g(\014le)e(is)h(either)g(blank)g(or)h(starts)
+g(with)e(a)i(k)m(eyw)m(ord)h(follo)m(w)m(ed)e(b)m(y)150
+5145 y(one)h(or)f(more)h(blanks.)45 b(F)-8 b(or)33 b(example,)g(a)g
+(commen)m(t)h(in)d(the)i(\014le)e(is)h(a)g(line)f(that)i(starts)g(with)
+e Fh(C=)43 b Fs(;)34 b(the)150 5258 y(remainder)28 b(of)j(the)f(line)e
+(is)h(an)m(y)i(commen)m(t)g(text.)41 b(Commen)m(ts)30
+b(ma)m(y)h(b)s(e)e(placed)h(an)m(ywhere)g(in)e(the)j(\014le.)1927
+5531 y(6)p eop
+%%Page: 7 11
+7 10 bop 150 573 a Fj(2.1)112 b(Sp)s(ecial)37 b(prin)m(t)f(c)m
+(haracters)i(in)f(tags)150 744 y Fy(L)-7 b(TX2X)35 b
+Fs(is)g(written)f(in)h(C)g([6].)56 b(The)35 b(C)g(language)h(enables)f
+(certain)g(non-prin)m(ting)e(c)m(haracters)k(to)g(b)s(e)150
+857 y(de\014ned.)h(These)28 b(are)f(t)m(ypically)g(written)f(in)g(the)i
+(form)f Fn(\\c)g Fs(where)f Fn(\\)i Fs(is)e(the)i(C)f(escap)s(e)g(c)m
+(haracter)i(and)e Fn(c)150 970 y Fs(is)h(a)h(particular)e(c)m
+(haracter.)42 b Fy(L)-7 b(TX2X)29 b Fs(understands)e(some)i(of)g(these)
+g(sp)s(ecial)f(prin)m(ting)e(c)m(haracters)31 b(and)150
+1083 y(the)g(command)f(table)g(enables)g(these)g(to)i(b)s(e)d(giv)m(en)
+i(non-default)e(v)-5 b(alues.)291 1183 y(The)30 b(default)f(escap)s(e)h
+(c)m(haracter)i(\()p Fn(\\)p Fs(\))e(ma)m(y)h(b)s(e)e(rede\014ned)g
+(via)h(the)g Fh(ESCAPE)p 2896 1183 27 4 v 29 w(CHAR=)e
+Fs(command.)40 b(F)-8 b(or)150 1282 y(example,)150 1457
+y Fh(ESCAPE_CHAR=)39 b(?)150 1644 y Fs(will)c(mak)m(e)k(the)f(question)
+f(mark)g(c)m(haracter)i(the)f(escap)s(e)g(c)m(haracter.)65
+b(T)m(ypically)-8 b(,)38 b(the)g(escap)s(e)g(c)m(har-)150
+1757 y(acter)j(is)d(c)m(hanged)i(in)e(most)i(command)g(tables)f(to)h(a)
+m(v)m(oid)g(clashing)e(with)g(the)i(L)3023 1741 y Fr(A)3062
+1757 y Fs(T)3113 1777 y(E)3163 1757 y(X)g Fn(\\)f Fs(c)m(haracter.)150
+1870 y(The)c(follo)m(wing)f(commands)h(can)h(b)s(e)f(used)g(to)h
+(rede\014ne)f(the)h(C)f(sp)s(ecial)f(c)m(haracters.)58
+b(Eac)m(h)36 b(of)f(these)150 1983 y(commands)f(tak)m(es)h(a)g(single)e
+(c)m(haracter)j(as)e(its)g(v)-5 b(alue.)51 b(If)34 b(a)h(relev)-5
+b(an)m(t)34 b(command)g(is)f(not)i(giv)m(en,)g(then)150
+2096 y(the)c(default)e(v)-5 b(alue)30 b(is)f(used.)150
+2284 y Fh(NEWLINE)p 463 2284 V 28 w(CHAR=)44 b Fs(a)31
+b(new)e(line)g(\(default)h(is)g Fn(n)p Fs(\))150 2584
+y Fh(HORIZONTAL)p 595 2584 V 27 w(TAB)p 754 2584 V 30
+w(CHAR=)44 b Fs(horizon)m(tal)30 b(tab)g(\(default)g(is)g
+Fn(t)p Fs(\))150 2885 y Fh(VERTICAL)p 507 2885 V 28 w(TAB)p
+667 2885 V 30 w(CHAR=)44 b Fs(v)m(ertical)30 b(tab)h(\(default)f(is)f
+Fn(v)p Fs(\))150 3185 y Fh(BACKSPACE)p 551 3185 V 28
+w(CHAR=)43 b Fs(bac)m(kspace)32 b(\(default)e(is)f Fn(b)p
+Fs(\))150 3486 y Fh(CARRIAGE)p 507 3486 V 28 w(RETURN)p
+799 3486 V 29 w(CHAR=)43 b Fs(carriage)31 b(return)f(\(default)f(is)h
+Fn(r)p Fs(\))150 3786 y Fh(FORMFEED)p 507 3786 V 28 w(CHAR=)43
+b Fs(formfeed)30 b(\(default)g(is)g Fn(f)p Fs(\))150
+4087 y Fh(AUDIBLE)p 463 4087 V 28 w(ALLERT)p 755 4087
+V 29 w(CHAR=)44 b Fs(b)s(eep)29 b(the)i(terminal)e(\(default)h(is)f
+Fn(a)p Fs(\))150 4387 y Fh(HEX)p 287 4387 V 30 w(CHAR=)44
+b Fs(follo)m(wing)25 b(c)m(haracters)j(form)e(the)h(hexadecimal)f(n)m
+(um)m(b)s(er)g(of)h(the)f(c)m(haracter)j(to)e(b)s(e)f(prin)m(ted)377
+4500 y(\(default)k(is)g Fn(x)p Fs(\))g(\(e.g.)42 b Fn(?xA3)p
+Fs(\))150 4801 y(These)29 b(command)g(lines)f(are)i(all)e(optional)h
+(within)d(a)k(command)f(table)h(and)e(their)h(ordering)f(is)g(imma-)150
+4914 y(terial.)61 b(Ho)m(w)m(ev)m(er,)42 b(if)36 b(an)m(y)i(are)g
+(presen)m(t)g(then)f(they)h(m)m(ust)f(b)s(e)g(at)h(the)g(b)s(eginning)d
+(of)i(the)h(command)150 5027 y(table.)291 5140 y(The)29
+b(ab)s(o)m(v)m(e)i(sp)s(ecial)d(c)m(haracters)i(are)g(useful)e(when)g
+(sp)s(ecifying)f(the)j(replacemen)m(t)g(text)g(for)f(L)3541
+5123 y Fr(A)3580 5140 y Fs(T)3631 5159 y(E)3682 5140
+y(X)150 5253 y(commands.)1927 5531 y(7)p eop
+%%Page: 8 12
+8 11 bop 150 573 a Fj(2.2)112 b(L)432 550 y Fg(A)476
+573 y Fj(T)535 595 y(E)596 573 y(X)37 b(command)g(t)m(yp)s(es)150
+731 y Fs(The)44 b(commands)g(for)f(con)m(trolling)h(the)g(actions)g(p)s
+(erformed)f(on)h(L)2539 714 y Fr(A)2578 731 y Fs(T)2629
+751 y(E)2679 731 y(X)h(commands)f(are)g(enclosed)150
+831 y(b)s(et)m(w)m(een)31 b(the)g(command)f(lines)e Fh(TYPE=)72
+b Fs(and)30 b Fh(END)p 1885 831 27 4 v 30 w(TYPE)p Fs(,)f(as)i(b)s(elo)
+m(w.)150 994 y Fh(TYPE=)42 b(CommandType)237 1093 y(C=)h(a)g(possibly)d
+(empty)i(set)g(of)h(commands)150 1193 y(END_TYPE)150
+1369 y Fs(where)26 b Fh(CommandType)c Fs(is)k(an)h Fy(L)-7
+b(TX2X)27 b Fs(k)m(eyw)m(ord)g(signifying)d(the)j(kind)e(of)i(L)2663
+1353 y Fr(A)2702 1369 y Fs(T)2753 1389 y(E)2803 1369
+y(X)g(command)g(b)s(eing)e(sp)s(ec-)150 1482 y(i\014ed.)150
+1720 y Ft(2.2.1)105 b(Built)35 b(in)g(command)f(t)m(yp)s(es)150
+1892 y Fs(Some)23 b(L)409 1875 y Fr(A)448 1892 y Fs(T)499
+1911 y(E)550 1892 y(X)g(commands)g(are)g(pre-de\014ned)f(within)e
+Fy(L)-7 b(TX2X)p Fs(.)24 b(Default)f(actions)g(are)h(pro)m(vided)e(for)
+g(these)150 2005 y(but)34 b(it)g(is)g(recommended)h(that)g(t)m(yp)s(e)g
+(sp)s(eci\014cations)f(for)g(eac)m(h)i(of)f(these)g(commands)g(b)s(e)f
+(put)g(in)g(the)150 2118 y(command)c(table)g(an)m(yw)m(a)m(y)-8
+b(.)43 b(The)30 b(k)m(eyw)m(ords)h(for)f(these)g(commands)g(are:)150
+2294 y Fh(BEGIN)p 375 2294 V 29 w(DOCUMENT)42 b Fs(Corresp)s(onds)29
+b(to)i(the)f(L)1609 2277 y Fr(A)1648 2294 y Fs(T)1699
+2314 y(E)1750 2294 y(X)g(command)g Fn(\\begin{document})p
+Fs(.)150 2477 y Fh(END)p 287 2477 V 30 w(DOCUMENT)42
+b Fs(Corresp)s(onds)29 b(to)i(the)f(L)1522 2460 y Fr(A)1561
+2477 y Fs(T)1612 2497 y(E)1663 2477 y(X)g(command)g Fn(\\end{document})
+p Fs(.)150 2660 y Fh(BEGIN)p 375 2660 V 29 w(VERBATIM)42
+b Fs(Corresp)s(onds)29 b(to)i(the)f(L)1609 2643 y Fr(A)1648
+2660 y Fs(T)1699 2680 y(E)1750 2660 y(X)g(commands)g
+Fn(\\begin{verbatim})c Fs(and)377 2773 y Fn(\\begin{verbatim*})p
+Fs(.)150 2956 y Fh(END)p 287 2956 V 30 w(VERBATIM)42
+b Fs(Corresp)s(onds)18 b(to)j(the)g(L)1492 2939 y Fr(A)1531
+2956 y Fs(T)1582 2976 y(E)1632 2956 y(X)g(commands)f
+Fn(\\end{verbatim})c Fs(and)k Fn(\\end{verbatim*})p Fs(.)150
+3139 y Fh(BEGIN)p 375 3139 V 29 w(VERB)44 b Fs(Corresp)s(onds)f(to)i
+(the)g(L)1478 3123 y Fr(A)1517 3139 y Fs(T)1568 3159
+y(E)1618 3139 y(X)g(commands)f Fn(\\verb)f Fs(and)i Fn(\\verb*)p
+Fs(,)h(together)g(with)e(the)377 3252 y(succeeding)30
+b(c)m(haracter.)150 3435 y Fh(END)p 287 3435 V 30 w(VERB)44
+b Fs(Corresp)s(onds)34 b(to)j(the)f(app)s(earance)h(of)f(the)g(c)m
+(haracter)i(that)f(completes)f(the)g(L)3313 3419 y Fr(A)3352
+3435 y Fs(T)3403 3455 y(E)3454 3435 y(X)g(com-)377 3548
+y(mands)30 b Fn(\\verb)f Fs(and)g Fn(\\verb*)p Fs(.)150
+3731 y Fh(LBRACE)43 b Fs(Corresp)s(onds)28 b(to)j(the)g(L)1273
+3715 y Fr(A)1312 3731 y Fs(T)1363 3751 y(E)1413 3731
+y(X)g(left)f(brace)g(c)m(haracter)i Fn({)p Fs(.)150 3914
+y Fh(RBRACE)43 b Fs(Corresp)s(onds)28 b(to)j(the)g(L)1273
+3898 y Fr(A)1312 3914 y Fs(T)1363 3934 y(E)1413 3914
+y(X)g(righ)m(t)f(brace)g(c)m(haracter)i Fn(})p Fs(.)150
+4098 y Fh(BEGIN)p 375 4098 V 29 w(DOLLAR)43 b Fs(Corresp)s(onds)36
+b(to)i(the)g(L)1544 4081 y Fr(A)1583 4098 y Fs(T)1634
+4117 y(E)1685 4098 y(X)g Fn($)f Fs(sym)m(b)s(ol)f(signalling)f(the)j
+(start)h(of)e(an)h(in-text)g(math)377 4210 y(form)m(ula.)150
+4394 y Fh(END)p 287 4394 V 30 w(DOLLAR)43 b Fs(Corresp)s(onds)32
+b(to)k(the)e(L)1447 4377 y Fr(A)1486 4394 y Fs(T)1537
+4413 y(E)1587 4394 y(X)h Fn($)f Fs(sym)m(b)s(ol)f(signalling)f(the)i
+(end)g(of)h(an)f(in-text)g(math)h(for-)377 4506 y(m)m(ula.)150
+4690 y Fh(PARAGRAPH)42 b Fs(Corresp)s(onds)31 b(to)j(the)f(L)1412
+4673 y Fr(A)1451 4690 y Fs(T)1502 4709 y(E)1552 4690
+y(X)g(proto)s(col)g(of)h(a)f(blank)f(line)f(signalling)f(the)k
+(start/end)f(of)h(a)377 4802 y(paragraph.)150 4986 y
+Fh(SLASH)p 375 4986 V 29 w(SPACE)44 b Fs(Corresp)s(onds)28
+b(to)j(the)g(L)1479 4969 y Fr(A)1518 4986 y Fs(T)1569
+5005 y(E)1619 4986 y(X)f Fn(\\ )g Fs(command.)150 5169
+y Fh(OTHER)p 375 5169 V 29 w(COMMAND)43 b Fs(Corresp)s(onds)e(to)j(an)m
+(y)g(L)1620 5152 y Fr(A)1659 5169 y Fs(T)1710 5188 y(E)1761
+5169 y(X)f(command)g(of)h(the)g(form)f Fn(\\command)e
+Fs(not)j(sp)s(eci\014ed)377 5282 y(elsewhere)30 b(within)e(the)i
+(command)h(table.)1927 5531 y(8)p eop
+%%Page: 9 13
+9 12 bop 150 573 a Fh(OTHER)p 375 573 27 4 v 29 w(BEGIN)44
+b Fs(Corresp)s(onds)35 b(to)i(an)m(y)h(L)1514 556 y Fr(A)1553
+573 y Fs(T)1604 592 y(E)1654 573 y(X)f(command)g(of)g(the)g(form)g
+Fn(\\begin{environment})32 b Fs(not)377 686 y(sp)s(eci\014ed)d
+(elsewhere)h(within)e(the)i(command)g(table.)150 873
+y Fh(OTHER)p 375 873 V 29 w(END)45 b Fs(Corresp)s(onds)26
+b(to)k(an)m(y)g(L)1403 857 y Fr(A)1442 873 y Fs(T)1493
+893 y(E)1543 873 y(X)f(command)g(of)g(the)g(form)g Fn
+(\\end{environment})24 b Fs(not)30 b(sp)s(eci-)377 986
+y(\014ed)g(elsewhere)g(within)e(the)i(command)g(table.)291
+1174 y(The)g(ordering)g(of)h(these)g(built)d(in)i(t)m(yp)s(e)h(sp)s
+(eci\014cations)e(is)h(immaterial.)40 b(If)31 b(an)m(y)g(of)g(the)g(ab)
+s(o)m(v)m(e)h(are)150 1287 y(not)38 b(sp)s(eci\014ed)f(within)f(the)i
+(command)g(table)g(then)g Fy(L)-7 b(TX2X)38 b Fs(will)e(use)i(their)f
+(default)h(action.)64 b(With)150 1400 y(the)35 b(exception)g(of)g(the)g
+Fh(SLASH)p 1216 1400 V 29 w(SPACE)d Fs(command)j(t)m(yp)s(e,)h(the)f
+(default)f(action)h(is)f(to)h(do)g(nothing)e(\(i.e.,)150
+1513 y(pro)s(duce)e(no)i(output\).)47 b(The)32 b(default)g(action)h
+(for)g(the)f Fh(SLASH)p 2299 1513 V 30 w(SPACE)e Fs(command)j(t)m(yp)s
+(e)f(is)g(to)h(output)g(a)150 1626 y(space.)150 1866
+y Ft(2.2.2)105 b(Optional)35 b(command)f(t)m(yp)s(es)150
+2037 y Fs(F)-8 b(or)24 b(the)g(purp)s(oses)e(of)h Fy(L)-7
+b(TX2X)p Fs(,)24 b(L)1267 2021 y Fr(A)1306 2037 y Fs(T)1357
+2057 y(E)1407 2037 y(X)g(commands)f(are)h(divided)d(in)m(to)j(v)-5
+b(arious)22 b(classes.)39 b(The)23 b(k)m(eyw)m(ords)150
+2150 y(for)30 b(these)h(clases,)g(and)f(the)g(class)g(descriptions,)f
+(are)i(listed)d(b)s(elo)m(w.)150 2363 y Fh(TEX)p 287
+2363 V 30 w(CHAR)44 b Fs(Corresp)s(onding)26 b(to)k(L)1274
+2346 y Fr(A)1313 2363 y Fs(T)1364 2382 y(E)1414 2363
+y(X's)f(sp)s(ecial)e(c)m(haracters)k(\(with)c(the)i(exception)g(of)g
+(the)g($,)h Fm(f)f Fs(and)g Fm(g)377 2476 y Fs(c)m(haracters\).)150
+2663 y Fh(CHAR)p 331 2663 V 30 w(COMMAND)42 b Fs(Corresp)s(onding)34
+b(to)k(L)1464 2647 y Fr(A)1503 2663 y Fs(T)1554 2683
+y(E)1604 2663 y(X)f(commands)f(of)h(the)g(t)m(yp)s(e)g
+Fn(\\c)f Fs(where)g Fn(c)g Fs(is)g(a)h(single)e(non-)377
+2776 y(alphab)s(etic)29 b(c)m(haracter.)150 2964 y Fh(COMMAND)43
+b Fs(Corresp)s(onding)33 b(to)38 b(L)1258 2947 y Fr(A)1297
+2964 y Fs(T)1348 2983 y(E)1398 2964 y(X)e(commands)h(of)f(the)h(t)m(yp)
+s(e)g Fn(\\command)p Fs(,)f(where)g Fn(command)e Fs(is)i(the)377
+3077 y(name)31 b(of)f(the)h(command)f(\(except)i(for)e
+Fn(\\begin)p Fs(,)f Fn(\\end)g Fs(and)h Fn(\\item)p Fs(\).)150
+3264 y Fh(BEGIN)p 375 3264 V 29 w(ENV)45 b Fs(Corresp)s(onding)40
+b(to)45 b(L)1347 3248 y Fr(A)1386 3264 y Fs(T)1437 3284
+y(E)1487 3264 y(X)f(commands)f(of)h(the)g(t)m(yp)s(e)g
+Fn(\\begin{environment})38 b Fs(where)377 3377 y Fn(environment)20
+b Fs(is)h(the)i(name)g(of)f(the)h(en)m(vironmen)m(t,)h(except)g(for)e
+(those)h(list)e(en)m(vironmen)m(ts)h(whose)377 3490 y(b)s(o)s(dies)29
+b(consist)h(of)g Fn(\\item)f Fs(commands.)150 3678 y
+Fh(END)p 287 3678 V 30 w(ENV)44 b Fs(Corresp)s(onding)21
+b(to)k(L)1220 3661 y Fr(A)1259 3678 y Fs(T)1310 3697
+y(E)1360 3678 y(X)f(commands)g(of)f(the)h(t)m(yp)s(e)g
+Fn(\\end{environment})p Fs(,)d(with)i(the)h(same)377
+3791 y(restrictions)29 b(as)i(for)f Fn(BEGIN_ENV)p Fs(.)150
+3978 y Fh(BEGIN)p 375 3978 V 29 w(LIST)p 580 3978 V 30
+w(ENV)44 b Fs(Corresp)s(onding)18 b(to)j(L)1506 3962
+y Fr(A)1545 3978 y Fs(T)1596 3998 y(E)1646 3978 y(X)f(commands)g(of)h
+(the)f(t)m(yp)s(e)h Fn(\\begin{environment})15 b Fs(where)377
+4091 y Fn(environment)21 b Fs(is)i(the)i(name)f(of)g(an)g(en)m
+(vironmen)m(t)f(whose)h(b)s(o)s(dy)f(consists)g(of)h
+Fn(\\item)f Fs(commands.)150 4279 y Fh(END)p 287 4279
+V 30 w(LIST)p 493 4279 V 30 w(ENV)44 b Fs(Corresp)s(onding)23
+b(to)k(L)1430 4262 y Fr(A)1469 4279 y Fs(T)1520 4298
+y(E)1570 4279 y(X)f(commands)g(of)g(the)g(t)m(yp)s(e)g
+Fn(\\end{environment})21 b Fs(to)27 b(matc)m(h)377 4392
+y Fn(BEGIN_LIST_ENV)p Fs(.)150 4579 y Fh(VCOMMAND)42
+b Fs(Corresp)s(onding)28 b(to)j(a)g(L)1365 4563 y Fr(A)1404
+4579 y Fs(T)1455 4599 y(E)1505 4579 y(X)f Fn(\\verb)p
+Fs(-lik)m(e)f(command.)150 4767 y Fh(BEGIN)p 375 4767
+V 29 w(VENV)44 b Fs(Corresp)s(onding)28 b(to)j(the)f(start)h(of)g(a)g
+(v)m(erbatim-lik)m(e)e(en)m(vironmen)m(t.)150 4955 y
+Fh(END)p 287 4955 V 30 w(VENV)44 b Fs(Corresp)s(onding)28
+b(to)j(the)f(end)g(of)g(a)h(v)m(erbatim-lik)m(e)f(en)m(vironmen)m(t.)
+150 5142 y Fh(SECTIONING)41 b Fs(Corresp)s(onding)30
+b(to)i(L)1379 5126 y Fr(A)1418 5142 y Fs(T)1469 5162
+y(E)1520 5142 y(X)g(commands)g(of)g(the)g(t)m(yp)s(e)g
+Fn(\\command)p Fs(,)f(where)g Fn(command)f Fs(is)i(a)377
+5255 y(do)s(cumen)m(t)e(sectioning)g(command)g(suc)m(h)g(as)h
+Fn(chapter)d Fs(or)j Fn(subsection)p Fs(.)1927 5531 y(9)p
+eop
+%%Page: 10 14
+10 13 bop 150 573 a Fh(SPECIAL)43 b Fs(Reserv)m(ed)30
+b(for)h(p)s(ossible)c(future)j(use.)150 758 y Fh(SPECIAL)p
+463 758 27 4 v 28 w(COMMAND)43 b Fs(Corresp)s(onding)29
+b(to)k(the)f Fn(COMMAND)e Fs(k)m(eyw)m(ord,)i(except)h(that)g(some)f
+(sp)s(ecial)e(output)377 871 y(pro)s(cessing)f(is)h(to)h(b)s(e)f
+(de\014ned.)150 1056 y Fh(SPECIAL)p 463 1056 V 28 w(BEGIN)p
+711 1056 V 30 w(ENV)44 b Fs(Corresp)s(onding)22 b(to)j(the)g
+Fn(BEGIN_ENV)d Fs(k)m(eyw)m(ord,)k(except)g(that)f(some)g(sp)s(ecial)e
+(out-)377 1169 y(put)30 b(pro)s(cessing)f(is)g(to)j(b)s(e)d(de\014ned.)
+150 1354 y Fh(SPECIAL)p 463 1354 V 28 w(END)p 623 1354
+V 31 w(ENV)44 b Fs(Corresp)s(onding)30 b(to)k(the)f Fn(END_ENV)f
+Fs(k)m(eyw)m(ord,)i(except)g(that)g(some)g(sp)s(ecial)d(output)377
+1466 y(pro)s(cessing)e(is)h(to)h(b)s(e)f(de\014ned.)150
+1651 y Fh(SPECIAL)p 463 1651 V 28 w(BEGIN)p 711 1651
+V 30 w(LIST)44 b Fs(Corresp)s(onding)23 b(to)j(the)g
+Fn(BEGIN_LIST_ENV)c Fs(k)m(eyw)m(ord,)28 b(except)f(that)f(some)g(sp)s
+(e-)377 1764 y(cial)k(output)g(pro)s(cessing)f(is)g(to)j(b)s(e)d
+(de\014ned.)150 1949 y Fh(SPECIAL)p 463 1949 V 28 w(END)p
+623 1949 V 31 w(LIST)43 b Fs(Corresp)s(onding)33 b(to)j(the)g
+Fn(END_LIST_ENV)c Fs(k)m(eyw)m(ord,)37 b(except)g(that)f(some)f(sp)s
+(ecial)377 2062 y(output)30 b(pro)s(cessing)f(is)h(to)h(b)s(e)f
+(de\014ned.)150 2247 y Fh(SPECIAL)p 463 2247 V 28 w(SECTIONING)42
+b Fs(Corresp)s(onding)32 b(to)k(the)f Fn(SECTIONING)d
+Fs(k)m(eyw)m(ord,)37 b(except)f(that)f(some)g(sp)s(ecial)377
+2360 y(output)30 b(pro)s(cessing)f(is)h(to)h(b)s(e)f(de\014ned.)p
+155 2545 V 181 2545 a Fh(PICTURE)p 494 2545 V 74 w Fs(Corresp)s(onding)
+e(to)j(some)g(of)f(the)h(L)1796 2528 y Fr(A)1835 2545
+y Fs(T)1886 2565 y(E)1936 2545 y(X)g(picture)e(dra)m(wing)g(commands.)
+150 2730 y Fh(COMMAND)p 463 2730 V 28 w(...)45 b Fs(Corresp)s(onding)18
+b(to)j(some)g(of)g(the)g(L)1847 2713 y Fr(A)1886 2730
+y Fs(T)1937 2750 y(E)1987 2730 y(X)g(commands)g(whose)f(arrangemen)m
+(ts)i(of)f(required)377 2843 y(and)30 b(optional)g(argumen)m(ts)g(are)h
+(un)m(t)m(ypical.)291 3048 y(The)f(ordering)f(of)i(these)f(t)m(yp)s(es)
+h(within)d(a)i(command)h(table)f(is)f(immaterial.)291
+3160 y(Eac)m(h)41 b(of)f(the)h(ab)s(o)m(v)m(e)g(t)m(yp)s(e)g(sp)s
+(eci\014cations)e(requires)f(a)j Fh(NAME=)d Fs(command,)43
+b(whose)d(v)-5 b(alue)39 b(is)h(the)150 3273 y(name)31
+b(of)f(the)h(relev)-5 b(an)m(t)31 b(command)g(or)f(en)m(vironmen)m(t)h
+(b)s(eing)e(sp)s(eci\014ed.)40 b(F)-8 b(or)31 b(example,)g(the)f(follo)
+m(wing)150 3386 y(is)f(a)i(\(partial\))f(sp)s(eci\014cation)f(of)i(the)
+f(\014gure)g(en)m(vironmen)m(t)g(and)g(the)g(caption)h(command.)150
+3578 y Fh(TYPE=)42 b(BEGIN_ENV)150 3677 y(NAME=)g(figure)150
+3777 y(END_TYPE)150 3976 y(TYPE=)g(END_ENV)150 4076 y(NAME=)g(figure)
+150 4175 y(END_TYPE)150 4375 y(TYPE=)g(COMMAND)150 4474
+y(NAME=)g(\\caption)150 4574 y(END_TYPE)150 4816 y Fj(2.3)112
+b(Command)37 b(action)g(tags)150 4988 y Fs(When)30 b
+Fy(L)-7 b(TX2X)30 b Fs(reads)h(a)f(L)1054 4971 y Fr(A)1093
+4988 y Fs(T)1144 5007 y(E)1195 4988 y(X)g(command)g(it)g(p)s(erforms)f
+(the)i(follo)m(wing)d(actions:)261 5169 y(1.)46 b(Lo)s(oks)36
+b(up)e(the)i(name)f(of)h(the)g(command)f(or)h(en)m(vironmen)m(t)f(in)f
+(the)i(command)f(table.)56 b(If)35 b(it)g(is)377 5282
+y(not)c(found,)e(then)h(the)h(appropriate)e(default)h(t)m(yp)s(e)g(is)g
+(used.)1905 5531 y(10)p eop
+%%Page: 11 15
+11 14 bop 261 573 a Fs(2.)46 b(Sets)31 b(the)f(prin)m(ting)e(mo)s(de)i
+(according)h(to)g(the)f Fh(PC)p 2087 573 27 4 v 31 w(AT)p
+2206 573 V 31 w(START=)d Fs(command.)261 760 y(3.)46
+b(P)m(erforms)30 b(the)h(actions)g(sp)s(eci\014ed)d(in)h(the)i(command)
+f(table)g(b)m(y)h(the)f Fh(START)p 3007 760 V 29 w(TAG=)f
+Fs(command.)261 948 y(4.)46 b(Pro)s(cesses)31 b(an)m(y)g(sp)s
+(eci\014ed)d(argumen)m(ts)j(to)g(the)g(command.)261 1136
+y(5.)46 b(P)m(erforms)30 b(the)h(actions)g(sp)s(eci\014ed)d(in)h(the)i
+(command)f(table)g(b)m(y)h(the)f Fh(END)p 2919 1136 V
+30 w(TAG=)f Fs(command.)261 1323 y(6.)46 b(Sets)31 b(the)f(prin)m(ting)
+e(mo)s(de)i(according)h(to)g(the)f Fh(PC)p 2087 1323
+V 31 w(AT)p 2206 1323 V 31 w(END=)e Fs(command.)150 1536
+y Ft(NOTES)44 b Fs(:)461 1724 y(1.)i(Except)21 b(for)g(the)f(default)g
+(pro)s(cessing)g(of)27 b Fh(OTHER)p 2200 1724 V 50 w
+Fs(t)m(yp)s(es,)c(it)d(do)s(es)g(not)h(output)f(the)h(command)577
+1836 y(itself.)461 1983 y(2.)46 b(If)31 b(a)h(tag)h(action)f(is)e(not)i
+(sp)s(eci\014ed,)e(then)h(the)h(default)f(action)h(is)e(n)m(ull)f
+(\(e.g.,)34 b(nothing)d(will)577 2095 y(app)s(ear)f(in)f(the)i
+(output\).)291 2295 y(Within)f(a)i(command)f(table)h(all)f(text)h
+(strings)f(for)g(output)g(are)h(enclosed)g(within)d(double)h(quotes.)
+150 2394 y(F)-8 b(or)31 b(example:)150 2569 y Fh(START_TAG=)214
+b("Some)41 b("text")g(string\\n)g(another)f(line)i(of)h(text.")291
+2743 y Fs(Assuming)32 b(that)j Fn(\\n)e Fs(means)h(a)g(newline,)f(when)
+g(this)g(string)g(action)h(is)f(p)s(erformed)g(b)m(y)h
+Fy(L)-7 b(TX2X)33 b Fs(it)150 2843 y(will)28 b(app)s(ear)h(in)h(the)g
+(output)g(\014le)g(as:)150 3017 y Fh(Some)42 b("text")f(string)150
+3117 y(another)g(line)h(of)g(text.)291 3304 y Fs(A)31
+b(text)h(string)d(starts)j(with)d(the)i(\014rst)f(double)f(quote)i(and)
+g(ends)f(with)f(the)i(last)f(double)g(quote)h(on)150
+3417 y(the)37 b(command)f(line.)58 b(A)36 b(text)i(string)d(has)h(to)i
+(b)s(e)e(written)f(on)i(a)f(single)g(line)e(within)g(the)j(command)150
+3530 y(table.)j(C)27 b(language)h(sp)s(ecial)e(prin)m(t)g(c)m
+(haracters)j(can)f(b)s(e)f(em)m(b)s(edded)f(within)f(the)j(text)g
+(string)f(\(e.g.)41 b(the)150 3643 y Fn(\\n)32 b Fs(for)h(a)g(newline)d
+(in)i(the)g(ab)s(o)m(v)m(e)i(example\).)48 b(Remem)m(b)s(er)32
+b(that)i(the)f(\014rst)f(section)g(of)h(the)g(command)150
+3756 y(table)d(is)g(used)f(for)h(sp)s(ecifying)f(the)h(particular)f
+(command)h(table)g(v)m(ersion)g(of)h(these.)291 3869
+y(If)i(a)g(text)h(string)e(is)g(to)s(o)i(long)e(to)i(\014t)f
+(comfortably)g(on)g(a)g(single)f(line)f(in)h(the)h(command)g(table,)g
+(it)150 3982 y(ma)m(y)h(b)s(e)f(con)m(tin)m(ued)g(via)g(the)h
+Fh(STRING:)c Fs(command.)50 b(As)33 b(man)m(y)h(of)f(these)h(can)g(b)s
+(e)f(used)f(in)g(succession)150 4095 y(as)f(required)d(\(sub)5
+b(ject)31 b(to)g(in)m(ternal)e(limitations)f(within)g
+Fy(L)-7 b(TX2X)p Fs(\).)291 4194 y(F)f(or)31 b(instance,)150
+4369 y Fh(START_TAG=)214 b("Some)41 b("text")g(string\\n")237
+4468 y(STRING:)g("another)f(line)i(of)h(text.")150 4656
+y Fs(has)30 b(the)h(same)f(e\013ect)i(as)f(the)g(previous)d(example.)
+291 4769 y(The)k(follo)m(wing)f(sp)s(eci\014cation)g(is)g(designed)g
+(to)i(write)e(out)i(the)f(con)m(ten)m(ts)i(of)f(the)f
+Fn(\\caption)e Fs(com-)150 4882 y(mand)373 4849 y Fr(4)412
+4882 y Fs(,)25 b(preceded)f(b)m(y)g(the)h(w)m(ord)f(`CAPTION')g(and)f
+(follo)m(w)m(ed)h(b)m(y)g(at)h(least)g(one)f(blank)f(line)g(\(assuming)
+150 4995 y(that)31 b(the)g(escap)s(e)f(c)m(haracter)i(has)e(b)s(een)g
+(set)h(to)g Fn(?)p Fs(\).)p 150 5079 1440 4 v 254 5133
+a Fl(4)288 5164 y Fp(Strictly)38 b(sp)r(eaking,)k(the)c(sp)r
+(eci\014cation)h(do)r(es)f(not)g(do)g(this)g(exactly)-6
+b(,)41 b(but)d(this)g(simpli\014ed)f(illustration)j(will)f(b)r(e)150
+5256 y(corrected)26 b(in)g(the)f(next)g(sections.)1905
+5531 y Fs(11)p eop
+%%Page: 12 16
+12 15 bop 150 573 a Fh(TYPE=)42 b(COMMAND)150 672 y(NAME=)g(\\caption)
+237 772 y(START_TAG=)e("?n)260 b(CAPTION)41 b(")237 872
+y(END_TAG=)f("?n?n")150 971 y(END_TYPE)150 1171 y Fs(Assuming)29
+b(that)i(somewhere)f(in)f(a)i(L)1431 1154 y Fr(A)1470
+1171 y Fs(T)1521 1190 y(E)1571 1171 y(X)g(\014le)e(there)i(is)e(the)i
+(command)150 1345 y Fh(stuff)150 1445 y(\\caption{This)38
+b(is)43 b(a)g(caption.})150 1544 y(more)f(stuff)150 1719
+y Fs(then)30 b(the)h(exp)s(ected)f(e\013ect)i(\(see)g(fo)s(otnote\))g
+(is)150 1893 y Fh(stuff)324 2092 y(CAPTION)41 b(This)h(is)h(a)g
+(caption.)150 2291 y(more)f(stuff)150 2535 y Fj(2.4)112
+b(Argumen)m(t)37 b(actions)150 2706 y Fs(L)174 2690 y
+Fr(A)213 2706 y Fs(T)264 2726 y(E)314 2706 y(X)26 b(commands)f(can)h
+(tak)m(e)h(argumen)m(ts.)39 b(The)25 b(text)i(for)e(a)h(required)d
+(argumen)m(t)j(is)f(enclosed)g(in)f(curly)150 2819 y(braces,)32
+b(while)d(the)j(text)g(for)f(an)g(optional)g(argumen)m(t)g(is)g
+(enclosed)g(in)f(square)h(brac)m(k)m(ets.)44 b Fy(L)-7
+b(TX2X)32 b Fs(can)150 2932 y(b)s(e)e(directed)f(to)j(p)s(erform)d
+(actions)h(at)h(the)g(start)g(and)e(end)h(of)h(eac)m(h)g(argumen)m(t.)
+291 3045 y(The)g(n)m(um)m(b)s(er)f(of)i(required)d(argumen)m(ts)j(is)f
+(sp)s(eci\014ed)e(b)m(y)j(the)f(command)g(line)f Fh(REQPARAMS=)d
+Fs(where)150 3158 y(the)k(v)-5 b(alue)29 b(of)i(the)g(command)f(is)f(a)
+i(digit)e(b)s(et)m(w)m(een)i(1)g(and)e(9)i(inclusiv)m(e.)291
+3271 y Fy(L)-7 b(TX2X)36 b Fs(assumes)f(that)i(a)f(command)f(can)i(ha)m
+(v)m(e)g(only)d(one)j(optional)e(argumen)m(t,)i(and)f(that)g(this)150
+3384 y(is)31 b(either)h(\014rst)f(or)h(last)g(in)e(the)j(argumen)m(t)f
+(list.)44 b(The)32 b(p)s(oten)m(tial)f(presence)h(of)g(an)g(optional)f
+(argumen)m(t)150 3497 y(is)h(indicated)f(b)m(y)h(the)h(command)f(line)f
+Fh(OPT)p 1654 3497 27 4 v 30 w(PARAM=)p Fs(,)f(where)i(the)h(v)-5
+b(alue)32 b(is)g(either)f(the)i(k)m(eyw)m(ord)g Fh(FIRST)150
+3610 y Fs(\(for)d(\014rst)g(in)f(the)i(list\))e(or)h
+Fh(LAST)f Fs(\(for)i(last)f(in)f(the)h(list\).)291 3723
+y(The)23 b(actions)h(to)h(b)s(e)e(p)s(erformed)f(at)i(the)g(start)h
+(and)e(end)g(of)h(eac)m(h)g(required)e(argumen)m(t)j(are)f(sp)s
+(eci\014ed)150 3836 y(via)40 b(the)g(commands)g Fh(START)p
+1160 3836 V 30 w(TAG)p 1322 3836 V 30 w(1=)f Fs(and)h
+Fh(END)p 1798 3836 V 30 w(TAG)p 1960 3836 V 30 w(1=)g
+Fs(for)g(the)g(\014rst)g(required)e(argumen)m(t,)44 b(through)150
+3948 y Fh(START)p 375 3948 V 29 w(TAG)p 536 3948 V 30
+w(9=)35 b Fs(and)f Fh(END)p 1002 3948 V 30 w(TAG)p 1164
+3948 V 31 w(9=)g Fs(for)h(the)g(nin)m(th)f(argumen)m(t.)56
+b(The)34 b(actions)i(to)g(b)s(e)e(p)s(erformed)g(at)i(the)150
+4061 y(start)30 b(and)f(end)g(of)h(the)g(optional)f(argumen)m(t)h(are)g
+(sp)s(eci\014ed)e(b)m(y)h(the)h(command)f(lines)f Fh(START)p
+3375 4061 V 30 w(OPT=)g Fs(and)150 4174 y Fh(END)p 287
+4174 V 30 w(OPT=)p Fs(.)291 4287 y(The)i(argumen)m(t)h(delimiters)d
+(\(the)j(braces)f(or)h(brac)m(k)m(ets\))h(are)f(not)f(prin)m(ted.)291
+4400 y(In)37 b(the)g(simplest)f(case,)k(the)e(action)f(is)g(to)h(prin)m
+(t)e(a)i(sp)s(eci\014ed)d(text)k(string)d(\(enclosed)h(in)f(double)150
+4513 y(quotes,)41 b(and)d(con)m(tin)m(ued)g(with)e Fh(STRING:)g
+Fs(commands)i(if)f(necessary\).)65 b(Other)37 b(kinds)g(of)h(actions)h
+(are)150 4626 y(also)30 b(p)s(ossible.)39 b(An)30 b(unsp)s(eci\014ed)d
+(tag)32 b(defaults)d(to)i(doing)f(no)g(action.)150 4866
+y Ft(2.4.1)105 b(Prin)m(t)36 b(options)150 5038 y(2.4.1.1)106
+b(Argumen)m(t)28 b(pro)s(cessing)93 b Fs(By)25 b(default,)h
+Fy(L)-7 b(TX2X)25 b Fs(pro)s(cesses)g(\(i.e.)39 b(outputs)25
+b(as)h(appropri-)150 5151 y(ate\))f(the)f(text)g(of)g(a)g(argumen)m(t.)
+38 b(Prin)m(ting)22 b(of)i(the)f(argumen)m(t)h(text)h(ma)m(y)f(b)s(e)f
+(disabled,)f(if)h(required.)36 b(The)150 5263 y(command)c(line)f(that)h
+(con)m(trols)h(argumen)m(t)f(prin)m(ting)e(is)i(of)g(the)g(form)g
+Fh(PRINT)p 2837 5263 V 30 w(P1=)e Fs(through)i Fh(PRINT)p
+3595 5263 V 29 w(P9=)1905 5531 y Fs(12)p eop
+%%Page: 13 17
+13 16 bop 150 573 a Fs(for)29 b(required)f(argumen)m(ts)i(and)f
+Fh(PRINT)p 1487 573 27 4 v 29 w(OPT=)f Fs(for)h(the)h(optional)f
+(argumen)m(t.)40 b(The)29 b(v)-5 b(alue)29 b(of)h(these)g(com-)150
+686 y(mands)37 b(is)h(one)g(from)g(sev)m(eral)h(k)m(eyw)m(ords,)i(the)e
+(most)f(common)h(b)s(eing)f Fh(NO)p 2794 686 V 31 w(PRINT)p
+Fs(;)e(this)h(switc)m(hes)i(o\013)150 799 y(prin)m(ting)30
+b(of)j(the)g(text)g(of)g(the)f(indicated)f(argumen)m(t.)48
+b(Default)32 b(prin)m(ting)f(is)g(resumed)h(after)h(the)f(indi-)150
+912 y(cated)f(argumen)m(t.)291 1011 y(Con)m(tin)m(uing)g(the)h(caption)
+g(example)g(from)g(earlier,)g(w)m(e)g(can)h(no)m(w)f(complete)h(it.)46
+b(The)31 b(full)f(syn)m(tax)150 1111 y(of)h(the)f(L)434
+1094 y Fr(A)473 1111 y Fs(T)524 1130 y(E)574 1111 y(X)h(command)f(is:)
+150 1280 y Fh(\\caption[optiona)o(l)38 b(table)j(of)i(contents)d
+(entry]{Caption)e(in)43 b(the)f(text})150 1461 y Fs(That)35
+b(is,)g(it)g(has)g(one)g(required)e(argumen)m(t,)k(whic)m(h)d(prin)m
+(ts)g(the)h(caption)g(text)h(b)s(oth)e(in)g(the)h(b)s(o)s(dy)f(of)150
+1574 y(the)c(do)s(cumen)m(t)f(and)g(in)f(the)i(table)f(of)h(con)m(ten)m
+(ts,)i(unless)c(the)h(\014rst)g(optional)g(argumen)m(t)h(is)e(presen)m
+(t,)i(in)150 1687 y(whic)m(h)f(case)j(its)d(v)-5 b(alue)30
+b(gets)i(prin)m(ted)c(in)h(the)i(table)f(of)h(con)m(ten)m(ts)h
+(instead.)291 1787 y(Assume)e(that)h(an)f(instance)g(of)h(the)f
+(caption)h(command)f(in)f(a)i(do)s(cumen)m(t)f(is:)150
+1956 y Fh(Some)42 b(stuff)150 2055 y(\\caption[Short)c(caption]{Long)g
+(caption)j(for)h(the)g(body)g(of)h(the)f(text.})150 2155
+y(More)g(stuff)150 2323 y Fs(Recall)21 b(the)h(previous)e(command)h
+(table)h(caption)f(sp)s(eci\014cation.)37 b(The)21 b(actual)h(output)f
+(from)g(pro)s(cessing)150 2423 y(this)29 b(w)m(ould)g(b)s(e)150
+2592 y Fh(Some)42 b(stuff)324 2791 y(CAPTION)f([Short)g(caption]{Long)d
+(caption)j(for)h(the)h(body)f(of)g(the)h(text.})150 2990
+y(More)f(stuff)150 3172 y Fs(b)s(ecause,)31 b(unless)d
+Fy(L)-7 b(TX2X)30 b Fs(is)g(told)g(that)h(there)f(are)h(command)f
+(argumen)m(ts)h(and)e(ho)m(w)i(they)f(should)f(b)s(e)150
+3285 y(treated,)j(it)e(will)d(just)j(prin)m(t)f(them)h(out)h(together)h
+(with)d(their)g(surrounding)e(delimiters.)291 3385 y(The)j(follo)m
+(wing)f(command)h(table)g(en)m(try)h(will)d(giv)m(e)i(more)h
+(acceptable)g(results.)150 3553 y Fh(TYPE=)42 b(COMMAND)150
+3653 y(NAME=)g(\\caption)237 3753 y(START_TAG=)e("?n)260
+b(CAPTION)41 b(")237 3852 y(END_TAG=)f("?n?n")237 3952
+y(OPT_PARAM=)g(FIRST)237 4052 y(PRINT_OPT=)g(NO_PRINT)237
+4151 y(REQPARAMS=)g(1)150 4251 y(END_TYPE)291 4419 y
+Fs(F)-8 b(or)31 b(the)g(ab)s(o)m(v)m(e)g(captioning)f(instance,)g(the)h
+(output)f(will)d(no)m(w)k(b)s(e:)150 4588 y Fh(Some)42
+b(stuff)324 4787 y(CAPTION)f(Long)h(caption)f(for)h(the)g(body)g(of)h
+(the)f(text.)150 4987 y(More)g(stuff)291 5169 y Fs(The)30
+b(default)g(prin)m(t)f(mo)s(de)h(is)f(to)i(prin)m(t)e(text)i(to)h(the)e
+(output)g(\014le.)291 5282 y(The)g(k)m(eyw)m(ords)h(that)g(can)f(b)s(e)
+g(used)g(to)h(con)m(trol)g(argumen)m(t)f(prin)m(ting)f(are:)1905
+5531 y(13)p eop
+%%Page: 14 18
+14 17 bop 150 573 a Fh(NO)p 243 573 27 4 v 31 w(PRINT)43
+b Fs(Do)31 b(not)g(prin)m(t)e(an)m(ything.)150 748 y
+Fh(TO)p 243 748 V 31 w(SYSBUF)43 b Fs(Prin)m(t)29 b(to)i(the)g
+Fy(L)-7 b(TX2X)30 b Fs(system)g(bu\013er.)150 922 y Fh(TO)p
+243 922 V 31 w(BUFFER)41 b(num)j Fs(Prin)m(t)29 b(to)i(the)g
+Fy(L)-7 b(TX2X)30 b Fs(bu\013er)g(n)m(um)m(b)s(er)f Fh(num)p
+Fs(.)150 1097 y Fh(TO)p 243 1097 V 31 w(FILE)41 b(name)j
+Fs(Prin)m(t)30 b(to)h(the)f(\014le)g(called)f Fh(name)p
+Fs(.)150 1272 y Fh(NO)p 243 1272 V 31 w(OP)44 b Fs(Skip)29
+b(all)g(pro)s(cessing)g(of)i(the)f(argumen)m(t.)150 1428
+y(Note)c(that)f(ev)m(en)g(if)f(the)h(prin)m(t)e(mo)s(de)h(is)g(set)h
+(to)g Fh(NO)p 1863 1428 V 31 w(PRINT)p Fs(,)d(the)j(argumen)m(t)g(text)
+h(will)c(still)g(b)s(e)i(pro)s(cessed.)150 1541 y(Only)29
+b(the)h Fh(NO)p 624 1541 V 31 w(OP)f Fs(sp)s(eci\014cation)h(temp)s
+(orarly)f(turns)g(o\013)i(the)f(pro)s(cessing.)150 1775
+y Ft(2.4.1.2)106 b(General)37 b(prin)m(ting)91 b Fs(Just)32
+b(as)g(the)g(prin)m(ting)e(mo)s(de)i(can)h(b)s(e)e(set)i(for)f(eac)m(h)
+h(argumen)m(t,)g(it)150 1888 y(can)e(also)f(b)s(e)g(set)h(at)g(the)f
+(start)h(and)f(end)g(of)g(pro)s(cessing)f(a)i(L)2240
+1871 y Fr(A)2279 1888 y Fs(T)2330 1907 y(E)2380 1888
+y(X)g(command)f(or)g(en)m(vironmen)m(t.)291 2001 y(The)f(sp)s
+(eci\014cations)g Fh(PC)p 1124 2001 V 30 w(AT)p 1242
+2001 V 31 w(START=)e Fs(and)i Fh(PC)p 1828 2001 V 31
+w(AT)p 1947 2001 V 30 w(END=)f Fs(can)i(b)s(e)f(used)g(to)h(set)h(the)e
+(prin)m(ting)f(mo)s(de)h(at)150 2113 y(the)h(start)g(of)g(pro)s
+(cessing)e(a)j(command)e(and)g(at)i(the)e(end,)h(resp)s(ectiv)m(ely)-8
+b(.)40 b(The)29 b(k)m(eyw)m(ords)h(that)h(can)f(b)s(e)150
+2226 y(used)g(in)f(these)h(sp)s(eci\014cations)g(are:)150
+2382 y Fh(NO)p 243 2382 V 31 w(PRINT)43 b Fs(Do)31 b(not)g(prin)m(t)e
+(an)m(ything.)150 2557 y Fh(TO)p 243 2557 V 31 w(SYSBUF)43
+b Fs(Prin)m(t)29 b(to)i(the)g Fy(L)-7 b(TX2X)30 b Fs(system)g
+(bu\013er.)150 2732 y Fh(TO)p 243 2732 V 31 w(BUFFER)41
+b(num)j Fs(Prin)m(t)29 b(to)i(the)g Fy(L)-7 b(TX2X)30
+b Fs(bu\013er)g(n)m(um)m(b)s(er)f Fh(num)p Fs(.)150 2906
+y Fh(TO)p 243 2906 V 31 w(FILE)41 b(name)j Fs(Prin)m(t)30
+b(to)h(the)f(\014le)g(called)f Fh(name)p Fs(.)150 3081
+y Fh(RESET)43 b Fs(Reset)32 b(the)e(prin)m(t)f(mo)s(de)h(bac)m(k)h(to)g
+(what)g(it)f(w)m(as.)291 3237 y(Unlik)m(e)g(the)i(argumen)m(t)g(prin)m
+(ting)d(con)m(trols,)j(the)g(prin)m(t)e(mo)s(de)g(is)h(not)g
+(automatically)h(reset.)44 b(This)150 3350 y(has)30 b(to)h(b)s(e)f
+(explicitly)e(sp)s(eci\014ed.)291 3449 y(As)38 b(an)g(example,)i
+(assume)d(that)i(it)e(is)g(required)f(to)j(remo)m(v)m(e)g(all)e
+Fh(figure)f Fs(en)m(vironmen)m(ts)h(from)h(a)150 3549
+y(L)174 3532 y Fr(A)213 3549 y Fs(T)264 3569 y(E)314
+3549 y(X)g(source)f(and)g(put)f(them)h(in)m(to)h(a)f(\014le)f(on)i
+(their)e(o)m(wn.)61 b(The)37 b(follo)m(wing)f(command)h(table)g(co)s
+(de)150 3649 y(could)29 b(b)s(e)h(used)g(to)h(accomplish)e(this.)150
+3791 y Fh(TYPE=)42 b(BEGIN_ENV)150 3891 y(NAME=)g(figure)237
+3990 y(PC_AT_START=)d(TO_FILE)h(allfigs.tex)237 4090
+y(START_TAG=)g("?n\\begin{figur)o(e}")150 4189 y(END_TYPE)150
+4389 y(TYPE=)i(END_ENV)150 4488 y(NAME=)g(figure)237
+4588 y(START_TAG=)e("\\end{figure}")237 4688 y(PC_AT_END=)g(RESET)150
+4787 y(END_TYPE)150 4943 y Fs(When)35 b(a)g(L)524 4926
+y Fr(A)563 4943 y Fs(T)614 4962 y(E)665 4943 y(X)g Fh(figure)e
+Fs(en)m(vironmen)m(t)h(is)h(started,)i(prin)m(ting)c(is)h(switc)m(hed)g
+(to)i(go)g(to)g(the)f(\014le)g(called)150 5056 y Fn(allfigs.tex)p
+Fs(.)i(A)m(t)31 b(the)f(end)g(of)g(the)g Fh(figure)d
+Fs(en)m(vironmen)m(t,)j(the)g(prin)m(t)f(mo)s(de)g(is)g(reset)i(bac)m
+(k)f(to)h(what)150 5169 y(it)h(w)m(as)i(b)s(efore)e(the)i(en)m
+(vironmen)m(t)e(b)s(egan.)48 b(If)33 b(at)h(the)f(\014rst)f
+Fh(figure)e Fs(en)m(vironmen)m(t)j(the)g Fn(allfigs.tex)150
+5282 y Fs(\014le)c(did)g(not)i(exist,)f(then)g Fy(L)-7
+b(TX2X)30 b Fs(w)m(ould)g(create)h(it)f(automatically)-8
+b(.)1905 5531 y(14)p eop
+%%Page: 15 19
+15 18 bop 150 573 a Ft(2.4.1.3)106 b(Read)41 b(actions)92
+b Fs(As)36 b(noted)g(ab)s(o)m(v)m(e,)j(one)d(of)h(the)f(actions)g(that)
+h(can)f(b)s(e)f(sp)s(eci\014ed)g(for)h(a)150 686 y(L)174
+669 y Fr(A)213 686 y Fs(T)264 705 y(E)314 686 y(X)25
+b(comand's)f(argumen)m(t)h(is)f(to)h(set)g(the)f(prin)m(t)f(mo)s(de)h
+(for)g(prin)m(ting)e(to)k(a)e(bu\013er)g(or)g(a)h(\014le.)38
+b(Similarly)150 799 y(there)32 b(are)g(actions)h(whic)m(h)d(will)f
+(read)j(from)g(a)g(bu\013er)f(or)h(a)g(\014le)f(and)g(prin)m(t)g(the)h
+(con)m(ten)m(ts.)47 b(Within)30 b(an)150 912 y(argumen)m(t)k(tag)h
+(these)g(kinds)d(of)i(actions)g(are)g(sp)s(eci\014ed)f(via)g(the)h(k)m
+(eyw)m(ord)h Fh(SOURCE:)p Fs(.)48 b(This)32 b(can)i(tak)m(e)150
+1024 y(one)d(of)f(sev)m(eral)h(v)-5 b(alues:)150 1212
+y Fh(SYSBUF)43 b Fs(Prin)m(t)29 b(the)i(con)m(ten)m(ts)h(of)f(the)f
+Fy(L)-7 b(TX2X)30 b Fs(system)h(bu\013er.)150 1400 y
+Fh(BUFFER)41 b(num)j Fs(Prin)m(t)30 b(the)g(con)m(ten)m(ts)i(of)f(the)f
+Fy(L)-7 b(TX2X)31 b Fs(bu\013er)e(n)m(um)m(b)s(er)g Fh(num)p
+Fs(.)150 1587 y Fh(FILE)42 b(name)i Fs(Prin)m(t)29 b(the)i(con)m(ten)m
+(ts)h(of)e(the)h(\014le)e(called)h Fh(name)p Fs(.)291
+1762 y(In)46 b(a)h(previous)f(example,)51 b(the)c(L)1491
+1745 y Fr(A)1530 1762 y Fs(T)1581 1781 y(E)1631 1762
+y(X)g Fh(figure)d Fs(en)m(vironmen)m(ts)i(w)m(ere)i(all)d(written)h(to)
+i(the)f(\014le)150 1861 y Fn(allfig.tex)p Fs(.)81 b(This)43
+b(\014le)h(could)g(b)s(e)g(read)g(in)g(again)h(just)f(b)s(efore)g(the)h
+(end)f(of)h(the)g(do)s(cumen)m(t)g(so)150 1961 y(that)31
+b(all)e(\014gures)h(will)e(b)s(e)h(t)m(yp)s(eset)i(after)g(ev)m
+(erything)g(else.)150 2135 y Fh(TYPE=)42 b(END_DOCUMENT)237
+2235 y(END_TAG=)e("?n)j(\045)87 b(figures)40 b(collected)g(here)i(by)h
+(LTX2X)e(?n")324 2335 y(SOURCE:)g(FILE)h(allfigs.tex)324
+2434 y(STRING:)f("?n\\end{document)o(}?n)o(")150 2534
+y(END_TYPE)291 2708 y Fs(As)j(another)g(example)f(of)h(the)g(use)f(of)h
+(the)g(prin)m(t)e(actions)i(consider)f(the)h(L)3021 2691
+y Fr(A)3060 2708 y Fs(T)3111 2728 y(E)3161 2708 y(X)g
+Fn(\\maketitle)150 2808 y Fs(command.)71 b(This)39 b(t)m(yp)s(esets)i
+(the)g(argumen)m(ts)f(of)h(the)g Fn(\\title)p Fs(,)g
+Fn(\\author)e Fs(and)h Fn(\\date)f Fs(commands,)150 2907
+y(whic)m(h)28 b(m)m(ust)h(ha)m(v)m(e)i(b)s(een)e(previously)e(sp)s
+(eci\014ed)g(but)i(not)h(necessarily)e(in)g(this)g(ordering.)39
+b(Here)30 b(is)f(one)150 3007 y(w)m(a)m(y)i(this)f(can)g(b)s(e)g(sim)m
+(ulated)f(using)g Fy(L)-7 b(TX2X)p Fs(.)150 3181 y Fh(TYPE=)42
+b(COMMAND)150 3281 y(NAME=)g(\\title)237 3381 y(START_TAG=)324
+3480 y(RESET_BUFFER:)d(1)237 3580 y(REQPARAMS=)h(1)237
+3680 y(PRINT_P1=)g(TO_BUFFER)g(1)150 3779 y(END_TYPE)150
+3978 y(TYPE=)i(COMMAND)150 4078 y(NAME=)g(\\author)237
+4178 y(START_TAG=)324 4277 y(RESET_BUFFER:)d(2)237 4377
+y(REQPARAMS=)h(1)237 4477 y(PRINT_P1=)g(TO_BUFFER)g(2)150
+4576 y(END_TYPE)150 4775 y(TYPE=)i(COMMAND)150 4875 y(NAME=)g(\\date)
+237 4975 y(START_TAG=)324 5074 y(RESET_BUFFER:)d(3)237
+5174 y(REQPARAMS=)h(1)237 5274 y(PRINT_P1=)g(TO_BUFFER)g(3)1905
+5531 y Fs(15)p eop
+%%Page: 16 20
+16 19 bop 150 573 a Fh(END_TYPE)150 772 y(TYPE=)42 b(COMMAND)150
+872 y(NAME=)g(\\maketitle)237 971 y(START_TAG=)e("?n")324
+1071 y(SOURCE:)h(BUFFER)g(1)324 1171 y(STRING:)g("?n?n")324
+1270 y(SOURCE:)g(BUFFER)g(2)324 1370 y(STRING:)g("?n?n")324
+1469 y(SOURCE:)g(BUFFER)g(3)324 1569 y(STRING:)g("?n?n")237
+1669 y(END_TAG=)324 1768 y(RESET_BUFFER:)e(1)324 1868
+y(RESET_BUFFER:)g(2)324 1968 y(RESET_BUFFER:)g(3)150
+2067 y(END_TYPE)150 2255 y Fs(F)-8 b(or)32 b(the)f Fn(\\title)e
+Fs(command,)i(the)g(prin)m(t)f(mo)s(de)g(for)h(its)f(argumen)m(t)h(is)f
+(set)i(for)e(prin)m(ting)f(to)j(the)f(bu\013er)150 2368
+y(n)m(um)m(b)s(er)h(1.)50 b(The)33 b(single)f(action)h(at)h(the)g
+(start)g(of)f(the)h(command)f(is)f(to)i(mak)m(e)g(sure)f(that)h
+(bu\013er)e(1)i(is)150 2481 y(empt)m(y)g(\(the)g(line)e
+Fh(RESET)p 1026 2481 27 4 v 29 w(BUFFER:)41 b(1)p Fs(\).)50
+b(The)33 b(actions)g(for)g(the)h Fn(\\author)e Fs(and)g
+Fn(\\date)g Fs(commands)i(are)150 2594 y(similar,)28
+b(except)j(that)g(they)g(prin)m(t)e(their)g(argumen)m(t)i(texts)g(to)g
+(bu\013ers)f(2)g(and)g(3)h(resp)s(ectiv)m(ely)-8 b(.)291
+2707 y(The)40 b Fn(\\maketitle)d Fs(command)i(tak)m(es)j(no)e(argumen)m
+(ts,)j(so)d(all)f(actions)h(m)m(ust)g(b)s(e)f(placed)g(under)150
+2819 y Fh(START)p 375 2819 V 29 w(TAG=)e Fs(and/or)i
+Fh(END)p 1061 2819 V 30 w(TAG=)p Fs(.)65 b(There)38 b(are)i(a)f(set)g
+(of)g(actions)h(sp)s(eci\014ed)d(for)h Fh(START)p 3195
+2819 V 30 w(TAG=)p Fs(.)64 b(Firstly)150 2932 y(a)38
+b(newline)d(is)h(prin)m(ted)g(and)h(this)f(is)h(follo)m(w)m(ed)g(b)m(y)
+g(the)h(con)m(ten)m(ts)h(of)e(bu\013er)g(1)g(\(i.e.,)j(the)e(text)g(of)
+g(the)150 3045 y(argumen)m(t)21 b(of)g(the)g Fn(\\title)e
+Fs(command\).)37 b(Then)20 b(t)m(w)m(o)i(new)e(lines)f(are)i(prin)m
+(ted,)h(follo)m(w)m(ed)e(b)m(y)g(the)h(con)m(ten)m(ts)150
+3158 y(of)31 b(bu\013er)f(2)h(\(the)g(author\).)43 b(Finally)28
+b(another)j(t)m(w)m(o)i(newlines)28 b(are)j(prin)m(ted,)f(the)h(con)m
+(ten)m(ts)i(of)e(bu\013er)f(3)150 3271 y(\(the)g(date\),)i(and)d
+(another)h(t)m(w)m(o)h(newlines.)39 b(The)29 b(actions)h(for)g
+Fh(END)p 2454 3271 V 30 w(TAG=)e Fs(are)i(to)h(clear)f(the)g(con)m(ten)
+m(ts)i(of)150 3384 y(the)f(three)f(bu\013ers.)291 3484
+y(Just)38 b(to)g(extend)g(the)h(example,)g(here)f(is)f(a)i(sp)s
+(eci\014cation)d(for)i(the)g(L)2722 3467 y Fr(A)2761
+3484 y Fs(T)2812 3503 y(E)2863 3484 y(X)g Fn(\\thanks)e
+Fs(command.)150 3583 y Fy(L)-7 b(TX2X)36 b Fs(is)g(not)h(designed)e(to)
+i(do)g(fo)s(otnoting)f(\(as)h(it)g(do)s(es)f(not)h(do)f(page)h
+(breaking\))f(so)h(instead)f(the)150 3683 y(thanks)30
+b(text)h(will)d(b)s(e)i(placed)g(inside)e(paren)m(theses)i(on)h(a)f
+(new)g(line.)150 3857 y Fh(TYPE=)42 b(COMMAND)150 3957
+y(NAME=)g(\\thanks)237 4056 y(START_TAG=)e("?n)i(\(")237
+4156 y(REQPARAMS=)e(1)237 4256 y(END_TAG=)g("\))j(")150
+4355 y(END_TYPE)291 4530 y Fs(Giv)m(en)25 b(these)g(command)g(table)g
+(sp)s(eci\014cation)e(and)i(the)g(follo)m(wing)e(p)s(ortion)g(of)j(a)f
+(L)3128 4513 y Fr(A)3167 4530 y Fs(T)3218 4549 y(E)3268
+4530 y(X)g(do)s(cumen)m(t)150 4704 y Fh(\\date{29)40
+b(February)h(2000})150 4804 y(\\title{The)e(Calculation)g(of)k(Leap)f
+(Days\\thanks{Origi)o(na)o(ll)o(y)c(published)i(in)i(JIR}})150
+4903 y(\\author{A.)d(N.)k(Other})150 5003 y(...)150 5103
+y(\\maketitle)150 5277 y Fs(then)30 b(output)g(from)g
+Fy(L)-7 b(TX2X)30 b Fs(will)e(b)s(e:)1905 5531 y(16)p
+eop
+%%Page: 17 21
+17 20 bop 150 573 a Fh(The)42 b(Calculation)d(of)k(Leap)f(Days)194
+672 y(\(Originally)d(published)g(in)k(JIR\))150 872 y(A.)g(N.)g(Other)
+150 1071 y(29)g(February)d(2000)150 1249 y Fs(Note)29
+b(that)g(as)f(the)g Fn(\\thanks)e Fs(command)i(app)s(ears)f(within)e
+(the)j(argumen)m(t)h(of)f(the)g Fn(\\title)e Fs(command,)150
+1362 y(it)35 b(is)g(written)f(to)j(the)e(same)h(place)g(as)g(the)g
+(text)g(of)g(the)g(argumen)m(t)g(of)g Fn(\\title)p Fs(.)54
+b(Th)m(us,)36 b(it)f(also)h(gets)150 1475 y(written)29
+b(to)j(the)e(output)g(\014le)g(when)f Fn(\\maketitle)f
+Fs(is)h(pro)s(cessed.)150 1713 y Ft(2.4.2)105 b(Prin)m(t)36
+b(switc)m(hing)150 1885 y Fs(There)42 b(are)h(individual)38
+b(actions)43 b(that)g(enable)f(the)h(prin)m(ting)d(destination)i(to)h
+(b)s(e)f(c)m(hanged)h(at)h(will)150 1998 y(within)28
+b(the)i(action)h(set)g(for)f(an)m(y)h(particular)e(tag.)150
+2176 y Fh(SWITCH)p 419 2176 27 4 v 29 w(TO)p 536 2176
+V 30 w(BUFFER:)41 b(num)j Fs(Direct)31 b(an)m(y)g(follo)m(wing)e(prin)m
+(ting)f(to)j(the)g Fy(L)-7 b(TX2X)30 b Fs(bu\013er)f(n)m(um)m(b)s(er)g
+Fh(num)p Fs(.)150 2360 y Fh(SWITCH)p 419 2360 V 29 w(TO)p
+536 2360 V 30 w(FILE:)42 b(name)i Fs(Direct)31 b(an)m(y)f(follo)m(wing)
+f(prin)m(ting)f(to)j(the)g(\014le)e(called)h Fh(name)p
+Fs(.)150 2544 y Fh(SWITCH)p 419 2544 V 29 w(TO)p 536
+2544 V 30 w(SYSBUF)43 b Fs(Direct)31 b(an)m(y)g(follo)m(wing)e(prin)m
+(ting)f(to)j(the)g Fy(L)-7 b(TX2X)30 b Fs(system)g(bu\013er.)150
+2728 y Fh(SWITCH)p 419 2728 V 29 w(BACK:)43 b Fs(Undo)30
+b(the)h(e\013ect)h(of)e(the)h(last)f Fh(SWITCH)p 2049
+2728 V 29 w(TO...)38 b Fs(action.)291 2893 y(As)26 b(an)f(example)g(of)
+h(the)g(utilit)m(y)e(of)i(this)e(t)m(yp)s(e)i(of)g(action,)h(consider)d
+(again)i(the)g(L)3039 2876 y Fr(A)3078 2893 y Fs(T)3129
+2912 y(E)3179 2893 y(X)g Fn(\\maketitle)150 2992 y Fs(command.)56
+b(When)36 b(L)910 2976 y Fr(A)949 2992 y Fs(T)1000 3012
+y(E)1050 2992 y(X)g(pro)s(cesses)f(this)g(command,)i(it)e(t)m(yp)s
+(esets)h(the)g(date)g(as)g(sp)s(eci\014ed)e(b)m(y)i(the)150
+3092 y Fn(\\date)e Fs(command,)i(or)f(if)f(this)g(has)h(not)g(b)s(een)g
+(sp)s(eci\014ed)e(then)i(it)g(prin)m(ts)e(the)j(curren)m(t)f(date)g
+(instead.)150 3192 y(W)-8 b(e)26 b(can)g(arrange)f(for)g
+Fy(L)-7 b(TX2X)25 b Fs(to)h(do)f(something)f(similar)f(b)m(y)i(adding)e
+(the)j(follo)m(wing)d(to)j(the)f(command)150 3291 y(table)30
+b(sho)m(wn)g(earlier)f(for)h(the)h Fn(\\date)e Fs(and)h
+Fn(\\maketitle)d Fs(commands.)150 3456 y Fh(TYPE=)42
+b(COMMAND)150 3556 y(NAME=)g(\\documentclass)237 3655
+y(OPT_PARAM=)e(FIRST)237 3755 y(REQPARAMS=)g(1)237 3855
+y(PRINT_OPT=)g(NO_PRINT)237 3954 y(PRINT_P1=)g(NO_PRINT)237
+4054 y(START_TAG=)412 4154 y(c=)i(Initialise)e(buffer)h(3)i(to)g
+(`Today')324 4253 y(RESET_BUFFER:)c(3)324 4353 y(SWITCH_TO_BUFFER:)e(3)
+324 4452 y(STRING:)k("Today")324 4552 y(SWITCH_BACK:)150
+4652 y(END_TYPE)150 4830 y Fs(A)m(t)30 b(the)g(start)g(of)f(the)h(do)s
+(cumen)m(t,)f(the)h(ab)s(o)m(v)m(e)g(actions)g(put)e(the)i(string)f
+Fh(Today)f Fs(in)m(to)h Fh(BUFFER)41 b(3)p Fs(,)29 b(ha)m(ving)150
+4943 y(\014rst)38 b(ensured)f(that)i(it)f(is)f(empt)m(y)-8
+b(.)66 b(If)38 b(the)g(L)1708 4926 y Fr(A)1747 4943 y
+Fs(T)1798 4962 y(E)1848 4943 y(X)h(source)g(includes)d(a)i
+Fn(\\date)f Fs(command,)k(then)d(the)150 5056 y(con)m(ten)m(ts)d(of)e
+(the)g(bu\013er)f(will)e(b)s(e)i(o)m(v)m(erwritten,)j(otherwise)d(it)g
+(will)f(b)s(e)h(as)h(initialised.)45 b(In)32 b(an)m(y)h(ev)m(en)m(t,)
+150 5169 y(when)g(the)h Fn(\\maketitle)d Fs(command)j(is)f(pro)s
+(cessed,)h(the)g(v)-5 b(alue)33 b(output)h(for)f(the)i(date)f(will)d(b)
+s(e)i(either)150 5282 y Fh(Today)28 b Fs(or)j(whatev)m(er)g(the)f
+(argumen)m(t)h(w)m(as)g(of)f(the)h Fn(\\date)e Fs(command.)1905
+5531 y(17)p eop
+%%Page: 18 22
+18 21 bop 150 573 a Ft(2.4.3)105 b(Notes)35 b(on)g(the)g(use)g(of)g
+(bu\013ers)g(and)g(\014les)150 744 y Fs(Resetting)c(a)g(bu\013er)e(or)h
+(a)h(\014le)f(alw)m(a)m(ys)g(has)h(the)f(e\013ect)i(of)f(empt)m(ying)f
+(it)f(of)i(an)f(prior)f(con)m(ten)m(ts.)291 857 y(When)h(prin)m(ting)e
+(from)i(a)g(bu\013er)f(or)h(a)h(\014le,)e(the)i(en)m(tire)f(con)m(ten)m
+(ts)i(are)e(prin)m(ted.)39 b(There)30 b(is)f(no)h(limit)150
+970 y(to)h(the)g(n)m(um)m(b)s(er)e(of)h(times)g(that)h(a)g(bu\013er)e
+(or)i(a)f(\014le)g(can)h(b)s(e)e(used)h(as)g(a)h(prin)m(ting)d(source.)
+291 1083 y(When)43 b(prin)m(ting)d(to)k(a)f(bu\013er,)i(the)e(new)f
+(strings)g(are)h(app)s(ended)e(at)i(the)g(end)f(of)h(the)g(curren)m(t)
+150 1196 y(con)m(ten)m(ts)i(of)f(the)f(bu\013er,)j(at)e(least)g(un)m
+(til)d(it)i(o)m(v)m(er\015o)m(ws.)81 b(Unlik)m(e)43 b(the)g(b)s(eha)m
+(viour)f(of)i(\014les,)i(this)c(is)150 1309 y(indep)s(endan)m(t)28
+b(of)j(an)m(y)f(in)m(terv)m(ening)g(prin)m(ts)f(from)h(the)g(bu\013er.)
+291 1422 y(When)d(prin)m(ting)d(to)k(a)f(\014le,)g(the)g(new)f(strings)
+g(are)h(app)s(ended)e(at)j(the)f(end)f(of)h(the)g(curren)m(t)f(con)m
+(ten)m(ts)150 1535 y(of)k(the)h(\014le.)39 b(Ho)m(w)m(ev)m(er,)33
+b(if)c(a)h(\014le)g(is)f(prin)m(ted)f(to)j(after)g(it)f(has)f(b)s(een)h
+(prin)m(ted)e(from,)i(the)h(prior)d(con)m(ten)m(ts)150
+1648 y(of)f(the)f(\014le)g(are)h(lost,)g(and)f(the)h(new)f(string)g(is)
+f(added)h(at)h(the)g(start)g(of)g(the)g(\014le.)38 b(In)26
+b(general,)i(it)e(is)f(safest)150 1761 y(to)31 b(treat)h(\014les)d(as)i
+(either)e(read-only)h(or)g(write-only)-8 b(.)150 2001
+y Ft(2.4.4)105 b(User)36 b(sp)s(eci\014ed)f(mo)s(des)150
+2172 y Fs(Consider)24 b(the)i(L)701 2156 y Fr(A)740 2172
+y Fs(T)791 2192 y(E)842 2172 y(X)g(command)g Fn(\\\\)p
+Fs(.)38 b(In)26 b(normal)f(text)i(this)e(signi\014es)f(that)i(a)h(line)
+d(break)i(m)m(ust)g(o)s(ccur.)150 2285 y(In)i(a)i Fn(tabular)d
+Fs(en)m(vironmen)m(t,)i(though,)g(it)g(signi\014es)e(the)i(end)f(of)i
+(a)f(ro)m(w)g(in)f(a)h(table.)40 b(Supp)s(ose)28 b(that)h(in)150
+2398 y(the)e Fy(L)-7 b(TX2X)27 b Fs(pro)s(cesing)f(of)h(a)h(tabular)e
+(en)m(vironmen)m(t)h(it)f(is)g(required)g(to)h(start)h(and)e(end)h(eac)
+m(h)h(ro)m(w)f(with)150 2511 y(a)f(v)m(ertical)f(bar)f(and)h(to)h(sep)s
+(erate)f(eac)m(h)i(column)c(also)j(with)d(a)j(v)m(ertical)f(bar.)39
+b(Ho)m(w)m(ev)m(er,)28 b(in)c(normal)g(text)150 2624
+y(a)38 b Fn(\\\\)g Fs(command)f(should)f(just)i(translate)g(in)m(to)g
+(a)g(newline.)61 b(Just)38 b(to)g(complicate)g(matters)h(further,)150
+2737 y(assume)f(that)g(in)f(an)h Fn(eqnarray)e Fs(en)m(vironmen)m(t,)k
+(the)e Fn(&)f Fs(column)g(sep)s(erator)h(is)f(to)i(b)s(e)f(translated)f
+(to)150 2850 y(some)31 b(spaces,)g(and)f(that)h(the)f(string)f(`\(X\)')
+j(is)e(to)h(b)s(e)e(put)h(at)h(the)g(end)e(of)i(ev)m(ery)g(ro)m(w.)291
+2949 y(In)d(other)h(w)m(ords,)g(w)m(e)g(need)g(to)h(pro)s(cess)e(some)h
+(commands)g(di\013eren)m(tly)e(according)i(to)g(where)g(they)150
+3049 y(app)s(ear)34 b(in)g(the)h(LaT)-8 b(eX)36 b(source.)54
+b(An)34 b Fy(L)-7 b(TX2X)35 b Fs(command)g(table)f(pro)m(vides)g(this)g
+(capabilit)m(y)g(through)150 3149 y(mo)s(de)25 b(setting)h(and)g(mo)s
+(de-dep)s(enden)m(t)f(actions.)39 b(Here)26 b(is)f(an)h(example)g(of)g
+(using)e(this)h(facilit)m(y)g(to)i(solv)m(e)150 3248
+y(the)k(requiremen)m(ts)e(outlined)g(ab)s(o)m(v)m(e.)150
+3423 y Fh(TYPE=)42 b(BEGIN_ENV)150 3522 y(NAME=)g(tabular)237
+3622 y(C=)h(starting)d(actions,)g(etc.,)i(here)237 3722
+y(END_TAG=)324 3821 y(SET_MODE:)e(tabular)150 3921 y(END_TYPE)150
+4120 y(TYPE=)i(END_ENV)150 4220 y(NAME=)g(tabular)237
+4319 y(START_TAG=)324 4419 y(RESET_MODE:)150 4519 y(END_TYPE)150
+4718 y(TYPE=)g(BEGIN_ENV)150 4817 y(NAME=)g(eqnarry)237
+4917 y(C=)h(starting)d(actions,)g(etc.,)i(here)237 5017
+y(END_TAG=)324 5116 y(SET_MODE:)e(eqn)150 5216 y(END_TYPE)1905
+5531 y Fs(18)p eop
+%%Page: 19 23
+19 22 bop 150 672 a Fh(TYPE=)42 b(END_ENV)150 772 y(NAME=)g(eqnarray)
+237 872 y(START_TAG=)e(")174 b(\(X\)?n")324 971 y(RESET_MODE:)150
+1071 y(END_TYPE)150 1270 y(TYPE=)42 b(TEX_CHAR)150 1370
+y(NAME=)g(&)237 1469 y(START_TAG=)e(")86 b(|)h(")150
+1569 y(IN_MODE=)40 b(eqn)237 1669 y(START_TAG=)g(")86
+b(")150 1768 y(END_MODE)150 1868 y(END_TYPE)150 2067
+y(TYPE=)42 b(CHAR_COMMAND)150 2167 y(NAME=)g(\\\\)237
+2267 y(START_TAG=)e("?n")150 2366 y(IN_MODE=)g(tabular)237
+2466 y(START_TAG=)g(")j(|?n")324 2565 y(STRING:)e(")218
+b(|)86 b(")150 2665 y(END_MODE)150 2765 y(IN_MODE=)40
+b(eqn)237 2864 y(START_TAG=)g(")174 b(\(X\)?n")150 2964
+y(END_MODE)150 3064 y(END_TYPE)291 3249 y Fs(Let)27 b(us)e(lo)s(ok)h
+(at)g(the)h(sp)s(eci\014cation)e(for)g(the)i Fn(\\tabular)c
+Fs(en)m(vironmen)m(t)j(\014rst.)39 b(The)25 b Fh(END)p
+3282 3249 27 4 v 30 w(TAG=)g Fs(action)150 3362 y(is)i(sp)s(eci\014ed)f
+(b)m(y)i(the)g(single)f(command)g(line)g Fh(SET)p 1850
+3362 V 30 w(MODE:)f(tabular)p Fs(,)f(where)j Fh(tabular)d
+Fs(is)i(an)m(y)h(con)m(v)m(enien)m(t)150 3475 y(name)g(for)f(iden)m
+(tifying)f(a)i(mo)s(de.)39 b(Th)m(us,)28 b(this)f(will)e(set)j(the)g
+(mo)s(de)f(to)i(b)s(e)e Fh(tabular)p Fs(.)37 b(The)27
+b(action)h(at)h(the)150 3588 y(end)34 b(of)h(the)g(en)m(vironmen)m(t)f
+(is)g(to)i(reset)f(the)g(mo)s(de)f(\()p Fh(RESET)p 2226
+3588 V 30 w(MODE:)p Fs(\))f(to)i(whatev)m(er)h(its)e(previous)f(v)-5
+b(alue)150 3701 y(w)m(as.)41 b(It)28 b(is)g(assumed)g(that)h(the)g
+(last)f(ro)m(w)h(in)e(an)m(y)i Fn(tabular)e Fs(en)m(vironmen)m(t)h(is)g
+(\014nished)e(b)m(y)i Fn(\\\\)p Fs(.)40 b(Similar)150
+3814 y(actions)d(are)g(p)s(erformed)e(for)i(the)g Fn(eqnarray)e
+Fs(en)m(vironmen)m(t,)j(except)g(that)f(the)g(mo)s(de)f(is)g(called)g
+Fh(eqn)150 3927 y Fs(instead)27 b(of)34 b Fh(tabular)p
+Fs(.)j(The)27 b(other)h(di\013erence)f(is)f(that)i(it)f(is)g(assumed)g
+(that)h(the)g(last)f(ro)m(w)g(is)g(not)h(ended)150 4040
+y(b)m(y)i Fn(\\\\)p Fs(,)g(so)h(the)f(end)g(of)h(the)f
+Fn(eqnarray)e Fs(en)m(vironmen)m(t)i(has)g(to)i(also)e(act)h(lik)m(e)f
+(the)h Fn(\\\\)p Fs(.)291 4152 y(T)-8 b(urning)31 b(no)m(w)i(to)g(the)g
+(sp)s(eci\014cation)f(for)g(the)h Fn(&)g Fs(command,)g(the)g(\014rst)f
+(part)h(of)g(the)g(sp)s(eci\014cation)150 4265 y(iden)m(ti\014es)h(the)
+h(t)m(yp)s(e)g(and)g(name)g(of)g(the)g(L)1629 4249 y
+Fr(A)1668 4265 y Fs(T)1719 4285 y(E)1770 4265 y(X)g(command.)55
+b(This)33 b(is)h(then)h(follo)m(w)m(ed)g(b)m(y)g(the)g(mo)s(de-)150
+4378 y(indep)s(enden)m(t)29 b(set)k(of)e(actions,)i(whic)m(h)d(in)h
+(this)f(case)j(consists)e(of)h(prin)m(ting)d(a)j(v)m(ertical)g(bar)f
+(with)g(some)150 4491 y(spaces)42 b(on)g(either)f(side)f(of)i(it.)74
+b(F)-8 b(ollo)m(wing)42 b(these)g(are)g(an)m(y)g(mo)s(de-dep)s(enden)m
+(t)e(actions,)45 b(brac)m(k)m(eted)150 4604 y(b)s(et)m(w)m(een)35
+b Fh(IN)p 598 4604 V 30 w(MODE=)e Fs(and)g Fh(END)p 1193
+4604 V 30 w(MODE)p Fs(.)g(The)h(v)-5 b(alue)34 b(for)g
+Fh(IN)p 2118 4604 V 30 w(MODE=)e Fs(is)h(the)i(name)f(of)h(the)f(relev)
+m(en)m(t)h(mo)s(de.)150 4717 y(In)c(this)h(case)h(the)f(only)f(mo)s
+(de-dep)s(enden)m(t)h(action)g(o)s(ccurs)g(when)f Fh(MODE)42
+b(eqn)31 b Fs(is)g(in)g(e\013ect)j(and)d(it)h(is)f(to)150
+4830 y(prin)m(t)e(some)i(spaces)g(instead)e(of)i(the)f(default)g
+(spaces)h(and)e(v)m(ertical)i(bar.)291 4943 y(The)g(sp)s(eci\014cation)
+g(for)g(the)h Fn(\\\\)f Fs(command)g(has)g(its)g(set)i(of)e(mo)s
+(de-indep)s(enden)m(t)f(default)g(actions,)150 5056 y(namely)c(just)g
+(to)i(prin)m(t)e(a)h(newline,)f(and)g(t)m(w)m(o)i(sets)f(of)h(mo)s
+(de-dep)s(enden)m(t)d(actions.)40 b(When)27 b(the)g Fh(tabular)150
+5169 y Fs(mo)s(de)d(is)g(in)f(e\013ect,)k(it)d(prin)m(ts)f(some)i
+(spaces,)h(a)f(v)m(ertical)g(bar,)g(a)g(newline,)f(more)g(spaces,)j(a)e
+(v)m(ertical)f(bar,)150 5282 y(and)30 b(\014nally)e(some)i(more)g
+(spaces.)41 b(On)30 b(the)g(other)g(hand,)g(when)f(the)h
+Fh(eqn)f Fs(mo)s(de)h(is)f(in)g(e\013ect,)j(it)d(prin)m(ts)1905
+5531 y(19)p eop
+%%Page: 20 24
+20 23 bop 1115 628 a Fs(T)-8 b(able)30 b(1:)41 b(A)30
+b(simple)f(table)h(t)m(yp)s(eset)h(b)m(y)f(L)2551 611
+y Fr(A)2590 628 y Fs(T)2641 647 y(E)2692 628 y(X.)p 1269
+659 1363 4 v 1267 772 4 113 v 1319 738 a(Sto)s(c)m(k)p
+1587 772 V 1604 772 V 228 w(1994)p 2108 772 V 2125 772
+V 342 w(1995)p 2629 772 V 1605 775 1027 4 v 1267 885
+4 113 v 1587 885 V 1604 885 V 1655 851 a(lo)m(w)p 1837
+885 V 99 w(high)p 2108 885 V 2125 885 V 115 w(lo)m(w)p
+2358 885 V 100 w(high)p 2629 885 V 1269 888 1363 4 v
+1267 1001 4 113 v 1319 967 a(ABC)p 1587 1001 V 1604 1001
+V 181 w(27)p 1837 1001 V 181 w(36)p 2108 1001 V 2125
+1001 V 160 w(23)p 2358 1001 V 181 w(45)p 2629 1001 V
+1267 1114 V 1319 1080 a(DEF)p 1587 1114 V 1604 1114 V
+189 w(53)p 1837 1114 V 181 w(72)p 2108 1114 V 2125 1114
+V 160 w(19)p 2358 1114 V 181 w(54)p 2629 1114 V 1267
+1227 V 1319 1193 a(GHI)p 1587 1227 V 1604 1227 V 207
+w(28)p 1837 1227 V 181 w(49)p 2108 1227 V 2125 1227 V
+160 w(17)p 2358 1227 V 181 w(79)p 2629 1227 V 1269 1230
+1363 4 v 150 1487 a(some)e(spaces,)h(the)f(string)e(`\(X\)')j(and)e(a)h
+(newline.)38 b(If)27 b(a)h(mo)s(de)f(is)g(in)f(e\013ect)j(that)g(is)d
+(not)i(de\014ned)e(within)150 1600 y(the)31 b(sp)s(eci\014cation)e
+(\(e.g.,)j(mo)s(de)e Fh(anon)p Fs(\))f(it)h(p)s(erforms)f(the)h
+(default)g(mo)s(de-indep)s(enden)m(t)e(actions.)291 1713
+y(As)36 b(a)h(p)s(erhaps)d(more)i(practical)g(example,)i(the)e(follo)m
+(wing)f(command)g(table)i(co)s(de)f(will)d(con)m(v)m(ert)150
+1826 y(simple)19 b(L)448 1809 y Fr(A)487 1826 y Fs(T)538
+1846 y(E)589 1826 y(X)i Fn(tabular)e Fs(en)m(vironmen)m(ts)i(to)h
+(appropriate)e(mark-up)g(for)h(HTML)h(tables.)37 b(It)21
+b(is)g(assumed)150 1939 y(that)31 b(the)g Fn(tabular)d
+Fs(en)m(vironmen)m(t)i(is)f(alw)m(a)m(ys)i(within)d(a)j
+Fn(table)e Fs(en)m(vironmen)m(t.)291 2039 y(T)-8 b(o)31
+b(set)g(the)f(p)s(ersp)s(ectiv)m(e)g(a)h(little,)e(here)h(is)g(the)g
+(co)s(de)h(for)f(a)h(simple)d(table)i(in)g(L)3028 2022
+y Fr(A)3067 2039 y Fs(T)3118 2058 y(E)3168 2039 y(X:)150
+2213 y Fh(\\begin{table}[tb)o(p])150 2313 y(\\centering)150
+2412 y(\\caption{A)39 b(simple)j(table)f(typeset)g(by)i(\\LaTeX.})d
+(\\label{tab:lxtab)o(})150 2512 y(\\begin{tabular}{)o(|l|)o(|r)o(|r)o
+(||r)o(|r)o(|})d(\\hline)150 2612 y(Stock)42 b(&)h(\\multicolumn{2})o
+({c|)o(|})o({19)o(94)o(})38 b(&)43 b(\\multicolumn{2})o({c|)o(}{)o(199)
+o(5})37 b(\\\\)43 b(\\cline{2-5})412 2711 y(&)86 b(low)173
+b(&)87 b(high)f(&)130 b(low)86 b(&)43 b(high)86 b(\\\\)42
+b(\\hline)150 2811 y(ABC)130 b(&)86 b(27)217 b(&)87 b(36)174
+b(&)130 b(23)g(&)43 b(45)217 b(\\\\)150 2910 y(DEF)130
+b(&)86 b(53)217 b(&)87 b(72)174 b(&)130 b(19)g(&)43 b(54)217
+b(\\\\)150 3010 y(GHI)130 b(&)86 b(28)217 b(&)87 b(49)174
+b(&)130 b(17)g(&)43 b(79)217 b(\\\\)43 b(\\hline)150
+3110 y(\\end{tabular})150 3209 y(\\end{table})150 3397
+y Fs(This)29 b(will)e(b)s(e)j(t)m(yp)s(eset)h(as)g(sho)m(wn)f(in)f
+(table)h(1.)291 3497 y(The)g(corresp)s(onding)e(HTML)j(co)s(de)f(for)g
+(the)h(table)f(after)h(translation)e(is:)150 3671 y Fh
+(<p><center><tabl)o(e)38 b(border>)150 3771 y(<caption>A)h(simple)j
+(table)f(typeset)g(by)i(LaTeX.</caption)o(>)37 b(<a)43
+b(name="tab:lxtab">)o(</)o(a>)150 3970 y(<tr><td>)d(Stock)i(</td><td)e
+(colspan=2>)g(1994)h(</td><td)g(colspan=2>)e(1995)j(</tr>)150
+4069 y(<tr><td)f(>)455 4169 y(</td><td)f(>)k(low)e(</td><td)e(>)j(high)
+f(</td><td)f(>)i(low)f(</td><td)e(>)k(high)d(</tr>)150
+4269 y(<tr><td)g(>)i(ABC)f(</td><td)e(>)k(27)e(</td><td)f(>)i(36)g
+(</td><td)d(>)j(23)g(</td><td)d(>)j(45)g(</tr>)150 4368
+y(<tr><td)e(>)150 4468 y(DEF)h(</td><td)f(>)i(53)g(</td><td)d(>)j(72)g
+(</td><td)d(>)j(19)g(</td><td)d(>)j(54)g(</tr>)150 4568
+y(<tr><td)e(>)150 4667 y(GHI)h(</td><td)f(>)i(28)g(</td><td)d(>)j(49)g
+(</td><td)d(>)j(17)g(</td><td)d(>)j(79)g(</tr>)150 4767
+y(<tr><td)e(>)150 4866 y(</table></center)o(>)291 5054
+y Fs(In)30 b(the)g(HTML)h(bro)m(wser)f(that)g(I)h(use)f(this)f(is)g
+(displa)m(y)m(ed)g(appro)m(ximately)h(as)h(sho)m(wn)e(for)i(table)f(2.)
+291 5167 y(In)d(HTML)g(a)h(table)g(is)f(enclosed)g(b)s(et)m(w)m(een)h
+Fh(<table>)d Fs(and)i Fh(</table>)d Fs(tags.)41 b(Eac)m(h)28
+b(ro)m(w)g(of)f(the)h(table)150 5280 y(is)36 b(enclosed)h(b)s(et)m(w)m
+(een)h Fh(<tr>)e Fs(and)h Fh(</tr>)e Fs(tags,)40 b(and)d(eac)m(h)i
+(elemen)m(t)f(in)e(a)h(ro)m(w)h(is)e(enclosed)h(b)s(et)m(w)m(een)1905
+5531 y(20)p eop
+%%Page: 21 25
+21 24 bop 764 628 a Fs(T)-8 b(able)30 b(2:)41 b(A)31
+b(simple)d(table)i(t)m(yp)s(eset)h(after)g(translation)f(to)h(HTML.)p
+1269 657 1363 4 v 1269 674 V 1267 786 4 113 v 1284 786
+V 1335 753 a(Sto)s(c)m(k)p 1603 786 V 101 w(1994)p 2091
+786 V 2108 786 V 324 w(1995)p 2629 786 V 1269 790 1363
+4 v 1267 903 4 113 v 1284 903 V 1603 903 V 1655 869 a(lo)m(w)p
+1837 903 V 99 w(high)p 2108 903 V 98 w(lo)m(w)p 2341
+903 V 100 w(high)p 2613 903 V 2630 903 V 1269 906 1363
+4 v 1267 1019 4 113 v 1284 1019 V 1335 985 a(ABC)p 1603
+1019 V 122 w(27)p 1837 1019 V 143 w(36)p 2108 1019 V
+181 w(23)p 2341 1019 V 144 w(45)p 2613 1019 V 2630 1019
+V 1267 1132 V 1284 1132 V 1335 1098 a(DEF)p 1603 1132
+V 130 w(53)p 1837 1132 V 143 w(72)p 2108 1132 V 181 w(19)p
+2341 1132 V 144 w(54)p 2613 1132 V 2630 1132 V 1267 1245
+V 1284 1245 V 1335 1211 a(GHI)p 1603 1245 V 148 w(28)p
+1837 1245 V 143 w(49)p 2108 1245 V 181 w(17)p 2341 1245
+V 144 w(79)p 2613 1245 V 2630 1245 V 1269 1248 1363 4
+v 1269 1265 V 150 1522 a Fh(<td>)f Fs(and)i Fh(</td>)e
+Fs(tags.)47 b(Under)31 b(certain)h(circumstances)f(the)i(closing)e
+(tags)i(\(i.e.,)g(those)g(lik)m(e)e Fh(</...>)p Fs(\))150
+1635 y(can)d(b)s(e)e(inferred)f(b)m(y)i(the)h(HTML)f(pro)s(cesors)g
+(and)f(need)h(not)h(b)s(e)e(explicitly)f(put)i(in)m(to)g(the)g(source)h
+(text.)150 1748 y(The)i(equiv)-5 b(alen)m(t)30 b(HTML)g(tags)h(to)h(a)e
+(L)1476 1731 y Fr(A)1515 1748 y Fs(T)1566 1767 y(E)1617
+1748 y(X)g Fn(\\multicolumn{num}{col}{te)o(xt})24 b Fs(command)30
+b(are)150 1861 y Fh(<td)42 b(colspan=num>)d(text)j(</td>)p
+Fs(.)291 1974 y(The)24 b(general)g(actions)h(that)g Fy(L)-7
+b(TX2X)24 b Fs(has)g(to)i(p)s(erform)d(in)g(doing)g(the)i(L)2684
+1957 y Fr(A)2723 1974 y Fs(T)2774 1993 y(E)2824 1974
+y(X)g(to)g(HTML)f(translation)150 2087 y(are:)286 2274
+y Fm(\017)46 b Fs(The)34 b(start)h(and)f(end)f(of)i(a)f
+Fn(table)f Fs(en)m(vironmen)m(t)h(has)g(to)h(translate)g(to)g(the)f
+(HTML)h(start)g(and)377 2387 y(end)24 b(table)f(tags)j
+Fh(<table>)21 b Fs(and)i Fh(</table>)p Fs(.)35 b(\(Actually)24
+b(this)f(also)h(needs)f(to)i(handle)d(the)j(cen)m(tering)377
+2500 y(of)31 b(the)f(HTML)h(table)f(and)g(dra)m(wing)f(a)i(b)s(order)e
+(round)f(it)i(as)h(w)m(ell.\))286 2688 y Fm(\017)46 b
+Fs(The)e(start)h(and)f(end)g(of)g(the)h Fn(tabular)e
+Fs(en)m(vironmen)m(t)h(has)g(to)h(translate)g(in)m(to)f(a)h(ro)m(w)f
+(start)377 2801 y Fh(<tr><td>)c Fs(and)j(end)f Fh(</tr>)g
+Fs(in)f(the)j(HTML)f(table)g(\(and)g(set)h(the)g(mo)s(de)e(for)h(the)h
+(L)3403 2784 y Fr(A)3442 2801 y Fs(T)3493 2820 y(E)3543
+2801 y(X)g Fn(\\\\)377 2914 y Fs(command\).)286 3101
+y Fm(\017)i Fs(The)f Fn(\\\\)f Fs(command)g(m)m(ust)h(end)f(one)h(ro)m
+(w)g(of)g(the)g(HTML)g(table)f(and)h(start)g(the)g(next)g(ro)m(w)377
+3214 y(\()p Fh(</tr>?n<tr><td>)p Fs(\).)36 b(It)31 b(need)f(not)h(end)e
+(a)i(data)h(elemen)m(t)f(as)f(this)g(is)f(automatically)i(closed)f(b)m
+(y)377 3327 y(the)h(end)f(of)g(the)h(ro)m(w.)286 3515
+y Fm(\017)46 b Fs(The)39 b Fn(&)g Fs(column)f(delimeter)g(m)m(ust)h
+(end)g(one)g(HTML)g(data)h(elemen)m(t)g(and)e(start)i(another)g(one)377
+3628 y(\(i.e.,)31 b Fh(</td><td>)p Fs(\).)286 3815 y
+Fm(\017)46 b Fs(The)28 b(di\016cult)m(y)f(is)g(in)g(handling)f(the)j
+Fn(\\multicolumn)c Fs(command.)39 b(In)28 b(the)h(easy)g(case)g(the)f
+(L)3541 3798 y Fr(A)3580 3815 y Fs(T)3631 3835 y(E)3682
+3815 y(X)377 3928 y(to)j(HTML)g(translation)e(is:)377
+4041 y Fh(...)86 b(&)43 b(text)f(&)h(...)d Fs(maps)30
+b(to)377 4154 y Fh(...)86 b(</td><td>)40 b(text)i(</td><td>)e(...)p
+Fs(.)377 4267 y(Ho)m(w)m(ev)m(er,)33 b(when)c(a)i(m)m(ulticolumn)d(is)h
+(in)m(v)m(olv)m(ed)h(the)h(translation)e(is)377 4380
+y Fn(...)47 b(&)h(\\multicolumn{N}{P}{text)o(})42 b(&)47
+b(...)30 b Fs(maps)g(to)377 4493 y Fh(...)86 b(</td><td)40
+b(colspan=N>)g(text)i(</td><td>)e(...)p Fs(.)377 4606
+y(As)22 b(there)g(is)e(no)i(lo)s(ok-ahead)g(in)e Fy(L)-7
+b(TX2X)21 b Fs(w)m(e)h(ha)m(v)m(e)h(to)g(b)s(e)e(careful)f(ab)s(out)i
+(starting)f(a)h(data)g(elemen)m(t)377 4718 y(after)32
+b(a)g Fn(&)f Fs(b)s(ecause)h(at)g(that)g(p)s(oin)m(t)e
+Fy(L)-7 b(TX2X)32 b Fs(cannot)g(kno)m(w)f(whether)g(or)h(not)f(a)h
+Fn(\\multicolumn)377 4831 y Fs(command)e(comes)i(next,)e(or)h(just)f
+(an)g(ordinary)e(data)k(elemen)m(t.)291 5019 y(W)-8 b(e)30
+b(solv)m(e)e(this)f(last)h(problem)f(partly)g(b)m(y)i(using)d
+(bu\013ers)h(\(n)m(um)m(b)s(ers)h Fh(8)f Fs(and)h Fh(9)g
+Fs(in)f(the)h(sp)s(eci\014cation)150 5132 y(b)s(elo)m(w\))39
+b(as)g(temp)s(orary)g(storage,)k(and)38 b(partly)h(b)m(y)g(a)g(subtle)f
+(sp)s(eci\014cation)g(for)h(the)g Fn(\\multicolumn)150
+5245 y Fs(command.)1905 5531 y(21)p eop
+%%Page: 22 26
+22 25 bop 150 573 a Fh(C=)130 b(start)41 b(of)i(a)g(table)150
+672 y(TYPE=)f(BEGIN_ENV)150 772 y(NAME=)g(table)237 872
+y(START_TAG=)e("<center><table)d(border>")237 971 y(OPT_PARAM=)j(FIRST)
+237 1071 y(C=)87 b(ignore)41 b(the)h(optional)e(positioning)f(argument)
+237 1171 y(PRINT_OPT=)h(NO_PRINT)150 1270 y(END_TYPE)150
+1469 y(C=)86 b(end)43 b(a)g(table)150 1569 y(TYPE=)f(END_ENV)150
+1669 y(NAME=)g(table)237 1768 y(START_TAG=)e("</table></cent)o(er>)o(")
+150 1868 y(END_TYPE)150 2067 y(C=)86 b(start)42 b(a)h(tabular)150
+2167 y(TYPE=)f(BEGIN_ENV)150 2267 y(NAME=)g(tabular)237
+2366 y(START_TAG=)e("?n<tr><td")324 2466 y(RESET_BUFFER:)f(8)324
+2565 y(RESET_BUFFER:)g(9)237 2665 y(OPT_PARAM=)h(FIRST)237
+2765 y(C=)87 b(ignore)41 b(the)h(optional)e(positioning)f(argument)237
+2864 y(PRINT_OPT=)h(NO_PRINT)237 2964 y(REQPARAMS=)g(1)237
+3064 y(C=)87 b(ignore)41 b(the)h(column)f(specification)237
+3163 y(PRINT_P1=)f(NO_OP)237 3263 y(END_TAG=)324 3362
+y(SET_MODE:)g(tabular)237 3462 y(PC_AT_END=)g(TO_BUFFER)f(9)150
+3562 y(END_TYPE)150 3761 y(C=)86 b(end)43 b(a)g(tabular)150
+3861 y(TYPE=)f(END_ENV)150 3960 y(NAME=)g(tabular)237
+4060 y(PC_AT_START=)d(RESET)237 4159 y(START_TAG=)h(">")324
+4259 y(RESET_BUFFER:)f(8)324 4359 y(RESET_BUFFER:)g(9)324
+4458 y(RESET_MODE:)150 4558 y(END_TYPE)150 4757 y(C=)86
+b(we)43 b(can)f(do)h(some)f(processing)e(of)i(the)h(\\mutlicolumn)38
+b(command)150 4857 y(TYPE=)k(COMMAND)150 4956 y(NAME=)g(\\multicolumn)
+237 5056 y(PC_AT_START=)d(TO_BUFFER)h(8)237 5156 y(REQPARAMS=)g(2)237
+5255 y(START_TAG_1=)f(")k(colspan=")1905 5531 y Fs(22)p
+eop
+%%Page: 23 27
+23 26 bop 237 573 a Fh(PRINT_P2=)40 b(NO_PRINT)237 672
+y(PC_AT_END=)g(RESET)150 772 y(END_TYPE)150 971 y(C=)86
+b(now)43 b(for)f(the)g(end/start)e(of)j(a)g(row)150 1071
+y(TYPE=)f(CHAR_COMMAND)150 1171 y(NAME=)g(\\\\)237 1270
+y(START_TAG=)e("<br>")150 1370 y(IN_MODE=)g(tabular)237
+1469 y(PC_AT_START=)f(RESET)237 1569 y(START_TAG=)324
+1669 y(SOURCE:)i(BUFFER)g(8)324 1768 y(STRING:)g(">)i(")324
+1868 y(RESET_BUFFER:)c(8)324 1968 y(SOURCE:)i(BUFFER)g(9)237
+2067 y(END_TAG=)f("</tr>?n<tr><td)e(")324 2167 y(RESET_BUFFER:)h(9)237
+2267 y(PC_AT_END=)h(TO_BUFFER)f(9)150 2366 y(END_MODE)150
+2466 y(END_TYPE)150 2665 y(C=)k(and)f(the)g(column)g(seperator)150
+2765 y(TYPE=)g(TEX_CHAR)150 2864 y(NAME=)g(&)237 2964
+y(PC_AT_START=)d(RESET)237 3064 y(START_TAG=)324 3163
+y(SOURCE:)i(BUFFER)g(8)324 3263 y(STRING:)g(">)i(")324
+3362 y(RESET_BUFFER:)c(8)324 3462 y(SOURCE:)i(BUFFER)g(9)237
+3562 y(END_TAG=)f(")k(</td><td)c(")324 3661 y(RESET_BUFFER:)f(9)237
+3761 y(PC_AT_END=)h(TO_BUFFER)f(9)150 3861 y(END_TYPE)291
+4073 y Fs(Regarding)29 b(the)h Fn(\\multicolumn)d Fs(sp)s
+(eci\014cation,)h(w)m(e)j(state)g(that)f(as)g(far)f(as)h
+Fy(L)-7 b(TX2X)30 b Fs(is)f(concerned,)150 4186 y(it)c(only)g(has)g(t)m
+(w)m(o)i(required)d(parameters,)j(and)e(that)h(the)g(action)g(for)f
+(the)h(second)g(one)g(is)e Fh(NO)p 3299 4186 27 4 v 31
+w(PRINT)p Fs(.)f(The)150 4299 y(\014rst)30 b(argumen)m(t)h(is)f
+(written)g(to)h(bu\013er)f Fh(8)g Fs(after)h(`colspan=')g(has)f
+(\014rst)g(b)s(een)g(put)g(in)m(to)h(it.)41 b Fy(L)-7
+b(TX2X)31 b Fs(will)150 4412 y(treat)g(the)g(actual)f(third)f(argumen)m
+(t)i(to)g(the)f Fn(\\multicolumn)d Fs(as)k(ordinary)d(text,)k(just)d
+(as)i(if)e(there)i(w)m(as)150 4525 y(no)23 b Fn(\\multicolumn)c
+Fs(in)j(the)h(L)1136 4508 y Fr(A)1175 4525 y Fs(T)1226
+4544 y(E)1276 4525 y(X)g(source.)39 b(W)-8 b(e)24 b(use)e(bu\013er)g
+Fh(9)g Fs(for)h(storing)f(the)h(text)h(of)f(a)h(data)f(elemen)m(t.)150
+4638 y(When)33 b Fy(L)-7 b(TX2X)34 b Fs(pro)s(cesses)f(a)h
+Fh(&)f Fs(column)f(delimeter)g(it)h(\014rst)g(outputs)g(the)g(con)m
+(ten)m(ts)i(of)f(bu\013er)e Fh(8)h Fs(\(the)150 4751
+y(n)m(um)m(b)s(er)c(of)i(columns)e(sp)s(eci\014cation\))h(and)g(then)g
+(appropriate)g(HTML)g(c)m(haracters.)43 b(It)30 b(then)g(outputs)150
+4863 y(the)h(con)m(ten)m(ts)h(of)f(bu\013er)f Fh(9)g
+Fs(\(the)h(elemen)m(t)h(text\),)g(\014nishes)d(o\013)i(the)g(elemen)m
+(t)g(and)f(partially)f(starts)i(the)150 4976 y(next)k(elemen)m(t.)54
+b(Similar)32 b(actions)j(are)g(p)s(erformed)e(at)j(the)e(start)i(of)f
+(the)f Fh(tabular)e Fs(en)m(vironmen)m(t)j(and)150 5089
+y(at)c(the)g(end)e(of)i(eac)m(h)g(ro)m(w)g(in)e(the)i(table.)1905
+5531 y(23)p eop
+%%Page: 24 28
+24 27 bop 150 573 a Fj(2.5)112 b(Sectioning)36 b(command)h(t)m(yp)s(es)
+150 744 y Fy(L)-7 b(TX2X)26 b Fs(do)s(es)f(some)i(particular)d(pro)s
+(cessing)g(for)i(sectioning)f(command)h(t)m(yp)s(es.)39
+b(Although)25 b(L)3379 728 y Fr(A)3418 744 y Fs(T)3469
+764 y(E)3520 744 y(X)h(can)150 857 y(determine)31 b(where)h(an)m(y)g
+(section)h(of)f(a)g(do)s(cumen)m(t)g(ends,)g(other)h(tagging)g(systems)
+f(cannot)g(alw)m(a)m(ys)h(do)150 970 y(this.)39 b(They)27
+b(require)g(b)s(oth)g(a)h(`b)s(egin)f(section')h(and)f(an)h(`end)g
+(section')g(tag.)41 b Fy(L)-7 b(TX2X)28 b Fs(can)g(tak)m(e)h(accoun)m
+(t)150 1083 y(of)f(the)g(nesting)f(depth)g(of)h(do)s(cumen)m(t)g
+(sections)f(and,)h(giv)m(en)g(appropriate)f(sp)s(eci\014cations,)g(can)
+h(supply)150 1196 y(b)s(oth)i(`b)s(egin)g(section')i(and)f(`end)f
+(section')i(tags)g(appropriately)-8 b(.)42 b(This)29
+b(requires)h(a)i(little)e(bit)g(more)h(in)150 1309 y(the)g(w)m(a)m(y)g
+(of)f(sp)s(eci\014cations)f(than)i(w)m(e)f(ha)m(v)m(e)i(met)f(so)f
+(far.)291 1422 y(F)-8 b(or)24 b(a)g Fh(SECTIONING)c Fs(command)j(t)m
+(yp)s(e,)i(the)f(command)f(line)f Fh(SECTIONING)p 2774
+1422 27 4 v 27 w(LEVEL=)f Fs(m)m(ust)j(b)s(e)f(included)150
+1535 y(within)28 b(the)i(sp)s(eci\014cation.)40 b(The)30
+b(v)-5 b(alue)30 b(of)g(this)f(command)i(is)e(a)i(k)m(eyw)m(ord)g(from)
+f(the)g(follo)m(wing)f(list.)150 1722 y Fh(PART)44 b
+Fs(F)-8 b(or)31 b(a)g(sectioning)e(command)i(equiv)-5
+b(alen)m(t)29 b(to)j(the)e(L)2171 1706 y Fr(A)2210 1722
+y Fs(T)2261 1742 y(E)2311 1722 y(X)h Fn(\\part)e Fs(command.)150
+1910 y Fh(CHAPTER)43 b Fs(F)-8 b(or)31 b(a)f(sectioning)g(command)g
+(equiv)-5 b(alen)m(t)30 b(to)h(the)g(L)2302 1893 y Fr(A)2341
+1910 y Fs(T)2392 1930 y(E)2442 1910 y(X)g Fn(\\chapter)d
+Fs(command.)150 2098 y Fh(SECT)44 b Fs(F)-8 b(or)31 b(a)g(sectioning)e
+(command)i(equiv)-5 b(alen)m(t)29 b(to)j(the)e(L)2171
+2081 y Fr(A)2210 2098 y Fs(T)2261 2117 y(E)2311 2098
+y(X)h Fn(\\section)d Fs(command.)150 2285 y Fh(SUBSECT)43
+b Fs(F)-8 b(or)31 b(a)f(sectioning)g(command)g(equiv)-5
+b(alen)m(t)30 b(to)h(the)g(L)2302 2269 y Fr(A)2341 2285
+y Fs(T)2392 2305 y(E)2442 2285 y(X)g Fn(\\subsection)c
+Fs(command.)150 2473 y Fh(SUBSUBSECT)41 b Fs(F)-8 b(or)28
+b(a)g(sectioning)e(command)h(equiv)-5 b(alen)m(t)27 b(to)h(the)f(L)2410
+2456 y Fr(A)2449 2473 y Fs(T)2500 2493 y(E)2550 2473
+y(X)h Fn(\\subsubsection)23 b Fs(command.)150 2661 y
+Fh(PARA)44 b Fs(F)-8 b(or)31 b(a)g(sectioning)e(command)i(equiv)-5
+b(alen)m(t)29 b(to)j(the)e(L)2171 2644 y Fr(A)2210 2661
+y Fs(T)2261 2680 y(E)2311 2661 y(X)h Fn(\\paragraph)c
+Fs(command.)150 2848 y Fh(SUBPARA)43 b Fs(F)-8 b(or)31
+b(a)f(sectioning)g(command)g(equiv)-5 b(alen)m(t)30 b(to)h(the)g(L)2302
+2832 y Fr(A)2341 2848 y Fs(T)2392 2868 y(E)2442 2848
+y(X)g Fn(\\subparagraph)26 b Fs(command.)291 3036 y(When)j(a)g
+(sectioning)f(command)g(is)g(read)h(from)f(the)h(L)2147
+3019 y Fr(A)2186 3036 y Fs(T)2237 3055 y(E)2287 3036
+y(X)g(source,)h Fy(L)-7 b(TX2X)28 b Fs(\014rstly)g(p)s(erforms)f(the)
+150 3149 y Fh(END)p 287 3149 V 30 w(TAG=)k Fs(actions)h(for)g(an)m(y)g
+(`lo)m(w)m(er)h(lev)m(el')f(sections)g(that)h(this)e(one)h(is)f
+(closing)g(o\013.)47 b(It)32 b(then)g(p)s(erforms)150
+3262 y(the)38 b Fh(START)p 539 3262 V 29 w(TAG=)e Fs(actions)h(for)h
+(the)f(curren)m(t)g(command,)j(and)c(stores)i(its)f(o)m(wn)h
+Fh(END)p 3089 3262 V 30 w(TAG=)e Fs(actions)h(for)150
+3375 y(later)27 b(use.)39 b(It)28 b(then)e(go)s(es)i(on)f(and)g(pro)s
+(cess)f(an)m(y)i(argumen)m(ts)f(as)h(usual.)38 b(The)26
+b Fh(END)p 2965 3375 V 30 w(DOCUMENT)e Fs(command)150
+3488 y(automatically)30 b(closes)h(o\013)g(an)m(y)f(op)s(ened)g
+(sections.)291 3600 y(As)i(an)g(example,)h(assume)f(that)h(some)f(kind)
+f(soul)g(has)h(supplied)c(a)33 b(L)2705 3584 y Fr(A)2744
+3600 y Fs(T)2795 3620 y(E)2845 3600 y(X)g(st)m(yle)f(\014le)f(that)i
+(mak)m(es)150 3713 y(the)j(commands)f Fn(\\clause)f Fs(synon)m(ymous)h
+(with)f Fn(\\subsection)p Fs(,)g(and)h Fn(\\sclause)e
+Fs(synon)m(ymous)i(with)150 3826 y Fn(\\subsubsection)p
+Fs(,)30 b(etc.)49 b(Also)32 b(assume)h(that)g(it)g(is)e(required)g(to)j
+(output)e(start)i(and)e(end)g(tags)i(of)f(the)150 3939
+y(form)24 b Fh(<div.1>)e Fs(and)h Fh(</div.1>)f Fs(for)i(sections,)i
+Fh(<div.2>)21 b Fs(for)k(clauses,)g(etc.,)i(and)d(surround)e(the)j
+(headings)150 4052 y(with)31 b(tags)h Fh(<heading>)c
+Fs(and)k Fh(</heading>)p Fs(.)41 b(F)-8 b(urther,)32
+b(the)g(\014rst)f(optional)g(argumen)m(t)h(is)f(of)h(no)g(in)m(terest)
+150 4165 y(as)k(the)f(output)g(is)g(going)g(to)i(b)s(e)d(used)h(b)m(y)g
+(a)h(pro)s(cessing)e(system)i(unable)e(to)i(automatically)f(handle)150
+4278 y(tables)30 b(of)h(con)m(ten)m(ts.)42 b(P)m(art)31
+b(of)g(an)f(appropriate)f(command)i(table)f(for)g(doing)f(this)h(is:)
+150 4477 y Fh(TYPE=)42 b(SECTIONING)150 4577 y(NAME=)g(\\section)237
+4676 y(SECTIONING_LEVEL=)37 b(SECT)237 4776 y(START_TAG=)j
+("?n?n<div.1>?n")237 4876 y(END_TAG=)g("?n</div.1>")237
+4975 y(OPT_PARAM=)g(FIRST)237 5075 y(PRINT_OPT=)g(NO_PRINT)237
+5175 y(REQPARAMS=)g(1)237 5274 y(START_TAG_1=)f("<heading>")1905
+5531 y Fs(24)p eop
+%%Page: 25 29
+25 28 bop 237 573 a Fh(END_TAG_1=)40 b("</heading>?n")150
+672 y(END_TYPE)150 872 y(TYPE=)i(SECTIONING)150 971 y(NAME=)g(\\clause)
+237 1071 y(SECTIONING_LEVEL=)37 b(SUBSECT)237 1171 y(START_TAG=)j
+("?n?n<div.2>?n")237 1270 y(END_TAG=)g("?n</div.2>")237
+1370 y(OPT_PARAM=)g(FIRST)237 1469 y(PRINT_OPT=)g(NO_PRINT)237
+1569 y(REQPARAMS=)g(1)237 1669 y(START_TAG_1=)f("<heading>")237
+1768 y(END_TAG_1=)h("</heading>?n")150 1868 y(END_TYPE)291
+2064 y Fs(An)35 b(example)g(output)g(resulting)f(from)h(this)f(command)
+h(table)h(\(if)e(it)h(had)g(b)s(een)g(applied)e(to)j(this)150
+2164 y(do)s(cumen)m(t\))31 b(is:)150 2336 y Fh(...)150
+2436 y(</div.2>)150 2535 y(</div.1>)150 2734 y(<div.1>)150
+2834 y(<heading>The)39 b(command)h(table)i(file</heading>)324
+3033 y(By)h(default,)d(...)150 3276 y Fj(2.6)112 b(List)37
+b(en)m(vironmen)m(t)f(t)m(yp)s(es)150 3448 y Fs(In)h(L)295
+3431 y Fr(A)334 3448 y Fs(T)385 3467 y(E)436 3448 y(X)h(the)h(use)f(of)
+g(the)g Fn(\\item)f Fs(command)h(is)f(restricted)h(to)h(within)d(a)j
+(list)e(en)m(vironmen)m(t.)63 b(The)150 3561 y(t)m(yp)s(eset)33
+b(app)s(earance)g(of)f(an)g Fn(\\item)f Fs(t)m(ypically)g(dep)s(ends)g
+(on)h(the)h(particular)d(en)m(vironmen)m(t)i(in)f(whic)m(h)150
+3674 y(it)k(is)f(used.)54 b Fy(L)-7 b(TX2X)35 b Fs(has)g(a)h(limited)d
+(capabilit)m(y)h(of)h(mo)s(difying)d(its)j Fn(\\item)f
+Fs(tagging)i(output.)54 b(It)36 b(can)150 3787 y(also)30
+b(pro)m(vide)g(an)g(`end)g(item')g(tag)i(for)e(those)h(tagging)g
+(systems)g(that)g(require)e(suc)m(h)h(a)g(thing.)291
+3900 y(F)-8 b(or)40 b(suc)m(h)e(list)g(en)m(vironmen)m(ts,)i(iden)m
+(ti\014ed)d(b)m(y)i(the)g(command)g(t)m(yp)s(e)g(k)m(eyw)m(ord)g
+Fh(BEGIN)p 3364 3900 27 4 v 29 w(LIST)p 3569 3900 V 30
+w(ENV)p Fs(,)150 4012 y(the)31 b(follo)m(wing)d(command)j(lines)d
+(should)h(b)s(e)g(included)f(within)g(the)i(t)m(yp)s(e)h(sp)s
+(eci\014cation.)150 4198 y Fh(START)p 375 4198 V 29 w(ITEM=)44
+b Fs(Actions)30 b(to)h(b)s(e)f(p)s(erformed)f(at)i(the)f(start)h(of)g
+(eac)m(h)g Fn(\\item)e Fs(command)h(in)g(the)g(list.)150
+4384 y Fh(END)p 287 4384 V 30 w(ITEM=)44 b Fs(Actions)30
+b(to)h(b)s(e)f(p)s(erformed)f(after)h(pro)s(cessing)g(all)f(the)h
+Fn(\\item)p Fs('s)f(text.)150 4571 y Fh(START)p 375 4571
+V 29 w(ITEM)p 580 4571 V 30 w(PARAM=)43 b Fs(Actions)36
+b(to)h(b)s(e)e(p)s(erformed)f(at)j(the)f(start)h(of)f(an)g
+Fn(\\item)p Fs('s)e(optional)h(argumen)m(t)377 4684 y(text.)150
+4871 y Fh(END)p 287 4871 V 30 w(ITEM)p 493 4871 V 30
+w(PARAM=)43 b Fs(Actions)29 b(to)g(b)s(e)f(p)s(erformed)f(at)j(the)f
+(end)f(of)h(an)f Fn(\\item)p Fs('s)g(optional)f(argumen)m(t)j(text.)150
+5056 y(As)g(usual,)f(an)i(unsp)s(eci\014ed)c(tag)32 b(defaults)d(to)j
+(no)e(actions.)291 5169 y(F)-8 b(or)34 b(example,)g(assume)f(that)h(w)m
+(e)g(are)g(not)f(in)m(terested)h(in)e(tagging)i(the)f(end)g(of)h(an)f
+(item,)h(but)e(w)m(e)150 5282 y(do)h(w)m(an)m(t)h(to)g(mark)f(eac)m(h)h
+(item)f(in)f(an)h Fn(itemize)e Fs(en)m(vironmen)m(t)i(with)e(the)j(lo)m
+(w)m(ercase)g(letter)g(`o',)h(eac)m(h)1905 5531 y(25)p
+eop
+%%Page: 26 30
+26 29 bop 150 573 a Fn(enumerate)35 b Fs(item)i(with)g(`\(N\)')i(and)e
+(put)f(a)i(colon)g(after)g(the)g(optional)f(argumen)m(t)h(in)e(a)i
+(description)150 686 y(en)m(vironmen)m(t.)i(Also,)31
+b(eac)m(h)g(item)f(should)f(ha)m(v)m(e)i(some)g(inden)m(tation)e(from)h
+(the)h(left)f(hand)f(margin.)150 885 y Fh(TYPE=)42 b(BEGIN_LIST_ENV)150
+985 y(NAME=)g(itemize)237 1084 y(START_ITEM=)d("?n)173
+b(o)43 b(")150 1184 y(END_TYPE)150 1383 y(TYPE=)f(END_LIST_ENV)150
+1483 y(NAME=)g(itemize)150 1582 y(END_TYPE)150 1782 y(TYPE=)g
+(BEGIN_LIST_ENV)150 1881 y(NAME=)g(enumerate)237 1981
+y(START_ITEM=)d("?n)173 b(\(N\))43 b(")150 2081 y(END_TYPE)150
+2280 y(TYPE=)f(END_LIST_ENV)150 2379 y(NAME=)g(enumerate)150
+2479 y(END_TYPE)150 2678 y(TYPE=)g(BEGIN_LIST_ENV)150
+2778 y(NAME=)g(description)237 2878 y(START_ITEM=)d("?n)86
+b(")237 2977 y(END_ITEM_PARAM=)38 b(")43 b(:)g(")150
+3077 y(END_TYPE)150 3276 y(TYPE=)f(END_LIST_ENV)150 3376
+y(NAME=)g(description)150 3475 y(END_TYPE)291 3688 y
+Fs(With)30 b(the)h(ab)s(o)m(v)m(e)g(commands,)f(this)g(L)1617
+3671 y Fr(A)1656 3688 y Fs(T)1707 3707 y(E)1757 3688
+y(X)g(text:)150 3875 y Fn(\\begin{description})150 3988
+y(\\item[An)46 b(example])245 4101 y(\\begin{itemize})245
+4214 y(\\item)h(the)g(first)f(item;)245 4327 y(\\item)h(the)g(second)f
+(item.)245 4440 y(\\end{itemize})150 4553 y(\\end{description})150
+4741 y Fs(will)28 b(b)s(e)h(transformed)h(in)m(to:)245
+4928 y Fn(An)48 b(example)d(:)341 5041 y(o)i(the)g(first)g(item;)341
+5154 y(o)g(the)g(second)f(item.)1905 5531 y Fs(26)p eop
+%%Page: 27 31
+27 30 bop 150 573 a Fj(2.7)112 b(Character)38 b(t)m(yp)s(es)150
+744 y Fs(L)174 728 y Fr(A)213 744 y Fs(T)264 764 y(E)314
+744 y(X)33 b(treats)h(some)f(c)m(haracters)h(sp)s(ecially)-8
+b(.)45 b(These)33 b(sp)s(ecial)e(c)m(haracters)j(are:)46
+b Fn(#)p Fs(,)33 b Fn($)p Fs(,)g Fn(\045)p Fs(,)g Fn(&)p
+Fs(,)g Fn(~)p Fs(,)g Fn(_)p Fs(,)g Fn(^)p Fs(,)g Fn(\\)p
+Fs(,)150 857 y Fn({)p Fs(,)f Fn(})p Fs(,)g(and,)f(under)f(some)i
+(circumstances,)g(also)g(the)f(c)m(haracter)j Fn(@)p
+Fs(.)44 b Fy(L)-7 b(TX2X)31 b Fs(recognizes)h(these)g(sp)s(ecial)150
+970 y(c)m(haracters)41 b(and,)h(if)d(directed,)j(will)37
+b(p)s(erform)i(sp)s(eci\014ed)f(actions;)45 b(otherwise)39
+b(it)h(treats)g(them)g(as)g(it)150 1083 y(treats)31 b(an)m(y)g(alphan)m
+(umeric)d(c)m(haracter,)33 b(whic)m(h)c(is)g(just)h(to)h(prin)m(t)e
+(it.)291 1183 y(It)35 b(has)g(already)f(b)s(een)h(stated)h(that)f
+(commands)g(for)f(the)i(left)e(and)h(righ)m(t)f(braces)h(\(i.e.)55
+b Fn({)35 b Fs(and)f Fn(})p Fs(\))150 1282 y(m)m(ust)i(b)s(e)g(giv)m
+(en)h(within)d(the)j(command)f(table)h(as)g(command)f(t)m(yp)s(es)h
+Fh(LBRACE)p Fs(,)d Fh(RBRACE)g Fs(resp)s(ectiv)m(ely)-8
+b(.)150 1382 y(The)28 b(dollar)g(sym)m(b)s(ol)g(\($\))i(m)m(ust)f(also)
+f(b)s(e)h(sp)s(eci\014ed)e(via)i(the)g(t)m(w)m(o)h(command)f(t)m(yp)s
+(es)g Fh(BEGIN)p 3289 1382 27 4 v 29 w(DOLLAR)e Fs(and)150
+1482 y Fh(END)p 287 1482 V 30 w(DOLLAR)p Fs(.)34 b(Here)k(is)d(an)i
+(example)f(of)h(replacing)e(the)i(dollar)e(signs)h(b)m(y)g(tags)i(in)m
+(tended)d(to)j(indicate)150 1581 y(the)31 b(start)f(and)g(end)g(of)h(a)
+f(mathematical)h(phrase.)150 1756 y Fh(TYPE=)42 b(BEGIN_DOLLAR)237
+1855 y(START_TAG=)e("<math>")150 1955 y(END_TYPE)150
+2154 y(TYPE=)i(END_DOLLAR)237 2254 y(START_TAG=)e("</math>")150
+2353 y(END_TYPE)291 2541 y Fs(Commands)31 b(for)h(the)g(other)g(sp)s
+(ecial)e(L)1627 2524 y Fr(A)1666 2541 y Fs(T)1717 2561
+y(E)1767 2541 y(X)i(c)m(haracters)i(are)e(sp)s(eci\014ed)e(with)h(the)h
+Fh(TEX)p 3327 2541 V 30 w(CHAR)e Fs(com-)150 2654 y(mand)g(t)m(yp)s(e)g
+(k)m(eyw)m(ord.)291 2754 y(The)j(c)m(haracters)j Fn(_)d
+Fs(\(underscore\))h(and)f Fn(^)g Fs(\(caret\))j(are)e(used)f(in)f(L)
+2591 2737 y Fr(A)2630 2754 y Fs(T)2681 2773 y(E)2732
+2754 y(X)h(math)h(mo)s(de)f(to)i(indicate)150 2853 y(subscripting)e
+(and)i(sup)s(erscripting)e(resp)s(ectiv)m(ely)-8 b(.)57
+b(The)35 b(follo)m(wing)g(will)e(replace)j Fn(^)g Fs(b)m(y)h
+Fh(<sup>)p Fs(,)e(prin)m(t)150 2953 y(the)28 b(sup)s(erscript)c(text)29
+b(\(whic)m(h)d(m)m(ust)h(b)s(e)g(enclosed)g(in)f(braces)2298
+2920 y Fr(5)2338 2953 y Fs(\))i(and)f(at)h(the)f(end)g(close)h(with)e
+Fh(</sup>)p Fs(.)150 3127 y Fh(TYPE=)42 b(TEX_CHAR)150
+3227 y(NAME=)g(^)237 3326 y(START_TAG=)e("<sup>")237
+3426 y(REQPARAMS=)g(1)237 3526 y(END_TAG=)g("</sup>")150
+3625 y(END_TYPE)291 3813 y Fs(Giv)m(en)30 b(the)h(ab)s(o)m(v)m(e)h(sp)s
+(eci\014cations,)d(then)h Fn($\(2^{15})45 b(-)j(1\)$)29
+b Fs(will)f(b)s(e)i(transformed)f(in)m(to)150 3926 y
+Fh(<math>\(2<sup>15<)o(/su)o(p>)37 b(-)43 b(1\)</math>)p
+Fs(.)150 4169 y Fj(2.8)112 b(V)-9 b(erbatim)36 b(lik)m(e)g(t)m(yp)s(es)
+150 4328 y Fs(The)29 b(command)g(t)m(yp)s(e)g Fh(VCOMMAND)d
+Fs(is)i(for)h(the)h(pro)s(cesing)e(of)h(L)2241 4311 y
+Fr(A)2280 4328 y Fs(T)2331 4347 y(E)2381 4328 y(X)h Fn(\\verb)p
+Fs(-lik)m(e)d(commands)i(where)g(the)150 4427 y(argumen)m(t)j(of)f(the)
+h(command)f(is)g(to)h(b)s(e)e(t)m(yp)s(eset)j(as-is.)43
+b(F)-8 b(or)32 b(example,)g(there)f(migh)m(t)h(b)s(e)e(a)i(command)150
+4527 y(called)d Fn(\\url)g Fs(whic)m(h)g(tak)m(es)j(one)e(argumen)m(t)h
+(whic)m(h)e(is)g(mean)m(t)i(to)g(b)s(e)e(an)h(In)m(ternet)h(URL.)f(If)f
+(the)i(appli-)150 4627 y(cation)h(w)m(as)g(the)g(con)m(v)m(ersion)g(of)
+f(a)h(L)1407 4610 y Fr(A)1446 4627 y Fs(T)1497 4646 y(E)1548
+4627 y(X)f(do)s(cumen)m(t)h(to)g(HTML,)g(then)f(the)h(follo)m(wing)e
+(sp)s(eci\014cation)150 4726 y(could)f(b)s(e)h(useful.)150
+4901 y Fh(TYPE=)42 b(VCOMMAND)150 5000 y(NAME=)g(\\url)p
+150 5068 1440 4 v 254 5122 a Fl(5)288 5154 y Fp(It)23
+b(is)g(go)r(o)r(d)h(practice)g(to)f(alw)n(a)n(ys)h(enclose)g(sup)r
+(erscript)f(and)g(subscript)f(text)h(in)g(braces,)h(ev)n(en)e(though)h
+(T)3345 5170 y(E)3388 5154 y(X)g(do)r(es)g(not)150 5245
+y(alw)n(a)n(ys)k(require)e(this.)1905 5531 y Fs(27)p
+eop
+%%Page: 28 32
+28 31 bop 237 573 a Fh(REQPARAMS=)40 b(1)237 672 y(PRINT_P1=)g
+(TO_BUFFER)g(7)237 772 y(START_TAG=)324 872 y(RESET_BUFFER:)f(7)237
+971 y(END_TAG=)h("<a)j(href="")324 1071 y(SOURCE:)e(BUFFER)g(7)324
+1171 y(STRING:)g("">")324 1270 y(SOURCE:)g(BUFFER)g(7)324
+1370 y(STRING:)g("</a>")324 1469 y(RESET_BUFFER:)e(7)150
+1569 y(END_TYPE)291 1735 y Fs(If)30 b(the)h(L)563 1718
+y Fr(A)602 1735 y Fs(T)653 1755 y(E)703 1735 y(X)f(source)h(included:)
+150 1901 y Fh(...)42 b(obtainable)e(from)150 2001 y(\\url{http://www.)o
+(cdr)o(om)o(.c)o(om/)o(pu)o(b/t)o(ex)o(})150 2167 y Fs(then)30
+b(the)h(resulting)d Fy(L)-7 b(TX2X)30 b Fs(output)g(w)m(ould)g(b)s(e:)
+150 2333 y Fh(...)42 b(obtainable)e(from)150 2432 y(<a)j
+(href="http://www)o(.c)o(dr)o(om.)o(co)o(m/p)o(ub)o(/te)o(x")o(>h)o
+(ttp)o(:/)o(/ww)o(w.)o(cd)o(rom)o(.c)o(om/)o(pu)o(b/t)o(ex)o(</)o(a>)
+150 2612 y Fs(whic)m(h,)k(if)d(this)g(w)m(as)h(then)g(read)f(via)h(an)g
+(appropriate)e(bro)m(wser,)49 b(a)c(link)e(to)i(the)g(URL)g(w)m(ould)f
+(b)s(e)150 2725 y(automatically)30 b(established.)291
+2824 y(Similarly)k Fn(verbatim)p Fs(-lik)m(e)g(en)m(vironmen)m(ts)j
+(can)g(also)g(b)s(e)g(sp)s(eci\014ed)e(with)h(the)h(t)m(yp)s(es)g
+Fh(BEGIN)p 3551 2824 27 4 v 30 w(VENV)150 2924 y Fs(and)j
+Fh(END)p 474 2924 V 30 w(VENV)p Fs(.)g(F)-8 b(or)41 b(example,)j(the)d
+Fn(html.sty)e Fs(pac)m(k)-5 b(age)42 b(de\014nes)e(three)i(L)2823
+2907 y Fr(A)2862 2924 y Fs(T)2913 2943 y(E)2963 2924
+y(X)f(en)m(vironmen)m(ts)f(for)150 3023 y(do)s(cumen)m(ts)34
+b(that)g(migh)m(t)g(b)s(e)f(con)m(v)m(erted)j(from)d(L)1858
+3007 y Fr(A)1897 3023 y Fs(T)1948 3043 y(E)1999 3023
+y(X)h(tagging)h(to)f(HTML)g(tagging.)53 b(One)33 b(of)h(these,)150
+3123 y Fn(latexonly)27 b Fs(is)h(for)h(L)861 3106 y Fr(A)900
+3123 y Fs(T)951 3143 y(E)1001 3123 y(X)h(co)s(de)f(that)h(is)e(not)i
+(to)g(o)s(ccur)f(in)f(the)i(HTMLed)f(do)s(cumen)m(t)g(and)f(another)i
+(is)150 3223 y Fn(htmlonly)20 b Fs(whic)m(h)h(con)m(tains)h(HTML)g(co)s
+(de)h(that)f(is)f(required)g(for)h(an)g(HTML)g(v)m(ersion)f(of)i(the)f
+(do)s(cumen)m(t)150 3322 y(but)34 b(whic)m(h)g(is)f(not)i(to)h(app)s
+(ear)e(in)g(the)h(L)1564 3306 y Fr(A)1603 3322 y Fs(T)1654
+3342 y(E)1704 3322 y(Xed)g(do)s(cumen)m(t.)53 b(The)35
+b(third)e(one)i(is)f Fn(rawhtml)e Fs(whic)m(h)i(is)150
+3422 y(for)k(HTML)g(co)s(de)h(to)g(b)s(e)e(output)h(v)m(erbatim)g(to)h
+(the)g(HTML)f(do)s(cumen)m(t)g(source.)64 b(These)38
+b(could)g(b)s(e)150 3522 y(sim)m(ulated)29 b(b)m(y:)150
+3688 y Fh(TYPE=)42 b(BEGIN_VENV)150 3787 y(NAME=)g(latexonly)237
+3887 y(PC_AT_START=)d(NO_PRINT)150 3986 y(END_TYPE)150
+4186 y(TYPE=)j(END_VENV)150 4285 y(NAME=)g(latexonly)237
+4385 y(PC_AT_END=)e(RESET)150 4485 y(END_TYPE)150 4684
+y(TYPE=)i(BEGIN_ENV)150 4783 y(NAME=)g(htmlonly)150 4883
+y(END_TYPE)150 5082 y(TYPE=)g(END_ENV)150 5182 y(NAME=)g(htmlonly)150
+5282 y(END_TYPE)1905 5531 y Fs(28)p eop
+%%Page: 29 33
+29 32 bop 150 672 a Fh(TYPE=)42 b(BEGIN_VENV)150 772
+y(NAME=)g(rawhtml)150 872 y(END_TYPE)150 1071 y(TYPE=)g(END_VENV)150
+1171 y(NAME=)g(rawhtml)150 1270 y(END_TYPE)150 1514 y
+Fj(2.9)112 b(Odd)38 b(command)f(t)m(yp)s(es)150 1685
+y Fs(The)20 b(ma)5 b(jorit)m(y)21 b(of)h(commands)e(in)g(L)1345
+1669 y Fr(A)1384 1685 y Fs(T)1435 1705 y(E)1485 1685
+y(X)h(that)h(tak)m(e)g(optional)e(argumen)m(ts)i(ha)m(v)m(e)g(only)e(a)
+h(single)f(optional)150 1798 y(argumen)m(t)26 b(that)h(is)d(either)i
+(immediately)e(after)i(the)g(command)g(or)f(after)i(all)d(the)i
+(required)e(argumen)m(ts.)150 1911 y(There)38 b(are,)j(ho)m(w)m(ev)m
+(er,)h(some)d(commands)f(that)i(do)e(not)h(\014t)f(this)f(pattern.)66
+b(This)36 b(set)j(of)g(command)150 2024 y(t)m(yp)s(es)30
+b(enables)g(at)h(least)g(some)g(of)f(these)h(`o)s(dd')f(commands)g(to)h
+(b)s(e)f(handled.)291 2137 y(The)f(command)g(t)m(yp)s(e)g(k)m(eyw)m
+(ord)h(is)e(of)h(the)g(form)g Fh(COMMAND)p 2325 2137
+27 4 v 28 w(code)p Fs(,)f(where)h Fh(code)e Fs(indicates)h(the)i(t)m
+(yp)s(e)150 2250 y(and)k(ordering)g(of)i(the)f(argumen)m(ts.)55
+b(The)34 b Fh(code)g Fs(is)g(comp)s(osed)h(from)f(com)m(binations)h(of)
+g(the)g(letters)g Fh(O)150 2363 y Fs(\(for)28 b(an)h(optional)e
+(argumen)m(t\))i(and)f Fh(P)g Fs(\(for)h(a)f(required)f(parameter)i
+(\(i.e.,)g(argumen)m(t\)\).)41 b(The)28 b(ordering)150
+2476 y(of)j(these)f(letters)h(in)e(the)i Fh(code)d Fs(sp)s(eci\014es)h
+(the)i(t)m(yp)s(e)f(and)g(ordering)f(of)i(the)f(command's)h(argumen)m
+(ts.)291 2589 y(The)f(`o)s(dd')g(command)g(t)m(yp)s(es)g(are:)150
+2776 y Fh(COMMAND)p 463 2776 V 28 w(OOP)45 b Fs(Corresp)s(onding)27
+b(to)k(a)g(L)1483 2759 y Fr(A)1522 2776 y Fs(T)1573 2796
+y(E)1623 2776 y(X)g(command)f(of)h(the)f(form)377 2889
+y Fn(\\com[OptParam][OptParam]{)o(ReqP)o(aram)o(})p Fs(.)k(F)-8
+b(or)31 b(example,)f(the)g Fn(\\makebox)e Fs(command)h(falls)377
+3002 y(in)m(to)i(this)e(category)-8 b(.)150 3190 y Fh(COMMAND)p
+463 3190 V 28 w(OOOPP)44 b Fs(Corresp)s(onding)27 b(to)32
+b(a)e(L)1570 3173 y Fr(A)1609 3190 y Fs(T)1660 3209 y(E)1711
+3190 y(X)g(command)g(of)h(the)f(form)377 3303 y Fn
+(\\com[OptParam][OptParam][)o(OptP)o(aram)o(]{R)o(eqPa)o(ram})o({Re)o
+(qPar)o(am})p Fs(.)68 b(F)-8 b(or)42 b(example,)j(the)377
+3415 y Fn(\\parbox)29 b Fs(command)h(falls)f(in)m(to)h(this)f(category)
+-8 b(.)150 3603 y Fh(COMMAND)p 463 3603 V 28 w(OPO)45
+b Fs(Corresp)s(onding)27 b(to)k(a)g(L)1483 3586 y Fr(A)1522
+3603 y Fs(T)1573 3623 y(E)1623 3603 y(X)g(command)f(of)h(the)f(form)377
+3716 y Fn(\\com[OptParam]{ReqParam}[)o(OptP)o(aram)o(])p
+Fs(.)72 b(F)-8 b(or)44 b(example,)i(the)d Fn(\\RequirePackage)c
+Fs(and)377 3829 y Fn(\\LoadClass)28 b Fs(commands)i(fall)f(in)m(to)h
+(this)g(category)-8 b(.)150 4017 y Fh(COMMAND)p 463 4017
+V 28 w(POOOP)44 b Fs(Corresp)s(onding)27 b(to)32 b(a)e(L)1570
+4000 y Fr(A)1609 4017 y Fs(T)1660 4036 y(E)1711 4017
+y(X)g(command)g(of)h(the)f(form)377 4129 y Fn
+(\\com{ReqParam}[OptParam][)o(OptP)o(aram)o(][O)o(ptPa)o(ram])o({Re)o
+(qPar)o(am})p Fs(.)150 4317 y Fh(COMMAND)p 463 4317 V
+28 w(POOP)44 b Fs(Corresp)s(onding)28 b(to)j(a)g(L)1527
+4300 y Fr(A)1566 4317 y Fs(T)1617 4337 y(E)1667 4317
+y(X)g(command)f(of)g(the)h(form)377 4430 y Fn
+(\\com{ReqParam}[OptParam][)o(OptP)o(aram)o(]{R)o(eqPa)o(ram})o
+Fs(.)i(F)-8 b(or)25 b(example,)g(the)g Fn(\\newcommand)377
+4543 y Fs(and)30 b(its)g(companion)f(commands)h(fall)f(in)m(to)i(this)e
+(category)-8 b(.)150 4731 y Fh(COMMAND)p 463 4731 V 28
+w(POOPP)44 b Fs(Corresp)s(onding)27 b(to)32 b(a)e(L)1570
+4714 y Fr(A)1609 4731 y Fs(T)1660 4750 y(E)1711 4731
+y(X)g(command)g(of)h(the)f(form)377 4843 y Fn
+(\\com{ReqParam}[OptParam][)o(OptP)o(aram)o(]{R)o(eqPa)o(ram})o({Re)o
+(qPar)o(am})p Fs(.)68 b(F)-8 b(or)42 b(example,)j(the)377
+4956 y Fn(\\newenvironment)26 b Fs(and)k(its)g(companion)g(command)g
+(fall)f(in)m(to)h(this)f(category)-8 b(.)291 5144 y(As)22
+b(usual,)h(the)f(command)g(name)h(is)e(required,)h(as)h(are)f(an)m(y)h
+(actions.)38 b(Ho)m(w)m(ev)m(er,)26 b(it)c(is)f(not)i(necessary)150
+5257 y(to)45 b(sp)s(ecify)e(the)i(n)m(um)m(b)s(er)e(of)h(required)f
+(argumen)m(ts)h(\(i.e.)83 b Fh(REQPARAMS=)p Fs(\))40
+b(nor)k(the)h(p)s(osition)d(of)j(the)1905 5531 y(29)p
+eop
+%%Page: 30 34
+30 33 bop 150 573 a Fs(optional)44 b(argumen)m(t)h(\(i.e.)84
+b Fh(OPT)p 1311 573 27 4 v 30 w(PARAM=)p Fs(\),)46 b(as)f
+Fy(L)-7 b(TX2X)45 b Fs(already)f(has)h(this)e(information.)83
+b(The)44 b(tag)150 686 y(actions)34 b(are)f(according)h(to)g(the)f
+(argumen)m(t)h(ordering)e(giv)m(en)h(in)f(the)i Fh(code)d
+Fs(and)i(are)h(sp)s(eci\014ed)e(b)m(y)h(the)150 799 y(required)23
+b(argumen)m(t)i(tags)h(\(e.g.)40 b Fh(START)p 1524 799
+V 29 w(TAG)p 1685 799 V 31 w(n=)23 b Fs(and)i Fh(END)p
+2131 799 V 30 w(TAG)p 2293 799 V 30 w(n=)p Fs(\).)38
+b(Do)26 b(not)f(use)f(an)m(y)h(of)g(the)g(command)150
+912 y(lines)k(for)h(optional)f(argumen)m(ts.)41 b(Argumen)m(t)31
+b(actions)f(are)h(con)m(trolled)f(in)f(the)i(usual)e(manner.)291
+1011 y(A)40 b(t)m(ypical)g(example)g(of)g(the)g(use)g(of)g(these)h
+(commands)f(is)f(to)i(supress)d(an)m(y)j(pro)s(cessing)d(of)j(the)150
+1111 y(L)174 1094 y Fr(A)213 1111 y Fs(T)264 1130 y(E)314
+1111 y(X)31 b Fn(\\newcommand)c Fs(and)j(its)g(ilk.)39
+b(F)-8 b(or)31 b(example:)150 1285 y Fh(TYPE=)42 b(COMMAND_POOP)150
+1385 y(NAME=)g(\\providecommand)237 1484 y(PRINT_P1=)e(NO_OP)237
+1584 y(PRINT_P2=)g(NO_OP)237 1684 y(PRINT_P3=)g(NO_OP)237
+1783 y(PRINT_P4=)g(NO_OP)150 1883 y(END_TYPE)150 2082
+y(TYPE=)i(COMMAND_POOPP)150 2182 y(NAME=)g(\\renewenvironme)o(nt)237
+2281 y(PRINT_P1=)e(NO_OP)237 2381 y(PRINT_P2=)g(NO_OP)237
+2481 y(PRINT_P3=)g(NO_OP)237 2580 y(PRINT_P4=)g(NO_OP)237
+2680 y(PRINT_P5=)g(NO_OP)150 2780 y(END_TYPE)150 3023
+y Fj(2.10)112 b(Other)38 b(command)f(t)m(yp)s(es)150
+3195 y Fs(The)28 b Fh(OTHER)p 560 3195 V 58 w Fs(command)g(t)m(yp)s(es)
+g(\()p Fh(OTHER)p 1523 3195 V 30 w(COMMAND)p Fs(,)d Fh(OTHER)p
+2131 3195 V 30 w(BEGIN)h Fs(and)i Fh(OTHER)p 2802 3195
+V 29 w(END)p Fs(\))g(are)g(v)m(ery)h(limited)d(in)150
+3308 y(what)g(can)h(b)s(e)e(a\013ected.)41 b(Basically)-8
+b(,)27 b(these)f(pro)m(vide)g(for)g(default)f(prin)m(ting)f(actions)i
+(if)g(the)g(corresp)s(ond-)150 3420 y(ing)k(L)326 3404
+y Fr(A)365 3420 y Fs(T)416 3440 y(E)466 3420 y(X)g(command)g(has)h(not)
+f(b)s(een)g(iden)m(ti\014ed)e(elsewhere)i(in)f(the)i(command)f(table.)
+291 3533 y(If)d(there)g(are)h(no)f(commands)f(within)f(the)i(sp)s
+(eci\014cation,)g(the)g(name)h(of)f(the)g(command)g(and)g(all)f(its)150
+3646 y(argumen)m(ts)31 b(will)c(b)s(e)j(prin)m(ted)f(v)m(erbatim.)291
+3759 y(The)44 b(command)g(lines)f Fh(START)p 1367 3759
+V 30 w(TAG=)f Fs(and)i Fh(END)p 1938 3759 V 30 w(TAG=)f
+Fs(cause)i(the)g(corresp)s(onding)e(actions)h(to)i(b)s(e)150
+3872 y(p)s(erformed)22 b(b)s(efore)h(and)g(after)i(the)e(name)h(of)g
+(the)g(command)f(is)g(prin)m(ted.)37 b(An)m(y)23 b(argumen)m(ts)h(are)g
+(prin)m(ted)150 3985 y(v)m(erbatim.)291 4098 y(The)30
+b(command)g(line)f Fh(PRINT)p 1289 4098 V 29 w(CONTROL=)f
+Fs(with)h(a)i(v)-5 b(alue)30 b(of)37 b Fh(NO)p 2414 4098
+V 31 w(PRINT)28 b Fs(causes)j(the)g(command)f(name)150
+4211 y(not)h(to)g(b)s(e)e(prin)m(ted,)h(nor)f(an)m(y)i(argumen)m(ts)g
+(that)g Fy(L)-7 b(TX2X)30 b Fs(ma)m(y)h(\014nd)e(asso)s(ciated)i(with)e
+(the)h(command.)150 4454 y Fj(2.11)112 b(Picture)36 b(t)m(yp)s(es)150
+4626 y Fs(The)p 350 4626 V 70 w Fh(PICTURE)p 690 4626
+V 67 w Fs(command)i(t)m(yp)s(es)h(di\013er)e(from)i(all)e(the)i(other)g
+(t)m(yp)s(es)g(in)e Fy(L)-7 b(TX2X)p Fs(,)39 b(just)f(as)h(they)g(do)
+150 4739 y(in)f(L)289 4722 y Fr(A)328 4739 y Fs(T)379
+4758 y(E)429 4739 y(X.)68 b(In)38 b(L)736 4722 y Fr(A)775
+4739 y Fs(T)826 4758 y(E)877 4739 y(X)h(some)h(of)f(the)h(picture)e
+(dra)m(wing)g(commands)h(tak)m(e)i(argumen)m(ts)e(of)h(the)f(form)150
+4852 y Fn(\(number,)46 b(number\))p Fs(,)25 b(represen)m(ting)h(a)h(co)
+s(ordinate)g(pair,)f(as)h(w)m(ell)f(as)h(the)g(usual)e(required)g
+(argumen)m(ts)150 4965 y(enclosed)39 b(in)g(curly)f(braces)i(and)e(p)s
+(ossibly)f(an)j(optional)e(argumen)m(t)i(enclosed)g(in)e(square)h(brac)
+m(k)m(ets.)150 5078 y(Within)k Fy(L)-7 b(TX2X)p Fs(,)46
+b(commands)e(that)i(tak)m(e)h(co)s(ordinate)e(argumen)m(ts)g(are)h
+(treated)g(sp)s(ecially)d(in)h(the)150 5190 y(command)30
+b(table.)1905 5531 y(30)p eop
+%%Page: 31 35
+31 34 bop 291 573 a Fs(Generally)21 b(sp)s(eaking,)i(the)g
+Fy(L)-7 b(TX2X)22 b Fs(command)f(t)m(yp)s(es)i(are)f(of)g(the)h(form)e
+Fh(PICTURE)p 3074 573 27 4 v 29 w(code)p Fs(,)h(where)g
+Fh(code)150 686 y Fs(indicates)j(the)h(t)m(yp)s(e)h(and)e(ordering)g
+(of)h(the)g(argumen)m(ts.)40 b(The)26 b Fh(code)e Fs(is)h(comp)s(osed)h
+(from)g(com)m(binations)150 799 y(of)42 b(the)f(letters)h
+Fh(C)f Fs(\(for)h(a)g(co)s(ordinate)f(argumen)m(t\),)46
+b Fh(O)41 b Fs(\(for)g(an)h(optional)f(argumen)m(t\))h(and)f
+Fh(P)g Fs(\(for)h(a)150 912 y(required)36 b(argumen)m(t\).)64
+b(F)-8 b(or)38 b(example,)i Fh(PICTURE)p 1888 912 V 28
+w(PCOP)c Fs(indicates)h(a)h(picture)f(command)h(that)g(has)g(a)150
+1024 y(required)33 b(argumen)m(t,)j(follo)m(w)m(ed)d(b)m(y)i(a)f(co)s
+(ordinate)h(argumen)m(t,)h(follo)m(w)m(ed)e(b)m(y)g(an)g(optional)f
+(argumen)m(t)150 1137 y(and)d(\014nally)e(another)j(required)d(argumen)
+m(t.)291 1250 y(The)i(pro)m(vided)f(picture)g(t)m(yp)s(es)i(are:)150
+1438 y Fh(BEGIN)p 375 1438 V 29 w(PICTURE)p 712 1438
+V 29 w(CC)44 b Fs(Corresp)s(onding)28 b(to)j(a)g(L)1689
+1421 y Fr(A)1728 1438 y Fs(T)1779 1458 y(E)1829 1438
+y(X)g(command)f(of)g(the)h(form)377 1551 y Fn
+(\\begin{PictureEnv}\(coords)o(\)\(co)o(ords)o(\))p Fs(,)25
+b(where)30 b(the)h(\014nal)e(co)s(ordinate)h(argumen)m(t)h(is)f(op-)377
+1664 y(tional.)150 1851 y Fh(PICTURE)p 463 1851 V 28
+w(CCPP)44 b Fs(Corresp)s(onding)28 b(to)j(a)g(L)1527
+1835 y Fr(A)1566 1851 y Fs(T)1617 1871 y(E)1667 1851
+y(X)g(command)f(of)g(the)h(form)377 1964 y Fn
+(\\com\(coords\)\(coords\){ReqP)o(aram)o(}{Re)o(qPa)o(ram})o
+Fs(.)54 b(F)-8 b(or)37 b(example,)h(the)f Fn(\\multiput)d
+Fs(com-)377 2077 y(mand)c(falls)f(in)m(to)h(this)f(category)-8
+b(.)150 2265 y Fh(PICTURE)p 463 2265 V 28 w(CO)45 b Fs(Corresp)s
+(onding)28 b(to)j(a)g(L)1440 2248 y Fr(A)1479 2265 y
+Fs(T)1530 2284 y(E)1580 2265 y(X)f(command)h(of)f(the)h(form)377
+2378 y Fn(\\com\(coords\)[OptParam])p Fs(.)56 b(F)-8
+b(or)38 b(example,)h(the)e(standard)g(L)2648 2361 y Fr(A)2687
+2378 y Fs(T)2738 2397 y(E)2788 2378 y(X)g Fn(\\oval)f
+Fs(command)h(falls)377 2491 y(in)m(to)31 b(this)e(category)-8
+b(.)150 2678 y Fh(PICTURE)p 463 2678 V 28 w(COP)45 b
+Fs(Corresp)s(onding)27 b(to)k(a)g(L)1483 2662 y Fr(A)1522
+2678 y Fs(T)1573 2698 y(E)1623 2678 y(X)g(command)f(of)h(the)f(form)377
+2791 y Fn(\\com\(coords\)[OptParam]{Re)o(qPar)o(am})p
+Fs(.)56 b(F)-8 b(or)39 b(example,)g(the)f Fn(\\makebox)d
+Fs(and)i Fn(\\framebox)377 2904 y Fs(commands)30 b(fall)f(in)m(to)i
+(this)e(category)-8 b(.)150 3092 y Fh(PICTURE)p 463 3092
+V 28 w(CP)45 b Fs(Corresp)s(onding)28 b(to)j(a)g(L)1440
+3075 y Fr(A)1479 3092 y Fs(T)1530 3111 y(E)1580 3092
+y(X)f(command)h(of)f(the)h(form)377 3205 y Fn
+(\\com\(coords\){ReqParam})p Fs(.)58 b(F)-8 b(or)38 b(example,)i(the)e
+Fn(\\put)p Fs(,)h Fn(\\line)e Fs(and)g Fn(\\vector)f
+Fs(commands)377 3318 y(fall)29 b(in)m(to)i(this)e(category)-8
+b(.)150 3505 y Fh(PICTURE)p 463 3505 V 28 w(OCC)45 b
+Fs(Corresp)s(onding)27 b(to)k(a)g(L)1483 3488 y Fr(A)1522
+3505 y Fs(T)1573 3525 y(E)1623 3505 y(X)g(command)f(of)h(the)f(form)377
+3618 y Fn(\\com[OptParam]\(coords\)\(co)o(ords)o(\))p
+Fs(.)42 b(F)-8 b(or)34 b(example,)f(the)g Fn(\\graphpaper)d
+Fs(command)i(from)377 3731 y(the)f Fn(graphpap)d Fs(pac)m(k)-5
+b(age)32 b(falls)d(in)m(to)i(this)e(category)-8 b(.)150
+3919 y Fh(PICTURE)p 463 3919 V 28 w(OCCC)44 b Fs(Corresp)s(onding)28
+b(to)j(a)g(L)1527 3902 y Fr(A)1566 3919 y Fs(T)1617 3938
+y(E)1667 3919 y(X)g(command)f(of)g(the)h(form)377 4032
+y Fn(\\com[OptParam]\(coords\)\(co)o(ords)o(\)\(co)o(ord)o(s\))p
+Fs(.)j(F)-8 b(or)31 b(example,)e(the)h Fn(\\qbezier)d
+Fs(command)377 4144 y(falls)i(in)m(to)i(this)e(category)-8
+b(.)150 4332 y Fh(PICTURE)p 463 4332 V 28 w(OCO)45 b
+Fs(Corresp)s(onding)27 b(to)k(a)g(L)1483 4315 y Fr(A)1522
+4332 y Fs(T)1573 4352 y(E)1623 4332 y(X)g(command)f(of)h(the)f(form)377
+4445 y Fn(\\com[OptParam]\(coords\)[Op)o(tPar)o(am])p
+Fs(.)52 b(F)-8 b(or)37 b(example,)h(the)e Fn(\\oval)f
+Fs(command)h(from)g(the)377 4558 y Fn(pict2e)29 b Fs(pac)m(k)-5
+b(age)32 b(falls)d(in)m(to)i(this)e(category)-8 b(.)150
+4746 y Fh(PICTURE)p 463 4746 V 28 w(PCOP)44 b Fs(Corresp)s(onding)28
+b(to)j(a)g(L)1527 4729 y Fr(A)1566 4746 y Fs(T)1617 4765
+y(E)1667 4746 y(X)g(command)f(of)g(the)h(form)377 4858
+y Fn(\\com{ReqParam}\(coords\)[Op)o(tPar)o(am]{)o(Req)o(Para)o(m})p
+Fs(.)52 b(F)-8 b(or)37 b(example,)h(the)e Fn(\\dashbox)f
+Fs(and)377 4971 y Fn(\\savebox)28 b Fs(commands)i(fall)f(in)m(to)i
+(this)e(category)-8 b(.)150 5159 y Fh(END)p 287 5159
+V 30 w(PICTURE)43 b Fs(Corresp)s(onding)27 b(to)k(a)g(L)1483
+5142 y Fr(A)1522 5159 y Fs(T)1573 5179 y(E)1623 5159
+y(X)g(command)f(of)h(the)f(form)377 5272 y Fn(\\end{PictureEnv})p
+Fs(.)1905 5531 y(31)p eop
+%%Page: 32 36
+32 35 bop 291 573 a Fs(As)22 b(usual,)h(the)f(command)g(name)h(is)e
+(required,)h(as)h(are)f(an)m(y)h(actions.)38 b(Ho)m(w)m(ev)m(er,)26
+b(it)c(is)f(not)i(necessary)150 686 y(to)45 b(sp)s(ecify)e(the)i(n)m
+(um)m(b)s(er)e(of)h(required)f(argumen)m(ts)h(\(i.e.)83
+b Fh(REQPARAMS=)p Fs(\))40 b(nor)k(the)h(p)s(osition)d(of)j(the)150
+799 y(optional)f(argumen)m(t)h(\(i.e.)84 b Fh(OPT)p 1311
+799 27 4 v 30 w(PARAM=)p Fs(\),)46 b(as)f Fy(L)-7 b(TX2X)45
+b Fs(already)f(has)h(this)e(information.)83 b(The)44
+b(tag)150 912 y(actions)34 b(are)f(according)h(to)g(the)f(argumen)m(t)h
+(ordering)e(giv)m(en)h(in)f(the)i Fh(code)d Fs(and)i(are)h(sp)s
+(eci\014ed)e(b)m(y)h(the)150 1024 y(required)23 b(argumen)m(t)i(tags)h
+(\(e.g.)40 b Fh(START)p 1524 1024 V 29 w(TAG)p 1685 1024
+V 31 w(n=)23 b Fs(and)i Fh(END)p 2131 1024 V 30 w(TAG)p
+2293 1024 V 30 w(n=)p Fs(\).)38 b(Do)26 b(not)f(use)f(an)m(y)h(of)g
+(the)g(command)150 1137 y(lines)k(for)h(optional)f(argumen)m(ts.)41
+b(Argumen)m(t)31 b(actions)f(con)m(trolled)g(in)f(the)i(usual)e
+(manner.)291 1250 y(As)e(an)g(example,)g(the)g(follo)m(wing)f(sp)s
+(eci\014cations)f(within)g(a)i(command)g(table)f(should)f(b)s(e)h
+(su\016cien)m(t)150 1363 y(to)k(ensure)f(that)i(an)m(y)f(picture)f
+(commands)g(in)f(a)j(source)f(\014le)e(are)j(not)f(passed)f(through)g
+(to)h(the)g(output)150 1476 y(\014le.)150 1675 y Fh(TYPE=)42
+b(BEGIN_PICTURE_C)o(C)150 1775 y(NAME=)g(picture)150
+1875 y(PRINT_P1=)e(NO_PRINT)150 1974 y(PRINT_P2)g(=)j(NO_PRINT)150
+2074 y(END_TYPE)150 2273 y(TYPE=)f(PICTURE_CP)150 2373
+y(NAME=)g(\\put)150 2472 y(PRINT_P1=)e(NO_PRINT)150 2572
+y(PRINT_P2=)g(NO_OP)150 2672 y(END_TYPE)150 2871 y(TYPE=)i
+(PICTURE_CCPP)150 2971 y(NAME=)g(\\multiput)150 3070
+y(PRINT_P1=)e(NO_PRINT)150 3170 y(PRINT_P2=)g(NO_PRINT)150
+3269 y(PRINT_P3=)g(NO_OP)150 3369 y(PRINT_P4=)g(NO_OP)150
+3469 y(END_TYPE)150 3668 y(TYPE=)i(PICTURE_PCOP)150 3768
+y(NAME=)g(\\savebox)150 3867 y(PRINT_P1=)e(NO_OP)150
+3967 y(PRINT_P2=)g(NO_PRINT)150 4066 y(PRINT_P3=)g(NO_OP)150
+4166 y(PRINT_P4=)g(NO_OP)150 4266 y(END_TYPE)150 4465
+y(TYPE=)i(PICTURE_OCC)150 4565 y(NAME=)g(\\graphpaper)150
+4664 y(PRINT_P1=)e(NO_OP)150 4764 y(PRINT_P2=)g(NO_PRINT)150
+4863 y(PRINT_P3=)g(NO_PRINT)150 4963 y(END_TYPE)150 5162
+y(TYPE=)i(PICTURE_OCCC)150 5262 y(NAME=)g(\\qbezier)1905
+5531 y Fs(32)p eop
+%%Page: 33 37
+33 36 bop 150 573 a Fh(PRINT_P1=)40 b(NO_OP)150 672 y(PRINT_P2=)g
+(NO_PRINT)150 772 y(PRINT_P3=)g(NO_PRINT)150 872 y(PRINT_P4=)g
+(NO_PRINT)150 971 y(END_TYPE)150 1171 y(TYPE=)i(END_PICTURE)150
+1270 y(NAME=)g(picture)150 1370 y(END_TYPE)150 1582 y
+Ft(NOTE)34 b(1:)45 b Fs(The)30 b(action)h Fh(NO)p 1166
+1582 27 4 v 31 w(OP)e Fs(cannot)i(b)s(e)f(applied)e(to)j(an)f(argumen)m
+(t)h(that)g(is)e(a)i(co)s(ordinate)f(pair.)150 1770 y
+Ft(NOTE)k(2:)45 b Fs(As)28 b Fy(L)-7 b(TX2X)27 b Fs(is)f(essen)m
+(tially)h(limited)e(to)j(prin)m(ting)d(actions,)k(and)d(cannot)i
+(actually)f(pro)s(cess)377 1883 y(an)m(y)h(L)570 1866
+y Fr(A)609 1883 y Fs(T)660 1903 y(E)710 1883 y(X)f(picture)f(dra)m
+(wing)g(commands,)i(the)f(suppression)d(of)k(picture)e(prin)m(ting)f
+(is)h(probably)377 1996 y(the)31 b(most)g(usual)d(use)j(of)f(the)h
+(picture)e(commands.)150 2239 y Fj(2.12)112 b(Sp)s(ecial)37
+b(command)g(t)m(yp)s(es)150 2411 y Fs(The)30 b Fh(SPECIAL)p
+650 2411 V 58 w Fs(commands,)h(namely)g Fh(SPECIAL)p
+1809 2411 V 28 w(COMMAND)p Fs(,)d Fh(SPECIAL)p 2506 2411
+V 28 w(BEGIN)p 2754 2411 V 29 w(ENV)p Fs(,)i Fh(SPECIAL)p
+3278 2411 V 28 w(BEGIN)p 3526 2411 V 29 w(LIST)p Fs(,)150
+2524 y Fh(SPECIAL)p 463 2524 V 28 w(END)p 623 2524 V
+31 w(ENV)p Fs(,)39 b Fh(SPECIAL)p 1158 2524 V 29 w(END)p
+1319 2524 V 30 w(LIST)g Fs(and)g Fh(SPECIAL)p 2058 2524
+V 29 w(SECTIONING)p Fs(,)e(are)j(pro)m(vided)g(for)g(cases)h(where)150
+2637 y(some)29 b(sp)s(ecial)e(kind)g(of)i(output)g(pro)s(cessing)e(is)h
+(required)f(that)i(is)f(not)h(built)d(in)m(to)j Fy(L)-7
+b(TX2X)p Fs(.)29 b(In)f(order)g(to)150 2750 y(implemen)m(t)j(an)m(y)h
+(commands)g(of)g(these)h(t)m(yp)s(es,)f(it)g(is)f(necessary)i(to)g(mo)s
+(dify)d(the)i(in)m(ternals)f(of)h Fy(L)-7 b(TX2X)150
+2863 y Fs(and)30 b(recompile)f(the)i(source)f(co)s(de.)41
+b(This)29 b(is)g(not)i(recommended.)150 3106 y Fj(2.13)112
+b(File)37 b(inclusion)150 3264 y Fs(A)c(command)g(table)g(\014le)g(can)
+g(include)e(other)j(command)f(table)g(\014les.)48 b(In)33
+b(turn)f(an)h(included)d(\014le)j(can)150 3364 y(recursiv)m(ely)c
+(include)f(other)j(command)f(table)g(\014les.)40 b(The)30
+b(\014le)f(inclusion)f(command)i(line)e(is)150 3538 y
+Fh(INCLUDE=)40 b(FileName)150 3726 y Fs(where)26 b Fh(FileName)e
+Fs(is)i(the)h(name)g(of)g(the)h(command)e(table)h(\014le)f(to)i(b)s(e)e
+(included.)37 b(The)27 b(e\013ect)h(is)e(that)i(the)150
+3839 y(ab)s(o)m(v)m(e)k(line)c(is)i(replaced)g(b)m(y)g(the)g(con)m(ten)
+m(ts)i(of)38 b Fh(FileName)p Fs(.)291 3938 y(F)-8 b(or)21
+b(example,)h(assume)e(that)h(there)g(are)f(three)h(command)f(table)g
+(\014les)f(called)h(resp)s(ectiv)m(ely)h Fn(detex.ct)p
+Fs(,)150 4038 y Fn(detex.l2x)28 b Fs(and)i Fn(detex.fl)p
+Fs(.)38 b(The)30 b(con)m(ten)m(ts)i(of)f(these)f(\014les)g(are:)150
+4212 y Fh(C=)86 b(----------file)38 b(detex.ct)150 4312
+y(...)150 4412 y(INCLUDE=)i(detex.l2x)150 4511 y(...)150
+4611 y(C=)j(----------end)38 b(of)43 b(detex.ct)150 4711
+y(END_CTFILE=)344 b(end)42 b(of)h(detex.ct)150 4885 y
+Fs(and)30 b(for)g Fn(detex.l2x)e Fs(as:)150 5059 y Fh(C=)43
+b(----------)c(file)j(detex.l2x)150 5259 y(TYPE=)g(COMMAND)1905
+5531 y Fs(33)p eop
+%%Page: 34 38
+34 37 bop 150 573 a Fh(NAME=)42 b(\\lx)237 672 y(START_TAG=)e("LTX2X")
+150 772 y(END_TYPE)150 971 y(INCLUDE=)g(detex.fl)150
+1171 y(TYPE=)i(COMMAND)150 1270 y(NAME=)g(\\ctab)237
+1370 y(START_TAG=)e("command)g(table")150 1469 y(END_TYPE)150
+1669 y(C=)j(----------)c(end)k(of)f(file)g(detex.l2x)150
+1768 y(END_CTFILE=)388 b(end)42 b(of)h(file)f(detex.l2x)150
+1943 y Fs(and)30 b(lastly)g Fn(detex.fl)f Fs(is:)150
+2117 y Fh(C=)43 b(----------)c(file)j(detex.fl)150 2316
+y(TYPE=)g(COMMAND)150 2416 y(NAME=)g(\\fl)237 2516 y(START_TAG=)e
+("FLaTTeN")150 2615 y(END_TYPE)150 2814 y(C=)j(----------)c(end)k(file)
+e(detex.fl)150 2914 y(END_CTFILE=)388 b(end)42 b(file)g(detex.fl)150
+3088 y Fs(Then,)32 b(as)g(far)g(as)g Fy(L)-7 b(TX2X)32
+b Fs(is)f(concerned,)i(the)f(original)e Fn(detex.ct)g
+Fs(\014le)h(is)g(treated)i(as)f(though)g(it)g(had)150
+3188 y(b)s(een)e(written)f(as:)150 3362 y Fh(C=)86 b(----------file)38
+b(detex.ct)150 3462 y(...)150 3562 y(C=)43 b(----------)c(file)j
+(detex.l2x)150 3761 y(TYPE=)g(COMMAND)150 3861 y(NAME=)g(\\lx)237
+3960 y(START_TAG=)e("LTX2X")150 4060 y(END_TYPE)150 4259
+y(C=)j(----------)c(file)j(detex.fl)150 4458 y(TYPE=)g(COMMAND)150
+4558 y(NAME=)g(\\fl)237 4658 y(START_TAG=)e("FLaTTeN")150
+4757 y(END_TYPE)150 4956 y(C=)j(----------)c(end)k(file)e(detex.fl)150
+5156 y(TYPE=)h(COMMAND)150 5255 y(NAME=)g(\\ctab)1905
+5531 y Fs(34)p eop
+%%Page: 35 39
+35 38 bop 237 573 a Fh(START_TAG=)40 b("command)g(table")150
+672 y(END_TYPE)150 872 y(C=)j(----------)c(end)k(of)f(file)g(detex.l2x)
+150 971 y(...)150 1071 y(C=)h(----------end)38 b(of)43
+b(detex.ct)150 1171 y(END_CTFILE=)344 b(end)42 b(of)h(detex.ct)291
+1358 y Fs(Note)32 b(that)f(nast)m(y)g(things)f(will)e(happ)s(en)h(if)g
+(y)m(ou)i(ha)m(v)m(e)h(a)f(cycle)g(of)g(inclusions.)38
+b(That)30 b(is,)g(y)m(ou)h(m)m(ust)150 1471 y(not)23
+b(ha)m(v)m(e)i(an)m(ything)d(similar)f(to)j(\014le)e
+Fn(A)g Fs(including)e(\014le)i Fn(B)h Fs(whic)m(h)f(includes)f(\014le)h
+Fn(C)h Fs(whic)m(h)f(in)f(turn)h(includes)150 1584 y(either)30
+b(\014le)f Fn(A)h Fs(or)h Fn(B)p Fs(.)150 1827 y Fj(2.14)112
+b(In)m(terpreter)37 b(commands)150 1999 y Fy(L)-7 b(TX2X)28
+b Fs(includes)e(an)h(in)m(terpreter)h(for)g(a)g(pro)s(cedural)e
+(programming)h(language)h(that)h(is)e(based)h(on)g(the)150
+2112 y(ISO)f(in)m(ternational)f(standard)h Fo(Express)f
+Fs(information)g(mo)s(deling)f(language)j([7)q(,)g(8].)40
+b(A)m(t)29 b(the)e(momen)m(t)150 2225 y(the)41 b(programming)f
+(language)h(within)d Fy(L)-7 b(TX2X)41 b Fs(is)f(anon)m(ymous,)k(but)c
+(for)h(ease)h(of)f(reference)g(I)g(will)150 2338 y(call)d(it)h
+Fo(Express-A)p Fs(\()p Fo(Express)e Fs(-Almost?)66 b(-Appro)m(ximate?)h
+(-Anon)m(ymous?\).)g(The)38 b Fo(Express-A)150 2451 y
+Fs(language)32 b(is)f(describ)s(ed)e(later)j(in)e(section)i(4,)h(but)e
+(for)g(no)m(w)h(it)f(is)f(su\016cien)m(t)h(to)i(kno)m(w)e(the)h
+(commands)150 2564 y(that)f(signify)d(the)j(start)g(and)f(end)f(of)i
+(this)e(co)s(de.)291 2677 y(The)35 b(command)g Fh(CODE)p
+1083 2677 27 4 v 29 w(SETUP=)e Fs(indicates)h(the)h(commencemen)m(t)i
+(of)e(co)s(de)g(to)h(b)s(e)e(run)g(b)s(efore)h(an)m(y)150
+2789 y(do)s(cumen)m(t)g(pro)s(cessing)f(o)s(ccurs.)54
+b(The)35 b Fh(END)p 1676 2789 V 30 w(CODE)e Fs(command)i(signi\014es)e
+(the)i(end)g(of)g(this)f(co)s(de)h(blo)s(c)m(k.)150 2902
+y(This)c(blo)s(c)m(k)g(should)g(b)s(e)g(placed)h(in)f(the)i(command)f
+(table)g(b)s(efore)g(an)m(y)g(other)h(commands)f(except)h(for)150
+3015 y(the)38 b Fh(ESCAPE...)60 b Fs(commands,)40 b(if)d(an)m(y)-8
+b(.)65 b(This)36 b(blo)s(c)m(k)i(can)g(con)m(tain)h(v)-5
+b(ariable)37 b(declarations,)i(function)150 3128 y(and)30
+b(pro)s(cedure)f(declarations,)h(and)g(statemen)m(ts.)291
+3241 y(Co)s(de)42 b(consisting)f(purely)g(of)i(statemen)m(ts)h(can)f(b)
+s(e)f(placed)g(an)m(ywhere)g(that)h(a)g(tagging)h(action)150
+3354 y(ma)m(y)e(b)s(e)f(sp)s(eci\014ed.)72 b(These)41
+b(statemen)m(ts)j(are)d(enclosed)h(b)s(et)m(w)m(een)g(a)g
+Fh(CODE:)d Fs(and)i Fh(END)p 3238 3354 V 30 w(CODE)f
+Fs(pair)g(of)150 3467 y(commands.)291 3580 y(The)28 b
+Fo(Express-A)f Fs(language)i(is)e(describ)s(ed)f(in)h(detail)h(in)f(4,)
+i(but)f(to)h(giv)m(e)f(a)h(\015a)m(v)m(our)g(of)f(it)g(here)g(is)g(a)
+150 3693 y(simple)g(p)s(ossible)g(application.)39 b(It)30
+b(has)g(b)s(een)f(noted)i(that)g Fy(L)-7 b(TX2X)30 b
+Fs(will)d(\014nd)i(di\016cult)m(y)f(in)h(pro)s(cessing)150
+3806 y(the)d(con)m(ten)m(ts)j(of)d(the)g(L)933 3789 y
+Fr(A)972 3806 y Fs(T)1023 3825 y(E)1074 3806 y(X)g Fh(picture)e
+Fs(en)m(vironmen)m(t.)39 b(The)25 b(follo)m(wing)g(p)s(ortions)g(of)h
+(a)h(command)f(table)150 3919 y(write)34 b(the)h(con)m(ten)m(ts)i(of)e
+(a)h Fh(figure)c Fs(en)m(vironmen)m(t)j(to)h(an)f(external)g(\014le)f
+(and)g(uses)h(the)g(programming)150 4032 y(language)c(to)g(k)m(eep)g(a)
+g(coun)m(t)g(of)f(the)h(n)m(um)m(b)s(er)e(of)h(\014gures)g(so)h(pro)s
+(cessed.)150 4231 y Fh(c=)86 b(declare)41 b(and)h(initialise)e(a)j
+(variable)150 4330 y(CODE_SETUP=)237 4430 y(LOCAL)324
+4530 y(fignum)e(:)j(INTEGER;)237 4629 y(END_LOCAL;)237
+4729 y(fignum)d(:=)i(0;)150 4829 y(END_CODE)150 5028
+y(c=)g(write)e(figure)g(contents)g(to)h(an)h(external)d(file)150
+5127 y(TYPE=)i(BEGIN_ENV)150 5227 y(NAME=)g(figure)1905
+5531 y Fs(35)p eop
+%%Page: 36 40
+36 39 bop 237 573 a Fh(OPT_PARAM=)40 b(FIRST)237 672
+y(PRINT_OPT=)g(NO_PRINT)237 772 y(PC_AT_START=)f(TO_FILE)h(figs.tmp)237
+872 y(START_TAG=)324 971 y(CODE:)412 1071 y(fignum)h(:=)h(fignum)f(+)j
+(1;)478 b(--)43 b(increment)d(figure)h(counter)412 1171
+y(println;)1042 b(--)43 b(print)f(a)h(blank)e(line)412
+1270 y(println\('\045\045\045)d(FIGURE)j(',)i(fignum\);)d(--)j(write)f
+(counter)e(as)j(a)g(LaTeX)f(comment)324 1370 y(END_CODE)324
+1469 y(STRING:)f("\\begin{figure}")150 1569 y(END_TYPE)150
+1768 y(c=)i(close)e(figure)g(environment,)e(back)j(to)h(normal)e
+(output,)f(and)j(output)150 1868 y(c=)g(text)f(indicating)d(that)j(a)h
+(figure)e(should)g(be)i(here)150 1968 y(TYPE=)f(END_ENV)150
+2067 y(NAME=)g(figure)237 2167 y(PC_AT_START=)d(RESET)237
+2267 y(START_TAG=)324 2366 y(SWITCH_TO_FILE:)f(figs.tmp)324
+2466 y(STRING:)j("\\end{figure}?n?)o(n")324 2565 y(SWITCH_BACK:)324
+2665 y(CODE:)412 2765 y(println;)412 2864 y(println\('PLACE)c(FOR)43
+b(FIGURE)e(',)i(fignum\);)412 2964 y(println;)281 3064
+y(END_CODE)150 3163 y(END_TYPE)150 3450 y Fu(3)135 b(The)44
+b(L)-11 b(TX2X)44 b(program)150 3653 y Fy(L)-7 b(TX2X)27
+b Fs(is)f(written)f(using)h(\015ex)g(and)h(bison.)38
+b(The)26 b(resulting)f(C)h(co)s(de)h(should)e(compile)h(on)g(an)m(y)i
+(system.)150 3765 y(More)i(details)e(are)h(giv)m(en)g(later,)g(but)f
+(for)h(the)g(end-user)f(the)h(next)g(section)h(describ)s(es)d(ho)m(w)i
+(to)g(run)f(the)150 3878 y(program,)i(assuming)f(that)i(is)f(a)m(v)-5
+b(ailable)29 b(on)i(y)m(our)f(system.)150 4122 y Fj(3.1)112
+b(Running)37 b(L)-9 b(TX2X)150 4293 y Fs(The)30 b(syn)m(tax)h(for)f
+(running)e(the)i(compiled)f(v)m(ersion)h(of)g Fy(L)-7
+b(TX2X)31 b Fs(is:)150 4481 y Fn(ltx2x)46 b([-c])h([-f)g(table-file])e
+([-p)i(number])e([-w])i([-D)g(dir_cat_char])436 4594
+y([-P)g(path_seperators])d([-S])436 4707 y([-i)j(number])f([-l)h
+(number])f([-t])g([-y)h(number])f([-C])h([-E])436 4820
+y(input-file)e(output-file)150 5007 y Fs(where)26 b(elemen)m(ts)h(in)e
+(square)h(brac)m(k)m(ets)i(are)f(options.)38 b(The)26
+b(options)g(fall)f(in)m(to)h(t)m(w)m(o)i(groups,)f(one)g(for)f(the)150
+5120 y(casual)32 b(user)g(and)g(the)h(other)g(for)f(those)h(who)f(ma)m
+(y)h(b)s(e)f(in)m(terested)h(in)e(the)i(in)m(ternals)e(of)i
+Fy(L)-7 b(TX2X)p Fs(.)32 b(The)150 5233 y(\014rst)e(group)f(of)i
+(options)f(includes:)1905 5531 y(36)p eop
+%%Page: 37 41
+37 40 bop 150 573 a Fn(-c)45 b Fs(By)39 b(default,)i
+Fy(L)-7 b(TX2X)39 b Fs(ignores)g(all)f(L)1571 556 y Fr(A)1610
+573 y Fs(T)1661 592 y(E)1711 573 y(X)h(commen)m(ts)h(in)e(the)h(input)f
+(\014le.)66 b(This)37 b(option)i(causes)377 686 y Fy(L)-7
+b(TX2X)31 b Fs(to)g(write)e(the)i(commen)m(ts)g(to)g(the)g(output)f
+(\014le.)150 873 y Fn(-f)45 b Fs(By)25 b(default,)h Fy(L)-7
+b(TX2X)25 b Fs(reads)g(the)h(command)f(table)g(from)f(a)i(\014le)e
+(called)h Fn(ltx2x.ct)p Fs(.)37 b(If)24 b(the)i(required)377
+986 y(command)31 b(table)h(is)e(in)g(a)i(\014le)f(with)f(another)h
+(name)h(this)e(option)h(is)f(used)h(to)h(c)m(hange)h(from)e(the)377
+1099 y(default)f(\014le.)40 b(F)-8 b(or)31 b(example,)377
+1324 y Fn(>)48 b(ltx2x)e(in.tex)g(out.l2x)377 1549 y
+Fs(reads)30 b(a)h(command)f(table)h(from)e Fn(ltx2x.ct)p
+Fs(,)g(while)377 1774 y Fn(>)48 b(ltx2x)e(-f)h(detex.ct)f(in.tex)g
+(out.l2x)377 1999 y Fs(reads)30 b(a)h(command)f(table)h(from)e(\014le)h
+Fn(detex.ct)p Fs(.)150 2187 y Fn(-p)45 b Fs(This)29 b(option)i(causes)h
+Fy(L)-7 b(TX2X)31 b Fs(to)h(`prett)m(y)g(prin)m(t')e(the)i(output)f
+(\014le)f(\(as)i(far)f(as)h(it)f(is)f(able)h(to\).)44
+b(The)377 2300 y Fn(number)35 b Fs(is)h(required)f(and)h(it)g
+(indicates)f(the)i(desired)e(maxim)m(um)h(n)m(um)m(b)s(er)f(of)i(c)m
+(haracters)h(p)s(er)377 2413 y(output)32 b(line.)45 b(If)32
+b(this)f(is)h(considered)f(to)i(b)s(e)f(to)s(o)h(small,)e(then)h
+Fy(L)-7 b(TX2X)33 b Fs(c)m(ho)s(oses)g(a)g(v)-5 b(alue.)46
+b(Note)377 2526 y(that)31 b(prett)m(y)f(prin)m(ting)e(is)h(only)g
+(applied)f(to)j(the)f(source)g(\014le)f(|)h(not)g(to)h(an)m(y)f
+(replacemen)m(t)h(tags.)377 2638 y(That)g(is,)e(it)h(only)g(tries)f(to)
+j(format)e(the)h(running)c(text)32 b(from)e(the)g(source)h(\014le.)150
+2826 y Fn(-w)45 b Fs(By)37 b(default,)g Fy(L)-7 b(TX2X)36
+b Fs(outputs)g(source)g(white)g(space)g(just)g(at)h(it)f(reads)g(it.)58
+b(This)35 b(option)h(causes)377 2939 y Fy(L)-7 b(TX2X)35
+b Fs(to)h(collapse)e(an)m(y)h(amoun)m(t)h(of)f(con)m(tiguous)g(white)f
+(space)h(to)h(a)f(single)e(space.)55 b(The)35 b Fn(-p)377
+3052 y Fs(option)30 b(includes)e(the)j Fn(-w)e Fs(option.)150
+3240 y Fn(-D)45 b Fs(The)39 b(v)-5 b(alue)39 b(of)h(this)e(option)i(is)
+e(the)i(c)m(haracter)h(that)f(the)g(op)s(erating)f(system)h(uses)f(to)i
+(catenate)377 3352 y(directory)31 b(names)f(to)i(form)e(a)h(path)g
+(\(see)g(3.1.1\).)44 b(The)31 b(default)f(v)-5 b(alue)30
+b(is)g(a)h(slash)e(\(i.e.)43 b Fn(/)p Fs(\).)e(The)377
+3465 y(default)30 b(could)f(b)s(e)h(c)m(hanged)h(to)g(a)g(bac)m
+(kslash,)f(for)g(example,)h(b)m(y)f Fn(-D)47 b(\\)p Fs(.)150
+3653 y Fn(-P)e Fs(The)33 b(en)m(vironmen)m(t)h(v)-5 b(ariable)33
+b(\(see)h(3.1.1\))i(con)m(tains)f(a)f(list)e(of)i(directories)f(\(also)
+i(kno)m(wn)e(as)h(path)377 3766 y(names\).)73 b(In)40
+b(the)h(op)s(erating)f(system)h(that)g(I)g(use,)i(these)f(are)f
+(separated)g(b)m(y)g(the)g(colon)g(\()p Fn(:)p Fs(\))377
+3879 y(c)m(haracter)32 b(whic)m(h,)e(together)i(with)e(the)g
+(semi-colon)h(and)f(space)h(c)m(haracters,)h(form)e(the)h
+Fy(L)-7 b(TX2X)377 3992 y Fs(default)34 b(separators.)56
+b(The)34 b(path)h(separator)h(c)m(haracters)g(can)f(b)s(e)g(c)m(hanged)
+h(with)d(this)h(option.)377 4105 y(F)-8 b(or)30 b(example,)f
+Fn(-P)47 b(:)29 b Fs(will)e(mak)m(e)j(the)f(separators)g(b)s(e)g(a)g
+(colon)g(or)g(a)h(space)f(\(space)h(is)e(automati-)377
+4218 y(cally)i(included)e(in)h(the)h(separator)h(list\).)150
+4405 y Fn(-S)45 b Fs(This)32 b(option)i(enables)f(the)h(source)g(lev)m
+(el)g(debugger)g(\(see)h(4.6\))g(for)f(an)m(y)g(em)m(b)s(edded)f
+Fo(Express-A)377 4518 y Fs(co)s(de.)291 4706 y(The)23
+b(second)g(group)f(of)i(options)e(are)h(principally)c(for)k(those)h
+(who)e(migh)m(t)h(b)s(e)f(extending)h(the)g Fy(L)-7 b(TX2X)150
+4819 y Fs(system.)150 5031 y Fn(-i)45 b Fs(This)21 b(pro)s(duces)h
+(information)f(that)j(ma)m(y)g(b)s(e)e(useful)f(for)i(debugging)f(the)h
+Fo(Express-A)f Fs(in)m(terpreter.)377 5144 y Fn(number)35
+b Fs(is)g(an)h(in)m(teger)g(b)s(et)m(w)m(een)h(1)f(and)f(9)i(inclusiv)m
+(e.)55 b(The)36 b(greater)h(the)f(n)m(um)m(b)s(er,)h(the)f(more)377
+5257 y(diagnostics)30 b(are)h(generated.)1905 5531 y(37)p
+eop
+%%Page: 38 42
+38 41 bop 150 573 a Fn(-l)45 b Fs(This)i(pro)s(duces)h(information)g
+(that)i(ma)m(y)g(b)s(e)e(useful)g(for)h(debugging)f(the)i
+Fy(L)-7 b(TX2X)49 b Fs(program.)377 686 y Fn(number)35
+b Fs(is)g(an)h(in)m(teger)g(b)s(et)m(w)m(een)h(1)f(and)f(9)i(inclusiv)m
+(e.)55 b(The)36 b(greater)h(the)f(n)m(um)m(b)s(er,)h(the)f(more)377
+799 y(diagnostics)30 b(are)h(generated.)150 986 y Fn(-t)45
+b Fs(This)28 b(generates)k(diagnostics)e(related)g(to)h(the)g(pro)s
+(cessing)e(of)i(the)f(command)g(table)g(\014le.)150 1174
+y Fn(-y)45 b Fs(Lik)m(e)29 b(the)g Fn(l)g Fs(option,)f(but)h(pro)s
+(duces)e(diagnostic)i(information)e(from)i(the)g(parser)f(\(this)g(is)g
+(actually)377 1287 y(a)j(n)m(ull)d(option,)i(but)g(ma)m(y)h(b)s(e)f
+(useful)e(in)h(the)i(future\).)150 1474 y Fn(-C)45 b
+Fs(Disable)28 b(an)m(y)h(in)m(terpreter)f(debugging)g(information)f
+(during)g(the)i(co)s(de)g(generation)g(pass.)40 b(This)27
+b(is)377 1587 y(not)k(necessary)g(unless)d(the)j Fn(-i)f
+Fs(option)g(is)f(used.)150 1775 y Fn(-E)45 b Fs(Disable)20
+b(an)m(y)h(in)m(terpreter)f(debugging)g(information)f(during)g(the)i
+(co)s(de)g(execution)g(pro)s(cessing.This)377 1888 y(is)30
+b(not)g(necessary)h(unless)e(the)h Fn(-i)g Fs(option)g(is)f(used.)291
+2100 y Fy(L)-7 b(TX2X)40 b Fs(\014rst)f(reads)h(the)g(sp)s(eci\014ed)e
+(command)i(table)g(\014le,)h(together)h(with)c(an)m(y)j(included)c
+(\014les,)150 2213 y(lo)s(oking)d(\014rst)g(in)f(the)i(curren)m(t)g
+(directory)-8 b(,)36 b(then)e(in)g(the)h(directories)f(sp)s(eci\014ed)f
+(b)m(y)h(the)h(en)m(vironmen)m(t)150 2326 y(v)-5 b(ariable)34
+b(\(if)h(it)g(exists\).)56 b(It)36 b(then)f(reads)g(the)h
+Fn(input-file)d Fs(from)i(the)g(curren)m(t)h(directory)-8
+b(,)37 b(p)s(erforms)150 2439 y(the)31 b(actions)f(sp)s(eci\014ed)f(in)
+g(the)h(command)h(table)f(and)g(outputs)f(the)i(results)e(to)i(the)g
+Fn(output-file)p Fs(.)291 2552 y(Three)f(other)h(\014les)e(are)i(also)f
+(generated.)286 2740 y Fm(\017)46 b Fn(ltx2xct.lis)29
+b Fs(|)j(This)e(con)m(tains)j(a)f(h)m(uman-readable)f(form)h(of)g(the)g
+(in)m(ternal)f(represen)m(tation)377 2853 y(of)23 b(the)g(command)g
+(table.)38 b(It)23 b(ma)m(y)g(b)s(e)f(useful)f(if)h(there)h(are)g(an)m
+(y)g(errors)f(in)f(the)i(original)e(command)377 2966
+y(table.)286 3153 y Fm(\017)46 b Fn(ltx2x.err)33 b Fs(|)h(This)g(con)m
+(tains)h(an)m(y)g(error)f(or)h(w)m(arning)f(messages)i(generated)g(b)m
+(y)f Fy(L)-7 b(TX2X)p Fs(.)35 b(It)377 3266 y(also)23
+b(con)m(tains)f(an)m(y)h(diagnostic)f(information)f(that)i(ma)m(y)g(ha)
+m(v)m(e)h(b)s(een)e(requested)g(via)g(a)h(command)377
+3379 y(line)29 b(option.)286 3567 y Fm(\017)46 b Fn(interp.csg)27
+b Fs(|)j(This)e(con)m(tains)i(a)g(h)m(uman)f(readable)g(listing)f(of)i
+(the)f(in)m(ternal)g(b)m(yte)h(co)s(de)g(gen-)377 3680
+y(erated)h(b)m(y)g(the)f Fo(Express-A)f Fs(in)m(terpreter.)291
+3867 y(When)41 b Fy(L)-7 b(TX2X)41 b Fs(is)f(running)f(normally)g(it)i
+(prin)m(ts)e(out)j(a)f(coun)m(ter)h(to)g(the)f(terminal)f(indicating)
+150 3980 y(ho)m(w)35 b(man)m(y)g(h)m(undreds)e(of)i(input)e(source)i
+(\014le)g(lines)e(it)h(has)h(pro)s(cessed.)54 b(Lac)m(k)36
+b(of)g(suc)m(h)e(output)h(is)f(an)150 4093 y(indication)d(that)i(the)g
+(program)g(ma)m(y)g(b)s(e)g(in)e(a)i(lo)s(op)f(and)h(c)m(hewing)f(up)g
+(CPU)g(cycles)h(to)h(no)f(a)m(v)-5 b(ail.)48 b(In)150
+4206 y(this)29 b(case,)j(stop)f(the)g(program)f(and)g(examine)g(the)h
+(output)f(for)h(indications)d(of)j(where)f(the)g(trouble)g(is)150
+4319 y(o)s(ccurring.)291 4432 y(A)39 b(limited)d(n)m(um)m(b)s(er)i(of)g
+(errors)g(are)h(allo)m(w)m(ed)g(when)f(pro)s(cessing)f(the)i(command)f
+(table)h(and)f(the)150 4545 y(input)27 b(L)415 4528 y
+Fr(A)454 4545 y Fs(T)505 4564 y(E)555 4545 y(X)i(\014le)f(b)s(efore)g
+Fy(L)-7 b(TX2X)29 b Fs(giv)m(es)g(up)f(and)g(quits.)39
+b(In)28 b(particular,)f(if)h(it)g(is)g(reading)g(a)h(command)150
+4658 y(table)i(\014le)f(that)h(includes)e(another)i(\014le,)f(sa)m(y)i
+(one)f(called)f Fn(zilch)p Fs(,)g(that)h(it)f(cannot)i(read,)f(it)f
+(prin)m(ts)g(the)150 4770 y(follo)m(wing)f(message)i(to)g(the)g(user's)
+f(terminal.)150 4958 y Fn(Can't)46 b(open)h(file)g(zilch)150
+5071 y(Enter)f(new)h(file)g(name,)f(or)h(I)h(to)f(ignore,)f(or)h(Q)h
+(to)f(quit)150 5184 y(:)1905 5531 y Fs(38)p eop
+%%Page: 39 43
+39 42 bop 150 573 a Fs(A)30 b Fn(Q)f Fs(\(or)i Fn(q)p
+Fs(\))f(resp)s(onse)e(stops)i Fy(L)-7 b(TX2X)30 b Fs(from)f(an)m(y)i
+(further)d(pro)s(cessing.)40 b(An)29 b Fn(I)h Fs(\(or)g
+Fn(i)p Fs(\))g(resp)s(onse)f(causes)150 686 y Fy(L)-7
+b(TX2X)35 b Fs(to)g(stop)g(lo)s(oking)e(for)i(the)g(included)d(\014le)h
+(and)h(con)m(tin)m(ue)h(pro)s(cessing)f(the)h(curren)m(t)f(\014le.)53
+b(An)m(y)150 799 y(other)43 b(resp)s(onse)f(is)g(tak)m(en)i(to)g(b)s(e)
+e(the)i(name)f(of)g(an)g(included)d(\014le,)45 b(whic)m(h)d
+Fy(L)-7 b(TX2X)43 b Fs(then)g(tries)f(to)150 912 y(read.)f(If)30
+b(it)f(fails,)h(then)g(the)g(ab)s(o)m(v)m(e)i(message)f(is)f(rep)s
+(eated.)41 b(The)29 b(user)h(is)f(giv)m(en)i(a)g(limited)d(n)m(um)m(b)s
+(er)h(of)150 1024 y(opp)s(ortunities)f(to)j(iden)m(tify)e(a)i(readable)
+e(\014le)h(b)s(efore)g Fy(L)-7 b(TX2X)30 b Fs(quits)f(altogether)j
+(with)d(this)g(message:)150 1212 y Fn(Last)47 b(attempt.)e(Can't)i
+(open)f(file)h(zilch.)f(I'm)h(giving)f(up.)291 1400 y
+Fs(Regarding)20 b(p)s(erformance,)j(the)e(time)f(tak)m(en)i(b)m(y)f
+Fy(L)-7 b(TX2X)21 b Fs(to)h(pro)s(cess)e(a)h(do)s(cumen)m(t)g(do)s(es)f
+(not)i(app)s(ear)150 1513 y(to)31 b(b)s(e)f(signi\014can)m(tly)e
+(di\013eren)m(t)i(from)g(the)h(time)f(to)h(L)1963 1496
+y Fr(A)2002 1513 y Fs(T)2053 1532 y(E)2103 1513 y(X)g(the)f(same)h(do)s
+(cumen)m(t.)150 1753 y Ft(3.1.1)105 b(Directory)36 b(searc)m(hing)150
+1924 y Fs(The)30 b(program)f(emplo)m(ys)h(a)g(searc)m(h)h(algorithm)e
+(to)i(\014nd)e(\014les)g(that)h(are)h(not)f(in)f(the)h(curren)m(t)g
+(directory)-8 b(.)150 2037 y(It)33 b(\014rst)g(lo)s(oks)g(in)f(the)h
+(curren)m(t)g(directory)g(and)g(if)f(a)i(\014le)e(of)i(the)f(giv)m(en)g
+(name)h(is)e(found,)h(then)g(that)h(is)150 2150 y(used.)61
+b(If)38 b(the)f(\014le)g(is)g(not)g(found,)i(then)e(it)g(searc)m(hes)h
+(for)g(it)f(among)h(directories)f(that)h(are)g(sp)s(eci\014ed)150
+2263 y(in)e(a)i(system)g(en)m(vironmen)m(t)f(v)-5 b(ariable.)62
+b(This)35 b(v)-5 b(ariable)37 b(sp)s(eci\014es)f(a)i(list)e(of)i
+(pathnames,)i(where)d(the)150 2376 y(directories)44 b(forming)g(the)h
+(path)g(are)h(com)m(bined)e(using)g(a)h(catenation)h(c)m(haracter.)87
+b(F)-8 b(or)46 b(example,)150 2489 y Fn(dir1/dir2/dir3)37
+b Fs(could)k(b)s(e)g(a)g(pathname,)j(where)d(the)h(slash)e(\()p
+Fn(/)p Fs(\))i(is)e(the)i(catenation)g(c)m(haracter.)150
+2602 y(If)g(it)f(is)g(lo)s(oking)g(for)h(\014le)f Fn(afile.txt)e
+Fs(it)j(will)d(catenate)44 b(the)e(\014le)g(name)g(to)g(the)h(path)e
+(name)h(\(e.g.)150 2715 y Fn(dir1/dir2/dir3/afile.txt)o
+Fs(\))29 b(and)34 b(lo)s(ok)g(for)g(that.)53 b(The)33
+b(pathnames)h(in)f(the)i(list)e(are)h(separated)150 2828
+y(b)m(y)f(another)g(c)m(haracter)h(\(in)e(fact)i(it)e(can)h(b)s(e)g
+(one)g(from)f(a)i(list)d(of)i(c)m(haracters\).)50 b(F)-8
+b(or)34 b(example)e(here)h(is)150 2941 y(a)d(list)f(of)h(t)m(w)m(o)h
+(pathnames;)f Fn(dir1/dir2;dir1/dir4)p Fs(,)25 b(where)k(the)h
+(semi-colon)g(\()p Fn(;)p Fs(\))g(is)f(the)h(pathname)150
+3054 y(separator.)291 3166 y(By)j(default,)e(the)i(program)f(uses)f(a)i
+(slash)e(\()p Fn(/)p Fs(\))h(as)h(the)f(directory)f(catenation)j(c)m
+(haracter)f(and)f(the)150 3279 y(pathname)41 b(separators)h(can)g(b)s
+(e)f(a)g(space,)k(or)d(a)f(colon)h(or)f(a)h(semi-colon)f(\(i.e.,)k(an)m
+(y)d(of)f Fn( :;)p Fs(\).)73 b(All)150 3392 y(these)34
+b(c)m(haracters)g(can)g(b)s(e)e(altered)i(via)e(the)i(program)f
+(command)g(line)e(options,)j(and)f(should)e(b)s(e)h(set)150
+3505 y(to)f(matc)m(h)g(the)g(con)m(v)m(en)m(tions)g(of)g(y)m(our)f(op)s
+(erating)g(system.)291 3618 y(The)36 b(en)m(vironmen)m(t)g(v)-5
+b(ariable)35 b(used)g(b)m(y)i(the)f(program)g(is)g(L)-8
+b(TX2XT)g(ABLES.)37 b(On)e(the)h(op)s(erating)150 3731
+y(system)31 b(that)f(I)h(use,)f(I)g(set)h(this)e(in)g(m)m(y)i(login)e
+(\014le)h(lik)m(e:)150 3919 y Fn(setenv)46 b(LTX2XTABLES)f
+(.:/dir1/dir2:/dir3/dir4)150 4106 y Fs(Y)-8 b(our)33
+b(system)h(ma)m(y)f(ha)m(v)m(e)i(di\013eren)m(t)d(con)m(v)m(en)m
+(tions.)50 b(Note)35 b(that)e(if)g(the)g(en)m(vironmen)m(t)g(v)-5
+b(ariable)32 b(is)g(not)150 4219 y(set,)f(only)f(\014les)f(in)g(the)i
+(curren)m(t)f(directory)g(are)g(considered.)150 4463
+y Fj(3.2)112 b(System)37 b(comp)s(onen)m(ts)150 4634
+y Fs(The)42 b(system)g(consists)f(of)h(\014v)m(e)h(main)e(comp)s(onen)m
+(ts)h(|)f(a)i(lexer,)i(a)d(parser,)j(a)d(library)e(of)i(supp)s(ort)150
+4747 y(functions)g(and)h(command)g(table)h(parsing)e(co)s(de,)47
+b(a)d(user-de\014ned)e(library)g(of)h(functions,)j(and)d(an)150
+4860 y(in)m(terpreter)30 b(for)g(the)g Fo(Express-A)g
+Fs(language.)1905 5531 y(39)p eop
+%%Page: 40 44
+40 43 bop 150 573 a Ft(3.2.1)105 b(The)35 b(lexer)150
+744 y Fs(The)i(lexer)g(is)f(generated)j(b)m(y)e(\015ex)h([9])g(\(a)g
+(more)g(functional)d(v)m(ersion)i(of)h(lex)f([10)q(]\).)63
+b(The)37 b(source)g(for)150 857 y(the)30 b(lexer)g(is)f(in)g(\014le)g
+Fn(l2x.l)p Fs(.)40 b(Its)30 b(principal)d(function)i(is)g(to)i(read)f
+(a)g(L)2546 841 y Fr(A)2585 857 y Fs(T)2636 877 y(E)2687
+857 y(X)g(source)g(\014le)g(and)f(recognize)150 970 y(L)174
+954 y Fr(A)213 970 y Fs(T)264 990 y(E)314 970 y(X)34
+b(commands.)51 b(In)34 b(general,)h(it)e(passes)h(o\013)g(the)g(relev)
+-5 b(an)m(t)35 b(command)e(tok)m(ens)i(to)g(the)f(parser)f(for)150
+1083 y(p)s(erforming)28 b(appropriate)i(actions.)291
+1196 y(Ho)m(w)m(ev)m(er,)j(the)d(lexer)g(do)s(es)g(do)h(some)f(pro)s
+(cessing)g(of)g(the)h(source)f(itself.)286 1365 y Fm(\017)46
+b Fs(It)33 b(recognizes)g(L)934 1348 y Fr(A)973 1365
+y Fs(T)1024 1385 y(E)1074 1365 y(X)f(commen)m(ts)i(\(i.e.)46
+b(an)m(y)33 b(text)g(starting)f(with)f(a)i(p)s(ercen)m(t)f(sign)g(and)f
+(ending)377 1478 y(with)e(a)i(newline\).)39 b(It)31 b(silen)m(tly)d
+(ignores)i(these)h(commen)m(ts,)g(unless)e(run)g(with)g(the)i
+Fn(-c)e Fs(option.)286 1658 y Fm(\017)46 b Fs(It)35 b(recognizes)h(the)
+g(`standard')e(L)1535 1642 y Fr(A)1574 1658 y Fs(T)1625
+1678 y(E)1676 1658 y(X)h(v)m(erbatims.)54 b(It)35 b(will)e(write)h(out)
+h(the)h(appropriate)e(tags)377 1771 y(at)d(the)e(start)h(and)f(end)g
+(of)h(the)f(v)m(erbatim)h(text,)h(while)c(writing)h(the)h(v)m(erbatim)g
+(text)i(directly)d(to)377 1884 y(the)35 b(output)e(\014le,)i(b)m
+(ypassing)d(the)j(parser.)51 b(It)34 b(do)s(es)g(not)g(distinguish)c(b)
+s(et)m(w)m(een)35 b(the)f(unstarred)377 1997 y(and)c(starred)g(v)m
+(ersions)g(of)g(the)h(v)m(erbatims.)286 2177 y Fm(\017)46
+b Fs(Newlines)32 b(and)g(whitespace)h(are)g(directly)f(written)g(to)h
+(the)h(output)e(\014le,)h(again)g(b)m(ypassing)f(the)377
+2290 y(parser.)54 b(The)35 b Fn(-p)f Fs(and)g Fn(-w)h
+Fs(options)f(con)m(trol)h(the)g(\014nal)f(app)s(earance)h(of)g
+(whitespace,)h(newlines)377 2403 y(and)30 b(paragraphing.)286
+2583 y Fm(\017)46 b Fs(It)38 b(recognizes)g(the)g(command)f
+Fn(\\ )g Fs(i.e.)63 b(a)38 b(bac)m(kslash)f(follo)m(w)m(ed)g(b)m(y)h(a)
+g(space,)i(and)d(writes)g(the)377 2696 y(tags)32 b(de\014ned)d(in)g
+(the)h Fn(SLASH_SPACE)e Fs(sp)s(eci\014cation)h(directly)g(to)i(the)g
+(output)f(\014le.)291 2865 y(The)g(lexer)g(is)f(designed)h(to)h
+(recognize)g(four)f(kinds)e(of)i(L)2221 2849 y Fr(A)2260
+2865 y Fs(T)2311 2885 y(E)2362 2865 y(X)g(commands.)286
+3034 y Fm(\017)46 b Fs(Commands)30 b(of)g(the)h(form)f
+Fn(\\begin{environment})286 3215 y Fm(\017)46 b Fs(Commands)30
+b(of)g(the)h(form)f Fn(\\end{environment})286 3395 y
+Fm(\017)46 b Fs(An)m(y)31 b(other)f(command)g(of)h(the)g(form)e
+Fn(\\command)286 3575 y Fm(\017)46 b Fs(As)31 b(sp)s(ecial)e(cases,)i
+(commands)f(that)h(are)g('v)m(erbatim-lik)m(e')f(or)g(`v)m(erb-lik)m
+(e'.)150 3744 y(When)e(it)f(\014nds)f(a)i(command,)h(it)e(lo)s(oks)g
+(up)g(the)h(command)g(or)f(en)m(vironmen)m(t)h(name)g(in)e(the)i
+(command)150 3857 y(table)36 b(and)f(sends)g(the)h(appropriate)e(tok)m
+(en)j(and)e(its)h(command)f(table)h(lo)s(cation)f(to)i(the)f(parser.)56
+b(As)150 3970 y(a)41 b(sp)s(ecial)f(case)h(the)g(con)m(ten)m(ts)i(of)e
+(v)m(erbatim-lik)m(e)f(en)m(vironmen)m(ts)g(and)g(the)h(argumen)m(t)g
+(of)g(v)m(erb-lik)m(e)150 4083 y(co)s(ommands)30 b(are)h(pro)s(cessesd)
+e(within)f(the)j(lexer)f(and)g(not)g(sen)m(t)h(to)g(the)g(parser.)150
+4320 y Ft(3.2.2)105 b(The)35 b(parser)150 4491 y Fs(The)e(parser)g(is)g
+(generated)i(b)m(y)f(bison)e([9)q(])i(\(a)g(more)g(p)s(o)m(w)m(erful)e
+(v)m(ersion)i(of)g(Y)-8 b(A)m(CC)34 b([11)q(]\).)51 b(The)34
+b(source)150 4604 y(for)k(the)g(parser)g(is)f(in)g(\014le)g
+Fn(l2x.y)p Fs(.)63 b(Essen)m(tially)37 b(it)g(de\014nes)h(a)g(v)m(ery)h
+(simple)d(grammar)i(for)g(a)g(L)3541 4587 y Fr(A)3580
+4604 y Fs(T)3631 4624 y(E)3682 4604 y(X)150 4717 y(do)s(cumen)m(t.)57
+b(That)35 b(is,)i(the)f(grammar)f(is)g(limited)f(to)i(generic)g(kinds)e
+(of)i(commands)f(and)g(command)150 4830 y(argumen)m(ts.)41
+b(It)31 b(do)s(es)f(not)g(understand)f(the)h(`meaning')g(of)h(an)m(y)g
+(of)f(the)h(commands)f(or)g(argumen)m(ts.)291 4943 y(When)39
+b(the)f(parser)g(receiv)m(es)i(a)f(tok)m(en)g(from)g(the)f(lexer)h(it)f
+(tries)g(to)h(matc)m(h)h(it)e(with)f(one)i(of)g(the)150
+5056 y(grammar)30 b(rules,)f(p)s(erforming)f(the)j(actions)f(sp)s
+(eci\014ed)e(b)m(y)j(the)f(command)g(table.)40 b(Here)31
+b(is)e(an)h(extract)150 5169 y(from)23 b(the)h(parser)f(grammar)h
+(\014le,)g Fn(l2x.y)p Fs(,)g(for)f(a)h(L)1838 5152 y
+Fr(A)1877 5169 y Fs(T)1928 5188 y(E)1978 5169 y(X)g(command)f(that)i
+(has)e(t)m(w)m(o)i(required)d(argumen)m(ts)150 5282 y(follo)m(w)m(ed)30
+b(b)m(y)g(an)h(optional)e(argumen)m(t.)1905 5531 y(40)p
+eop
+%%Page: 41 45
+41 44 bop 150 573 a Fh(l2xComm2Opt:)39 b(COMMAND_2_OPT)499
+672 y({)586 772 y(start_with_req\($)o(1\))o(;)499 872
+y(})499 971 y(ReqParam)499 1071 y({)586 1171 y(action_p_p1\($1,1)o(\);)
+499 1270 y(})499 1370 y(ReqParam)499 1469 y({)586 1569
+y(action_p_opt\($1,)o(2\))o(;)499 1669 y(})499 1768 y(OptParam)499
+1868 y({)586 1968 y(action_last_opt\()o($1)o(\);)499
+2067 y(})499 2167 y(;)291 2379 y Fs(The)29 b(actions)g(are)g(enclosed)g
+(in)e(braces,)j(and)e(are)h(in)m(tersp)s(ersed)e(with)h(the)h(elemen)m
+(ts)g(of)g(the)g(gram-)150 2492 y(mar.)291 2605 y(The)40
+b(tok)m(en)h Fn(COMMAND_2_OPT)36 b Fs(indicates)j(that)h(the)g(lexer)g
+(has)f(found)g(a)h(command)g(that)g(tak)m(es)150 2718
+y(t)m(w)m(o)30 b(required)e(argumen)m(ts)h(follo)m(w)m(ed)g(b)m(y)g(an)
+f(optional)h(argumen)m(t.)40 b(The)29 b(parser)f(then)h(p)s(erforms)f
+(some)150 2831 y(actions.)42 b(The)30 b Fn(start_with_req)d
+Fs(function)i(is)h(the)h(standard)e Fy(L)-7 b(TX2X)31
+b Fs(function)e(for)i(the)g(\014rst)f(action)150 2944
+y(in)21 b(a)j(command)e(pro)s(duction)f(where)h(the)h(\014nal)f
+(argumen)m(t)h(is)f(optional.)37 b(The)22 b Fn($1)g Fs(refers)h(to)g
+(the)g(lo)s(cation)150 3057 y(of)32 b(the)g(particular)e(command)h(in)f
+(the)i(command)g(table,)g(and)f(its)g(v)-5 b(alue)31
+b(is)g(passed)g(to)h(the)g(parser)f(b)m(y)150 3170 y(the)g(lexer.)291
+3283 y(The)41 b(parser)f(then)h(exp)s(ects)g(a)h(required)d(argumen)m
+(t)j(\(i.e.)73 b Fn({)p Fs(,)44 b(tok)m(en)e Fn(LBRACE)p
+Fs(\))d(as)j(the)f(start)h(of)150 3396 y(the)d(required)f(argumen)m(t,)
+k(follo)m(w)m(ed)c(b)m(y)h(the)h(text)g(of)f(the)h(argumen)m(t)f(and)g
+(\014nished)d(o\013)k(b)m(y)f(a)g(righ)m(t)150 3509 y(brace)j(\(i.e.)74
+b Fn(})p Fs(,)44 b(tok)m(en)f Fn(RBRACE)p Fs(\);)d(the)i(grammar)g(for)
+f(all)f(of)i(this)f(is)f(sp)s(eci\014ed)g(in)g(the)i(pro)s(duction)150
+3621 y(called)28 b Fn(ReqParam)p Fs(\).)39 b(If)29 b(it)g(\014nds)e
+(these)j(it)f(p)s(erforms)e(some)j(further)e(actions,)i(otherwise)f(it)
+g(rep)s(orts)f(an)150 3734 y(error.)39 b(In)26 b(this)g(case)h(the)g
+(action)g(is)f(de\014ned)f(b)m(y)i(the)g(function)e Fn(action_p_p1)p
+Fs(,)g(whic)m(h)g(is)h(the)h(standard)150 3847 y(action)39
+b(p)s(erformed)e(b)s(et)m(w)m(een)i(t)m(w)m(o)h(required)d(argumen)m
+(ts)i(\(the)g(second)f(argumen)m(t)h(in)f(the)g(function)150
+3960 y(call)d(sp)s(eci\014es)f(the)h(Pth)g(argumen)m(t)h(that)g(has)f
+(b)s(een)g(recognized\).)56 b(Another)36 b(required)d(argumen)m(t)j(is)
+150 4073 y(then)41 b(exp)s(ected.)73 b(In)41 b(this)f(case)i(the)f
+(action)h(is)e(de\014ned)g(b)m(y)h(the)h(function)d Fn(action_p_opt)p
+Fs(,)i(whic)m(h)150 4186 y(is)35 b(the)i(standard)e(action)h(p)s
+(erformed)f(b)s(et)m(w)m(een)i(the)f(end)g(of)g(the)g(Pth)g(required)f
+(argumen)m(t)h(and)g(the)150 4299 y(start)i(of)f(an)g(optional)g
+(argumen)m(t.)62 b(It)37 b(then)g(lo)s(oks)g(for)g(an)g(optional)g
+(argumen)m(t,)i(the)f(grammar)f(for)150 4412 y(whic)m(h)d(is)g(sp)s
+(eci\014ed)g(in)g(the)i(pro)s(duction)d(called)i Fn(OptParam)p
+Fs(.)53 b(The)35 b(\014nal)f(action)h(is)g(sp)s(eci\014ed)f(b)m(y)h
+(the)150 4525 y(standard)24 b(function)g Fn(action_last_opt)d
+Fs(for)j(\014nishing)e(o\013)j(a)h(command)f(that)g(ends)f(with)g(an)h
+(optional)150 4638 y(argumen)m(t.)291 4751 y(The)36 b(grammar)g(for)g
+(a)h(command)f(that)h(that)g(has)f(t)m(w)m(o)i(required)c(argumen)m
+(ts,)39 b(and)d(p)s(ossibly)d(an)150 4863 y(initial)28
+b(optional)h(argumen)m(t)i(is)e(similar:)150 5063 y Fh(l2xComm2:)40
+b(COMMAND_2)499 5162 y({)586 5262 y(start_with_opt\($)o(1\))o(;)1905
+5531 y Fs(41)p eop
+%%Page: 42 46
+42 45 bop 499 573 a Fh(})499 672 y(OptParam)499 772 y({)586
+872 y(action_opt_first)o(\($)o(1\);)499 971 y(})499 1071
+y(ReqParam)499 1171 y({)586 1270 y(action_p_p1\($1,1)o(\);)499
+1370 y(})499 1469 y(ReqParam)499 1569 y({)586 1669 y(action_last_p\($1)
+o(,2)o(\);)499 1768 y(})499 1868 y(;)150 2107 y Ft(3.2.3)105
+b(The)35 b(supp)s(ort)g(libraries)150 2279 y Fs(Source)d(co)s(de)h(for)
+f(the)g(C)g(main)g(program)g(and)f(supp)s(ort)g(functions)g(is)g(in)g
+(\014le)h Fn(l2xlib.c)p Fs(.)44 b(The)32 b(main)150 2391
+y(program)i(is)e(resp)s(onsible)f(for)j(reading)f(in)f(the)i(command)g
+(table)g(and)f(calling)f(the)i(lexer)f(and)h(parser)150
+2504 y(to)d(do)f(the)g(appropriate)f(pro)s(cessing.)39
+b(The)30 b(\014le)f(also)h(con)m(tains)g(a)g(v)-5 b(ariet)m(y)30
+b(of)h(supp)s(ort)d(functions)g(that)150 2617 y(are,)j(or)f(could)g(b)s
+(e,)g(used)f(in)g(the)i(lexer,)f(parser,)g(action)h(library)-8
+b(,)29 b(or)h(user-de\014ned)f(library)-8 b(.)291 2730
+y(The)30 b(standard)g(actions)g(for)g(the)h(grammar)f(are)h(con)m
+(tained)g(in)e(\014le)g Fn(l2xacts.c)p Fs(.)150 2969
+y Ft(3.2.4)105 b(The)35 b(user-de\014ned)g(library)150
+3141 y Fs(The)g(in)m(ten)m(t)h(of)f(this)g(library)e(is)h(that)j(maso)s
+(c)m(histic)e(users)f(can)i(de\014ne)f(their)f(o)m(wn)i(functions)e
+(for)h(use)150 3254 y(within)e Fy(L)-7 b(TX2X)36 b Fs(when)f(pro)s
+(cessing)f(their)h Fn(SPECIAL_)f Fs(commands,)j(without)e(ha)m(ving)g
+(to)i(mo)s(dify)d(the)150 3367 y Fy(L)-7 b(TX2X)30 b
+Fs(supp)s(ort)f(or)h(action)h(libraries.)291 3479 y(Source)23
+b(co)s(de)h(for)g(the)f(user-de\014ned)f(library)f(should)h(b)s(e)h
+(main)m(tained)f(in)g(a)i(\014le)f(called)g Fn(l2xusrlb.c)150
+3592 y Fs(and)30 b(a)h(corresp)s(onding)d(header)i(\014le)g(called)f
+Fn(l2xusrlb.h)p Fs(.)150 3831 y Ft(3.2.5)105 b(The)35
+b Fo(Express-A)f Ft(in)m(terpreter)150 4003 y Fs(The)24
+b Fo(Express-A)f Fs(in)m(terpreter)g(is)g(based)h(on)g(algorithms)f
+(originally)f(dev)m(elop)s(ed)h(b)m(y)i(Ronald)e(Mak)i([19)q(])150
+4116 y(for)33 b(in)m(terpreting)f(P)m(ascal.)50 b(His)32
+b(original)g(algorithms)g(ha)m(v)m(e)i(b)s(een)f(mo)s(di\014ed)e(and)i
+(extended)g(to)h(cater)150 4229 y(for)26 b Fo(Express-A)p
+Fs(.)f(The)h(in)m(terpreter)g(mo)s(dule)e(has)i(a)h(minimal)c(in)m
+(terface)k(with)e(the)h(rest)g(of)h(the)f Fy(L)-7 b(TX2X)150
+4342 y Fs(system,)36 b(and)e(could)f(easily)h(b)s(e)f(mo)s(di\014ed)g
+(to)i(b)s(e)e(a)i(stand-alone)g(program)f(\(in)f(fact)j(it)d(started)i
+(that)150 4455 y(w)m(a)m(y)30 b(in)e(the)h(\014rst)f(place\).)41
+b(The)28 b(in)m(terface)i(b)s(et)m(w)m(een)g Fy(L)-7
+b(TX2X)29 b Fs(and)f(the)h(in)m(terpreter)g(is)f(con\014ned)g(to)i(the)
+150 4568 y(small)f Fn(l2xistup.c)e Fs(\014le.)150 4853
+y Fu(4)135 b(The)44 b Ff(Express-A)g Fu(programming)i(language)150
+5056 y Fo(Express)22 b Fs(is)g(a)i(language)f(for)g(information)f(mo)s
+(deling)f(and)i(includes)e(b)s(oth)h(declarativ)m(e)i(and)f(pro)s
+(cedu-)150 5169 y(ral)j(asp)s(ects)g([7)q(].)39 b(There)26
+b(are)h(also)f(t)m(w)m(o)i(other)f(companion)e(languages)i(called)e
+(resp)s(ectiv)m(ely)h Fo(Express-)150 5282 y(G)40 b Fs(and)g
+Fo(Express-I)p Fs(.)f(The)h(former)f(of)i(these)f(is)f(a)i(graphical)e
+(form)g(of)i(the)f(declaritiv)m(e)f(asp)s(ects)i(of)1905
+5531 y(42)p eop
+%%Page: 43 47
+43 46 bop 150 573 a Fo(Express)p Fs(,)39 b(and)f(the)g(later)g(is)g(an)
+g(instiation)e(and)i(test)h(case)h(sp)s(eci\014cation)d(language.)64
+b(These)38 b(lan-)150 686 y(guages)31 b(are)g(either)f(ISO)f(in)m
+(ternational)h(standards)f([8)q(])h(or)h(on)f(the)g(w)m(a)m(y)i(to)f(b)
+s(ecoming)e(so)i([12)q(].)291 799 y(Certain)24 b(of)i(the)f(pro)s
+(cedural)e(asp)s(ects)j(of)f Fo(Express)f Fs(and)g Fo(Express-I)g
+Fs(are)i(relev)m(en)m(t)g(to)g(the)f Fy(L)-7 b(TX2X)150
+912 y Fs(concepts)40 b(and)e(so,)k(together)e(with)e(some)h(other)g
+(reasons,)j(it)c(seemed)h(appropriate)f(to)i(pro)m(vide)e(an)150
+1024 y(in)m(terpreter)22 b(for)g(a)h(similar)d(language)j(for)g(use)f
+(within)e Fy(L)-7 b(TX2X)p Fs(.)23 b Fo(Express-A)e Fs(pro)m(vides)h(a)
+h(ma)5 b(jor)23 b(subset)150 1137 y(of)h(the)g Fo(Express)f
+Fs(pro)s(cedural)f(language,)k(together)g(with)d(some)h(P)m(ascal-lik)m
+(e)g(additions)f(for)g(input)g(and)150 1250 y(output.)58
+b(Of)36 b(particular)f(note,)j(strings)e(are)g(a)h(built-in)c(t)m(yp)s
+(e)k(in)e Fo(Express-A)p Fs(.)g(The)h(language)h(also)150
+1363 y(supp)s(orts)28 b(three-v)-5 b(alued)30 b(logic)h(and)e(the)i
+(concept)g(of)g(an)f(`indeterminate')g(v)-5 b(alue)29
+b(of)i(an)m(y)g(t)m(yp)s(e.)291 1463 y(Earlier)c(I)g(ga)m(v)m(e)j(an)e
+(example)g(command)g(table)g(to)g(replace)g(the)g(text)h(of)g(a)f(L)
+2920 1446 y Fr(A)2959 1463 y Fs(T)3010 1482 y(E)3060
+1463 y(X)g(do)s(cumen)m(t)g(with)150 1562 y(the)37 b(w)m(ords)g(`Go)s
+(o)s(db)m(y)m(e)h(do)s(cumen)m(t'.)62 b(Here)38 b(is)e(an)h
+Fo(Express-A)f Fs(program)h(that)h(outputs)f(`Go)s(o)s(db)m(y)m(e)150
+1662 y(do)s(cumen)m(t'.)150 1836 y Fh(println\('Goodbye)g(document'\);)
+150 1936 y(END_CODE)291 2124 y Fs(The)27 b(follo)m(wing)g(giv)m(es)h(a)
+g(brief)e(o)m(v)m(erview)j(of)f Fo(Express-A)p Fs(.)f(F)-8
+b(or)28 b(more)g(details)f(consult)g(Sc)m(henc)m(k)h(&)150
+2237 y(Wilson)h([7)q(].)150 2480 y Fj(4.1)112 b(Basic)37
+b(elemen)m(ts)150 2652 y Fo(Express-A)h Fs(is)g(a)i(case-insensitiv)m
+(e)e(language)i(and)e(uses)h(the)g(ASCI)s(I)f(c)m(haracter)i(set.)68
+b(Tw)m(o)39 b(kinds)150 2765 y(of)f(commen)m(ts)h(are)f(supp)s(orted)e
+(|)i(an)g(end)f(of)h(line)f(commen)m(t,)k(whic)m(h)36
+b(starts)j(with)d(a)j Fn(--)e Fs(pair)g(and)150 2877
+y(con)m(tin)m(ues)k(un)m(til)e(the)i(end)f(of)h(the)g(curren)m(t)g
+(line)e(|)i(and)f(an)h(extended)f(commen)m(t.)74 b(An)40
+b(extended)150 2990 y(commen)m(t)e(starts)g(with)e(a)i
+Fn(\(*)f Fs(pair)f(and)h(is)f(ended)h(b)m(y)g(a)h(matc)m(hing)f
+Fn(*\))g Fs(pair;)j(extended)d(commen)m(ts)150 3103 y(ma)m(y)31
+b(b)s(e)f(nested.)291 3216 y(The)j(language)h(con)m(tains)f(man)m(y)h
+(reserv)m(ed)f(w)m(ords,)h(some)g(of)f(whic)m(h)f(are)i(only)e
+(applicable)g(to)i(the)150 3329 y Fo(Express)29 b Fs(and)h
+Fo(Express-I)f Fs(languages.)291 3442 y(Iden)m(ti\014ers)g(are)i(comp)s
+(osed)f(of)g(an)g(initial)e(letter,)i(p)s(ossibly)e(follo)m(w)m(ed)i(b)
+m(y)g(an)m(y)g(n)m(um)m(b)s(er)f(of)i(letters,)150 3555
+y(digits,)e(and)h(the)h(underscore)e(c)m(haracter.)291
+3668 y(Literals)22 b(are)h(self)g(de\014ning)e(constan)m(t)j(v)-5
+b(alues.)38 b(An)22 b(in)m(teger)i(literal)d(consists)i(of)g(one)g(or)g
+(more)g(digits,)150 3781 y(the)34 b(\014rst)g(of)g(whic)m(h)e(shall)h
+(not)h(b)s(e)f(zero.)53 b(Real)34 b(n)m(um)m(b)s(ers)f(start)h(with)f
+(one)h(or)g(more)g(digits,)g(follo)m(w)m(ed)150 3894
+y(b)m(y)g(a)g(decimal)e(p)s(oin)m(t.)50 b(F)-8 b(urther)34
+b(digits)e(ma)m(y)i(o)s(ccur)g(after)g(the)g(p)s(oin)m(t,)g(and)f
+(\014naly)g(there)h(ma)m(y)g(b)s(e)f(an)150 4007 y(exp)s(onen)m(t)d(in)
+f(the)i(`e')g(notation)g(format)g(\(e.g.,)h Fn(123.456e-78)p
+Fs(\).)291 4120 y(A)d(string)f(literal)f(is)h(an)m(y)i(sequence)f(of)g
+(c)m(haracters)h(enclosed)f(b)m(y)g(single)e(quote)j(marks.)40
+b(If)28 b(a)h(single)150 4232 y(quote)40 b(mark)f(is)f(mean)m(t)j(to)f
+(form)e(part)i(of)f(the)h(string,)g(t)m(w)m(o)h(quote)f(marks)f(m)m
+(ust)g(b)s(e)g(used)f(at)i(that)150 4345 y(p)s(oin)m(t.)291
+4458 y(Logical)31 b(literals)d(consists)i(of)h(one)f(of)h(these)g(k)m
+(eyw)m(ords:)41 b Fh(FALSE)p Fs(,)28 b Fh(UNKNOWN)g Fs(or)i
+Fh(TRUE)p Fs(.)291 4571 y Fo(Express-A)21 b Fs(also)h(includes)e(some)i
+(other)g(constan)m(ts.)39 b Fh(PI)21 b Fs(stands)h(for)g(the)g(v)-5
+b(alue)21 b(of)h(the)h(mathemat-)150 4684 y(ical)h(constan)m(t)j
+Fe(\031)h Fs(\(3.1415.)18 b(.)e(.)f(\),)27 b(and)d Fh(CONST)p
+1645 4684 27 4 v 29 w(E)h Fs(stands)g(for)f(the)i(v)-5
+b(alue)24 b(of)i(the)f(mathematical)g(constan)m(t)i Fe(e)150
+4797 y Fs(\(2.7182.)18 b(.)e(.)f(\),)26 b(the)e(base)h(of)f(natural)f
+(logarithms.)38 b(The)24 b(sp)s(ecial)e(tok)m(en)k Fn(?)e
+Fs(stands)f(for)h(an)g(indeterminate)150 4910 y(v)-5
+b(alue)32 b(of)h(an)m(y)g(t)m(yp)s(e.)47 b(The)32 b(three)h(constan)m
+(ts)h Fh(THE)p 1879 4910 V 30 w(DAY)p Fs(,)d Fh(THE)p
+2229 4910 V 30 w(MONTH)g Fs(and)h Fh(THE)p 2821 4910
+V 30 w(YEAR)f Fs(are)i(in)m(teger)g(v)-5 b(alues)150
+5023 y(for)27 b(the)h(curren)m(t)f(date)i(holding)c(the)j(da)m(y)g(of)f
+(the)h(mon)m(th)g(\(1{31\),)i(the)e(mon)m(th)g(of)f(the)h(y)m(ear)h
+(\(1{12\))h(and)150 5136 y(the)h(y)m(ear)g(\(four)f(digits\),)f(resp)s
+(ectiv)m(ely)-8 b(.)1905 5531 y(43)p eop
+%%Page: 44 48
+44 47 bop 150 573 a Fj(4.2)112 b(Data)38 b(t)m(yp)s(es)150
+744 y Fo(Express-A)f Fs(is)h(a)h(t)m(yp)s(ed)f(language.)65
+b(The)38 b(simple)e(data)j(t)m(yp)s(es)g(are:)57 b Fh(INTEGER)p
+Fs(,)36 b Fh(REAL)p Fs(,)h Fh(STRING)f Fs(and)150 857
+y Fh(LOGICAL)p Fs(.)291 970 y(The)47 b(aggregation)h(data)g(t)m(yp)s
+(es)f(are)g Fh(ARRAY)p Fs(,)e Fh(BAG)p Fs(,)h Fh(LIST)p
+Fs(,)g(and)g Fh(SET)p Fs(.)g(The)h(arra)m(y)g(data)h(t)m(yp)s(e)f(is)
+150 1083 y(of)c(a)h(\014xed)e(size)h(and)f(m)m(ust)h(ha)m(v)m(e)h
+(declared)f(lo)m(w)m(er)g(and)f(upp)s(er)f(b)s(ounds)g(\(index)h
+(range\),)47 b(suc)m(h)c(as)150 1196 y Fn(ARRAY)j([-7:10])g(OF)p
+Fs(.)22 b(The)g(other)h(aggregate)i(data)e(t)m(yp)s(es)f(are)h(dynamic)
+e(in)g(size,)j(but)e(ma)m(y)h(ha)m(v)m(e)h(lo)m(w)m(er)150
+1309 y(and)30 b(upp)s(er)e(b)s(ounds)g(sp)s(eci\014ed)h(for)h(the)g(n)m
+(um)m(b)s(er)f(of)h(elemen)m(ts,)h(suc)m(h)f(as)h Fn(SET)47
+b([2:5])f(OF)p Fs(,)30 b(meaning)g(a)150 1422 y(set)e(that)g(should)d
+(ha)m(v)m(e)k(b)s(et)m(w)m(een)f(t)m(w)m(o)g(and)f(\014v)m(e)h(mem)m(b)
+s(ers.)39 b(F)-8 b(or)28 b(the)f(dynamic)f(aggregates)k(the)e(upp)s(er)
+150 1535 y(b)s(ound)c(ma)m(y)j(b)s(e)f(giv)m(en)g(as)h
+Fn(?)p Fs(,)g(whic)m(h)e(means)h(an)g(unlimited)d(upp)s(er)h(b)s(ound,)
+i(suc)m(h)g(as)g Fn(LIST)47 b([2:?])f(OF)p Fs(.)150 1648
+y(If)34 b(a)h(b)s(ound)e(sp)s(eci\014cation)g(is)h(absen)m(t,)i(then)f
+(the)f(dynamic)g(aggregate)j(can)e(hold)f(from)g(zero)h(to)h(an)m(y)150
+1761 y(n)m(um)m(b)s(er)29 b(of)i(elemen)m(ts.)951 1728
+y Fr(6)291 1860 y Fs(Aggregates)48 b(are)d(one)h(dimensional,)g(but)e
+(can)i(b)s(e)e(c)m(hained)g(together)j(for)e(m)m(ulti-dimensional)150
+1960 y(aggregates,)33 b(lik)m(e)150 2134 y Fh(ARRAY)42
+b([1:4])f(OF)i(LIST)f(OF)g(INTEGER;)291 2308 y Fs(The)25
+b(en)m(umeration)g(data)h(t)m(yp)s(e)g(is)e(a)i(paren)m(thesised)f
+(comma)h(sep)s(erated)f(list)f(of)i(iden)m(ti\014ers.)37
+b(These)150 2408 y(iden)m(ti\014ers)28 b(represen)m(t)j(the)f(v)-5
+b(alues)30 b(of)h(the)f(en)m(umerated)h(t)m(yp)s(e;)g(for)f(instance)
+150 2582 y Fh(ENUMERATION)39 b(OF)k(\(red,)e(green,)g(blue\))291
+2756 y Fs(A)28 b(de\014ned)f(data)i(t)m(yp)s(e)f(is)f(one)h(declared)f
+(and)h(named)f(b)m(y)h(the)g(user)f(using)g(the)h Fh(TYPE)e
+Fs(and)i Fh(END)p 3551 2756 27 4 v 30 w(TYPE)150 2856
+y Fs(construct.)41 b(F)-8 b(or)31 b(example)150 3030
+y Fh(TYPE)42 b(length)f(=)i(REAL;)f(END_TYPE;)150 3130
+y(TYPE)g(crowd_size)d(=)44 b(INTEGER;)c(END_TYPE;)150
+3229 y(TYPE)i(signal_colour)c(=)43 b(ENUMERATION)c(OF)k(\(red,)f
+(amber,)f(green\);)f(END_TYPE;)291 3403 y Fs(An)29 b(en)m(tit)m(y)h
+(data)h(t)m(yp)s(e)e(consists)g(of)h(a)g(list)e(of)i(attributes)f(and)g
+(their)f(t)m(yp)s(es,)i(enclosed)f(in)g(a)g Fh(ENTITY)150
+3503 y Fs(and)h Fh(END)p 464 3503 V 30 w(ENTITY)e Fs(pair.)39
+b(An)30 b(en)m(tit)m(y)h(t)m(yp)s(e)g(is)e(named.)150
+3677 y Fh(ENTITY)41 b(an_ent;)237 3777 y(auditorium_width)c(:)43
+b(length;)237 3876 y(audience)389 b(:)43 b(crowd_size;)237
+3976 y(title)521 b(:)43 b(STRING;)237 4076 y(profit)477
+b(:)43 b(REAL;)150 4175 y(END_ENTITY;)291 4363 y Fo(Express-A)29
+b Fs(pro)m(vides)h(for)g(algorithms)f(in)g(the)i(form)f(of)g(functions)
+f(and)h(pro)s(cedures.)291 4462 y(A)i Fh(FUNCTION)d Fs(is)i(an)h
+(algorithm)f(that)i(op)s(erates)f(on)g(parameters)h(and)e(returns)g(a)i
+(single)d(resultan)m(t)150 4562 y(v)-5 b(alue)27 b(of)g(a)g(sp)s
+(eci\014ed)e(data)j(t)m(yp)s(e.)40 b(An)27 b(in)m(v)m(o)s(cation)g(of)g
+(a)g(function)f(in)g(an)h(expression)e(ev)-5 b(aluates)28
+b(to)g(the)150 4662 y(resultan)m(t)i(v)-5 b(alue)30 b(at)h(the)g(p)s
+(oin)m(t)e(of)i(in)m(v)m(o)s(cation.)40 b(F)-8 b(or)31
+b(example:)150 4836 y Fh(FUNCTION)40 b(func)i(\(par1)g(:)h(INTEGER;)d
+(par2)i(:)h(STRING\))e(:)i(STRING;)237 4935 y(LOCAL)324
+5035 y(str)g(:)g(STRING;)324 5135 y(--)g(other)f(variable)e
+(declarations)p 150 5196 1440 4 v 254 5250 a Fl(6)288
+5282 y Fp(The)26 b(dynamic)e(aggregates)29 b(ma)n(y)24
+b(not)h(b)r(e)h(fully)g(implemen)n(ted)d(due)i(to)h(lac)n(k)g(of)h
+(time.)1905 5531 y Fs(44)p eop
+%%Page: 45 49
+45 48 bop 237 573 a Fh(END_LOCAL;)237 672 y(--)43 b(the)f(algorithm)e
+(statements)g(are)i(here)237 772 y(RETURN\(str\);)150
+872 y(END_FUNCTION;)150 1059 y Fs(Note)32 b(that)f(the)f(parameters)h
+(are)g(t)m(yp)s(ed.)291 1159 y(A)g Fh(PROCEDURE)c Fs(is)j(an)h
+(algorithm)e(that)j(receiv)m(es)f(parameters)h(from)e(the)h(p)s(oin)m
+(t)f(of)h(in)m(v)m(o)s(cation)g(and)150 1259 y(op)s(erates)37
+b(on)g(them)g(in)e(some)i(manner.)59 b(Changes)37 b(to)h(the)f
+(parameters)g(within)d(the)j(pro)s(cedure)f(are)150 1358
+y(only)k(re\015ected)i(to)g(the)f(p)s(oin)m(t)f(of)i(in)m(v)m(o)s
+(cation)f(when)f(the)i(formal)e(parameter)i(is)e(preceded)h(b)m(y)g
+(the)150 1458 y(k)m(eyw)m(ord)31 b Fh(VAR)p Fs(.)e(F)-8
+b(or)31 b(example:)150 1632 y Fh(PROCEDURE)40 b(proc)i(\(par1)f(:)i
+(INTEGER;)e(VAR)h(par2)g(:)h(STRING\);)237 1732 y(--)g(local)e
+(declarations)e(and)j(the)h(algorithm)d(statements)150
+1831 y(END_PROCEDURE;)150 2019 y Fs(Note)32 b(that)f(the)f(parameters)h
+(are)g(t)m(yp)s(ed.)40 b(In)30 b(this)f(case)i(the)g(v)-5
+b(alue)30 b(of)37 b Fh(par2)29 b Fs(ma)m(y)i(b)s(e)f(c)m(hanged.)291
+2119 y(V)-8 b(ariables)32 b(are)g(declared)g(in)f(a)i(lo)s(cal)e(blo)s
+(c)m(k,)i(enclosed)f(b)m(y)g(the)g(k)m(eyw)m(ords)h Fh(LOCAL)d
+Fs(and)i Fh(END)p 3482 2119 27 4 v 30 w(LOCAL)p Fs(.)150
+2218 y(A)e(v)-5 b(ariable)30 b(declaration)g(consists)f(of)i(an)f(iden)
+m(tifer)f(and)h(its)g(t)m(yp)s(e,)g(suc)m(h)g(as:)150
+2393 y Fh(LOCAL)237 2492 y(str)173 b(:)43 b(STRING;)237
+2592 y(e1,)g(e2)f(:)h(an_ent;)215 b(--)43 b(e1)g(and)f(e2)h(are)f(both)
+g(of)h(type)f(an_ent)237 2692 y(e3)217 b(:)43 b(an_ent;)215
+b(--)43 b(so)g(is)g(e3)237 2791 y(num)173 b(:)43 b(INTEGER;)237
+2891 y(col)173 b(:)43 b(signal_colour;)237 2990 y(matrix)e(:)i(ARRAY)f
+([1:15])f(OF)i(ARRAY)e([1:15])g(OF)i(REAL;)150 3090 y(END_LOCAL;)291
+3278 y Fs(The)30 b(ab)s(o)m(v)m(e)i(declarations)d(m)m(ust)i(b)s(e)e
+(in)g(the)i(follo)m(wing)e(order:)261 3465 y(1.)46 b
+Fh(ENTITY)28 b Fs(and/or)i Fh(TYPE)f Fs(declarations)261
+3653 y(2.)46 b Fh(FUNCTION)27 b Fs(and/or)k Fh(PROCEDURE)26
+b Fs(declarations)261 3841 y(3.)46 b(a)31 b Fh(LOCAL)d
+Fs(declaration)i(blo)s(c)m(k)291 4028 y(After)h(the)f(ab)s(o)m(v)m(e)i
+(can)f(come)g(an)m(y)g(n)m(um)m(b)s(er)e(of)h(statemen)m(ts.)150
+4272 y Fj(4.3)112 b(Statemen)m(ts)150 4443 y Fo(Express-A)29
+b Fs(supp)s(orts)g(the)h(follo)m(wing)f(statemen)m(ts:)286
+4631 y Fm(\017)46 b Fs(Null)29 b(statemen)m(t)286 4819
+y Fm(\017)46 b Fs(Assignmen)m(t)30 b(statemen)m(t)286
+5006 y Fm(\017)46 b Fs(Call)29 b(statemen)m(t)286 5194
+y Fm(\017)46 b Fh(BEGIN)29 b Fs(.)15 b(.)g(.)h Fh(END)29
+b Fs(comp)s(ound)g(statemen)m(t)1905 5531 y(45)p eop
+%%Page: 46 50
+46 49 bop 286 573 a Fm(\017)46 b Fh(CASE)29 b Fs(.)15
+b(.)h(.)f Fh(END)p 840 573 27 4 v 30 w(CASE)29 b Fs(statemen)m(t)286
+760 y Fm(\017)46 b Fh(IF)30 b Fs(.)15 b(.)h(.)f Fh(THEN)29
+b Fs(.)15 b(.)g(.)h Fh(ELSE)28 b Fs(.)16 b(.)f(.)h Fh(END)p
+1405 760 V 30 w(IF)29 b Fs(statemen)m(t)286 948 y Fm(\017)46
+b Fh(REPEAT)25 b Fs(.)16 b(.)f(.)h Fh(WHILE)25 b Fs(.)16
+b(.)f(.)h Fh(UNTIL)25 b Fs(.)16 b(.)f(.)g Fh(END)p 1658
+948 V 30 w(REPEAT)26 b Fs(statemen)m(t.)41 b(This)26
+b(also)i(includes)d(the)j Fh(ESCAPE)e Fs(and)377 1061
+y Fh(SKIP)j Fs(statemen)m(ts)286 1249 y Fm(\017)46 b
+Fh(RETURN)28 b Fs(statemen)m(t)291 1436 y(All)36 b(the)h(ab)s(o)m(v)m
+(e)i(statemen)m(ts)g(are)e(completed)g(b)m(y)g(a)h Fh(;)i
+Fs(\(semicolon\).)61 b(The)37 b Fi(nul)5 b(l)46 b Fs(statemen)m(t)40
+b(just)150 1549 y(consists)30 b(of)g(a)h(semicolon.)291
+1649 y(The)25 b Fi(assignment)35 b Fs(statemen)m(t)27
+b(is)d(used)h(to)h(assign)e(an)i(instance)f(to)h(a)f(lo)s(cal)g(v)-5
+b(ariable)24 b(or)h(parameter.)150 1748 y(The)30 b(data)h(t)m(yp)s(es)f
+(m)m(ust)h(b)s(e)e(compatible.)150 1923 y Fh(LOCAL)237
+2022 y(a,)43 b(b,)g(c)g(:)g(REAL;)150 2122 y(END_LOCAL;)150
+2222 y(...)237 2321 y(a)g(:=)g(2.3E-6;)237 2421 y(b)g(:=)g(a;)237
+2521 y(a)g(:=)g(-27.0;)237 2620 y(c)g(:=)g(33.3*b;)291
+2795 y Fs(The)31 b Fi(c)-5 b(al)5 b(l)41 b Fs(statemen)m(t)33
+b(in)m(v)m(ok)m(es)e(a)h(pro)s(cedure)e(or)h(a)g(function.)41
+b(The)31 b(actual)g(parameters)g(pro)m(vided)150 2894
+y(with)c(the)h(call)f(m)m(ust)h(agree)h(in)d(n)m(um)m(b)s(er,)h(order)h
+(and)f(t)m(yp)s(e)h(with)f(the)h(formal)f(parameters)h(sp)s(eci\014ed)e
+(in)150 2994 y(the)31 b(pro)s(cedure)f(or)h(function)f(declaration.)43
+b(The)31 b(supplied)c(parameter)32 b(v)-5 b(alues)31
+b(m)m(ust)g(b)s(e)f(assignmen)m(t)150 3093 y(compatible)42
+b(with)g(the)i(formal)e(parameters.)80 b(This)41 b(is)i(an)g(example)g
+(of)g(calling)f(the)h Fo(Express-A)150 3193 y Fs(de\014ned)29
+b Fh(INSERT)f Fs(pro)s(cedure)h(whic)m(h)g(tak)m(es)j(three)f
+(parameters:)150 3367 y Fh(INSERT\(my_list,)37 b(list_element,)i(0\);)
+291 3542 y Fs(The)31 b Fi(c)-5 b(omp)g(ound)43 b Fs(statemen)m(t)33
+b(consists)e(of)h(one)f(or)h(more)f(statemen)m(ts)i(enclosed)e(b)s(et)m
+(w)m(een)h(a)g Fh(BEGIN)150 3641 y Fs(and)e Fh(END)f
+Fs(pair.)39 b(The)30 b(enclosed)g(statemen)m(ts)i(are)f(treated)g(as)g
+(a)g(single)e(statemen)m(t.)150 3816 y Fh(...)237 3915
+y(BEGIN)324 4015 y(a)44 b(:=)e(2.3e-7;)324 4115 y(b)i(:=)e(a;)324
+4214 y(c)i(:=)e(b*33.3;)237 4314 y(END;)291 4488 y Fs(The)27
+b Fi(c)-5 b(ase)35 b Fs(statemen)m(t)29 b(is)e(a)h(means)f(of)h
+(selectiv)m(ely)g(executing)f(statemen)m(ts)i(based)f(on)f(the)h(v)-5
+b(alue)27 b(of)150 4588 y(an)j(expresion.)150 4762 y
+Fh(LOCAL)237 4862 y(a)43 b(:)h(INTEGER;)237 4961 y(x,)f(y)g(:)g(REAL;)
+150 5061 y(END_LOCAL;)150 5161 y(...)237 5260 y(a)g(:=)g(2;)1905
+5531 y Fs(46)p eop
+%%Page: 47 51
+47 50 bop 237 573 a Fh(x)43 b(:=)g(21.9;)237 672 y(CASE)f(2*a)g(OF)324
+772 y(1)392 b(:)43 b(x)h(:=)e(SIN{x};)324 872 y(2)392
+b(:)43 b(x)h(:=)e(SQRT\(x\);)324 971 y(3)392 b(:)43 b(x)h(:=)e
+(LOG\(x\);)324 1071 y(4)392 b(:)43 b(x)h(:=)e(COS\(x\);)85
+b(--)42 b(this)g(is)h(executed)324 1171 y(5,)g(6)261
+b(:)43 b(y)h(:=)e(y**x;)324 1270 y(OTHERWISE)e(:)j(x)h(:=)e(0.0;)237
+1370 y(END_CASE;)150 1557 y Fs(The)31 b(in)m(teger)g(expression)f
+(follo)m(wing)f(the)j Fh(CASE)d Fs(k)m(eyw)m(ord)i(is)g(ev)-5
+b(aluated.)42 b(The)31 b(result)f(is)g(compared)h(to)150
+1670 y(the)24 b(v)-5 b(alues)23 b(of)h(the)g(case)h(lab)s(els)d(and)i
+(the)g(statemen)m(t)h(follo)m(wing)e(the)h(\014rst)f(matc)m(hing)h(lab)
+s(el)e(is)h(executed.)150 1783 y(Execution)f(then)f(con)m(tin)m(ues)i
+(at)f(the)h(statemen)m(t)h(follo)m(wing)c(the)i Fh(END)p
+2485 1783 27 4 v 30 w(CASE;)p Fs(.)36 b(If)22 b(no)g(lab)s(el)e(matc)m
+(hes,)25 b(then)150 1896 y(no)31 b(statemen)m(ts)h(within)c(the)j(case)
+g(blo)s(c)m(k)g(are)g(executed,)g(except)h(if)d(an)i
+Fh(OTHERWISE)c Fs(lab)s(el)i(is)g(included,)150 2009
+y(whic)m(h)e(will)f(matc)m(h)j(an)m(ything.)39 b(All)27
+b(other)i(lab)s(els)d(are)j(examined)e(b)s(efore)h(lo)s(oking)f(for)h
+(the)g Fh(OTHERWISE)p Fs(.)291 2109 y(The)43 b Fi(if)h(.)14
+b(.)g(.)g(then)45 b(.)14 b(.)g(.)g(else)49 b Fs(statemen)m(t)d(allo)m
+(ws)c(the)i(conditional)e(execution)h(of)h(statemen)m(ts)h(de-)150
+2208 y(p)s(ending)31 b(on)j(the)g(v)-5 b(alue)33 b(of)h(a)g
+Fh(LOGICAL)d Fs(expression.)50 b(When)33 b(the)h(expression)f(ev)-5
+b(aluates)34 b(to)h Fh(TRUE)d Fs(the)150 2308 y(statemen)m(t\(s\))38
+b(follo)m(wing)33 b(the)i Fh(THEN)f Fs(are)h(executed,)j(after)d(whic)m
+(h)f(con)m(trol)i(passes)f(to)h(the)f(statemen)m(t)150
+2408 y(follo)m(wing)28 b(the)i(closing)f Fh(END)p 1124
+2408 V 31 w(IF)p Fs(.)f(When)i(the)f(logical)g(expression)f(ev)-5
+b(aluates)30 b(to)h Fh(FALSE)c Fs(or)i Fh(UNKNOWN)e Fs(the)150
+2507 y Fh(THEN)22 b Fs(statemen)m(ts)k(are)e(jump)s(ed)d(o)m(v)m(er)k
+(and)f(execution)g(starts)g(at)g(the)g(statemen)m(t\(s\))i(follo)m
+(wing)d(the)h Fh(ELSE)150 2607 y Fs(k)m(eyw)m(ord)31
+b(if)e(presen)m(t,)i(or)f(at)h(the)g(statemen)m(t)h(follo)m(wing)d(the)
+i Fh(END)p 2413 2607 V 30 w(IF)e Fs(k)m(eyw)m(ord.)150
+2781 y Fh(IF)43 b(a)g(>)g(20)g(THEN)237 2881 y(b)g(:=)g(a)g(+)g(2;)237
+2980 y(c)g(:=)g(c)g(-)g(1;)150 3080 y(ELSE)237 3180 y(IF)g(a)g(>)g(10)g
+(THEN)324 3279 y(b)h(:=)e(a)h(+)h(1;)237 3379 y(ELSE)324
+3479 y(c)g(:=)e(c)h(+)h(1;)237 3578 y(END_IF;)150 3678
+y(END_IF;)291 3866 y Fs(The)35 b Fi(r)-5 b(ep)g(e)g(at)46
+b Fs(statemen)m(t)38 b(is)c(used)h(to)h(con)m(trol)g(the)g(conditional)
+d(rep)s(etition)h(of)i(a)g(series)f(of)g(state-)150 3978
+y(men)m(ts.)41 b(The)30 b(con)m(trol)h(conditions)e(are:)286
+4166 y Fm(\017)46 b Fs(\014nite)30 b(iteration)g(un)m(til)e(an)i(in)m
+(teger)h(expression)e(reac)m(hes)j(a)f(sp)s(eci\014ed)d(v)-5
+b(alue;)286 4354 y Fm(\017)46 b Fh(WHILE)29 b Fs(a)h(logical)g
+(condition)f(is)g Fh(TRUE)p Fs(;)286 4541 y Fm(\017)46
+b Fh(UNTIL)29 b Fs(a)h(logical)g(condition)f(is)g Fh(TRUE)p
+Fs(.)150 4741 y Fh(REPEAT)41 b(i)i(:=)g(100)f(TO)h(0)g(BY)g(-7)g(WHILE)
+e(r)j(>=)e(0.0)h(UNTIL)e(err)h(<)i(1.0e-8;)237 4840 y(...)237
+4940 y(r)f(:=)g(...;)237 5039 y(err)g(:=)f(...;)150 5139
+y(END_REPEAT;)1905 5531 y Fs(47)p eop
+%%Page: 48 52
+48 51 bop 150 573 a Fs(A)m(t)41 b(en)m(try)g(to)g(the)g
+Fh(REPEAT)d Fs(statemen)m(t)k(the)f(iteration)f(v)-5
+b(ariable)39 b(is)h(initialized)d(to)k(the)g(\014rst)f(b)s(ound.)150
+686 y(If)g(the)g(v)-5 b(ariable)39 b(less)g(than)h(or)h(equal)e(to)i
+(the)f Fh(TO)g Fs(b)s(ound)e(and)h(the)i(incremen)m(t)f(is)f(p)s
+(ositiv)m(e,)j(or)e(the)150 799 y(v)-5 b(ariable)29 b(is)g(less)h(than)
+g(the)g Fh(TO)g Fs(b)s(ound)e(and)i(the)g(incremen)m(t)g(is)f(negativ)m
+(e,)j(pro)s(cessing)d(jumps)f(to)j(after)150 912 y(the)e
+Fh(END)p 442 912 27 4 v 30 w(REPEAT)p Fs(,)e(otherwise)i(pro)s(cessing)
+f(con)m(tin)m(ues.)40 b(The)29 b Fh(WHILE)e Fs(condition)h(is)g(c)m
+(hec)m(k)m(ed)j(and)d(if)36 b Fh(TRUE)150 1024 y Fs(then)f(the)g
+(statemen)m(ts)i(in)d(the)h(b)s(o)s(dy)f(are)i(executed.)56
+b(After)35 b(these)h(ha)m(v)m(e)g(b)s(een)f(executed)h(the)f
+Fh(UNTIL)150 1137 y Fs(condition)41 b(is)g(c)m(hec)m(k)m(ed.)77
+b(If)42 b(this)f(is)g(not)h Fh(TRUE)e Fs(then)i(pro)s(cessing)f(con)m
+(tin)m(ues)h(b)m(y)g(incremen)m(ting)f(the)150 1250 y(iteration)e(v)-5
+b(ariable)38 b(b)m(y)h(either)f(unit)m(y)g(or)h(b)m(y)g(the)h
+Fh(BY)e Fs(v)-5 b(alue)39 b(if)f(presen)m(t.)67 b(The)38
+b(whole)h(pro)s(cess)f(then)150 1363 y(starts)31 b(again)f(with)f(the)i
+(c)m(hec)m(king)g(of)g(the)f(iteration)g(v)-5 b(ariable)29
+b(against)i(the)f Fh(TO)g Fs(b)s(ound.)291 1463 y(All)36
+b(three)h(t)m(yp)s(es)g(of)g(con)m(trols)h(are)f(optional.)60
+b(If)36 b(none)h(are)h(giv)m(en)f(then)f(the)i Fh(REPEAT)c
+Fs(statemen)m(t)150 1562 y(will)g(lo)s(op)i(for)g(ev)m(er.)60
+b(The)37 b Fi(esc)-5 b(ap)g(e)44 b Fs(statemen)m(t)39
+b(causes)e(an)f(immediate)g(transfer)g(out)h(of)g(the)f
+Fh(REPEAT)150 1662 y Fs(statemen)m(t)f(in)d(whic)m(h)h(it)g(o)s(ccurs.)
+49 b(The)33 b Fi(skip)40 b Fs(statemen)m(t)35 b(causes)f(a)g(jump)e(to)
+i(the)f(end)g(of)h(the)f Fh(REPEAT)150 1762 y Fs(statemen)m(t)f(in)d
+(whic)m(h)g(it)h(o)s(ccurs)g(\(i.e.,)h(to)h(the)e(p)s(oin)m(t)f(where)h
+(the)h Fh(UNTIL)d Fs(expression)h(is)h(tested\).)150
+1902 y Fh(REPEAT)41 b(UNTIL)h(\(a)g(=)i(1\);)237 2002
+y(...)237 2102 y(IF)f(a)g(=)g(0)g(THEN)324 2201 y(ESCAPE;)237
+2301 y(END_IF;)237 2401 y(...)237 2500 y(IF)g(a)g(>)g(10)g(THEN)324
+2600 y(SKIP;)237 2699 y(END_IF;)237 2799 y(...)237 2899
+y(...)150 2998 y(--)g(SKIP)f(transfers)e(control)g(to)j(here)150
+3098 y(END_REPEAT;)194 3198 y(--)f(ESCAPE)f(transfers)f(control)h(to)i
+(here)291 3338 y Fs(The)29 b Fi(r)-5 b(eturn)37 b Fs(statemen)m(t)32
+b(terminates)d(the)h(execution)f(of)h(a)g Fh(FUNCTION)c
+Fs(or)k Fh(PROCEDURE)p Fs(.)c(The)i Fh(RETURN)150 3438
+y Fs(statemen)m(t)42 b(within)c(a)i(function)f(m)m(ust)h(sp)s(ecify)f
+(an)h(expression,)i(the)e(v)-5 b(alue)40 b(of)g(whic)m(h)f(is)g(the)h
+(v)-5 b(alue)150 3538 y(returned)29 b(b)m(y)h(the)h(function.)39
+b(A)31 b Fh(RETURN)d Fs(in)h(a)i(pro)s(cedure)e(m)m(ust)h(not)h(sp)s
+(ecify)e(an)h(expression.)150 3678 y Fh(RETURN\(a)40
+b(<>)j(b\);)86 b(--)43 b(example)d(for)j(within)e(a)i(function)150
+3778 y(RETURN;)433 b(--)43 b(example)d(for)j(within)e(a)i(procedure)150
+4015 y Fj(4.4)112 b(Expressions)150 4187 y Fs(Expressions)25
+b(are)h(com)m(binations)g(of)g(op)s(erators,)i(op)s(erands)d(and)h
+(function)f(calls)h(whic)m(h)f(are)i(ev)-5 b(aluated)150
+4299 y(to)23 b(pro)s(duce)e(a)i(v)-5 b(alue.)37 b(The)22
+b(simplest)f(expression)g(is)g(either)h(a)h(literal)e(v)-5
+b(alue)21 b(or)i(the)f(name)h(of)f(a)h(v)-5 b(ariable.)150
+4533 y Ft(4.4.1)105 b(Arithmetic)34 b(op)s(erators)150
+4705 y Fs(The)22 b(arithmetic)f(op)s(erators)h(act)h(on)f(n)m(um)m(b)s
+(er)f(v)-5 b(alues)22 b(and)f(pro)s(duce)g(a)h(n)m(um)m(b)s(er)f
+(result.)37 b(If)22 b(an)m(y)g(op)s(erand)150 4818 y(is)29
+b(indeterminate)g(\(i.e.,)j Fn(?)p Fs(\))e(then)g(the)h(result)e(is)g
+(also)i(indeterminate.)39 b(The)30 b(op)s(erators)g(are:)150
+4972 y Ft(Unary)46 b Fs(The)30 b(op)s(erators)g Fn(+)g
+Fs(and)g Fn(-)p Fs(,)g(the)h(latter)g(of)f(whic)m(h)f(negates)j(its)e
+(follo)m(wing)f(op)s(erand.)150 5146 y Ft(Binary)46 b
+Fs(Addition)28 b(\()p Fn(+)p Fs(\),)k(subtraction)d(\()p
+Fn(-)p Fs(\),)i(m)m(ultiplication)d(\()p Fn(*)p Fs(\),)j(real)f
+(division)d(\()p Fn(/)p Fs(\),)32 b(exp)s(onen)m(tiation)377
+5259 y(\()p Fn(**)p Fs(\),)f(in)m(teger)g(division)c(\()p
+Fh(DIV)p Fs(\),)j(and)g(mo)s(dulo)f(\()p Fh(MOD)p Fs(\).)1905
+5531 y(48)p eop
+%%Page: 49 53
+49 52 bop 150 573 a Ft(4.4.2)105 b(Relational)35 b(op)s(erators)150
+744 y Fs(The)30 b(result)f(of)h(a)h(relational)e(expression)g(is)g(a)i
+Fh(LOGICAL)c Fs(v)-5 b(alue.)40 b(If)30 b(either)g(op)s(erand)f(is)g
+(indeterminate,)150 857 y(the)i(expression)e(ev)-5 b(aluates)31
+b(to)g Fh(UNKNOWN)p Fs(.)150 1070 y Ft(V)-9 b(alue)35
+b(comparison)46 b Fs(Equal)25 b(\()p Fn(=)p Fs(\),)i(not)f(equal)f(\()p
+Fn(<>)p Fs(\),)i(greater)g(than)e(\()p Fn(>)p Fs(\),)j(less)d(than)g
+(\()p Fn(<)p Fs(\),)i(greater)g(than)377 1183 y(or)k(equal)f(\()p
+Fn(>=)p Fs(\),)g(and)g(less)g(than)g(or)g(equal)g(\()p
+Fn(<=)p Fs(\).)150 1370 y Ft(Mem)m(b)s(ership)45 b Fs(The)27
+b Fh(IN)f Fs(op)s(erator)i(tests)g(an)f(item)g(for)g(mem)m(b)s(ership)e
+(in)h(a)i(dynamic)e(aggregate)k(\(e.g.,)377 1483 y Fh(IF)43
+b(fred)f(IN)h(mylist)e(THEN)h(...)p Fs(\).)150 1671 y
+Ft(Matc)m(hing)k Fs(The)37 b Fh(LIKE)f Fs(op)s(erator)i(compares)g(a)f
+(string)g(against)h(a)f(pattern,)j(ev)-5 b(aluating)37
+b(to)h Fh(TRUE)e Fs(if)377 1784 y(they)31 b(matc)m(h.)41
+b(The)30 b(pattern)h(c)m(haracters)h(are:)486 1972 y
+Fm(\017)46 b Fn(@)30 b Fs(Matc)m(hes)i(an)m(y)f(letter.)486
+2118 y Fm(\017)46 b Fn(^)30 b Fs(Matc)m(hes)i(an)m(y)f(upp)s(er-case)f
+(letter.)486 2264 y Fm(\017)46 b Fn(?)30 b Fs(Matc)m(hes)i(an)m(y)f(c)m
+(haracter.)486 2410 y Fm(\017)46 b Fn(&)30 b Fs(Matc)m(hes)i(remainder)
+d(of)i(string.)486 2556 y Fm(\017)46 b Fn(#)30 b Fs(Matc)m(hes)i(an)m
+(y)f(digit.)486 2702 y Fm(\017)46 b Fn($)30 b Fs(Matc)m(hes)i(a)f
+(substring)d(terminated)i(b)m(y)h(a)f(space)h(c)m(haracter)h(or)f
+(end-of-string.)486 2848 y Fm(\017)46 b Fn(*)30 b Fs(Matc)m(hes)i(an)m
+(y)f(n)m(um)m(b)s(er)e(of)i(c)m(haracters.)486 2994 y
+Fm(\017)46 b Fn(\\)30 b Fs(Begins)g(a)h(pattern)g(escap)s(e)g
+(sequence.)486 3140 y Fm(\017)46 b Fn(!)30 b Fs(Negation)i(c)m
+(haracter)g(\(used)e(with)f(the)h(other)h(c)m(haracters\).)486
+3287 y Fm(\017)46 b Fs(An)m(y)31 b(other)f(c)m(haracter)i(matc)m(hes)g
+(itself.)377 3474 y(Some)f(examples:)486 3662 y Fm(\017)46
+b Fn('The)h(quick)f(red)h(fox')g(LIKE)f('$$$$')29 b Fs(is)h
+Fh(TRUE)p Fs(.)486 3808 y Fm(\017)46 b Fn('Page)h(231')f(LIKE)h('$)g
+(###')29 b Fs(is)h Fh(TRUE)p Fs(.)486 3954 y Fm(\017)46
+b Fn('Page)h(27')g(LIKE)f('Page)h(###')29 b Fs(is)g Fh(FALSE)p
+Fs(.)486 4100 y Fm(\017)46 b Fn('\\aaaa')g(LIKE)h('\\\\aaaa')28
+b Fs(is)h Fh(TRUE)p Fs(.)486 4246 y Fm(\017)46 b Fn('\\aaaa')g(LIKE)h
+('\\aaaa')28 b Fs(is)i Fh(FALSE)p Fs(.)486 4392 y Fm(\017)46
+b Fn('aaaa')g(LIKE)h('a@@a')29 b Fs(is)g Fh(TRUE)p Fs(.)150
+4633 y Ft(4.4.3)105 b(Logical)36 b(op)s(erators)150 4804
+y Fs(The)28 b(logical)g(op)s(erators)h(pro)s(duce)e(a)i(logical)f
+(result.)39 b(Except)29 b(for)f(the)h Fh(NOT)e Fs(op)s(erator)h(whic)m
+(h)g(tak)m(es)i(one)150 4917 y(logical)g(op)s(erand)f(\(e.g.,)j
+Fh(NOT)43 b(op)p Fs(\),)30 b(they)g(tak)m(e)i(t)m(w)m(o)g(logical)e(op)
+s(erands)f(\(e.g.,)j Fh(op1)43 b(XOR)f(op2)p Fs(\).)291
+5030 y(The)30 b(ev)-5 b(aluation)30 b(of)g(the)h Fh(NOT)e
+Fs(op)s(erator)i(is)e(giv)m(en)h(in)g(table)g(3.)291
+5143 y(The)g(ev)-5 b(aluation)30 b(of)g(the)h Fh(AND)p
+Fs(,)e Fh(OR)h Fs(and)g Fh(XOR)f Fs(op)s(erators)h(is)g(giv)m(en)g(in)f
+(table)h(4.)1905 5531 y(49)p eop
+%%Page: 50 54
+50 53 bop 1249 628 a Fs(T)-8 b(able)30 b(3:)41 b(The)30
+b(NOT)g(logical)g(op)s(erator)p 1315 657 1270 4 v 1313
+770 4 113 v 1365 736 a(Op)s(erand)f(v)-5 b(alue)p 1994
+770 V 99 w(Result)29 b(v)-5 b(alue)p 2583 770 V 1315
+773 1270 4 v 1313 886 4 113 v 1568 852 a Fh(TRUE)p 1994
+886 V 437 w(FALSE)p 2583 886 V 1313 999 V 1503 965 a(UNKNOWN)p
+1994 999 V 327 w(UNKNOWN)p 2583 999 V 1313 1112 V 1547
+1078 a(FALSE)p 1994 1112 V 436 w(TRUE)p 2583 1112 V 1315
+1115 1270 4 v 929 1361 a Fs(T)d(able)30 b(4:)41 b(The)30
+b(AND,)h(OR)f(and)g(X)m(OR)g(logical)g(op)s(erators)p
+622 1390 2656 4 v 620 1503 4 113 v 741 1469 a(Op1)p 1025
+1503 V 238 w(Op2)p 1430 1503 V 1447 1503 V 185 w(Op1)g
+Fh(AND)f Fs(Op2)p 2071 1503 V 99 w(Op1)h Fh(OR)g Fs(Op2)p
+2652 1503 V 99 w(Op1)g Fh(XOR)f Fs(Op2)p 3276 1503 V
+622 1506 2656 4 v 620 1619 4 113 v 737 1585 a Fh(TRUE)p
+1025 1619 V 229 w(TRUE)p 1430 1619 V 1447 1619 V 355
+w(TRUE)p 2071 1619 V 427 w(TRUE)p 2652 1619 V 405 w(FALSE)p
+3276 1619 V 620 1732 V 737 1698 a(TRUE)p 1025 1732 V
+164 w(UNKNOWN)p 1430 1732 V 1447 1732 V 223 w(UNKNOWN)p
+2071 1732 V 360 w(TRUE)p 2652 1732 V 361 w(UNKNOWN)p
+3276 1732 V 620 1845 V 737 1811 a(TRUE)p 1025 1845 V
+207 w(FALSE)p 1430 1845 V 1447 1845 V 312 w(FALSE)p 2071
+1845 V 404 w(TRUE)p 2652 1845 V 426 w(TRUE)p 3276 1845
+V 620 1958 V 672 1924 a(UNKNOWN)p 1025 1958 V 162 w(TRUE)p
+1430 1958 V 1447 1958 V 290 w(UNKNOWN)p 2071 1958 V 360
+w(TRUE)p 2652 1958 V 361 w(UNKNOWN)p 3276 1958 V 620
+2071 V 672 2037 a(UNKNOWN)p 1025 2071 V 97 w(UNKNOWN)p
+1430 2071 V 1447 2071 V 223 w(UNKNOWN)p 2071 2071 V 294
+w(UNKNOWN)p 2652 2071 V 295 w(UNKNOWN)p 3276 2071 V 620
+2184 V 672 2150 a(UNKNOWN)p 1025 2184 V 140 w(FALSE)p
+1430 2184 V 1447 2184 V 312 w(FALSE)p 2071 2184 V 338
+w(UNKNOWN)p 2652 2184 V 295 w(UNKNOWN)p 3276 2184 V 620
+2297 V 716 2263 a(FALSE)p 1025 2297 V 206 w(TRUE)p 1430
+2297 V 1447 2297 V 334 w(FALSE)p 2071 2297 V 404 w(TRUE)p
+2652 2297 V 426 w(TRUE)p 3276 2297 V 620 2410 V 716 2376
+a(FALSE)p 1025 2410 V 141 w(UNKNOWN)p 1430 2410 V 1447
+2410 V 267 w(FALSE)p 2071 2410 V 338 w(UNKNOWN)p 2652
+2410 V 295 w(UNKNOWN)p 3276 2410 V 620 2522 V 716 2489
+a(FALSE)p 1025 2522 V 184 w(FALSE)p 1430 2522 V 1447
+2522 V 312 w(FALSE)p 2071 2522 V 382 w(FALSE)p 2652 2522
+V 383 w(FALSE)p 3276 2522 V 622 2526 2656 4 v 150 2783
+a Ft(4.4.4)105 b(Miscellaneous)150 2941 y(F)-9 b(unction)36
+b(call)45 b Fs(A)28 b(function)f(ma)m(y)h(b)s(e)f(called)g(without)g
+(the)h(result)f(necessarily)g(b)s(eing)f(assigned)h(to)i(a)377
+3041 y(v)-5 b(ariable.)46 b(If)39 b Fh(fun)30 b Fs(is)i(a)h(function)e
+(with)g(t)m(w)m(o)i(argumen)m(ts)g(\(for)f(simplicitly)d(in)m(teger)j
+(argumen)m(ts\))377 3140 y(and)e(returning)f(a)h(logical)g(v)-5
+b(alue,)30 b(then)377 3351 y Fh(log)43 b(:=)f(fun\(i1,)f(i2\);)377
+3451 y(fun\(i3,)g(24*i4\);)377 3675 y Fs(are)31 b(b)s(oth)f(legitimate)
+g(calls.)150 3862 y Ft(Dot)35 b(op)s(erator)45 b Fs(The)29
+b(dot)g(op)s(erator)g(is)e(used)h(to)i(access)g(an)e(attribute)h(from)f
+(an)g(en)m(tit)m(y)-8 b(.)42 b(If)35 b Fh(ent)27 b Fs(is)h(an)377
+3975 y Fh(ENTITY)k Fs(t)m(yp)s(e)j(with)e(an)h(attribute)g
+Fh(att)p Fs(,)h(then)f Fh(ent.attr)d Fs(ev)-5 b(aluates)35
+b(to)g(the)g(v)-5 b(alue)33 b(of)i(the)g Fh(attr)377
+4088 y Fs(attribute)30 b(within)e(the)j Fh(ent)p Fs(.)150
+4262 y Ft(String)k(op)s(erators)377 4362 y Fs(The)f Fn(+)h
+Fs(op)s(erator)g(tak)m(es)h(t)m(w)m(o)g(strings)d(as)i(its)f(op)s
+(erands)g(and)g(ev)-5 b(aluates)35 b(to)g(the)g(string)f(that)h(is)377
+4461 y(the)c(concatenation)h(of)e(its)g(op)s(erands.)39
+b(F)-8 b(or)32 b(example:)377 4672 y Fh(str1)42 b(:=)h('string1';)377
+4772 y(str2)f(:=)h('string2';)377 4871 y(str1)f(:=)h(str1)f(+)h(str2;)
+377 4971 y(--)g(str1)f(=)h('string1string2')124 b(is)43
+b(TRUE)377 5182 y Fs(The)33 b(substring)e(op)s(erator)i
+Fn([i1:i2])e Fs(is)h(a)i(p)s(ost\014x)e(op)s(erator)h(that)h(when)e
+(applied)f(to)i(a)h(string,)377 5282 y(ev)-5 b(alutes)33
+b(to)g(the)g(string)e(whose)h(c)m(haracters)i(are)f(comp)s(osed)f(of)h
+(the)f Fn(i1)p Fs('th)g(through)g(the)g Fn(i2)p Fs('th)1905
+5531 y(50)p eop
+%%Page: 51 55
+51 54 bop 377 573 a Fs(c)m(haracters,)32 b(inclusiv)m(ely)-8
+b(,)28 b(of)i(its)f(op)s(erand.)39 b(Note)32 b(that)e
+Fn(i2)f Fs(m)m(ust)h(b)s(e)f(greater)i(than)f(or)g(equal)f(to)377
+672 y Fn(i1)p Fs(,)g(and)f(b)s(oth)g(m)m(ust)g(b)s(e)g(within)e(the)j
+(limits)d(of)i(the)h(n)m(um)m(b)s(er)e(of)i(c)m(haracters)h(in)d(the)i
+(string.)39 b(F)-8 b(or)377 772 y(example:)377 984 y
+Fh(str1)42 b(:=)h('string';)377 1083 y(str2)f(:=)h(str1[2:4];)377
+1183 y(str1)f(:=)h(str1)f(+)h(str2;)377 1283 y(--)g(str1)f(=)h
+('tristring')126 b(is)43 b(TRUE)150 1494 y Ft(Aggregate)35
+b(op)s(erators)377 1594 y Fs(The)41 b(index)e(op)s(erator)i
+Fn([i])f Fs(is)g(a)h(p)s(ost\014x)f(op)s(erator)h(that)h(can)f(b)s(e)f
+(applied)f(to)i(an)g(aggregate)377 1694 y(op)s(erand;)29
+b(the)g(expression)f(ev)-5 b(aluates)30 b(to)f(the)h(v)-5
+b(alue)28 b(of)i(the)f(aggregate)j(at)e(the)f(index)f(p)s(osition.)377
+1793 y(F)-8 b(or)31 b(example,)g(if)36 b Fh(lagg)29 b
+Fs(is)g(a)i(list)e(of)h(in)m(tegers:)377 2005 y Fh(insert\(lagg,)39
+b(20,)j(0\);)377 2105 y(insert\(lagg,)d(40,)j(0\);)377
+2204 y(insert\(lagg,)d(60,)j(0\);)377 2304 y(insert\(lagg,)d(80,)j
+(0\);)377 2403 y(--)h(lagg[2])e(=)i(60)173 b(is)43 b(TRUE)150
+2615 y Ft(In)m(terv)-6 b(al)35 b(expression)377 2715
+y Fs(An)f Fi(interval)j(expr)-5 b(ession)43 b Fs(is)33
+b(a)h Fh(LOGICAL)e Fs(expression)h(consisting)f(of)j(three)f(op)s
+(erands)f(and)h(t)m(w)m(o)377 2814 y(op)s(erators.)41
+b(It)31 b(has)f(the)g(form:)377 3026 y Fh({)43 b(low)g(op1)f(test)g
+(op2)g(high)g(})377 3238 y Fs(where)35 b Fh(op1)g Fs(and)f
+Fh(op2)h Fs(are)h(either)f(of)g(the)h(t)m(w)m(o)h(relational)d(op)s
+(erators)i Fn(<)f Fs(or)h Fn(<=)p Fs(,)g(and)f Fh(low)p
+Fs(,)h Fh(test)377 3337 y Fs(and)30 b Fh(high)f Fs(are)h(expressions)f
+(of)i(the)g(same)f(t)m(yp)s(e.)41 b(The)30 b(in)m(terv)-5
+b(al)30 b(expression)f(is)g(equiv)-5 b(alen)m(t)30 b(to:)377
+3549 y Fh(\(\(low)42 b(op1)g(test\))g(AND)g(\(test)g(op2)g(high\)\))377
+3774 y Fs(The)30 b(v)-5 b(alue)30 b(of)h(the)f(in)m(terv)-5
+b(al)30 b(expression)f(is)g(giv)m(en)i(b)m(y)461 3962
+y(1.)46 b(If)30 b(an)m(y)h(op)s(erand)e(is)h(indeterminate,)f(then)h
+(it)g(ev)-5 b(auates)32 b(to)f Fh(UNKNOWN)p Fs(.)461
+4108 y(2.)46 b(If)27 b(either)f(of)h(the)g(logical)f(relationships)e
+(ev)-5 b(aluates)28 b(to)f Fh(FALSE)p Fs(,)e(then)i(it)f(ev)-5
+b(auates)28 b(to)g Fh(FALSE)p Fs(.)461 4254 y(3.)46 b(If)30
+b(b)s(oth)g(logical)g(relationships)d(ev)-5 b(alute)31
+b(to)g Fh(TRUE)p Fs(,)e(then)h(it)g(ev)-5 b(auates)31
+b(to)h Fh(TRUE)p Fs(.)461 4400 y(4.)46 b(Otherwise)29
+b(it)h(ev)-5 b(aluates)31 b(to)g Fh(UNKNOWN)p Fs(.)377
+4575 y(F)-8 b(or)31 b(example:)377 4786 y Fh(i)43 b(:=)g(10;)377
+4886 y({1)g(<=)g(i)g(<)g(20})86 b(--)43 b(is)g(TRUE)377
+4985 y({1)g(<=)g(i)g(<)g(10})86 b(--)43 b(is)g(FALSE)377
+5085 y(i)g(:=)g(?;)377 5185 y({1)g(<=)g(i)g(<)g(10})86
+b(--)43 b(is)g(UNKNOWN)1905 5531 y Fs(51)p eop
+%%Page: 52 56
+52 55 bop 150 573 a Fj(4.5)112 b(Built)35 b(in)i(pro)s(cedures)h(and)h
+(functions)150 744 y Ft(4.5.1)105 b(Pro)s(cedures)150
+916 y Fs(The)27 b(follo)m(wing)f(pro)s(cedures)g(are)h(an)h(in)m
+(tegral)f(part)g(of)g Fo(Express-A)p Fs(.)g(They)g(are)g(sho)m(wn)g(as)
+h(signatures)150 1029 y(to)35 b(inidicate)e(the)h(data)h(t)m(yp)s(es)f
+(of)h(the)f(formal)g(parameters.)52 b(F)-8 b(or)36 b(con)m(v)m
+(enience,)g Fh(GENERIC)31 b Fs(is)j(used)f(to)150 1142
+y(indicate)c(an)m(y)i(t)m(yp)s(e.)286 1354 y Fm(\017)46
+b Fh(INSERT)41 b(\(VAR)h(L:LIST)f(OF)i(GENERIC;)d(E:GENERIC;)g
+(P:INTEGER\))377 1467 y(INSERT)19 b Fs(inserts)i(the)h(elemen)m(t)g
+Fh(E)f Fs(in)m(to)g(a)i(list)d Fh(L)h Fs(at)h(p)s(osition)e
+Fh(P)p Fs(.)h(The)h(insertion)d(follo)m(ws)i(the)h(existing)377
+1580 y(elemen)m(t)31 b(at)g Fh(P)p Fs(,)f(so)h(that)g(if)36
+b Fh(P=0)p Fs(,)30 b Fh(E)g Fs(will)d(b)s(ecome)k(the)g(\014rst)e
+(elemen)m(t.)286 1768 y Fm(\017)46 b Fh(REMOVE)41 b(\(VAR)h(L:LIST)f
+(OF)i(GENERIC;)d(P:INTEGER\))377 1881 y(REMOVE)28 b Fs(mo)s(di\014es)h
+(the)h(list)f Fh(L)h Fs(b)m(y)g(deleting)g(the)g(elemen)m(t)h(at)g(p)s
+(osition)e Fh(P)p Fs(.)286 2068 y Fm(\017)46 b Fh(SYSTEM)41
+b(\(V:STRING\))377 2181 y(SYSTEM)30 b Fs(passes)j(the)g(string)g
+Fh(V)f Fs(to)h(the)g(op)s(erating)f(system.)48 b(This)31
+b(is)g(t)m(ypically)h(used)g(to)h(get)h(the)377 2294
+y(op)s(erating)c(system)h(to)g(p)s(erform)e(some)h(action.)286
+2482 y Fm(\017)90 b Fh(READ\(VAR)40 b(V1,)i(V2,...:GENERIC\))p
+Fs(,)25 b Fh(READLN\(VAR)39 b(V1,)k(V2,...:GENERIC\))377
+2595 y Fs(These)29 b(t)m(w)m(o)h(pro)s(cedures)d(are)j(similar)c(to)j
+(the)g(P)m(ascal)h(pro)s(cedures)d(of)i(the)g(same)h(name)e(and)h(put)
+377 2708 y(data)i(from)f(standard)g(input)e(in)m(to)j(the)f(v)-5
+b(ariable\(s\))30 b Fh(V1)p Fs(,)g(etc.)377 2858 y(The)23
+b(argumen)m(t)g(is)f(a)h(comma-sep)s(erated)h(list)d(of)i(v)-5
+b(ariables.)37 b(The)22 b(v)-5 b(ariables)22 b(ma)m(y)h(b)s(e)f(of)h
+(di\013eren)m(t)377 2971 y(t)m(yp)s(es,)28 b(but)d(the)i(t)m(yp)s(es)f
+(are)h(limited)d(to)j Fh(INTEGER)p Fs(,)d Fh(REAL)p Fs(,)h
+Fh(LOGICAL)p Fs(,)e(and)j Fh(STRING)p Fs(.)e(The)i(pro)s(cedure)377
+3084 y(gets)37 b(the)e(next)h(v)-5 b(alue)35 b(of)g(the)h(v)-5
+b(ariable's)34 b(t)m(yp)s(e)i(from)f(standard)g(input)e(and)i(assigns)g
+(it)g(to)h(the)377 3197 y(v)-5 b(ariable.)63 b(An)37
+b(in)m(teger)i(is)e(recognised)g(as)i(a)f(set)h(of)f(digits,)g
+(optinally)e(preceeded)i(b)m(y)g(a)h(sign.)377 3310 y(A)c(real)f(is)g
+(in)f(either)h(decimal)g(or)g(scien)m(ti\014c)g(notation)h(\(e.g.,)i
+Fn(12.34)d Fs(or)g Fn(1.234e1)p Fs(\).)52 b(A)34 b(logical)377
+3423 y(is)e Fn(TRUE)p Fs(,)g Fn(FALSE)f Fs(or)i Fn(UNKNOWN)d
+Fs(\(case)k(indep)s(enden)m(t,)d(so)i Fn(TRUE)f Fs(could)g(also)g(b)s
+(e)g Fn(tRuE)p Fs(\).)g(A)h(string)377 3535 y(is)e(an)m(y)h(non-empt)m
+(y)g(set)g(of)g(c)m(haracters)i(ended)d(b)m(y)g(white)g(space)h
+(\(e.g.,)i Fn(string )c Fs(is)h(one)h(string)377 3648
+y(but)d Fn(ball of str8 string )23 b Fs(is)28 b(four)h(strings\).)39
+b(The)29 b(di\013erence)f(b)s(et)m(w)m(een)i Fh(READ)d
+Fs(and)h Fh(READLN)377 3761 y Fs(is)i(that)i(the)f(former)g(p)s
+(erforms)f(the)h(actions)g(describ)s(ed)e(ab)s(o)m(v)m(e,)k(while)c
+(the)i(latter)h(will)c(discard)377 3874 y(an)m(y)j(remaining)d(c)m
+(haracters)k(in)d(the)i(input)d(line)h(after)i(pro)s(cessing)e(its)h
+(argumen)m(ts.)286 4062 y Fm(\017)90 b Fh(WRITE\(format\))p
+Fs(,)25 b Fh(WRITELN\(format\))377 4175 y Fs(These)34
+b(t)m(w)m(o)h(pro)s(cedures)d(are)j(similar)c(to)j(the)g(P)m(ascal)h
+(pro)s(cedures)d(of)i(the)g(same)g(name.)51 b(They)377
+4288 y(write)30 b(data)h(to)g(standard)f(output.)377
+4425 y(The)25 b Fh(format)e Fs(consists)i(of)h(a)g(comma-sep)s(erated)h
+(list)d(of)i(v)-5 b(ariables)24 b(with)g(optional)h(spacing)g(sp)s(ec-)
+377 4524 y(i\014cations.)40 b(The)29 b(v)-5 b(ariable)28
+b(t)m(yp)s(es)i(ma)m(y)g(b)s(e)f Fh(INTEGER)p Fs(,)e
+Fh(REAL)p Fs(,)i Fh(LOGICAL)p Fs(,)e(or)i Fh(STRING)p
+Fs(.)f(The)h Fh(LOGICAL)377 4624 y Fs(and)41 b Fh(STRING)d
+Fs(t)m(yp)s(es)j(tak)m(e)i(no)e(spacing)g(declarations.)72
+b(An)41 b Fh(INTEGER)d Fs(v)-5 b(ariable)40 b(can)h(tak)m(e)i(one)377
+4723 y(optional)29 b(space)i(sp)s(eci\014cation)e(whic)m(h)g(is)g(an)h
+(in)m(teger)g(n)m(um)m(b)s(er)f(sp)s(ecifying)f(the)i(minim)m(um)d
+(\014eld)377 4823 y(width)e(for)i(prin)m(ting)e(the)i(v)-5
+b(alue)26 b(\(e.g.,)k Fh(int:6)25 b Fs(to)i(sp)s(ecify)f(a)h(minim)m
+(um)d(\014eld)i(width)f(of)i(6)g(c)m(harac-)377 4923
+y(ters\).)41 b(A)28 b Fh(REAL)e Fs(v)-5 b(ariable)27
+b(can)h(tak)m(e)i(t)m(w)m(o)f(optional)e(space)i(sp)s(eci\014cations.)
+38 b(The)28 b(\014rst)f(is)g(the)h(\014eld)377 5022 y(width)j(and)h
+(the)h(second)f(is)g(the)h(n)m(um)m(b)s(er)e(of)h(digits)g(to)h(b)s(e)f
+(prin)m(ted)f(\(e.g.,)k Fh(r:10:5)30 b Fs(for)i(prin)m(ting)377
+5122 y(with)d(a)i(\014eld)e(width)g(of)h(10)h(c)m(haracters)h(and)e(to)
+h(a)g(p)s(ecision)d(of)j(5)g(digits\).)39 b(F)-8 b(or)31
+b(example:)1905 5531 y(52)p eop
+%%Page: 53 57
+53 56 bop 377 573 a Fh(BEGIN_LOCAL)464 672 y(int)43 b(:)g(INTEGER;)464
+772 y(r)131 b(:)43 b(REAL;)464 872 y(log)g(:)g(LOGICAL;)464
+971 y(str)g(:)g(STRING;)377 1071 y(END_LOCAL;)464 1171
+y(int)g(:=)g(23;)464 1270 y(r)h(:=)e(23.0;)464 1370 y(log)h(:=)g(true;)
+464 1469 y(str)g(:=)g('This)e(is)i(a)g(string.';)377
+1569 y(WRITE\('Example',)37 b(int,)42 b(r:10:5,)f(')i(',)g(log,)f(')h
+(',)g(str\);)377 1767 y Fs(will)28 b(pro)s(duce:)377
+1965 y Fh(Example)259 b(23)217 b(23.000)41 b(TRUE)h(This)g(is)h(a)g
+(string.)377 2177 y Fs(The)33 b(di\013erence)f(b)s(et)m(w)m(een)i
+Fh(WRITE)c Fs(and)j Fh(WRITELN)d Fs(is)i(that)h(the)g(latter)g(will)e
+(end)h(the)h(output)g(line)377 2290 y(after)f(it)g(has)f(output)g(the)h
+(v)-5 b(alues)31 b(of)h(its)f(argumen)m(ts.)45 b(\()p
+Fh(WRITELN)29 b Fs(need)j(tak)m(e)h(no)f(argumen)m(ts,)g(in)377
+2403 y(whic)m(h)d(case)j(it)e(justs)f(ends)h(the)h(curren)m(t)f(output)
+g(line\).)286 2586 y Fm(\017)90 b Fh(PRINT\(format\))p
+Fs(,)25 b Fh(PRINTLN\(format\))377 2699 y Fs(These)31
+b Fh(PRINT)d Fs(pro)s(cedures)h(are)i(the)g(same)g(as)g(the)g
+Fh(WRITE)d Fs(pro)s(cedures,)i(except)i(that)f(they)g(send)377
+2811 y(the)g(data)g(to)g(the)g(curren)m(t)f Fy(L)-7 b(TX2X)30
+b Fs(output)g(destination.)150 3049 y Ft(4.5.2)105 b(F)-9
+b(unctions)150 3221 y Fs(The)22 b(follo)m(wing)e(functions)h(are)h
+(supplied)d(as)k(part)f(of)g Fo(Express-A)p Fs(.)f(They)h(are)g
+(exhibited)e(as)j(signatures)150 3334 y(to)33 b(sho)m(w)g(the)g(formal)
+e(parameters.)48 b(F)-8 b(or)33 b(con)m(v)m(enience,)i
+Fh(NUMBER)30 b Fs(is)i(b)s(eing)f(used)h(to)h(denote)g(either)f(an)150
+3447 y Fh(INTEGER)27 b Fs(or)k(a)g Fh(REAL)d Fs(n)m(um)m(b)s(er.)286
+3646 y Fm(\017)46 b Fh(ABS)d(\(V:NUMBER\))c(:)k(NUMBER;)377
+3759 y(ABS)29 b Fs(returns)g(the)i(absolute)f(v)-5 b(alue)30
+b(of)h(its)e(argumen)m(t.)286 3942 y Fm(\017)46 b Fh(COS)d
+(\(V:NUMBER\))c(:)k(REAL;)377 4055 y Fs(Returns)30 b(the)g(cosine)g(of)
+h(an)f(an)h(angle)f(sp)s(eci\014ed)f(in)g(radians.)286
+4238 y Fm(\017)46 b Fh(EOF)d(\(\))f(:)87 b(LOGICAL;)377
+4351 y Fs(Returns)37 b Fh(TRUE)f Fs(if)h(the)h(next)g(c)m(haracter)h
+(from)e(standard)g(input)f(is)h(`end-of-\014le',)i(otherwise)e(it)377
+4464 y(returns)29 b Fh(FALSE)p Fs(.)286 4647 y Fm(\017)46
+b Fh(EOLN)c(\(\))h(:)87 b(LOGICAL;)377 4760 y Fs(Returns)35
+b Fh(TRUE)f Fs(if)h(the)g(next)h(c)m(haracter)i(from)d(standard)g
+(input)e(is)i(`end-of-line',)h(otherwise)f(it)377 4873
+y(returns)29 b Fh(FALSE)p Fs(.)286 5056 y Fm(\017)46
+b Fh(EXISTS)41 b(\(V:GENERIC\))e(:)44 b(LOGICAL;)377
+5169 y Fs(The)30 b(function)f Fh(EXISTS)f Fs(returns)h
+Fh(FALSE)f Fs(if)h(its)g(argumen)m(t)i(is)e(indeterminate)g(or)i(do)s
+(es)e(not)i(exist,)377 5282 y(otherwise)f(it)g(returns)f
+Fh(TRUE)p Fs(.)1905 5531 y(53)p eop
+%%Page: 54 58
+54 57 bop 286 573 a Fm(\017)46 b Fh(EXP)d(\(V:NUMBER\))c(:)k(REAL;)377
+686 y Fs(Returns)30 b Fe(e)g Fs(\(the)h(base)g(of)f(natural)g
+(logarithms)f(\()p Fh(CONST)p 2322 686 27 4 v 30 w(E)p
+Fs(\)\))h(raised)g(to)h(the)f(p)s(o)m(w)m(er)h(of)37
+b Fh(V)p Fs(.)286 873 y Fm(\017)46 b Fh(HIBOUND)41 b(\(V:AGGREGATE)e
+(OF)j(GENERIC\))f(:)i(INTEGER;)377 986 y(HIBOUND)27 b
+Fs(returns)h(the)h(declared)g(upp)s(er)e(index)h(of)h(an)g
+Fh(ARRAY)e Fs(or)i(the)h(declared)e(upp)s(er)g(b)s(ound)f(of)377
+1099 y(a)k Fh(BAG)p Fs(,)e Fh(LIST)g Fs(or)h Fh(SET)p
+Fs(.)286 1287 y Fm(\017)46 b Fh(HIINDEX)41 b(\(V:AGGREGATE)e(OF)j
+(GENERIC\))f(:)i(INTEGER;)377 1400 y(HIINDEX)28 b Fs(returns)h(the)h
+(declared)g(upp)s(er)e(index)h(of)h(an)h Fh(ARRAY)d Fs(or)i(the)h(n)m
+(um)m(b)s(er)d(of)j(elemen)m(ts)g(in)e(a)377 1513 y Fh(BAG)p
+Fs(,)h Fh(LIST)e Fs(or)j Fh(SET)p Fs(.)286 1700 y Fm(\017)46
+b Fh(LENGTH)41 b(\(V:STRING\))f(:)j(INTEGER;)377 1813
+y Fs(Returns)30 b(the)g(n)m(um)m(b)s(er)f(of)i(c)m(haracters)h(in)d
+(its)h(argumen)m(t.)286 2001 y Fm(\017)46 b Fh(LOBOUND)41
+b(\(V:AGGREGATE)e(OF)j(GENERIC\))f(:)i(INTEGER;)377 2114
+y(LOBOUND)30 b Fs(returns)h(the)i(declared)f(lo)m(w)m(er)g(index)f(of)i
+(an)f Fh(ARRAY)f Fs(or)h(the)h(declared)f(lo)m(w)m(er)g(b)s(ound)f(of)
+377 2227 y(a)g Fh(BAG)p Fs(,)e Fh(LIST)g Fs(or)h Fh(SET)p
+Fs(.)286 2414 y Fm(\017)46 b Fh(LOG)d(\(V:NUMBER\))c(:)k(REAL;)377
+2527 y Fs(Returns)30 b(the)g(natural)g(logarithm)f(of)i(its)e(argumen)m
+(t.)286 2715 y Fm(\017)46 b Fh(LOG2)c(\(V:NUMBER\))e(:)j(REAL;)377
+2828 y Fs(Returns)30 b(the)g(base)h(2)g(logarithm)e(of)i(its)e(argumen)
+m(t.)286 3015 y Fm(\017)46 b Fh(LOG10)c(\(V:NUMBER\))d(:)k(REAL;)377
+3128 y Fs(Returns)30 b(the)g(base)h(10)g(logarithm)e(of)i(its)f
+(argumen)m(t.)286 3316 y Fm(\017)46 b Fh(LOINDEX)41 b(\(V:AGGREGATE)e
+(OF)j(GENERIC\))f(:)i(INTEGER;)377 3429 y(LOINDEX)27
+b Fs(returns)h(the)h(declared)g(lo)m(w)m(er)g(index)f(of)i(an)f
+Fh(ARRAY)e Fs(or)i(the)h(v)-5 b(alue)29 b(1)g(for)g(a)h
+Fh(BAG)p Fs(,)e Fh(LIST)g Fs(or)377 3542 y Fh(SET)p Fs(.)377
+3679 y(The)34 b Fh(..INDEX)d Fs(functions)i(are)h(useful)f(for)h
+(iterating)f(o)m(v)m(er)j(aggregates.)55 b(F)-8 b(or)34
+b(example,)h(if)41 b Fh(lagg)377 3778 y Fs(is)27 b(a)i(list)e(of)h(in)m
+(teger,)h(then)f(all)f(the)i(elemen)m(ts)f(can)h(b)s(e)e(prin)m(ted)g
+(out)h(as)h(a)f(comma-sep)s(erated)h(list)377 3878 y(enclosed)h(in)f
+(paren)m(theses)i(b)m(y:)377 4090 y Fh(writeln;)377 4189
+y(write\('lagg)39 b(=)k(\('\);)377 4289 y(REPEAT)e(i)j(:=)e
+(LOINDEX\(lagg\))d(TO)j(HIINDEX\(lagg\);)464 4389 y(IF)h(\(i)g(=)g
+(HIINDEX\(lagg\)\))38 b(THEN)k(write\(lagg[i]:1\))o(;)464
+4488 y(ELSE)g(write\(lagg[i]:1,)37 b(',)43 b('\);)464
+4588 y(END_IF;)377 4687 y(END_REPEAT;)377 4787 y(writeln\('\)'\);)286
+5012 y Fm(\017)j Fh(NVL)d(\(V:GENERIC;)c(SUBS:GENERIC\))f(:)43
+b(GENERIC;)377 5125 y Fs(If)29 b(the)g(argumen)m(t)h
+Fh(V)e Fs(exists)h(then)f(it)h(is)f(returned,)g(otherwise)h(the)g
+(argumen)m(t)h Fh(SUBS)d Fs(is)h(returned.)377 5238 y(Both)j(argumen)m
+(ts)g(m)m(ust)f(b)s(e)g(of)g(the)h(same)g(t)m(yp)s(e.)1905
+5531 y(54)p eop
+%%Page: 55 59
+55 58 bop 286 573 a Fm(\017)46 b Fh(ODD)d(\(V:INTEGER\))c(:)k(LOGICAL;)
+377 686 y Fs(Returns)30 b Fh(TRUE)e Fs(or)j Fh(FALSE)d
+Fs(dep)s(ending)g(on)i(whether)g(or)g(not)h(its)f(argumen)m(t)g(is)g(o)
+s(dd)f(or)h(ev)m(en.)286 870 y Fm(\017)46 b Fh(REXPR)c(\(V:STRING;)d
+(E:STRING\))h(:)j(LOGICAL;)377 983 y Fs(This)36 b(function)f(tests)j
+(whether)f(the)g Fh(V)g Fs(string)f(parameter)h(matc)m(hes)h(a)g
+(regular)e(expression)g Fh(E)p Fs(.)377 1096 y Fh(REXPR)27
+b Fs(returns)h Fh(TRUE)f Fs(if)g(there)i(is)f(a)h(matc)m(h,)i
+Fh(FALSE)26 b Fs(if)i(there)h(is)f(not)h(a)g(matc)m(h,)h(or)f
+Fh(UNKNOWN)d Fs(if)i(the)377 1209 y(regular)i(expression)f(is)g
+(ill-formed.)377 1358 y(In)g(the)g(regular)f(expression,)h(most)g(c)m
+(haracters)i(stand)e(for)g(themselv)m(es,)h(but)e Fn(\\)h
+Fs(can)g(b)s(e)g(used)f(to)377 1471 y(escap)s(e)j(an)m(y)g(of)f(the)h
+(meta-c)m(haracters.)480 1655 y Ft({)45 b Fs(The)30 b(meta-c)m
+(haracters)j Fh(\()d Fs(and)g Fh(\))g Fs(are)h(used)e(for)h(grouping)f
+(sub-expressions.)480 1798 y Ft({)45 b Fn(|)30 b Fs(b)s(et)m(w)m(een)h
+(expressions)e(means)i(one)f(or)h(the)f(other.)480 1942
+y Ft({)45 b Fh(+)30 b Fs(follo)m(wing)f(an)h(expression)f(means)i(matc)
+m(h)g(one)g(or)f(more)g(times.)480 2085 y Ft({)45 b Fh(*)30
+b Fs(follo)m(wing)f(an)h(expression)f(means)i(matc)m(h)g(zero)g(or)f
+(more)h(times.)480 2228 y Ft({)45 b Fh(?)40 b Fs(follo)m(wing)29
+b(an)h(expression)f(means)i(matc)m(h)g(zero)g(or)g(one)f(times.)480
+2371 y Ft({)45 b Fn([...])27 b Fs(is)f(an)i(expression)e(indicating)g
+(that)i(an)m(y)h(of)e(the)h(enclosed)g(c)m(haracters)h(are)f(accept-)
+577 2484 y(able.)480 2627 y Ft({)45 b Fn([^...])26 b
+Fs(is)h(an)h(expression)e(indicating)g(that)i(an)m(y)g(c)m(haracters)h
+(except)g(those)f(enclosed)g(are)577 2740 y(acceptable.)480
+2883 y Ft({)45 b Fs(Within)30 b(a)h(brac)m(k)m(et)i(expression)d(a)i
+(range)f(of)h(c)m(haracters)g(can)g(b)s(e)e(sp)s(eci\014ed)g(b)m(y)h
+(pro)m(viding)577 2996 y(the)36 b(\014rst)e(and)g(last)h(with)f(a)i
+(sep)s(erating)e(h)m(yphen.)54 b(F)-8 b(or)36 b(instance,)g
+Fh([a-zA-Z])c Fs(will)g(matc)m(h)577 3109 y(an)m(y)f(alphab)s(etic)e(c)
+m(haracter.)377 3293 y(Some)i(examples:)480 3478 y Ft({)45
+b Fn([a-zA-Z]+)28 b Fs(matc)m(h)j(one)g(or)f(more)h(letters.)480
+3621 y Ft({)45 b Fn([0-9]+.[0-9]+\([eE][\\-\\+]?)o([0-9)o(]+\)?)24
+b Fs(matc)m(h)31 b(a)g(\015oating)f(p)s(oin)m(t)f(n)m(um)m(b)s(er)577
+3734 y(\(e.g.,)k Fn(1.23e-27)28 b Fs(or)i Fn(0.987)p
+Fs(\))480 3877 y Ft({)45 b Fn([a-zA-Z][0-9a-zA-Z_]*)25
+b Fs(matc)m(h)31 b(an)f Fo(Express-A)g Fs(v)-5 b(ariable.)480
+4020 y Ft({)45 b Fn([^0-9a-zA-Z])27 b Fs(matc)m(h)32
+b(an)m(ything)d(except)j(letters)e(or)h(digits.)480 4163
+y Ft({)45 b Fn(\(I|i\)\(F|f\))28 b Fs(case)j(insensitiv)m(e)e(matc)m(h)
+i(for)f(the)h(w)m(ord)f Fn(IF)p Fs(.)286 4348 y Fm(\017)46
+b Fh(ROUND)c(\(V:NUMBER\))d(:)k(INTEGER;)377 4461 y Fs(Returns)30
+b(the)g(nearest)h(in)m(teger)g(to)g(its)f(argumen)m(t)h(v)-5
+b(alue.)286 4645 y Fm(\017)46 b Fh(SIN)d(\(V:NUMBER\))c(:)k(REAL;)377
+4758 y Fs(Returns)30 b(the)g(sine)g(of)g(an)g(an)h(angle)f(sp)s
+(eci\014ed)f(in)g(radians.)286 4943 y Fm(\017)46 b Fh(SIZEOF)41
+b(\(V:AGGREGATE)e(OF)k(GENERIC\))d(:)j(INTEGER;)377 5056
+y(SIZEOF)23 b Fs(returns)i(the)h(n)m(um)m(b)s(er)e(of)i(elemen)m(ts)g
+(in)f(its)g(argumen)m(t.)40 b(When)25 b Fh(V)g Fs(is)g(an)h
+Fh(ARRAY)d Fs(this)i(is)g(the)377 5169 y(declared)30
+b(n)m(um)m(b)s(er)g(of)g(elemen)m(ts.)42 b(When)30 b
+Fh(V)h Fs(is)e(a)i Fh(BAG)p Fs(,)f Fh(LIST)f Fs(or)h
+Fh(SET)f Fs(this)h(is)g(the)g(actual)h(n)m(um)m(b)s(er)377
+5282 y(of)g(elemen)m(ts.)1905 5531 y(55)p eop
+%%Page: 56 60
+56 59 bop 286 573 a Fm(\017)46 b Fh(SQRT)c(\(V:NUMBER\))e(:)j(REAL;)377
+686 y Fs(Returns)30 b(the)g(square)g(ro)s(ot)h(of)g(its)e(argumen)m(t.)
+286 871 y Fm(\017)46 b Fh(TAN)d(\(V:NUMBER\))c(:)k(REAL;)377
+984 y Fs(Returns)30 b(the)g(tangen)m(t)i(of)f(an)f(an)g(angle)h(sp)s
+(eci\014ed)d(in)h(radians.)286 1170 y Fm(\017)46 b Fh(TRUNC)c
+(\(V:NUMBER\))d(:)k(INTEGER;)377 1283 y Fs(Chops)24 b(o\013)g(an)m(y)h
+(decimal)f(part)g(of)h(its)e(argumen)m(t,)k(returning)22
+b(the)j(corresp)s(onding)d(in)m(teger)j(v)-5 b(alue.)150
+1525 y Fj(4.6)112 b(Source)38 b(lev)m(el)e(debugger)150
+1697 y Fs(The)22 b Fo(Express-A)g Fs(in)m(terpreter)g(includes)f(a)i
+(source)g(lev)m(el)g(debugger)g(for)f(use)h(when)f(y)m(our)h(co)s(de)g
+(app)s(ears)150 1809 y(to)41 b(b)s(e)e(misb)s(eha)m(ving.)68
+b(When)39 b(in)g(op)s(eration)g(the)i(debugger)e(will)f(prompt)h(for)h
+(a)g(command)g(to)h(b)s(e)150 1922 y(en)m(tered.)g(It)31
+b(understands)d(the)j(follo)m(wing)e(commands.)286 2128
+y Fm(\017)46 b Fh(<return>)27 b Fs(Con)m(tin)m(ue)j(pro)s(cessing.)286
+2314 y Fm(\017)46 b Fh(break)29 b(<number>)d Fs(Place)31
+b(a)g(breakp)s(oin)m(t)e(at)i(the)g(statemen)m(t)h(on)e(line)f
+Fh(<number>)p Fs(.)286 2499 y Fm(\017)46 b Fh(break)29
+b Fs(Prin)m(t)g(the)h(line)f(n)m(um)m(b)s(ers)g(of)i(all)e(the)h
+(breakp)s(oin)m(ts.)286 2685 y Fm(\017)46 b Fh(unbreak)28
+b(<number>)f Fs(Remo)m(v)m(e)32 b(the)e(breakp)s(oin)m(t)g(from)g(line)
+e Fh(<number>)p Fs(.)286 2870 y Fm(\017)46 b Fh(unbreak)28
+b Fs(Remo)m(v)m(e)k(all)d(breakp)s(oin)m(ts.)286 3056
+y Fm(\017)46 b Fh(trace)29 b Fs(T)-8 b(urn)29 b(on)h(statemen)m(t)i
+(tracing.)286 3241 y Fm(\017)46 b Fh(untrace)28 b Fs(T)-8
+b(urn)29 b(o\013)h(statemen)m(t)j(tracing.)286 3427 y
+Fm(\017)46 b Fh(entry)29 b Fs(T)-8 b(urn)29 b(on)h(tracing)g(of)h(en)m
+(try)f(to)h(pro)s(cedures)e(and)h(functions.)286 3612
+y Fm(\017)46 b Fh(unentry)28 b Fs(T)-8 b(urn)29 b(o\013)h(en)m(try)h
+(tracing.)286 3798 y Fm(\017)46 b Fh(exit)29 b Fs(T)-8
+b(urn)29 b(on)h(tracing)h(of)f(exits)g(from)g(pro)s(cedures)f(and)h
+(functions.)286 3983 y Fm(\017)46 b Fh(unexit)28 b Fs(T)-8
+b(urn)29 b(o\013)i(exit)f(tracing.)286 4169 y Fm(\017)46
+b Fh(traceall)27 b Fs(T)-8 b(urn)29 b(on)i(all)e(tracing.)286
+4354 y Fm(\017)46 b Fh(untraceall)26 b Fs(T)-8 b(urn)29
+b(o\013)i(all)e(tracing.)286 4540 y Fm(\017)46 b Fh(stack)29
+b Fs(T)-8 b(urn)29 b(on)h(displa)m(y)e(of)j(the)f(run)m(time)g(stac)m
+(k)h(accesses.)286 4725 y Fm(\017)46 b Fh(unstack)28
+b Fs(T)-8 b(urn)29 b(o\013)h(stac)m(k)i(displa)m(y)-8
+b(.)286 4911 y Fm(\017)46 b Fh(step)29 b Fs(T)-8 b(urn)29
+b(on)h(single-stepping.)286 5096 y Fm(\017)46 b Fh(unstep)28
+b Fs(T)-8 b(urn)29 b(o\013)i(single)e(stepping.)286 5282
+y Fm(\017)46 b Fh(fetch)29 b(<variable>)d Fs(Prin)m(t)j(data)i(fetc)m
+(hes)h(for)e Fh(<variable>)p Fs(.)1905 5531 y(56)p eop
+%%Page: 57 61
+57 60 bop 286 573 a Fm(\017)46 b Fh(store)29 b(<variable>)d
+Fs(Prin)m(t)j(data)i(stores)g(for)f Fh(<variable>)p Fs(.)286
+760 y Fm(\017)46 b Fh(watch)29 b(<variable>)d Fs(Prin)m(t)j(b)s(oth)h
+(data)h(fetc)m(hes)g(and)f(stores)h(for)f Fh(<variable>)p
+Fs(.)286 948 y Fm(\017)46 b Fh(watch)29 b Fs(Prin)m(t)g(the)h(names)h
+(of)f(all)g(v)-5 b(ariables)29 b(b)s(eing)f(w)m(atc)m(hed.)286
+1136 y Fm(\017)46 b Fh(unwatch)28 b(<variable>)e Fs(Remo)m(v)m(e)32
+b(the)f(w)m(atc)m(h)g(from)f Fh(<variable>)p Fs(.)286
+1323 y Fm(\017)46 b Fh(unwatch)28 b Fs(Remo)m(v)m(e)k(all)d(w)m(atc)m
+(hes.)286 1498 y Fm(\017)46 b Fh(show)35 b(<expression>)d
+Fs(Prin)m(t)k(the)h(v)-5 b(alue)37 b(of)g(the)g Fo(Express-A)e
+Fs(expresion)h Fh(<expression>)p Fs(.)55 b(The)377 1597
+y(v)-5 b(ariables)40 b(in)f(the)i(expression)e(m)m(ust)i(ha)m(v)m(e)h
+(b)s(een)e(declared)g(in)g(the)h Fo(Express-A)e Fs(co)s(de.)72
+b(F)-8 b(or)377 1697 y(example:)377 1909 y Fh(show)42
+b(\(23.0)g(+)h(LOG\(num\)\)/\(PI*r*)o(*2)o(\))286 2120
+y Fm(\017)j Fh(assign)19 b(<variable)40 b(:=)j(expression>)17
+b Fs(Assign)j(the)i(v)-5 b(alue)20 b(of)29 b Fh(<expression>)16
+b Fs(to)23 b(the)e Fo(Express-A)377 2220 y Fs(v)-5 b(ariable)29
+b Fh(<variable>)p Fs(.)37 b(F)-8 b(or)31 b(example:)377
+2432 y Fh(assign)41 b(num)i(:=)f(SIN\(theta/300.0\))286
+2657 y Fm(\017)k Fh(where)22 b Fs(Prin)m(t)g(the)i(curren)m(t)f(line)f
+(n)m(um)m(b)s(er)g(and)h(the)h(text)g(of)g(the)g(next)f(statemen)m(t)j
+(to)e(b)s(e)f(executed.)286 2844 y Fm(\017)46 b Fh(kill)29
+b Fs(T)-8 b(erminate)30 b(the)h(execution)f(of)h(the)f
+Fy(L)-7 b(TX2X)31 b Fs(program.)150 3088 y Fj(4.7)112
+b(Example)37 b Fd(Express-A)e Fj(co)s(de)150 3259 y Fs(The)i(follo)m
+(wing)f(demonstrates)i(most)g(of)g(the)f(functionalit)m(y)f(of)i
+Fo(Express-A)p Fs(.)f(Most)h(of)g(this)e(is)h(not)150
+3372 y(particularly)23 b(in)m(teresting,)i(except)i(p)s(ossibly)22
+b(for)j(the)g(algorithms)f(for)h(calculating)f(the)h(date)h(of)f
+(Easter)150 3485 y(and)30 b(for)g(generating)h(magic)f(squares.)412
+3684 y Fh(c=)347 b(fun.ct)85 b(Test)42 b(of)h(CODE)f(ltx2x)150
+3884 y(CODE_SETUP=)237 3983 y(ENTITY)f(ent;)324 4083
+y(attr1,)g(attr3)h(:)h(INTEGER;)324 4183 y(attr2)f(:)h(STRING;)237
+4282 y(END_ENTITY;)237 4481 y(TYPE)f(joe)g(=)i(INTEGER;)237
+4581 y(END_TYPE;)237 4780 y(TYPE)e(colour)f(=)i(ENUMERATION)c(OF)k
+(\(red,)f(blue,)f(green\);)237 4880 y(END_TYPE;)150 5179
+y(PROCEDURE)f(easter;)150 5278 y(\(*)j(calculates)c(the)k(date)e(of)i
+(Easter)e(for)i(the)f(present)f(year)1905 5531 y Fs(57)p
+eop
+%%Page: 58 62
+58 61 bop 281 573 a Fh(The)42 b(algorithm)e(can)i(be)h(applied)e(to)i
+(any)f(year)g(between)281 672 y(1900)g(and)g(2099)g(inclusive,)d(but)k
+(if)g(so,)f(then)g(the)g(year)281 772 y(should)f(be)i(checked)d(to)j
+(ensure)e(that)h(it)h(is)g(within)e(this)h(range.)f(*\))237
+872 y(LOCAL)324 971 y(n,)i(a,)g(b,)g(m,)f(q,)h(w)g(:)g(INTEGER;)324
+1071 y(day)g(:)g(INTEGER;)324 1171 y(month)f(:)h(STRING;)237
+1270 y(END_LOCAL;)237 1469 y(n)g(:=)g(THE_YEAR)d(-)k(1900;)237
+1569 y(a)f(:=)g(n)g(MOD)g(19;)237 1669 y(b)g(:=)g(\(7*a)f(+)h(1\))g
+(DIV)f(19;)237 1768 y(m)h(:=)g(\(11*a)f(+)h(4)g(-)g(b\))g(MOD)f(29;)237
+1868 y(q)h(:=)g(n)g(DIV)g(4;)237 1968 y(w)g(:=)g(\(n)g(+)g(q)g(+)g(31)g
+(-)g(m\))g(MOD)f(7;)237 2067 y(day)h(:=)f(25)h(-)g(m)g(-)h(w;)237
+2167 y(month)e(:=)g('April';)237 2267 y(IF)h(\(day)f(<)h(1\))g(THEN)324
+2366 y(month)f(:=)h('March';)324 2466 y(day)g(:=)f(day)h(+)g(31;)237
+2565 y(END_IF;)237 2665 y(writeln\('In)c(',)k(THE_YEAR:1,)c(')k(Easter)
+e(is)i(on)g(',)g(month,)84 b(day:3\);)150 2765 y(END_PROCEDURE;)150
+3064 y(FUNCTION)40 b(magic_square\(orde)o(r:)o(INT)o(EG)o(ER\))o(:)d
+(LOGICAL;)150 3163 y(\(*)43 b(calculates)c(magic)j(squares)e(from)i
+(order)g(1)h(through)e(15.)281 3263 y(The)h(order)g(must)g(be)g(an)h
+(odd)f(number.)f(*\))237 3362 y(LOCAL)237 3462 y(row,)h(col,)g(num)g(:)
+i(INTEGER;)237 3562 y(sqr_order)c(:)j(INTEGER;)237 3661
+y(magic)f(:)h(ARRAY[1:15])c(OF)k(ARRAY[1:15])c(OF)j(INTEGER;)237
+3761 y(END_LOCAL;)237 3960 y(IF)h(\(order)e(>)i(15\))g(THEN)85
+b(--)43 b(only)f(squares)e(up)j(to)g(order)e(15)324 4060
+y(RETURN\(FALSE\);)237 4159 y(ELSE)324 4259 y(IF)i(\(order)e(<)i(1\))g
+(THEN)f(--)h(squares)e(have)g(at)i(least)f(one)g(entry)412
+4359 y(RETURN\(FALSE\);)324 4458 y(ELSE)412 4558 y(IF)g(\(NOT)g
+(ODD\(order\)\))d(THEN)j(--)h(squares)e(are)h(odd)499
+4658 y(RETURN\(FALSE\);)412 4757 y(END_IF;)324 4857 y(END_IF;)237
+4956 y(END_IF;)237 5156 y(sqr_order)e(:=)j(order**2;)237
+5255 y(row)g(:=)f(1;)1905 5531 y Fs(58)p eop
+%%Page: 59 63
+59 62 bop 237 573 a Fh(col)43 b(:=)f(\(order)f(+)j(1\))e(DIV)h(2;)237
+672 y(REPEAT)e(num)i(:=)f(1)i(TO)e(sqr_order;)324 772
+y(magic[row][col])c(:=)k(num;)324 872 y(IF)h(\(\(num)f(MOD)g(order\))f
+(<>)i(0\))g(THEN)412 971 y(IF)f(\(row)g(=)h(1\))g(THEN)f(row)g(:=)h
+(order;)e(ELSE)h(row)h(:=)f(row)h(-)g(1;)g(END_IF;)412
+1071 y(IF)f(\(col)g(=)h(order\))e(THEN)h(col)h(:=)g(1;)f(ELSE)g(col)h
+(:=)f(col)h(+)g(1;)g(END_IF;)324 1171 y(ELSE)412 1270
+y(IF)f(\(num)g(<>)h(sqr_order\))c(THEN)j(row)h(:=)f(row)h(+)g(1;)g
+(END_IF;)324 1370 y(END_IF;)237 1469 y(END_REPEAT;)237
+1669 y(writeln\(Magic)38 b(square)j(of)i(order)f(',order:2\);)237
+1768 y(REPEAT)f(row)i(:=)f(1)i(TO)e(order;)324 1868 y(REPEAT)f(col)i
+(:=)g(1)g(TO)f(order;)412 1968 y(write\(magic[row)o(][)o(col)o(]:)o
+(4\);)324 2067 y(END_REPEAT;)324 2167 y(writeln;)237
+2267 y(END_REPEAT;)237 2366 y(writeln;)237 2565 y(RETURN\(TRUE\);)150
+2665 y(END_FUNCTION;)150 2864 y(FUNCTION)e(month\(mnum:INTEGE)o(R\))d
+(:)43 b(STRING;)150 2964 y(\(*)g(Given)e(an)i(integer)e(representing)d
+(the)43 b(month)e(in)i(a)g(year,)281 3064 y(returns)d(the)j(name)f(of)g
+(the)h(month.)e(*\))150 3163 y(LOCAL)237 3263 y(str)i(:)g(STRING;)150
+3362 y(END_LOCAL;)237 3562 y(CASE)f(mnum)g(OF)324 3661
+y(1)i(:)f(str)f(:=)h('January';)324 3761 y(2)h(:)f(str)f(:=)h
+('February';)324 3861 y(3)h(:)f(str)f(:=)h('March';)324
+3960 y(4)h(:)f(str)f(:=)h('April';)324 4060 y(5)h(:)f(str)f(:=)h
+('May';)324 4159 y(6)h(:)f(str)f(:=)h('June';)324 4259
+y(7)h(:)f(str)f(:=)h('July';)324 4359 y(8)h(:)f(str)f(:=)h('August';)
+324 4458 y(9)h(:)f(str)f(:=)h('September';)324 4558 y(10)g(:)g(str)g
+(:=)f('October';)324 4658 y(11)h(:)g(str)g(:=)f('November';)324
+4757 y(12)h(:)g(str)g(:=)f('December';)324 4857 y(OTHERWISE)e(:)j(str)g
+(:=)f('';)237 4956 y(END_CASE;)150 5056 y(RETURN\(str\);)150
+5156 y(END_FUNCTION;)1905 5531 y Fs(59)p eop
+%%Page: 60 64
+60 63 bop 194 573 a Fh(LOCAL)237 672 y(a)43 b(:)h(array[1:3])39
+b(of)k(integer;)237 772 y(lagg)f(:)h(list)f([0:5])g(of)g(integer;)237
+872 y(a23)h(:)g(array[1:2])c(of)k(array[1:3])c(of)k(integer;)237
+971 y(i,)g(n)g(:)g(integer;)237 1071 y(s1,)g(s2)f(:)h(string;)237
+1171 y(b)g(:)h(logical;)237 1270 y(r1,)f(r2)f(:)h(real;)237
+1370 y(nega)f(:)h(array[-3:-1])c(of)k(integer;)237 1469
+y(posa)f(:)h(array[3:5])d(of)i(integer;)237 1569 y(j)h(:)h(joe;)237
+1669 y(ex)f(:)g(ent;)194 1768 y(END_LOCAL;)324 1968 y(--)g(start)f
+(with)g(a)h(massive)d(compound)h(statement)194 2067 y(BEGIN)237
+2267 y(writeln;)237 2366 y(println;)237 2565 y(\(*)i(write)e(today's)g
+(date)h(*\))237 2665 y(writeln\('Today)c(is)43 b(',)f(THE_DAY:1,)e(')j
+(',)g(month\(THE_MONTH\))o(,)37 b(')44 b(',)e(THE_YEAR:1\);)237
+2765 y(writeln;)237 2964 y(\(*)h(The)f(user)g(might)g(be)g(interested)e
+(in)j(Easter)e(*\))237 3064 y(easter;)237 3163 y(writeln;)237
+3362 y(\(*)i(Call)f(some)g(math)g(functions)e(*\))237
+3462 y(r1)j(:=)g(PI/4;)237 3562 y(writeln\('r1)c(=)k(PI/4)f
+(\(0.78539...\)',)c(r1\);)237 3661 y(writeln\('cos\(r1\))f
+(\(0.70710...\)',)h(cos\(r1\)\);)237 3761 y(writeln\('sin\(r1\))f
+(\(0.70710...\)',)h(sin\(r1\)\);)237 3861 y(writeln\('tan\(r1\))f
+(\(1.0\)',)k(tan\(r1\)\);)237 4060 y(r1)i(:=)g(CONST_E;)237
+4159 y(writeln\('r1)c(=)k(CONST_E)e(\(2.7182...\)',)d(r1\);)237
+4259 y(writeln\('log\(4.5\))f(\(1.50407...\)',)h(log\(4.5\)\);)237
+4359 y(writeln\('log2\(8\))f(\(3.0\)',)k(log2\(8\)\);)237
+4458 y(writeln\('log10\(10)o(\))c(\(1.0\)',)k(log10\(10\)\);)237
+4658 y(r2)i(:=)g(exp\(10\);)237 4757 y(writeln\('exp\(10\))37
+b(\(2.203...e4\)',)h(r2\);)237 4956 y(r2)43 b(:=)g(sqrt\(121\);)237
+5056 y(writeln\('sqrt\(121)o(\))37 b(\(11.0\)',)k(r2\);)237
+5255 y(\(*)i(populate)d(and)j(print)e(some)h(arrays)f(*\))1905
+5531 y Fs(60)p eop
+%%Page: 61 65
+61 64 bop 237 573 a Fh(writeln;)237 672 y(posa[3])41
+b(:=)i(10;)237 772 y(posa[4])e(:=)i(20;)237 872 y(posa[5])e(:=)i(30;)
+237 971 y(REPEAT)e(i)i(:=)g(LOINDEX\(posa\))38 b(TO)43
+b(HIINDEX\(posa\);)324 1071 y(writeln\('posa[',)37 b(i:1,)42
+b('])h(=)g(',)g(posa[i]\);)237 1171 y(END_REPEAT;)237
+1370 y(writeln;)237 1469 y(nega[-3])d(:=)j(1;)237 1569
+y(nega[-2])d(:=)j(2;)237 1669 y(nega[-1])d(:=)j(3;)237
+1768 y(REPEAT)e(i)i(:=)g(LOINDEX\(nega\))38 b(TO)43 b(HIINDEX\(nega\);)
+324 1868 y(writeln\('nega[',)37 b(i:1,)42 b('])h(=)g(',)g(nega[i]\);)
+237 1968 y(END_REPEAT;)237 2167 y(\(*)g(Do)g(some)f(things)f(with)h(a)h
+(list)f(*\))412 2366 y(--)g(check)g(the)g(initial)f(size)h(\(should)e
+(be)j(empty\))237 2466 y(i)g(:=)g(SIZEOF\(lagg\);)237
+2565 y(writeln\('no.)c(of)k(els)f(in)h(lagg)f(=)h(',)g(i\);)412
+2765 y(--)f(insert)f(elements)g(at)h(the)h(front)237
+2864 y(INSERT\(lagg,)c(10,)j(0\);)237 2964 y(i)h(:=)g(SIZEOF\(lagg\);)
+237 3064 y(writeln\('no.)c(of)k(els)f(in)h(lagg)f(=)h(',)g(i\);)237
+3163 y(INSERT\(lagg,)c(20,)j(0\);)237 3263 y(writeln\('no.)d(of)k(els)f
+(in)h(lagg)f(=)h(',)g(SIZEOF\(lagg\)\);)368 3462 y(--)g(print)e(some)h
+(of)h(the)f(elements)237 3562 y(i)h(:=)g(lagg[1];)237
+3661 y(writeln\('first)38 b(in)43 b(lagg)f(=)h(',)g(i\);)237
+3761 y(writeln\('lagg[2])37 b(=)43 b(',)g(lagg[2]\);)412
+3960 y(--)f(check)g(if)h(a)g(value)e(in)i(in)g(the)f(list)237
+4060 y(b)h(:=)g(10)g(IN)g(lagg;)237 4159 y(writeln\(b\);)475
+b(--)43 b(should)e(be)i(TRUE)237 4259 y(b)g(:=)g(30)g(IN)g(lagg;)237
+4359 y(writeln\(b\);)475 b(--)43 b(should)e(be)i(FALSE)412
+4558 y(--)f(write)g(all)g(the)g(elements)237 4658 y(REPEAT)f(i)i(:=)g
+(LOINDEX\(lagg\))38 b(TO)43 b(HIINDEX\(lagg\);)324 4757
+y(writeln\('lagg[',)37 b(i:1,)42 b('])h(=)g(',)g(lagg[i]\);)324
+4857 y(println\('lagg[',)37 b(i:1,)42 b('])h(=)g(',)g(lagg[i]\);)237
+4956 y(END_REPEAT;)237 5156 y(\(*)g(see)f(what)g(happens)f(with)h(an)h
+(indeterminate)38 b(value)j(*\))237 5255 y(b)i(:=)g(FALSE;)1905
+5531 y Fs(61)p eop
+%%Page: 62 66
+62 65 bop 237 573 a Fh(b)43 b(:=)g(?;)237 672 y(writeln\(b\);)237
+772 y(println\(b\);)237 872 y(\(*)g(Some)f(more)g(attempts)e(with)i
+(indeterminate)c(*\))237 971 y(i)43 b(:=)g(2;)237 1071
+y(n)g(:=)g(3*i;)237 1171 y(writeln\(i,)d(n\);)173 b(--)42
+b(should)g(be)g(2)i(6)237 1270 y(n)f(:=)g(3*?;)237 1370
+y(writeln\(i,)d(n\);)173 b(--)42 b(should)g(be)g(2)i(?)237
+1469 y(i)f(:=)g(?;)237 1569 y(n)g(:=)g(3*i;)237 1669
+y(writeln\(i,)d(n\);)173 b(--)42 b(should)g(be)g(?)i(?)150
+1868 y(END;)129 b(--)43 b(end)f(of)h(compound)d(statement)455
+1968 y(--)j(but)f(we)h(can)f(have)g(individual)e(statements)237
+2267 y(\(*)j(Try)f(to)h(provide)e(some)h(excitement)d(by)k(making)e(a)i
+(magic)f(square)f(*\))237 2366 y(writeln;)237 2466 y(write\('Enter)e
+(an)k(odd)f(number)f(between)g(1)i(and)f(15:)h('\);)237
+2565 y(readln\(n\);)237 2665 y(IF)g(NOT)f(magic_square\(n\))c(THEN)324
+2765 y(writeln\('I)i(did)i(not)g(like)g(your)g(number)f(which)h(was)g
+(',)h(n:1\);)324 2864 y(writeln\('If)c(you)k(get)f(it)h(right)e(next)h
+(time,)g(something)e(magic)h(will)h(happen.'\);)324 2964
+y(write\('Enter)d(an)k(odd)f(number)f(between)g(1)i(and)f(15:)h('\);)
+324 3064 y(readln\(n\);)324 3163 y(magic_square\(n\);)237
+3263 y(END_IF;)237 3562 y(\(*)g(Try)f(a)h(couple)f(of)g(REPEAT)f
+(statements)f(*\))237 3661 y(writeln\('Test)e(REPEAT)j(\(should)g
+(print)h(-2\)'\);)237 3761 y(i)h(:=)g(-2;)237 3861 y(REPEAT)e(UNTIL)h
+(i)h(=)g(0;)324 3960 y(writeln\(i\);)324 4060 y(println\(i\);)324
+4159 y(ESCAPE;)324 4259 y(i)h(:=)e(i)h(+)h(1;)237 4359
+y(END_REPEAT;)237 4558 y(writeln\('Test)38 b(REPEAT)j(\(should)g(print)
+h(3,)g(2,)h(1\)'\);)237 4658 y(REPEAT)e(i)i(:=)g(3)g(TO)g(1)g(BY)g(-1;)
+324 4757 y(writeln\(i\);)237 4857 y(END_REPEAT;)237 5156
+y(\(*)g(Try)f(the)h(LIKE)f(operator)e(*\))237 5255 y(writeln\('Test)e
+(LIKE'\);)1905 5531 y Fs(62)p eop
+%%Page: 63 67
+63 66 bop 237 573 a Fh(writeln\(\('A')39 b(LIKE)j('A'\)\);)564
+b(--)43 b(should)e(be)h(TRUE)237 672 y(writeln\(\('A')d(LIKE)j
+('b'\)\);)564 b(--)43 b(should)e(be)h(FALSE)237 772 y(writeln\(\('Page)
+c(407')k(LIKE)g('$###'\)\);)127 b(--)43 b(should)e(be)h(TRUE)237
+872 y(writeln\(\('Page)c(23')k(LIKE)g('$###'\)\);)171
+b(--)43 b(should)e(be)h(FALSE)237 1171 y(\(*)h(Try)f(the)h(REXPR)e
+(function)f(*\))237 1270 y(writeln\('Test)e(rexpr'\);)237
+1370 y(writeln\(rexpr\('A')o(,)f('A'\)\);)521 b(--)43
+b(should)e(be)h(TRUE)237 1469 y(writeln\(rexpr\('A')o(,)37
+b('b'\)\);)521 b(--)43 b(should)e(be)h(FALSE)237 1569
+y(writeln\(rexpr\('Pa)o(ge)37 b(407',)k('[a-zA-Z]+\\)e([0-9]+'\)\);)h
+(--)j(should)e(be)i(TRUE)237 1669 y(writeln\(rexpr\('Pa)o(ge)37
+b(23',)42 b('[a-zA-Z]+\\)d([0-9]'\)\);)127 b(--)43 b(should)e(be)i
+(FALSE)237 1968 y(\(*)g(Try)f(an)h(ARRAY)f(OF)g(ARRAY)g(*\))237
+2067 y(a23[1][1])e(:=)j(11;)237 2167 y(a23[1][2])d(:=)j(12;)237
+2267 y(a23[1][3])d(:=)j(13;)237 2366 y(a23[2][1])d(:=)j(21;)237
+2466 y(a23[2][2])d(:=)j(22;)237 2565 y(a23[2][3])d(:=)j(23;)237
+2765 y(writeln\('Test)38 b(REPEAT)j(\(should)g(be)i(1)g(1)g(11,)g(1)g
+(2)g(12,)f(1)h(3)h(13,)e(2)h(1)g(21,)g(2)g(2)g(22)g(etc\)'\);)237
+2864 y(REPEAT)e(n)i(:=)g(1)g(TO)g(2;)324 2964 y(REPEAT)e(i)j(:=)e(1)i
+(TO)e(3;)499 3064 y(writeln\(n,)d(i,)k(a23[n][i]\);)324
+3163 y(END_REPEAT;)237 3263 y(END_REPEAT;)237 3562 y(\(*)g(do)g(some)f
+(simple)f(string)g(operations)e(*\))237 3661 y(s1)k(:=)g('string';)237
+3761 y(writeln\(s1\);)344 b(--)43 b(should)e(be)i(string)237
+3861 y(s2)g(:=)g(s1[2:4];)237 3960 y(writeln\(s2\);)344
+b(--)43 b(should)e(be)i(tri)237 4060 y(b)g(:=)g(s1)g(<>)g(s2;)237
+4159 y(writeln\(b\);)388 b(--)43 b(should)e(be)i(TRUE)237
+4259 y(writeln\(s2)d(+)j(s1\);)129 b(--)43 b(should)e(be)i(tristring)
+237 4558 y(\(*)g(Assign)e(and)h(print)g(to)h(a)g(user-defined)38
+b(type)k(*\))237 4658 y(j)h(:=)g(33;)237 4757 y(writeln\(j*3\);)213
+b(--)42 b(should)g(be)g(99)237 4956 y(\(*)h(Do)g(something)d(with)h(a)j
+(variable)c(of)j(type)f(ENTITY)f(*/)237 5056 y(ex.attr1)f(:=)j(33;)237
+5156 y(ex.attr2)d(:=)j('The)f(attribute)e(named)i(attr2';)237
+5255 y(ex.attr3)e(:=)j(ex.attr1/3;)1905 5531 y Fs(63)p
+eop
+%%Page: 64 68
+64 67 bop 237 573 a Fh(writeln\('ex.attr1)37 b(should)k(be)i(33)f(and)h
+(is:)f(',)h(ex.attr1\);)237 672 y(writeln\('ex.attr2)37
+b(is:)42 b(',)h(ex.attr2\);)237 772 y(writeln\('ex.attr3)37
+b(should)k(be)i(11)f(and)h(is:)f(',)h(ex.attr3\);)150
+971 y(END_CODE)150 1257 y Fu(5)135 b(Sp)t(ecifying)45
+b(a)g Fc(SPECIAL)p 1551 1257 37 4 v 86 w Fu(command)150
+1460 y Fs(This)22 b(section)i(giv)m(es)g(some)g(hin)m(ts)f(on)g(ho)m(w)
+h(to)g(sp)s(ecify)f(a)h(L)2098 1443 y Fr(A)2137 1460
+y Fs(T)2188 1479 y(E)2238 1460 y(X)g(command)g(that)g(requires)e(some)i
+(sp)s(ecial)150 1573 y(pro)s(cessing.)37 b(The)23 b(fain)m(t-hearted)h
+(should)e(skip)g(this.)37 b(It)24 b(is)f(assumed)g(that)h(the)g
+(implemen)m(tor)e(will)f(ha)m(v)m(e)150 1686 y(kno)m(wledge)34
+b(of)f(L)723 1669 y Fr(A)762 1686 y Fs(T)813 1705 y(E)864
+1686 y(X,)i(C)e(programming,)g(and)g(lex)g(and)g(Y)-8
+b(A)m(CC)35 b(st)m(yle)f(lexer)f(and)g(parser)g(generator)150
+1799 y(systems.)291 1911 y(There)28 b(are)h(t)m(w)m(o)h(w)m(a)m(ys)g
+(of)f(de\014ning)e Fn(SPECIAL_)f Fs(kinds)h(of)i(commands)f(though)g
+(neither)g(is)g(particu-)150 2024 y(larly)h(simple.)40
+b(The)30 b(easiest)h(is)f(b)m(y)h(what)f(is)g(termed)h(the)g
+Fi(c)-5 b(o)g(ding)32 b Fs(metho)s(d.)41 b(This)29 b(in)m(v)m(olv)m(es)
+i(mo)s(difying)150 2137 y(the)i(standard)f(actions.)49
+b(The)33 b(more)g(complicated)f(means)h(is)f(b)m(y)h(the)g
+Fi(gr)-5 b(ammar)36 b Fs(metho)s(d,)d(whic)m(h)f(in-)150
+2250 y(v)m(olv)m(es)f(extending)f(the)g(pro)s(duction)f(grammar)h(and,)
+g(t)m(ypically)-8 b(,)30 b(also)g(co)s(ding)g(new)g(kinds)e(of)j
+(actions.)291 2363 y(The)f(pro)s(cess)g(of)g(sp)s(ecifying)f(one)h(of)h
+(the)f Fn(SPECIAL_)f Fs(kinds)f(of)j(command)f(actions)g(is:)286
+2546 y Fm(\017)46 b Fs(Seriously)39 b(question)i(the)h(need)f(for)g
+(the)g(sp)s(ecial)f(command.)74 b(One)41 b(is)f(only)h(required)e(if)i
+(the)377 2659 y(standard)26 b(actions)h(cannot)g(b)s(e)f(co)s(erced)h
+(in)m(to)g(serving)e(the)i(needs)f(of)h(the)g(command)f(pro)s(cessing)
+377 2771 y(and/or)31 b(the)f(command)g(grammar)h(is)e(not)i(supp)s
+(orted)d(b)m(y)i(the)h Fy(L)-7 b(TX2X)30 b Fs(system.)286
+2957 y Fm(\017)46 b Fs(Design)30 b(the)h(required)e(en)m(try)h(for)g
+(the)h(command)f(table.)286 3143 y Fm(\017)46 b Fs(Decide)24
+b(whether)f(the)h(co)s(ding)f(or)h(the)f(grammar)h(metho)s(d)f(is)g(to)
+h(b)s(e)f(used)g(for)h(extending)f Fy(L)-7 b(TX2X)p Fs(.)377
+3328 y Ft(Co)s(ding)35 b(metho)s(d)45 b Fs(Mo)s(dify)23
+b(the)i(actions)g(in)e Fn(l2xusrlb.c)p Fs(,)g(and)h(p)s(ossibly)d(add)j
+(new)g(functions)577 3441 y(in)29 b Fn(l2xusrlb.c)f Fs(and)i
+Fn(l2xusrlb.h)p Fs(.)377 3585 y Ft(Grammar)j(metho)s(d)45
+b Fs(Extend)25 b(the)g(grammar)g(in)f Fn(l2x.y)p Fs(.)37
+b(T)m(ypically)24 b(it)h(b)s(e)f(necessary)i(to)g(add)577
+3698 y(new)k(functions)f(to)i(the)g(user-de\014ned)e(library)g
+Fn(l2xusrlb)f Fs(as)j(w)m(ell.)286 3884 y Fm(\017)46
+b Fs(Compile)29 b(the)h(mo)s(di\014ed)f Fy(L)-7 b(TX2X)30
+b Fs(system.)41 b(A)30 b Fn(make)f Fs(\014le)h(for)g(this)f(is)h(giv)m
+(en)g(in)f(App)s(endix)f(E.)286 4070 y Fm(\017)46 b Fs(T)-8
+b(est)31 b(the)g(extensions)f(and)f(debug)h(the)h(program.)291
+4252 y(The)h Fn(l2xlib)f Fs(has)h(man)m(y)h(functions)e(that)i(ma)m(y)h
+(b)s(e)d(of)i(use)g(in)e(this)g(pro)s(cess.)47 b(Some)33
+b(of)g(these)g(are)150 4365 y(indicated)c(b)s(elo)m(w.)286
+4572 y Fm(\017)46 b Fn(char)h(*strsave\(char)d(s[]\))29
+b Fs(sa)m(v)m(es)j(a)f(string)e(somewhere)286 4757 y
+Fm(\017)46 b Fn(void)h(myprint\(char)d(s[]\))24 b Fs(writes)f(a)i
+(string)e(to)i(the)g(output)f(medium.)37 b(Its)24 b(particular)f
+(action)377 4870 y(is)30 b(con)m(trolled)g(b)m(y)g(the)g
+Fn(set_print)e Fs(and)i Fn(reset_print)d Fs(functions,)i(as)i(w)m(ell)e
+(as)i(the)f Fn(-p)g Fs(option.)286 5056 y Fm(\017)46
+b Fn(void)h(verbatim_print\(char)42 b(s[]\))20 b Fs(lik)m(e)f
+Fn(myprint)p Fs(,)i(writes)e(a)i(string)e(to)i(the)f(output)g(medium.)
+377 5169 y(Its)30 b(actions)h(are)f(con)m(trolled)g(b)m(y)g(the)g
+(curren)m(t)g(prin)m(t)f(mo)s(de,)h(and)f(newlines)f(are)i(ob)s(ey)m
+(ed)h(\(i.e.,)f(it)377 5282 y(ignores)g(an)m(y)h(prett)m(y-prin)m(ting)
+e(option\).)1905 5531 y(64)p eop
+%%Page: 65 69
+65 68 bop 286 573 a Fm(\017)46 b Fn(void)h(yyerror\(char)d(s[]\))d
+Fs(used)g(b)m(y)h(the)g(lexer)g(and)f(parser)g(to)i(prin)m(t)d(an)i
+(error)g(message)377 686 y(string.)286 873 y Fm(\017)k
+Fn(void)h(warning\(char)d(s[]\))30 b Fs(writes)f(a)i(w)m(arning)e
+(message)i(string.)286 1061 y Fm(\017)46 b Fn(void)h(do_newline\(\))20
+b Fs(used)j(within)e(the)j(lexer)f(to)h(set)g(in)m(ternal)e(v)-5
+b(ariables)23 b(whenev)m(er)g(a)h(newline)377 1174 y(is)30
+b(encoun)m(tered)h(in)e(the)h(input.)286 1362 y Fm(\017)46
+b Fn(void)h(initialise_sysbuf\(\))25 b Fs(initialises)i(the)k(system)f
+(supplied)d(string)j(bu\013er.)286 1549 y Fm(\017)46
+b Fn(void)h(print_sysbuf\(\))33 b Fs(writes)j(the)h(con)m(ten)m(t)i(of)
+e(the)g(system)g(string)f(bu\013er)g(to)h(the)g(output)377
+1662 y(\014le.)286 1850 y Fm(\017)46 b Fn(void)h(copy_sysbuf\(char)c
+(s[]\))29 b Fs(copies)i(the)f(con)m(ten)m(ts)i(of)f(the)f(system)h
+(string)e(bu\013er)h(to)h(the)377 1963 y(user-supplied)37
+b(string.)69 b(It)41 b(is)e(the)h(user's)g(resp)s(onsibilit)m(y)c(to)41
+b(ensure)f(that)h(the)f(string)f(is)h(big)377 2076 y(enough.)286
+2263 y Fm(\017)46 b Fn(void)h(set_print\(PSTRWC)c(pswitch\))33
+b Fs(con)m(trols)h(the)h(action)g(of)g Fn(myprint)p Fs(,)f
+Fn(print_newline)377 2376 y Fs(and)44 b Fn(verbatim_print)p
+Fs(.)79 b(If)44 b(the)h(input)e(argumen)m(t)i(is)e Fn(p_default_print)d
+Fs(then)45 b(the)f(prin)m(t)377 2489 y(functions)26 b(should)g(write)g
+(to)i(the)g(output)f(\014le;)g(this)g(is)f(the)i(default)e(b)s(eha)m
+(vior.)39 b(If)27 b(the)g(argumen)m(t)377 2602 y(is)i
+Fn(p_no_print)p Fs(,)f(then)h(no)h(writing)e(o)s(ccurs.)41
+b(If)29 b(the)h(argumen)m(t)h(is)e Fn(p_print_to_sysbuf)p
+Fs(,)c(then)377 2715 y(the)31 b(prin)m(t)e(functions)g(write)g(to)i
+(the)g(system)g(string)e(bu\013er.)286 2902 y Fm(\017)46
+b Fn(void)h(reset_print\(\))23 b Fs(resets)k(the)h(b)s(eha)m(vior)e(of)
+h(the)g(prin)m(t)e(functions.)38 b(This)25 b(function)h(should)377
+3015 y(alw)m(a)m(ys)31 b(b)s(e)f(used)f(after)i(a)g(call)f(to)h
+Fn(set_print)p Fs(.)286 3203 y Fm(\017)46 b Fn(int)h
+(lookup_entry\(char)c(s[],)k(int)g(kind\))26 b Fs(returns)h(the)h(lo)s
+(cation)f(within)e(the)j(command)377 3316 y(table)33
+b(of)g(the)g(command)g(name)g(giv)m(en)g(in)f Fn(s)g
+Fs(of)i(the)f(command)f(t)m(yp)s(e)i(giv)m(en)f(in)e
+Fn(kind)p Fs(.)48 b(If)32 b Fn(kind)377 3429 y Fs(is)e
+Fn(DONT_CARE)e Fs(then)i(the)g(p)s(osition)f(of)h(the)h(\014rst)e(o)s
+(ccurrence)i(of)f Fn(s)g Fs(is)g(returned.)286 3616 y
+Fm(\017)46 b Fn(void)h(get_env_name\(char)c(s[]\))35
+b Fs(extracts)j(the)f(name)f(of)h(a)g(L)2682 3600 y Fr(A)2721
+3616 y Fs(T)2772 3636 y(E)2822 3616 y(X)g(en)m(vironmen)m(t)f(from)g
+Fn(s)p Fs(,)377 3729 y(whic)m(h)29 b(is)h(assumed)f(to)i(ha)m(v)m(e)h
+(the)e(form)g Fn(\\something)45 b({)i(environment)e(})p
+Fs(.)40 b(The)30 b(name)g(of)h(the)377 3842 y(en)m(vironmen)m(t)f(is)g
+(put)f(in)m(to)i(the)f(global)g(string)f Fn(env_name)p
+Fs(.)286 4030 y Fm(\017)46 b Fn(PSENTRY)g(get_mode_sym\(int)d(loc\))h
+Fs(returns)g(a)h(p)s(oin)m(ter)f(to)i(the)f(sym)m(b)s(ol)e(table)i(en)m
+(try)g(at)377 4143 y(p)s(osition)29 b Fn(loc)g Fs(in)g(the)i(command)f
+(table)g(for)g(the)h(curren)m(t)f(mo)s(de.)286 4330 y
+Fm(\017)46 b Fn(int)h(command_type\(int)d(loc\))19 b
+Fs(returns)h(the)h(system)g(de\014ned)f(kind)f(of)i(command)g(at)g(lo)s
+(cation)377 4443 y Fn(loc)30 b Fs(in)f(the)h(command)h(table.)286
+4631 y Fm(\017)46 b Fn(int)h(get_user_type\(int)c(loc\))35
+b Fs(returns)g(the)i(user)e(input)g(\()p Fn(TYPE=)p Fs(\))g(kind)g(of)h
+(command)g(at)377 4744 y(lo)s(cation)30 b Fn(loc)g Fs(in)f(the)h
+(command)g(table.)286 4932 y Fm(\017)46 b Fn(PSTRWC)g(get_t\(PSENTRY)f
+(loc\))34 b Fs(returns)h(a)h(p)s(oin)m(ter)f(to)h(the)g
+Fn(START_TAG=)e Fs(sp)s(eci\014cation)g(for)377 5044
+y(sym)m(b)s(ol)29 b(en)m(try)i Fn(loc)p Fs(.)40 b(There)30
+b(are)g(similar)e(functions)h(for)h(other)h(tagging)g(sp)s
+(eci\014cations.)1905 5531 y(65)p eop
+%%Page: 66 70
+66 69 bop 286 573 a Fm(\017)46 b Fn(PSTRWC)g(get_tag_t\(PSENTRY)d(loc,)
+k(int)g(n\))20 b Fs(returns)f(a)h(p)s(oin)m(ter)g(to)h(the)f
+Fn(START_TAG_n)d Fs(sp)s(ec-)377 686 y(i\014cation)31
+b(for)h(the)g Fn(n)p Fs('th)f(argumen)m(t)i(for)e(sym)m(b)s(ol)g(en)m
+(try)h Fn(loc)p Fs(.)44 b(There)31 b(are)i(similar)c(functions)h(for)
+377 799 y(other)h(argumen)m(t)g(tagging)g(sp)s(eci\014cations.)286
+986 y Fm(\017)46 b Fn(PSTRWC)g(get_param_print\(PSENTRY)c(loc,)k(int)h
+(n\))27 b Fs(returns)e(a)i(p)s(oin)m(ter)f(to)i(the)f(prin)m(t)e(con-)
+377 1099 y(trol)41 b(sp)s(eci\014cation)f(for)h(the)h
+Fn(n)p Fs('th)f(required)f(argumen)m(t)h(for)g(sym)m(b)s(ol)f(en)m(try)
+i Fn(loc)p Fs(.)73 b(There)41 b(are)377 1212 y(similar)28
+b(functions)h(for)h(other)h(prin)m(t)e(con)m(trols.)286
+1400 y Fm(\017)46 b Fn(int)h(get_level\(PSENTRY)c(loc\))27
+b Fs(returns)g(the)h Fn(SECTIONING_LEVEL=)23 b Fs(v)-5
+b(alue)27 b(for)h(sym)m(b)s(ol)f(en-)377 1513 y(try)k
+Fn(loc)p Fs(.)291 1725 y(The)f(pro)s(cess)g(of)g(sp)s(ecifying)f(a)h
+Fn(SPECIAL_)f Fs(is)g(b)s(est)h(describ)s(ed)e(via)i(an)g(example.)150
+1969 y Fj(5.1)112 b(Example)150 2140 y Fs(Assume)33 b(that)h(there)f
+(is)g(a)g(`non-standard')g(L)1732 2124 y Fr(A)1771 2140
+y Fs(T)1822 2160 y(E)1872 2140 y(X)h(command)f(whic)m(h)f(has)h(one)h
+(required)d(argumen)m(t.)150 2253 y(When)26 b(this)f(command)h(is)g
+(pro)s(cessed)g(b)m(y)g(L)1632 2236 y Fr(A)1671 2253
+y Fs(T)1722 2273 y(E)1772 2253 y(X)h(its)e(e\013ect)j(is)d(to)j(start)e
+(a)h(new)f(section)g(in)f(a)i(do)s(cumen)m(t)150 2366
+y(en)m(titled)32 b Fi(Normative)k(R)-5 b(efer)g(enc)g(es)p
+Fs(.)48 b(Some)33 b(b)s(oilerplate)e(text)j(is)d(then)i(t)m(yp)s(eset)g
+(\(sp)s(eci\014ed)f(within)e(the)150 2479 y(de\014nition)k(of)j(the)f
+(command\).)59 b(This)35 b(b)s(oilerplate)f(includes)g(t)m(w)m(o)j
+(instances)f(of)h(the)f(text)i(from)e(the)150 2592 y(argumen)m(t)31
+b(of)f(the)h(command.)40 b(Finally)-8 b(,)29 b(a)i Fn(description)c
+Fs(list)j(en)m(vironmen)m(t)f(is)h(started.)291 2692
+y(In)g(L)429 2675 y Fr(A)468 2692 y Fs(T)519 2711 y(E)569
+2692 y(X)h(terms,)f(this)f(command)i(could)e(ha)m(v)m(e)j(b)s(een)d
+(de\014ned)g(as:)150 2866 y Fh(\\newcommand{\\XXs)o(pec)o(ia)o(l})o
+([1])o({\\)o(sec)o(ti)o(on{)o(No)o(rm)o(ati)o(ve)37 b(References})586
+2965 y(Some)42 b(boilerplate)d(text)j(with)g(#1)586 3065
+y(in)h(the)f(middle.)f(Now)h(there)g(is)586 3165 y(some)g(more)g
+(boilerplate)d(with)j(#1)586 3264 y(in)h(the)f(middle)f(of)i(it.)586
+3364 y(\\begin{descripti)o(on)o(})38 b(})291 3552 y Fs(F)-8
+b(or)22 b(the)f(purp)s(oses)f(of)h(the)g(example,)i(it)e(is)f(desired)g
+(to)h(replace)h(the)f(o)s(ccurrence)g(of)g(the)h Fn(\\XXspecial)150
+3665 y Fs(command)35 b(b)m(y)f(the)h(`normal')f(section)h(heading)f
+(for)h(the)f(output)h(tagged)h(st)m(yle,)g(and)f(also)f(prin)m(t)g(out)
+150 3777 y(the)h(b)s(oilerplate)f(text)i(including)c(the)j(argumen)m(t)
+h(text)g(in)e(the)h(righ)m(t)g(places.)55 b(The)35 b(start)g(of)h(the)f
+(list)150 3890 y(en)m(vironmen)m(t)i(has)h(also)f(to)i(b)s(e)e(tak)m
+(en)i(in)m(to)e(accoun)m(t.)64 b(The)38 b Fn(\\item)e
+Fs(optional)h(argumen)m(t)h(text)g(is)f(to)150 4003 y(b)s(e)32
+b(enclosed)g(in)f(paren)m(theses,)i(with)e(a)i(dash)f(b)s(efore)g(the)g
+(main)g(text.)47 b(These)32 b(requiremen)m(ts)g(are)h(not)150
+4116 y(something)d(that)h(can)f(b)s(e)g(curren)m(tly)g(accomplished)f
+(with)g(the)h(standard)g Fy(L)-7 b(TX2X)30 b Fs(system.)291
+4216 y(T)-8 b(o)31 b(mak)m(e)g(the)g(requiremen)m(ts)e(more)i
+(concrete,)h(if)d(the)i(input)d(L)2478 4199 y Fr(A)2517
+4216 y Fs(T)2568 4235 y(E)2619 4216 y(X)i(source)h(includes:)150
+4390 y Fh(....)150 4490 y(\\XXspecial{REQ)38 b(PARAM)j(TEXT})150
+4689 y(\\item[Ref)f(1])j(Text)f(1.)150 4789 y(\\item[Ref)e(2])j(Text)f
+(2.)150 4888 y(\\end{description)o(})150 4988 y(....)150
+5162 y Fs(then)30 b(the)h(desired)d(output)i(is)g(to)h(lo)s(ok)f(lik)m
+(e:)1905 5531 y(66)p eop
+%%Page: 67 71
+67 70 bop 150 573 a Fh(....)150 772 y(</div.1>)150 971
+y(<div.1>)150 1071 y(<heading>Normati)o(ve)37 b(References</headi)o(ng)
+o(>)150 1270 y(Some)42 b(boilerplate)d(text)j(with)g(REQ)g(PARAM)g
+(TEXT)150 1370 y(in)h(the)f(middle.)f(Now)h(there)g(is)150
+1469 y(some)g(more)g(boilerplate)d(with)j(REQ)g(PARAM)g(TEXT)150
+1569 y(in)h(the)f(middle)f(of)i(it.)324 1768 y(\(Ref)f(1\))h(--)g(Text)
+f(1.)324 1868 y(\(Ref)g(2\))h(--)g(Text)f(2.)150 1968
+y(....)291 2142 y Fs(No)m(w,)48 b(let's)43 b(write)g(a)h(sp)s
+(eci\014cation)e(for)h(the)h(command)f(table,)k(whic)m(h)42
+b(w)m(e)i(will)d(do)i(in)f(pieces,)150 2242 y(starting)31
+b(with)f(the)h(sectioning)f(tags.)44 b(In)30 b(this)g(tagging)i(st)m
+(yle,)g(end)e(tags)j(for)d(sections)h(tak)m(e)i(the)e(form)150
+2341 y Fh(</div.1>)p Fs(,)42 b(and)f(start)i(tags)g(the)f(form)f
+Fh(<div.1>)p Fs(.)73 b(The)42 b(titles)f(of)h(sections)g(are)h
+(enclosed)e(b)s(et)m(w)m(een)150 2441 y Fh(<heading>)23
+b Fs(and)i Fh(</heading>)e Fs(tags.)40 b(W)-8 b(e)28
+b(also)e(w)m(an)m(t)h(some)g(newlines)d(in)h(the)i(output)f(to)h(set)g
+(things)e(o\013.)150 2540 y(If)30 b Fn(?)g Fs(is)f(used)h(as)h(the)f
+(escap)s(e)h(c)m(haracter,)h(then)e(w)m(e)h(can)g(sp)s(ecify)e(for)h
+(the)g(sectioning)g(tagging:)150 2715 y Fh(SECTIONING_LEVEL)o(=)38
+b(SECT)150 2814 y(START_TAG=)h("?n?n<div.1>?n")237 2914
+y(STRING:)i("<heading>Normat)o(iv)o(e)d(References</hea)o(din)o(g>)o
+(?n)o(")150 3014 y(END_TAG=)i("?n</div.1>")291 3188 y
+Fs(There)30 b(is)f(one)i(required)e(argumen)m(t)h(and)g(no)h(optional)e
+(argumen)m(ts,)i(so)g(w)m(e)f(need:)150 3362 y Fh(REQPARAMS=)39
+b(1)291 3537 y Fs(The)31 b(L)503 3520 y Fr(A)542 3537
+y Fs(T)593 3556 y(E)643 3537 y(X)h(command)f(also)h(starts)g(o\013)g(a)
+g Fn(description)c Fs(en)m(vironmen)m(t,)k(so)g(w)m(e)g(ha)m(v)m(e)g
+(to)h(set)f(the)150 3636 y(tags)f(for)g(the)f Fn(\\item)f
+Fs(commands)h(that)h(will)d(follo)m(w.)40 b(This)28 b(is)i(done)g(b)m
+(y:)150 3811 y Fh(START_ITEM=)39 b("?n")150 3910 y(START_ITEM_PARAM)o
+(=)f(")173 b(\(")150 4010 y(END_ITEM_PARAM=)37 b("\))43
+b(--)g(")291 4184 y Fs(Most)38 b(of)f(the)g(w)m(ork)g(is)e(no)m(w)i
+(completed)g(though)f(w)m(e)i(still)c(ha)m(v)m(e)k(to)g(giv)m(e)f(the)g
+(command)g(name,)150 4284 y(decide)i(what)g(sort)g(of)g
+Fn(SPECIAL_)e Fs(it)i(will)d(b)s(e)j(and)g(set)g(the)h
+Fn(SPECIAL_TOKEN)35 b Fs(v)-5 b(alue.)67 b(None)39 b(of)h(the)150
+4384 y(pro)m(vided)i Fn(SPECIAL_)f Fs(t)m(yp)s(es)i(exactly)h(\014t)f
+(this)f(en)m(try)h(as)h(it)e(is)g(a)i(mixture)e(of)h(sectioning)g(and)f
+(list)150 4483 y(en)m(vironmen)m(t,)34 b(so)f(w)m(e)h(will)c(just)j
+(call)f(it)h(a)h Fn(SPECIAL_COMMAND)29 b Fs(t)m(yp)s(e.)49
+b(T)-8 b(o)34 b(summarize,)f(the)g(e\013ectiv)m(e)150
+4583 y(state)f(of)e(the)h(command)f(table)g(en)m(try)h(is:)150
+4757 y Fh(TYPE=)42 b(SPECIAL_COMMAND)150 4857 y(C=)304
+b(NAME=)42 b(to)h(be)f(specified)150 4956 y(C=)304 b(SPECIAL_TOKEN=)38
+b(to)43 b(be)g(specified)237 5056 y(SECTIONING_LEVEL=)37
+b(SECT)237 5156 y(START_TAG=)j("?n?n<div.1>?n")324 5255
+y(STRING:)h("<heading>Normat)o(ive)c(References</head)o(in)o(g>)o(?n")
+1905 5531 y Fs(67)p eop
+%%Page: 68 72
+68 71 bop 237 573 a Fh(END_TAG=)40 b("?n</div.1>")237
+672 y(REQPARAMS=)g(1)237 772 y(START_ITEM=)f("?n")237
+872 y(START_ITEM_PARAM=)e(")174 b(\(")237 971 y(END_ITEM_PARAM=)38
+b("\))k(--)h(")150 1071 y(END_TYPE)291 1259 y Fs(F)-8
+b(or)27 b(p)s(edagogical)f(purp)s(oses,)f(this)g(sp)s(ecial)g(will)e(b)
+s(e)j(implemen)m(ted)e(using)h(b)s(oth)g(the)h(grammar)h(and)150
+1372 y(co)s(de)37 b(metho)s(ds,)g(and)f(the)h(command)f(names)h(used)f
+(will)e(b)s(e)h Fn(\\GRAMMspecial)e Fs(and)j Fn(\\CODEspecial)150
+1484 y Fs(resp)s(ectiv)m(ely)-8 b(.)150 1725 y Ft(5.1.1)105
+b(Grammar)33 b(metho)s(d)h(implemen)m(tation)150 1896
+y Fs(The)c(command)g(name)g(for)h(this)e(implemen)m(tation)g(will)f(b)s
+(e)h Fn(\\GRAMMspecial)p Fs(.)291 2009 y(The)h(grammar)g(metho)s(d)g
+(requires)f(c)m(hanges)i(to)h(the)e(grammar)h(sp)s(eci\014ed)d(in)h
+Fn(l2x.y)p Fs(.)261 2208 y(1.)46 b(A)41 b(new)g(tok)m(en)g(has)g(to)h
+(b)s(e)e(de\014ned,)i(call)e(it)h Fn(GRAMMSPECIAL)p Fs(,)c(in)j(the)h
+(\014rst)f(part)h(of)g(the)g(\014le.)377 2308 y(There)f(is)f(a)i(slot)f
+(for)g(this)f(under)g(the)i(commen)m(t)g Fn(/*)47 b(specials)f(*/)p
+Fs(.)69 b(An)40 b(in)m(teger)h(n)m(um)m(b)s(er,)377 2408
+y(greater)34 b(than)e(or)h(equal)f(to)h(10,000)i(\(ten)e(thousand\))f
+(and)g(less)g(than)g(32,768)j(\(2)3210 2375 y Fr(15)3285
+2408 y Fs(\),)f(has)e(to)i(b)s(e)377 2507 y(asso)s(ciated)c(with)e
+(this)g(tok)m(en.)1432 2474 y Fr(7)1513 2507 y Fs(F)-8
+b(urther,)29 b(this)f(n)m(um)m(b)s(er)g(m)m(ust)h(not)g(b)s(e)g(the)g
+(same)h(as)f(an)m(y)h(other)377 2607 y(n)m(um)m(b)s(er)35
+b(asso)s(ciated)i(with)e(an)m(y)i(other)f(tok)m(en.)60
+b(Let)37 b(us)e(use)h(the)h(maxim)m(um)e(n)m(um)m(b)s(er)g(32,767.)377
+2706 y(The)30 b(relev)-5 b(an)m(t)31 b(p)s(ortion)e(of)37
+b Fn(l2x.y)29 b Fs(will)f(lo)s(ok)i(lik)m(e)2034 2918
+y Fh(/*)42 b(specials)f(*/)377 3018 y(\045token)g(<pos>)h(/*)h(other)e
+(specials)f(here)i(*/)377 3117 y(\045token)f(<pos>)h(GRAMMSPECIAL)d
+(32767)2034 3217 y(/*)j(precedences)d(*/)377 3429 y Fs(This)26
+b(n)m(um)m(b)s(er)h(is)g(used)g(for)h(comm)m(unication)f(within)f(the)i
+Fy(L)-7 b(TX2X)28 b Fs(system,)h(and)e(is)g(the)h(n)m(um)m(b)s(er)377
+3528 y(set)37 b(as)f(the)g(v)-5 b(alue)35 b(of)h(the)g
+Fn(SPECIAL_TOKEN)c Fs(in)j(the)h(command)f(table.)57
+b(W)-8 b(e)37 b(can)f(no)m(w)g(\014nalize)377 3628 y(the)31
+b(command)f(table)g(en)m(try)h(as:)377 3840 y Fh(TYPE=)42
+b(SPECIAL_COMMAND)377 3939 y(NAME=)g(\\GRAMMspecial)377
+4039 y(SPECIAL_TOKEN=)c(32767)464 4139 y(SECTIONING_LEVEL=)f(SECT)464
+4238 y(START_TAG=)j("?n?n<div.1>?n")552 4338 y(STRING:)g
+("<heading>Normati)o(ve)d(References</head)o(ing)o(>?)o(n")464
+4437 y(END_TAG=)k("?n</div.1>")464 4537 y(REQPARAMS=)f(1)464
+4637 y(START_ITEM=)f("?n")464 4736 y(START_ITEM_PARAM=)e(")174
+b(\(")464 4836 y(END_ITEM_PARAM=)38 b("\))43 b(--)f(")377
+4936 y(END_TYPE)p 150 5005 1440 4 v 254 5059 a Fl(7)288
+5090 y Fp(The)26 b(upp)r(er)f(limit)g(of)i(\(2)1005 5059
+y Fl(15)1087 5090 y Fb(\000)17 b Fp(1\))26 b(is)g(set)g(b)n(y)f(the)g
+(bison)h(pro)r(cessor.)1905 5531 y Fs(68)p eop
+%%Page: 69 73
+69 72 bop 261 573 a Fs(2.)46 b(A)29 b(new)f(pro)s(duction,)f(or)i(pro)s
+(ductions,)e(has)h(to)i(b)s(e)e(added)g(to)h(the)g(grammar.)40
+b(There)28 b(is)g(a)h(place)377 672 y(for)38 b(this)f(at)h(the)h(end)e
+(of)h(the)g(rules)e(section)i(in)f(the)h(\014le,)h(under)e(the)h
+(prede\014ned)e(pro)s(duction)377 772 y Fn(l2xSpecials)p
+Fs(.)i(Let)31 b(us)e(call)h(our)g(new)g(pro)s(duction)e
+Fn(GrammSpecial)p Fs(,)g(and)h(add)h(it)g(as:)377 984
+y Fh(l2xSpecials:)39 b(ASpecial)595 1083 y(|)k(AnotherSpecial)595
+1183 y(|)g(GrammSpecial)595 1283 y(;)377 1508 y Fs(where)30
+b(the)h Fn(ASpecial)d Fs(and)i Fn(AnotherSpecial)c Fs(are)31
+b(pre-existing)e(sp)s(ecials.)261 1682 y(3.)46 b(The)34
+b(pro)s(duction)e(no)m(w)i(has)g(to)h(b)s(e)f(de\014ned,)g(sp)s
+(ecifying)e(the)j(exp)s(ected)f(syn)m(tax)h(and)f(required)377
+1782 y(actions.)41 b(This)29 b(lo)s(oks)h(lik)m(e:)377
+1993 y Fh(GrammSpecial:)38 b(GRAMMSPECIAL)552 2093 y({)682
+2193 y(start_section\($1\))o(;)682 2292 y(myprint\(get_t\($1\))o(\);)
+682 2392 y(myprint\(get_tag_t)o(\($1)o(,1)o(\)\))o(;)682
+2491 y(initialise_sysbuf)o(\(\);)682 2591 y(set_print\(p_print)o(_to)o
+(_s)o(ys)o(buf)o(\);)552 2691 y(})552 2790 y(ReqParam)552
+2890 y({)639 2990 y(initialise_strin)o(g\()o(gra)o(mm)o(bu)o(f\);)639
+3089 y(copy_sysbuf\(gram)o(mb)o(uf\))o(;)639 3189 y(reset_print\(\);)
+639 3289 y(prwboiler1\(\);)639 3388 y(print_sysbuf\(\);)639
+3488 y(prwboiler2\(\);)639 3587 y(myprint\(grammbuf)o(\);)639
+3687 y(prwboiler3\(\);)639 3787 y(start_list\($1\);)552
+3886 y(})552 3986 y(;)377 4211 y Fs(The)30 b(actions)h(are)f(enclosed)h
+(in)e(braces)h(and)g(are)h(de\014ned)e(in)g(terms)h(of)h(C)f(co)s(de.)
+377 4361 y(Once)49 b(the)f(parser)g(has)g(b)s(een)g(giv)m(en)h(the)f
+Fn(GRAMMSPECIAL)d Fs(tok)m(en)50 b(from)e(the)h(lexer,)k(it)48
+b(will)377 4474 y(attempt)d(to)f(p)s(erform)f(the)g(actions)h(within)d
+(the)j(\014rst)f(set)h(of)g(braces.)80 b(The)44 b(\014rst)e(of)i
+(these,)377 4587 y Fn(start_section\($1\))p Fs(,)32 b(is)i(the)h
+Fy(L)-7 b(TX2X)34 b Fs(action)h(for)g(starting)g(a)g(sectioning)f
+(command.)54 b(Basi-)377 4700 y(cally)-8 b(,)33 b(this)d(deals)i(with)e
+(an)m(y)j(closing)e(of)h(prior)e(sections)i(of)g(the)g(do)s(cumen)m(t)g
+(and)f(remem)m(b)s(ering)377 4813 y(the)41 b(closing)f(tag)i(for)f
+(this)e(section.)72 b(The)41 b(next)g(t)m(w)m(o)h(actions)f(prin)m(t)e
+(the)i(start)g(tags)h(for)f(the)377 4926 y(command)h(and)f(its)g
+(required)f(argumen)m(t,)45 b(taking)d(the)g(strings)e(from)h(the)h
+(command)g(table.)377 5039 y Fn(initialise_sysbuf\(\))25
+b Fs(initializes)h(the)k(system)g(string)f(bu\013er)f(ready)i(for)f
+(new)g(input.)39 b(Then)377 5152 y(the)25 b(prin)m(t)d(con)m(trol)j(is)
+e(set)h(so)h(that)f(an)m(y)h(output)e(will)f(b)s(e)h(directed)h(in)m
+(to)g(the)g(system)g(string)f(bu\013er)377 5264 y(rather)31
+b(than)f(the)g(output)g(\014le.)40 b(This)29 b(\014nishes)f(the)i
+(\014rst)g(set)h(of)f(actions.)1905 5531 y(69)p eop
+%%Page: 70 74
+70 73 bop 377 573 a Fs(The)43 b(pro)s(duction)e(grammar)i(for)g(the)h
+(required)d(argumen)m(t)j(comes)g(next.)79 b(If)43 b(this)f(is)g
+(incor-)377 686 y(rect,)k(the)41 b(parser)g(automatically)h(giv)m(es)g
+(an)f(\(uninformativ)m(e\))f(error)i(message.)75 b(Otherwise,)377
+799 y(the)41 b(last)f(set)h(of)g(actions)g(are)g(done.)71
+b(A)m(t)41 b(this)f(p)s(oin)m(t,)i(the)f(text)g(of)g(the)g(required)d
+(argumen)m(t)377 912 y(will)g(b)s(e)h(con)m(tained)i(in)e(the)h(system)
+g(string)g(bu\013er.)69 b(This)38 b(is)h(then)h(copied)g(to)h(a)f(temp)
+s(orary)377 1024 y(bu\013er)26 b Fn(grammbuf)p Fs(,)g(that)i(w)m(e)f
+(ha)m(v)m(e)i(y)m(et)f(to)g(de\014ne,)f(b)m(y)g(calling)f
+Fn(copy_sysbuf\(grammbuf\))21 b Fs(ha)m(v-)377 1137 y(ing)38
+b(\014rst)h(made)g(sure)f(that)i(this)e(bu\013er)g(has)g(b)s(een)h
+(cleared)g(of)g(an)m(y)g(previous)f(con)m(ten)m(ts)i(\(the)377
+1250 y Fn(initialise_string\(grammbu)o(f\))f Fs(action\).)85
+b(The)44 b(prin)m(ting)f(con)m(trol)i(m)m(ust)g(no)m(w)g(b)s(e)f(reset)
+377 1363 y(\()p Fn(reset_print\(\))p Fs(\),)33 b(or)h(things)g(migh)m
+(t)g(get)h(corrupted)f(later.)52 b(A)35 b(function)e
+Fn(prwboiler1\(\))e Fs(is)377 1476 y(called)f(to)h(prin)m(t)e(the)i
+(\014rst)f(part)g(of)h(the)f(b)s(oilerplate)f(text,)j(follo)m(w)m(ed)e
+(b)m(y)g(prin)m(ting)f(the)h(con)m(ten)m(ts)377 1589
+y(of)h(the)h(system)f(bu\013er)f(b)m(y)h(the)g(action)g
+Fn(print_sysbuf\(\))c Fs(\(remem)m(b)s(er)k(that)g(this)f(should)f
+(con-)377 1702 y(tain)f(the)h(text)h(of)f(the)f(required)f(argumen)m
+(t\).)41 b(The)28 b(second)h(part)f(of)h(the)g(b)s(oilerplate)d(is)i
+(written)377 1815 y(b)m(y)g(the)f(function)f Fn(prwboiler2\(\))p
+Fs(.)37 b(Just)26 b(for)h(p)s(edagogical)h(purp)s(oses,)e(the)i
+(required)d(argumen)m(t)377 1928 y(text)f(is)d(written)h(out)g(using)f
+(the)i(text)g(stored)g(in)e(the)i(temp)s(orary)f(bu\013er)f(\()p
+Fn(myprint\(grammbuf\))p Fs(\))377 2041 y(rather)27 b(than)g(from)g
+(the)g(system)h(bu\013er.)38 b(The)27 b(p)s(en)m(ultimate)f(action)i
+(is)e(the)h(prin)m(ting)e(of)j(the)f(last)377 2154 y(piece)k(of)f(b)s
+(oilerplate.)377 2304 y(The)h(\014nal)f(action)h(|)g
+Fn(start_list\($1\))c Fs(|)k(is)f(the)h(standard)g Fy(L)-7
+b(TX2X)31 b Fs(action)g(at)h(the)f(start)h(of)377 2417
+y(a)f(list)e(en)m(vironmen)m(t.)40 b(This)29 b(remem)m(b)s(ers)h(the)g
+(v)-5 b(arious)29 b(tags)j(for)e(the)h(list)e(items)h(to)h(follo)m(w.)
+377 2554 y(A)k(c)m(haracter)h(bu\013er,)f Fn(grammbuf)p
+Fs(,)f(is)f(no)m(w)i(de\014ned)e(in)h(the)g(initial)e(section)j(of)g
+(the)f Fn(l2x.y)g Fs(\014le,)377 2653 y(as:)377 2865
+y Fh(char)42 b(grammbuf[80];)377 3090 y Fs(whic)m(h)27
+b(is)h(in)m(tended)f(to)i(b)s(e)f(large)g(enough)g(to)h(hold)e(the)i
+(text)g(of)f(the)h(required)d(argumen)m(t)j(of)g(the)377
+3203 y(command.)377 3353 y(This)g(completes)i(the)f(c)m(hanges)h(to)h
+(the)e(grammar)h(\014le.)261 3528 y(4.)46 b(The)38 b(three)g(functions)
+e(called)h(out)h(in)f(the)h(ab)s(o)m(v)m(e)h(actions)f(for)g(prin)m
+(ting)e(the)i(b)s(oilerplate)e(are)377 3627 y(co)s(ded)20
+b(and)g(placed)g(in)f(the)h(user)g(library)e(\014le)h
+Fn(l2xusrlb.c)e Fs(and)j(are)h(also)f(added)f(to)j Fn(l2xusrlb.h)p
+Fs(.)377 3727 y(Here)31 b(is)f(the)g(relev)-5 b(an)m(t)31
+b(co)s(de)f(as)h(it)f(w)m(ould)f(app)s(ear)h(in)f Fn(l2xusrlb.c)p
+Fs(.)944 3939 y Fh(/*)43 b(demonstration)38 b(string)j(definition)e(*/)
+377 4138 y(STRING)i(boiler_string_3)d(=)43 b("\\nin)e(the)i(middle)e
+(of)i(it.\\n\\n";)1205 4337 y(/*)g(demonstration)38 b(functions)i(*/)
+377 4536 y(/*)j(PRWBOILER1)c(print)j(some)g(demonstration)c
+(boilerplate)h(*/)377 4636 y(void)j(prwboiler1\(\))377
+4736 y({)464 4835 y(myprint\("\\nSome)c(boilerplate)h(text)j(with)g
+("\);)377 4935 y(})1438 b(/*)43 b(end)f(PRWBOILER1)e(*/)377
+5134 y(/*)j(PRWBOILER2)c(print)j(some)g(demonstration)c(boilerplate)h
+(*/)377 5234 y(void)j(prwboiler2\(\))1905 5531 y Fs(70)p
+eop
+%%Page: 71 75
+71 74 bop 377 573 a Fh({)464 672 y(myprint\("\\nin)39
+b(the)j(middle.)f(Now)h(there)g(is\\n"\);)464 772 y(myprint\("some)d
+(more)j(boilerplate)d(with)j("\);)377 872 y(})1438 b(/*)43
+b(end)f(PRWBOILER2)e(*/)377 1071 y(/*)j(PRWBOILER3)c(yet)k(more)f
+(demonstration)c(boilerplate)h(*/)377 1171 y(void)j(prwboiler3\(\))377
+1270 y({)464 1370 y(myprint\(boiler_st)o(rin)o(g_)o(3\);)377
+1469 y(})1438 b(/*)43 b(end)f(PRWBOILER1)e(*/)261 1694
+y Fs(5.)46 b(The)30 b(system)h(is)e(recompiled,)g(using)g
+Fn(make)p Fs(,)h(and)f(tested)i(on)g(some)g(example)f(L)3106
+1678 y Fr(A)3145 1694 y Fs(T)3196 1714 y(E)3246 1694
+y(X)g(\014les.)150 1935 y Ft(5.1.2)105 b(Co)s(de)35 b(metho)s(d)f
+(implemen)m(tation)150 2093 y Fs(This)g(metho)s(d)i(`merely')g
+(requires)f(extending)h(the)g(standard)f(actions)i(to)g(accoun)m(t)h
+(for)e(the)g(new)g(re-)150 2193 y(quiremen)m(ts.)50 b(First,)34
+b(ho)m(w)m(ev)m(er,)i(w)m(e)e(m)m(ust)g(complete)g(the)g(de\014nition)d
+(of)j(the)g(command)f(table)h(en)m(try)-8 b(.)150 2292
+y(W)g(e)25 b(will)d(call)h(the)h(new)g(command)g Fn(\\CODEspecial)p
+Fs(.)35 b(Also)24 b(a)h(unique)d(v)-5 b(alue)23 b(has)h(to)h(b)s(e)f
+(assigned)f(to)i(the)150 2392 y Fn(SPECIAL_TOKEN)p Fs(.)31
+b(This)i(m)m(ust)i(ha)m(v)m(e)h(a)f(v)-5 b(alue)34 b(greater)i(than)e
+(or)h(equal)f(to)h(50,000)i(\(\014ft)m(y)e(thousand\).)150
+2491 y(W)-8 b(e)34 b(will)c(use)i(a)h(v)-5 b(alue)32
+b(59,999.)49 b(Later)33 b(this)f(v)-5 b(alue)32 b(is)f(used)h(within)e
+(the)j(action)g(co)s(de)g(to)g(iden)m(tify)e(the)150
+2591 y(sp)s(ecial.)39 b(The)30 b(command)g(table)h(en)m(try)f(is)g(th)m
+(us:)150 2765 y Fh(TYPE=)42 b(SPECIAL_COMMAND)150 2865
+y(NAME=)g(\\CODEspecial)150 2965 y(SPECIAL_TOKEN=)c(59999)237
+3064 y(SECTIONING_LEVEL=)f(SECT)237 3164 y(START_TAG=)j
+("?n?n<div.1>?n")324 3264 y(STRING:)h("<heading>Normat)o(ive)c
+(References</head)o(in)o(g>)o(?n")237 3363 y(END_TAG=)j("?n</div.1>")
+237 3463 y(REQPARAMS=)g(1)237 3562 y(START_ITEM=)f("?n")237
+3662 y(START_ITEM_PARAM=)e(")174 b(\(")237 3762 y(END_ITEM_PARAM=)38
+b("\))k(--)h(")150 3861 y(END_TYPE)150 4049 y Fs(whic)m(h)30
+b(only)g(di\013ers)g(from)g(that)i(for)e(the)i(grammar)f(implemen)m
+(ted)e(sp)s(ecial)h(in)g(the)h Fn(SPECIAL_TOKEN=)150
+4162 y Fs(and)f(the)g Fn(NAME=)f Fs(v)-5 b(alues.)291
+4275 y(Before)32 b(pro)s(ceeding)d(further,)h(some)h(explanation)f(of)h
+(the)f(in)m(ternals)g(of)g(the)h Fy(L)-7 b(TX2X)31 b
+Fs(system)g(is)e(in)150 4388 y(order.)150 4600 y Ft(Command)k(table)h
+(en)m(try)46 b Fs(In)m(ternally)-8 b(,)43 b(an)e(arra)m(y)g(of)h(C)f
+Fn(struct)p Fs(s)e(is)h(used)g(for)h(storing)g(the)g(data)377
+4713 y(corresp)s(onding)34 b(to)i(the)f(command)g(table.)56
+b(The)34 b Fn(struct)g Fs(is)g(fully)f(de\014ned)i(in)f(\014le)g
+Fn(l2xcom.h)p Fs(,)377 4826 y(and)k(t)m(yp)s(e)h Fn(PSENTRY)e
+Fs(is)g(a)j(p)s(oin)m(ter)d(to)j(an)e(instance)g(of)h(the)g
+Fn(struct)p Fs(.)64 b(There)38 b(is)g(an)g(en)m(try)h(in)377
+4939 y(the)e(in)m(ternal)f(command)h(table)g(for)f(eac)m(h)j(command.)
+60 b(Where)37 b(a)g(command)g(sp)s(eci\014cation)f(is)377
+5052 y(mo)s(de-dep)s(enden)m(t,)42 b(then)d(the)h(en)m(tries)g(for)f
+(this)g(are)h(stored)g(as)g(a)g(list)e(\(the)j(command)e(table)377
+5165 y(arra)m(y)31 b(is)f(actually)g(an)g(arra)m(y)h(of)f(lists)f(of)i
+(command)f(sp)s(eci\014cations,)f(one)i(list)e(p)s(er)g(command\).)1905
+5531 y(71)p eop
+%%Page: 72 76
+72 75 bop 377 573 a Fs(F)-8 b(or)33 b(the)f(purp)s(oses)e(at)j(hand,)e
+(only)g(a)i(few)e(of)h(the)g(elemen)m(ts)h(are)f(of)g(concern;)h(these)
+g(are)f Fn(kind)p Fs(,)377 686 y Fn(parse_kind)42 b Fs(and)h
+Fn(special_token)p Fs(.)78 b(The)44 b(elemen)m(t)g Fn(kind)f
+Fs(con)m(tains)h(an)g(iden)m(ti\014er)f(of)h(the)377
+799 y Fn(TYPE=)30 b Fs(v)-5 b(alue;)31 b(that)h(is,)e(the)i(t)m(yp)s(e)
+f(of)g(the)h(command)f(as)g(sp)s(eci\014ed)e(b)m(y)i(the)h(user.)42
+b(The)30 b(elemen)m(t)377 912 y Fn(special_token)h Fs(con)m(tains)k
+(the)g Fn(SPECIAL_TOKEN=)c Fs(v)-5 b(alue.)53 b(The)34
+b Fn(parse_kind)e Fs(elemen)m(t)j(con-)377 1024 y(tains)28
+b(an)h(iden)m(ti\014er)e(of)i(the)g(t)m(yp)s(e)g(of)g(command)f(as)h
+(assigned)f(in)m(ternally)f(b)m(y)h Fy(L)-7 b(TX2X)p
+Fs(.)29 b(This)e(last)377 1137 y(iden)m(ti\014er)33 b(is)h(generated)i
+(b)m(y)f(the)f(table)h(pro)s(cessing)f(co)s(de)h(in)e
+Fn(l2xlib.c)g Fs(and)h(corresp)s(onds)f(to)377 1250 y(one)e(of)f(the)h
+(tok)m(en)h(v)-5 b(alues)29 b(acceptable)j(to)f(the)f(parser.)150
+1438 y Ft(The)35 b(lexer)45 b Fs(The)29 b(lexer)h(reads)f(the)h(source)
+g(L)1733 1421 y Fr(A)1772 1438 y Fs(T)1823 1458 y(E)1873
+1438 y(X)g(\014le,)f(lo)s(oking)g(for)g(L)2622 1421 y
+Fr(A)2661 1438 y Fs(T)2712 1458 y(E)2762 1438 y(X)h(commands)g(\(essen)
+m(tially)377 1551 y(an)m(ything)j(starting)f(with)g(a)h(bac)m
+(kslash\).)48 b(Eac)m(h)34 b(time)f(it)f(\014nds)f(a)j(command)e(it)h
+(lo)s(oks)f(it)g(up)g(in)377 1664 y(the)37 b(command)g(table)f(arra)m
+(y)-8 b(,)39 b(and)d(sends)g(its)g(parser)g(tok)m(en)i(v)-5
+b(alue)36 b(\(the)h Fn(parse_kind)d Fs(v)-5 b(alue\))377
+1777 y(and)30 b(the)h(command)f(table)g(arra)m(y)h(p)s(osition)d(to)j
+(the)g(parser.)150 1964 y Ft(The)k(parser)45 b Fs(Giv)m(en)31
+b(a)g(tok)m(en)i(from)d(the)h(lexer,)g(the)g(parser)g(\014nds)e(the)i
+(appropriate)f(grammar)h(pro-)377 2077 y(duction)d(and)g(p)s(erforms)g
+(the)h(sp)s(eci\014ed)e(actions.)40 b(It)29 b(is)f(able)g(to)i(access)g
+(command)f(information)377 2190 y(through)h(ha)m(ving)g(the)g(command)h
+(table)f(p)s(osition.)150 2378 y Ft(The)35 b(grammar)43
+b Fs(The)35 b(grammar)h(used)e(for)h(the)h(L)1952 2361
+y Fr(A)1991 2378 y Fs(T)2042 2397 y(E)2092 2378 y(X)g(general)f
+(commands)g(\(and)g(en)m(vironmen)m(ts\))377 2491 y(is)28
+b(actually)g(v)m(ery)h(simple)d(|)i(the)h(complexit)m(y)f(is)g(reserv)m
+(ed)g(for)h(the)f(lexer)g(and)g(the)h(actions.)40 b(A)m(t)377
+2604 y(the)33 b(grammar)f(lev)m(el,)h(no)f(distinction)d(is)j(made)g(b)
+s(et)m(w)m(een)h(a)f(command)g(and)g(an)g(en)m(vironmen)m(t.)377
+2716 y(There)k(are)i(a)f(total)g(of)g(19)g(di\013eren)m(t)g(command)f
+(t)m(yp)s(es)h(\(tok)m(ens\),)j(whic)m(h)35 b(fall)h(in)m(to)g(a)h
+(smaller)377 2829 y(n)m(um)m(b)s(er)29 b(of)i(groups.)461
+3017 y(1.)46 b(A)31 b(command)f(with)f(no)h(argumen)m(ts.)461
+3163 y(2.)46 b(A)31 b(command)f(with)f(just)h(a)h(single)e(optional)g
+(argumen)m(t.)461 3309 y(3.)46 b(Commands)32 b(with)g(a)h(\014nal)f
+(optional)g(argumen)m(t)i(and)e(b)s(et)m(w)m(een)i(1)g(and)e(8)h
+(required)f(argu-)577 3422 y(men)m(ts.)461 3568 y(4.)46
+b(Commands)33 b(with)f(b)s(et)m(w)m(een)j(1)f(and)f(8)h(required)e
+(argumen)m(ts.)51 b(In)33 b(this)g(case)h(it)g(is)e(alw)m(a)m(ys)577
+3681 y(assumed)e(that)h(there)f(migh)m(t)h(b)s(e)e(an)i(initial)c
+(optional)j(argumen)m(t.)461 3827 y(5.)46 b(A)31 b(command)f(with)f(9)i
+(required)d(argumen)m(ts.)377 4015 y(Note)34 b(that)e(this)f
+(partitioning)f(is)h(based)g(solely)g(on)h(the)g(n)m(um)m(b)s(er)f(of)h
+(required)e(argumen)m(ts)j(and)377 4128 y(the)e(p)s(osition)d(\(if)i
+(an)m(y)h(is)e(declared\))h(of)h(an)f(optional)g(argumen)m(t.)377
+4265 y(F)-8 b(or)30 b(example,)f(if)e(a)j(command/en)m(vironmen)m(t)e
+(is)g(sp)s(eci\014ed)f(in)g(the)i(command)g(table)f(as)h(ha)m(ving)377
+4364 y(one)44 b(required)d(argumen)m(t)i(and)g(no)g(optional)f(argumen)
+m(ts,)47 b(then)42 b(this)g(will)f(b)s(e)h(treated)i(as)g(a)377
+4464 y(command)26 b(with)f(p)s(ossibly)e(an)i(initial)f(optional)h
+(argumen)m(t)h(and)f(one)i(required)d(argumen)m(t.)39
+b(The)377 4564 y(grammar)31 b(for)f(this)f(is:)377 4775
+y Fh(l2xComm1:)40 b(COMMAND_1)726 4875 y({)813 4975 y
+(start_with_opt\($1)o(\);)726 5074 y(})726 5174 y(OptParam)726
+5274 y({)1905 5531 y Fs(72)p eop
+%%Page: 73 77
+73 76 bop 813 573 a Fh(action_opt_first\()o($1)o(\);)726
+672 y(})726 772 y(ReqParam)726 872 y({)813 971 y(action_last_p\($1,)o
+(1\))o(;)726 1071 y(})726 1171 y(;)377 1390 y Fs(where)32
+b(the)h(w)m(ords)e(in)g(all)h(upp)s(er)e(case)j(are)g(grammar)f(tok)m
+(ens,)i(and)e(w)m(ords)g(in)f(mixed)g(case)j(are)377
+1503 y(other)e(grammar)f(pro)s(ductions.)40 b(The)31
+b(actions)g(are)g(enclosed)g(b)s(et)m(w)m(een)h(braces.)43
+b(The)30 b Fn($1)h Fs(is)f(the)377 1616 y(p)s(osition)f(of)h(the)h
+(command)f(in)f(the)i(command)f(table)g(arra)m(y)-8 b(.)150
+1788 y Ft(Actions)46 b Fs(The)32 b(standard)g(actions)h(are)g(con)m
+(tained)g(in)e(\014le)h Fn(l2xacts.c)p Fs(.)45 b(Within)31
+b(the)i(co)s(de)f(for)h(eac)m(h)377 1888 y(standard)21
+b(action,)i(pro)m(vision)d(is)g(made)h(for)g(calling)f(action)i(co)s
+(de)f(for)g(sp)s(ecials.)36 b(All)20 b(the)h(functions)377
+1987 y(ha)m(v)m(e)k(the)e(same)g(general)h(structure.)37
+b(Here,)26 b(for)d(instance,)h(is)e(the)i(co)s(de)f(for)g(the)g
+(standard)g(action)377 2087 y(that)31 b(is)f(called)f(b)s(et)m(w)m(een)
+i(the)g(start)g(of)f(a)h(command)f(and)g(a)h(\014rst)e(optional)h
+(argumen)m(t.)377 2293 y Fh(/*)43 b(START_WITH_OPT)38
+b(start)j(action)g(for)i(command)d(with)i(optional)f(param)g(*/)377
+2392 y(void)h(start_with_opt\(po)o(s\))377 2492 y(int)h(pos;)1000
+b(/*)43 b(position)d(of)j(command)e(in)i(table)e(*/)377
+2592 y({)464 2691 y(int)i(user_kind;)649 b(/*)43 b(user-specified)38
+b(command)j(type)h(*/)464 2890 y(user_kind)e(=)j(get_user_type\(pos)o
+(\);)464 3090 y(switch\(user_kind\))37 b({)464 3189 y(case)42
+b(TEX_CHAR:)650 b(/*)43 b(the)g(general,)d(non-specials)e(*/)464
+3289 y(case)k(CHAR_COMMAND:)464 3389 y(case)g(COMMAND:)464
+3488 y(case)g(BEGIN_ENV:)464 3588 y(case)g(END_ENV:)464
+3688 y(case)g(BEGIN_LIST_ENV:)464 3787 y(case)g(END_LIST_ENV:)464
+3887 y(case)g(SECTIONING:)552 3986 y(start_it\(pos\);)735
+b(/*)43 b(command)d(start)i(action)f(*/)552 4086 y(default_start_w)o
+(ith)o(_o)o(pt\()o(po)o(s\))o(;)125 b(/*)43 b(start)e(optional)f(param)
+i(*/)552 4186 y(break;)464 4285 y(case)g(SPECIAL:)869
+b(/*)43 b(the)f(specials)e(*/)464 4385 y(case)i(SPECIAL_BEGIN_ENV)o(:)
+464 4485 y(case)g(SPECIAL_END_ENV:)464 4584 y(case)g(SPECIAL_BEGIN_LIS)
+o(T:)464 4684 y(case)g(SPECIAL_END_LIST:)464 4783 y(case)g
+(SPECIAL_COMMAND:)464 4883 y(case)g(SPECIAL_SECTIONIN)o(G:)552
+4983 y(special_start_w)o(ith)o(_o)o(pt\()o(po)o(s\))o(;)552
+5082 y(break;)464 5182 y(default:)1087 b(/*)43 b(should)e(not)h(be)h
+(here!)e(*/)552 5282 y(warning\("\(start)o(_wi)o(th)o(_op)o(t\))c
+(Unrecognized)h(command)j(type"\);)1905 5531 y Fs(73)p
+eop
+%%Page: 74 78
+74 77 bop 552 573 a Fh(break;)464 672 y(})44 b(/*)e(end)h(switch)e(on)i
+(user_kind)c(*/)377 772 y(})1482 b(/*)43 b(end)f(START_WITH_OPT)c(*/)
+377 984 y Fs(The)i(sp)s(ecial)e(actions)i(co)s(de)h(is)e(in)f(\014le)h
+Fn(l2xusrlib.c)p Fs(.)67 b(The)39 b(co)s(de)h(for)g(these)h(all)e
+(follo)m(w)g(the)377 1083 y(same)32 b(general)f(pattern.)43
+b(F)-8 b(or)32 b(example,)f(here)g(is)f(the)h(co)s(de)h(implemen)m
+(ting)d(the)i(sp)s(ecial)f(action)377 1183 y(b)s(et)m(w)m(een)h(the)g
+(start)g(of)f(a)h(command)f(and)g(a)h(\014rst)e(optional)h(argumen)m
+(t.)377 1395 y Fh(/*)43 b(SPECIAL_START_WI)o(TH_)o(OP)o(T)38
+b(special)i(start)i(for)g(command)f(with)h(opt)g(param)g(*/)377
+1494 y(void)g(special_start_wit)o(h_)o(opt)o(\(p)o(os)o(\))377
+1594 y(int)h(pos;)1175 b(/*)43 b(command)d(position)h(in)h(table)g(*/)
+377 1694 y({)464 1793 y(int)h(special_kind;)692 b(/*)43
+b(user-specified)37 b(special)k(token)h(*/)464 1993 y(special_kind)d(=)
+k(get_special_token)o(\(p)o(os\))o(;)464 2192 y(switch\(special_ki)o
+(nd\))37 b({)552 2291 y(/*)42 b(additional)e(cases)h(for)i(specials)d
+(added)h(here)h(*/)552 2491 y(/*)g(end)h(of)f(cases)g(for)g(specials)f
+(*/)464 2590 y(default:)1043 b(/*)43 b(should)e(not)h(be)h(here!)f(*/)
+552 2690 y(warning\("\(speci)o(al_)o(st)o(art)o(_w)o(it)o(h_o)o(pt)o
+(\))c(Unrecognized)g(SPECIAL"\);)552 2790 y(tdebug_str_int\()o("SP)o
+(EC)o(IAL)o(_T)o(OK)o(EN)f(=",special_kind\);)552 2889
+y(break;)464 2989 y(})87 b(/*)43 b(end)f(of)h(switch)e(on)i(user_kind)d
+(*/)377 3088 y(})1220 b(/*)43 b(end)f(SPECIAL_START_WIT)o(H_O)o(PT)37
+b(*/)377 3313 y Fs(Note)32 b(that)f(the)g(co)s(de)f(as)h(pro)m(vided)e
+(just)h(issues)f(a)h(w)m(arning)g(message.)291 3526 y(With)g(this)f
+(bac)m(kground,)i(w)m(e)g(will)c(no)m(w)k(go)g(on)f(with)f(the)i
+(example.)261 3738 y(1.)46 b(Decide)29 b(on)g(ho)m(w)f(the)h
+Fy(L)-7 b(TX2X)28 b Fs(system)h(will)d(translate)i(y)m(our)h
+(command/en)m(vironmen)m(t)f(descrip-)377 3851 y(tion)39
+b(in)m(to)g(its)f(in)m(ternal)g(grammar)h(command)g(t)m(yp)s(e.)67
+b(In)39 b(this)f(case)i(it)f(will)d(translate)j(in)m(to)h(a)377
+3964 y(command)30 b(with)f(p)s(ossibly)f(an)i(initial)e(optional)h
+(argumen)m(t)i(and)f(one)h(required)d(argumen)m(t.)261
+4152 y(2.)46 b(Examine)c(the)g(grammar)g(for)g(the)g(command)g(and)g
+(hence)g(determine)g(whic)m(h)e(standard)i(ac-)377 4265
+y(tions)36 b(will)e(b)s(e)h(called.)58 b(In)36 b(this)f(case)i(there)g
+(are)f(three)h(of)f(these,)j(namely)d Fn(start_with_opt)p
+Fs(,)377 4378 y Fn(action_opt_first)g Fs(and)j Fn(action_last_p)p
+Fs(.)65 b(These)39 b(are)i(the)e(actions)h(that)h(migh)m(t)e(require)
+377 4491 y(mo)s(di\014cation.)261 4665 y(3.)46 b(Determine)30
+b(what)f(actions)h(are)g(required)e(for)h(y)m(our)h(sp)s(ecial.)39
+b(Conceptually)28 b(replace)i(the)g(stan-)377 4765 y(dard)j(actions)i
+(in)e(the)h(grammar)g(b)m(y)g(y)m(our)g(actions.)52 b(Then)33
+b(determine)h(ho)m(w)g(these)g(should)f(b)s(e)377 4864
+y(incorp)s(orated)21 b(in)m(to)h(the)g(sp)s(ecial)f(action)h(co)s(de)g
+(in)f Fn(l2xusrlb)p Fs(.)35 b(In)22 b(plain)d(language,)25
+b(the)d(grammar)377 4964 y(and)30 b(conceptual)h(actions)f(for)g(the)h
+(example)f(are:)377 5176 y Fh(l2xComm1:)40 b(COMMAND_1)726
+5275 y({)1905 5531 y Fs(74)p eop
+%%Page: 75 79
+75 78 bop 813 573 a Fh(start)42 b(of)g(as)h(a)g(sectioning)d(command)
+813 672 y(ignore)h(the)i(optional)d(argument)g(as)j(there)e(isn't)h
+(one)726 772 y(})726 872 y(OptParam)726 971 y({)813 1071
+y(finish)f(processing)f(the)i(non-existent)d(optional)813
+1171 y(get)j(ready)g(to)h(store)e(the)i(argument)d(text)i(in)h(a)g
+(buffer)726 1270 y(})726 1370 y(ReqParam)726 1469 y({)813
+1569 y(print)f(the)g(boilerplate)d(and)j(argument)f(text)813
+1669 y(start)h(the)g(description)d(list)726 1768 y(})726
+1868 y(;)377 2063 y Fs(Note)34 b(that)e(this)f(is)g(essen)m(tially)g
+(the)h(same)h(as)f(w)m(e)g(did)f(for)g(the)i(grammar)f(implemen)m
+(tation)e(for)377 2176 y Fn(\\GRAMMspecial)p Fs(,)40
+b(except)h(that)g(there)g(is)e(the)i(additional)d(optional)h(argumen)m
+(t)i(to)g(b)s(e)f(dealt)377 2289 y(with.)261 2467 y(4.)46
+b(Mo)s(dify)29 b(the)i(requisite)e(sp)s(ecial)g(action)i(co)s(de.)377
+2599 y(In)e(the)i(example,)e(three)i(standard)e(actions)h(ha)m(v)m(e)h
+(to)f(b)s(e)g(mo)s(di\014ed.)38 b(Here)31 b(is)d(the)j(mo)s
+(di\014cation)377 2699 y(to)g Fn(special_start_with_opt)p
+Fs(:)377 2881 y Fh(/*)43 b(SPECIAL_START_WI)o(TH_)o(OP)o(T)38
+b(special)i(start)i(for)g(command)f(with)h(opt)g(param)g(*/)377
+2981 y(void)g(special_start_wit)o(h_)o(opt)o(\(p)o(os)o(\))377
+3080 y(int)h(pos;)1175 b(/*)43 b(command)d(position)h(in)h(table)g(*/)
+377 3180 y({)464 3279 y(int)h(special_kind;)692 b(/*)43
+b(user-specified)37 b(special)k(token)h(*/)464 3479 y(special_kind)d(=)
+k(get_special_token)o(\(p)o(os\))o(;)464 3678 y(switch\(special_ki)o
+(nd\))37 b({)552 3778 y(/*)42 b(additional)e(cases)h(for)i(specials)d
+(added)h(here)h(*/)464 3877 y(case)g(59999:)870 b(/*)42
+b(example)f(coded)h(special)e(*/)552 3977 y(codespecial_sta)o(rt\()o
+(po)o(s\);)552 4076 y(default_start_w)o(ith)o(_o)o(pt\()o(po)o(s\))o(;)
+552 4176 y(break;)552 4375 y(/*)i(end)h(of)f(cases)g(for)g(specials)f
+(*/)464 4475 y(default:)1043 b(/*)43 b(should)e(not)h(be)h(here!)f(*/)
+552 4575 y(warning\("\(speci)o(al_)o(st)o(art)o(_w)o(it)o(h_o)o(pt)o
+(\))c(Unrecognized)g(SPECIAL"\);)552 4674 y(tdebug_str_int\()o("SP)o
+(EC)o(IAL)o(_T)o(OK)o(EN)f(=",special_kind\);)552 4774
+y(break;)464 4874 y(})87 b(/*)43 b(end)f(of)h(switch)e(on)i(user_kind)d
+(*/)377 4973 y(})1220 b(/*)43 b(end)f(SPECIAL_START_WIT)o(H_O)o(PT)37
+b(*/)377 5169 y Fs(The)31 b(addition)f(is)h(done)h(b)m(y)f(adding)f(a)i
+(new)g Fn(case)46 b(59999:)30 b Fs(together)j(with)e(appropriate)f(co)s
+(de.)377 5282 y(The)43 b(n)m(um)m(b)s(er)f(59999)j(is)d(that)i(corresp)
+s(onding)d(to)i(the)h(v)-5 b(alue)42 b(for)h Fn(SPECIAL_TOKEN=)c
+Fs(in)j(the)1905 5531 y(75)p eop
+%%Page: 76 80
+76 79 bop 377 573 a Fs(command)33 b(table)g(sp)s(eci\014cation)f(of)h
+Fn(\\CODEspecial)p Fs(.)45 b(The)32 b(function)g Fn(codespecial_start)c
+Fs(is)377 686 y(to)37 b(b)s(e)f(written,)g(while)e Fn
+(default_start_with_opt)c Fs(is)36 b(an)g Fy(L)-7 b(TX2X)36
+b Fs(de\014ned)e(function)h(whic)m(h)377 799 y(initiates)29
+b(pro)s(cessing)g(of)i(an)f(initial)e(optional)h(argumen)m(t.)377
+936 y(Similarly)-8 b(,)28 b(here)i(is)f(the)i(mo)s(di\014cation)d(to)k
+Fn(special_action_opt_firs)o(t)p Fs(:)595 1147 y Fh(/*)43
+b(additional)c(cases)j(for)g(specials)f(added)g(here)h(*/)639
+1247 y(case)g(59999:)607 b(/*)43 b(example)e(coded)g(special)g(*/)726
+1347 y(default_end_star)o(t_o)o(pt)o(\(p)o(os\))o(;)726
+1446 y(codespecial_p1\(p)o(os\))o(;)726 1546 y(break;)595
+1745 y(/*)i(end)f(of)h(cases)f(for)g(specials)e(*/)377
+1970 y Fs(where)26 b Fn(codespecial_p1)d Fs(is)i(to)i(b)s(e)f(written)f
+(and)h Fn(default_end_start_opt)21 b Fs(is)k(the)i(standard)377
+2083 y Fy(L)-7 b(TX2X)31 b Fs(action)f(at)h(the)g(end)f(of)g(an)g
+(initial)e(optional)i(argumen)m(t.)377 2220 y(Finally)-8
+b(,)29 b(here)i(is)e(the)h(mo)s(di\014cation)f(to)i Fn
+(special_action_last_p)p Fs(:)377 2432 y Fh(/*)43 b(SPECIAL_ACTION_L)o
+(AST)o(_P)37 b(action)k(after)h(last)f(req)i(argument)d(*/)377
+2531 y(void)i(special_action_la)o(st)o(_p\()o(po)o(s,)o(p\))377
+2631 y(int)h(pos;)1000 b(/*)43 b(position)d(of)j(command)e(in)i(table)e
+(*/)377 2731 y(int)i(p;)1088 b(/*)43 b(number)e(of)i(last)f(argument)e
+(*/)377 2830 y({)464 2930 y(int)j(special_kind;)692 b(/*)43
+b(user-specified)37 b(special)k(token)h(*/)464 3129 y(special_kind)d(=)
+k(get_special_token)o(\(p)o(os\))o(;)464 3328 y(switch\(special_ki)o
+(nd\))37 b({)595 3428 y(/*)43 b(additional)c(cases)j(for)g(specials)f
+(added)g(here)h(*/)639 3528 y(case)g(59999:)607 b(/*)43
+b(example)e(coded)g(special)g(*/)726 3627 y(if)i(\(p)f(==)h(1\))g({)435
+b(/*)43 b(has)g(only)e(one)i(req)f(param)g(*/)813 3727
+y(codespecial_end\(p)o(os)o(\);)726 3826 y(})726 3926
+y(break;)595 4125 y(/*)h(end)f(of)h(cases)f(for)g(specials)e(*/)508
+4225 y(/*)j(stuff)e(deleted)g(to)i(save)f(space)f(*/)261
+4450 y Fs(5.)46 b(Co)s(de)30 b(the)h(functions)e(for)h(the)g(new)g
+(actions.)377 4600 y(Co)s(de)43 b(for)g(these)h(functions)e(should)g(b)
+s(e)g(put)h(in)m(to)g(\014le)g Fn(l2xusrlb.c)d Fs(and)j(\014le)g
+Fn(l2xusrlb.h)377 4713 y Fs(mo)s(di\014ed)28 b(accordingly)-8
+b(.)377 4850 y(Here)31 b(is)f(the)g(co)s(de)h(for)f(the)g(three)h
+Fn(codespecial_)c Fs(functions.)377 5062 y Fh(char)42
+b(codebuf[80];)780 b(/*)43 b(a)g(string)e(buffer)g(*/)377
+5261 y(/*)i(CODESPECIAL_STAR)o(T)38 b(actions)i(for)j(start)e(of)i
+(CODEspecial)c(command)i(*/)1905 5531 y Fs(76)p eop
+%%Page: 77 81
+77 80 bop 377 573 a Fh(void)42 b(codespecial_start)o(\(p)o(os\))377
+672 y(int)h(pos;)1000 b(/*)43 b(command)e(table)g(position)g(*/)377
+772 y({)464 872 y(start_section\(pos)o(\);)429 b(/*)43
+b(do)g(start)e(of)i(sectioning)d(*/)464 971 y(myprint\(get_t\(pos)o
+(\)\);)385 b(/*)43 b(print)f(start)f(tag)i(*/)377 1071
+y(})1307 b(/*)43 b(end)g(CODESPECIAL_STA)o(RT)37 b(*/)377
+1270 y(/*)43 b(CODESPECIAL_P1)38 b(actions)j(at)h(start)g(of)h
+(CODEspecial)c(param)i(1)i(*/)377 1370 y(void)f(codespecial_p1\(po)o
+(s\))377 1469 y(int)h(pos;)1000 b(/*)43 b(command)e(table)g(position)g
+(*/)377 1569 y({)464 1669 y(myprint\(get_tag_t)o(\(po)o(s,)o(1\)\))o(;)
+124 b(/*)43 b(print)f(1st)g(param)g(start)f(tag)h(*/)464
+1768 y(initialise_sysbuf)o(\(\);)385 b(/*)43 b(clear)f(system)f(string)
+g(buffer)g(*/)464 1868 y(set_print\(p_print)o(_to)o(_s)o(ysb)o(uf)o
+(\);)c(/*)43 b(put)f(arg)g(text)g(into)g(sys)h(buffer)e(*/)377
+1968 y(})1307 b(/*)43 b(end)g(CODESPECIAL_P1)37 b(*/)377
+2167 y(/*)43 b(CODESPECIAL_END)37 b(actions)k(at)i(end)f(of)h
+(CODEspecial)c(command)i(*/)377 2267 y(void)h(codespecial_end\(p)o(os)o
+(\))377 2366 y(int)h(pos;)1000 b(/*)43 b(command)e(table)g(position)g
+(*/)377 2466 y({)464 2565 y(initialise_string)o(\(co)o(de)o(buf)o(\);)
+80 b(/*)43 b(clear)f(this)g(string)f(buffer)g(*/)464
+2665 y(copy_sysbuf\(codeb)o(uf\))o(;)342 b(/*)43 b(copy)f(sys)g(buffer)
+g(into)g(codebuf)e(*/)464 2765 y(reset_print\(\);)648
+b(/*)43 b(normal)e(printing)g(*/)464 2864 y(prwboiler1\(\);)692
+b(/*)43 b(print)f(some)g(boilerplate)d(*/)464 2964 y(print_sysbuf\(\);)
+604 b(/*)43 b(print)f(system)f(buffer)g(*/)464 3064 y(prwboiler2\(\);)
+692 b(/*)43 b(print)f(more)g(boilerplate)d(*/)464 3163
+y(myprint\(codebuf\);)516 b(/*)43 b(print)f(codebuff)e(*/)464
+3263 y(prwboiler3\(\);)692 b(/*)43 b(print)f(yet)g(more)g(boilerplate)d
+(*/)464 3362 y(start_list\(pos\);)560 b(/*)43 b(start)f(a)h(list)f
+(environment)d(*/)377 3462 y(})1307 b(/*)43 b(end)g(CODESPECIAL_END)37
+b(*/)377 3687 y Fs(Note)30 b(that)e(these)h(actions)f(are)h(almost)f
+(iden)m(tical)f(to)i(those)f(that)h(w)m(ere)f(used)g(within)d(the)j
+(gram-)377 3800 y(mar)i(when)g(implemen)m(ting)e(the)j
+Fn(\\GRAMMspecial)26 b Fs(command.)261 3988 y(6.)46 b(Compile)29
+b(the)h(mo)s(di\014ed)f(system)h(and)g(test)h(it)f(on)g(example)g(L)
+2516 3971 y Fr(A)2555 3988 y Fs(T)2606 4007 y(E)2657
+3988 y(X)g(\014les.)150 4231 y Fj(5.2)112 b(Notes)261
+4403 y Fs(1.)46 b(Installation)28 b(of)h(a)g Fh(SPECIAL)p
+1348 4403 27 4 v 57 w Fs(can)h(b)s(e)e(limited)f(to)i(making)g(c)m
+(hanges)h(to)f(the)g(parser)g(\(\014le)f Fn(l2x.y)p Fs(\))377
+4516 y(and/or)22 b(the)f(user)g(library)e(\(\014les)i
+Fn(l2xusrlb.c)e Fs(and)i Fn(l2xusrlb.h)p Fs(\).)35 b(It)21
+b(should)f(not)i(b)s(e)f(necessary)377 4628 y(to)31 b(touc)m(h)g(an)m
+(y)g(other)g(part)f(of)g(the)h(system.)261 4816 y(2.)46
+b(Changes)e(to)h Fn(l2x.y)d Fs(will)g(necessitate)j(executing)f(the)g
+(parser)g(generator)h(on)f(this)e(\014le)i(and)377 4929
+y(system)31 b(compilation.)39 b(Changes)30 b(to)h(the)g(other)g
+(\014les)e(will)f(only)h(necessitate)j(compilation.)261
+5117 y(3.)46 b(Alw)m(a)m(ys)23 b(use)f(the)g Fh(myprint)p
+Fs(,)f Fh(verbatim)p 1691 5117 V 29 w(print)f Fs(or)i
+Fh(print)p 2283 5117 V 29 w(sysbuf)e Fs(functions)h(for)h(prin)m(ting)e
+(b)s(ecause)377 5230 y(they)31 b(incorp)s(orate)f(the)g(prin)m(t)f(con)
+m(trol)i(capabilit)m(y)-8 b(.)1905 5531 y(77)p eop
+%%Page: 78 82
+78 81 bop 261 573 a Fs(4.)46 b(The)35 b(prin)m(ting)f(in)g(the)h(ab)s
+(o)m(v)m(e)i(example)e(is)g(trivial.)54 b(Ho)m(w)m(ev)m(er,)39
+b(it)c(is)f(go)s(o)s(d)i(practice)f(to)i(de\014ne)377
+686 y(prin)m(ted)e(output)h(separately)g(from)g(the)g(parser.)57
+b(It)37 b(mak)m(es)g(for)e(easier)h(main)m(tenance.)59
+b(If,)37 b(for)377 799 y(example)g(the)h(b)s(oilerplate)d(ab)s(o)m(v)m
+(e)k(w)m(as)f(sev)m(eral)g(thousand)e(c)m(haracters,)41
+b(it)c(migh)m(t)g(ha)m(v)m(e)i(b)s(een)377 912 y(an)j(idea)f(to)h
+(store)g(the)g(text)g(in)f(a)g(\014le,)j(or)e(\014les,)h(and)e(then)g
+(ha)m(v)m(e)i(the)f(b)s(oilerplate)d(prin)m(ting)377
+1024 y(functions)34 b(read)h(from)f(the)h(\014le\(s\).)54
+b(If)35 b(the)g(text)h(is)e(in)g(a)h(state)h(of)g(\015ux)e(this)f
+(could)h(b)s(e)h(a)g(go)s(o)s(d)377 1137 y(design)i(decision)f(in)g(an)
+m(y)h(case,)k(as)c(c)m(hanging)h(the)f(text)i(w)m(ould)d(only)g(in)m(v)
+m(olv)m(e)i(mo)s(difying)d(the)377 1250 y(text)d(\014le\(s\))e(and)f(a)
+m(v)m(oid)i(recompilation)e(of)i Fy(L)-7 b(TX2X)p Fs(.)150
+1490 y Ft(5.2.1)105 b(An)35 b(up)s(dated)g(metho)s(d)150
+1649 y Fs(The)41 b(ab)s(o)m(v)m(e)h(descriptions)e(of)h(installing)e(a)
+i Fn(SPECIAL_)f Fs(command)h(w)m(ere)h(written)e(for)h(the)h(original)
+150 1748 y(release)24 b(of)g(the)h Fy(L)-7 b(TX2X)24
+b Fs(system,)h(whic)m(h)e(did)f(not)i(ha)m(v)m(e)i(the)e(input)e(and)h
+(output)h(sp)s(eci\014cation)f(facilities)150 1848 y(curren)m(tly)h(a)m
+(v)-5 b(ailable)25 b(within)e(a)i(command)g(table.)39
+b(Belo)m(w)26 b(is)f(giv)m(en)g(a)h(p)s(ossible)c(command)j(table)h(en)
+m(try)150 1948 y(using)j(these)i(facilities.)150 2122
+y Fh(TYPE=)42 b(SPECIAL_COMMAND)150 2222 y(NAME=)g(\\THIRDspecial)237
+2321 y(C=)h(SPECIAL_TOKEN=)81 b(set)43 b(the)f(appropriate)d(number)237
+2421 y(SECTIONING_LEVEL=)e(SECT)237 2521 y(START_TAG=)j
+("?n?n<div.1>?n")324 2620 y(STRING:)h("<heading>Normat)o(ive)c
+(References</head)o(in)o(g>)o(?n")324 2720 y(RESET_SYSBUF:)237
+2819 y(END_TAG=)j("?n</div.1>")237 2919 y(REQPARAMS=)g(1)237
+3019 y(PRINT_P1=)g(TO_SYSBUF)237 3118 y(END_TAG_1=)324
+3218 y(STRING:)h("?nSome)g(boilerplate)e(text)j(with)g(")324
+3318 y(SOURCE:)f(SYSBUF)324 3417 y(STRING:)g("?nin)h(the)g(middle.)f
+(Now)h(there)f(is?n")324 3517 y(STRING:)g("some)h(more)f(boilerplate)f
+(with)h(")324 3616 y(SOURCE:)g(SYSBUF)324 3716 y(STRING:)g("?nin)h(the)
+g(middle)f(of)i(it.?n")237 3816 y(START_ITEM=)c("?n")237
+3915 y(START_ITEM_PARAM=)e(")174 b(\(")237 4015 y(END_ITEM_PARAM=)38
+b("\))k(--)h(")150 4115 y(END_TYPE)150 4302 y Fs(The)33
+b(actual)i(implemen)m(tation)d(of)i(this)f(as)h(either)f(a)h(grammar)g
+(sp)s(ecial)f(or)h(a)g(co)s(de)g(sp)s(ecial)e(is)h(left)h(as)150
+4415 y(an)c(exercise)f(for)h(the)g(reader.)40 b(Basically)29
+b(it)g(in)m(v)m(olv)m(es)h(the)g(deletion)e(of)i(the)g(sp)s(eci\014c)e
+(prin)m(t)h(action)h(and)150 4528 y(bu\013er)c(co)s(de)h(b)s(ecause)g
+(this)f(is)g(no)m(w)h(handled)e(automatically)i(via)f(the)h(command)g
+(table)g(sp)s(eci\014cation.)1905 5531 y(78)p eop
+%%Page: 79 83
+79 82 bop 150 573 a Fu(A)134 b(Example)46 b(command)f(table)h(\014le)f
+(for)g(de-T)2567 599 y(E)2638 573 y(Xing)150 776 y Fs(This)38
+b(app)s(endix)f(pro)m(vides)h(the)i(sk)m(eleton)g(of)f(a)h(command)f
+(table)g(\014le)g(that)h(could)e(b)s(e)h(used)g(for)g(de-)150
+889 y(T)201 908 y(E)251 889 y(Xing)30 b(a)g(L)570 872
+y Fr(A)609 889 y Fs(T)660 908 y(E)711 889 y(X)g(do)s(cumen)m(t.)150
+1088 y Fh(C=)86 b(detex.ct)41 b(command)f(table)i(file)g(for)g(ltx2x)g
+(to)g(deTeX)g(source)150 1287 y(C=)130 b(----------------)o(--)o(---)o
+(--)o(---)o(--)o(---)o(--)o(--)o(esc)o(ap)o(e)38 b(sequences)150
+1486 y(C=)43 b(don't)e(use)i(default)d(here)i(as)h(it)g(may)f(clash)g
+(with)g(command)e(name)i(output)150 1586 y(ESCAPE_CHAR=)d(?)150
+1686 y(C=)304 b(keep)42 b(tye)h(default)d(vaues)i(for)g(the)g(rest)150
+1885 y(C=)130 b(----------------)o(--)o(---)o(--)o(---)o(--)o(---)o(--)
+o(--)37 b(the)42 b(built)g(in)h(commands)150 1985 y(TYPE=)f
+(BEGIN_DOCUMENT)150 2084 y(END_TYPE)150 2283 y(TYPE=)g(END_DOCUMENT)150
+2383 y(END_TYPE)150 2582 y(TYPE=)g(BEGIN_VERB)150 2682
+y(END_TYPE)150 2881 y(TYPE=)g(END_VERB)150 2981 y(END_TYPE)150
+3180 y(TYPE=)g(BEGIN_VERBATIM)237 3280 y(START_TAG=)e("?n")150
+3379 y(END_TYPE)150 3579 y(TYPE=)i(END_VERBATIM)237 3678
+y(START_TAG=)e("?n")150 3778 y(END_TYPE)150 3977 y(TYPE=)i
+(BEGIN_DOLLAR)150 4077 y(END_TYPE)150 4276 y(TYPE=)g(END_DOLLAR)150
+4376 y(END_TYPE)150 4575 y(TYPE=)g(SLASH_SPACE)237 4675
+y(START_TAG=)e(")j(")150 4774 y(END_TYPE)150 4973 y(TYPE=)f
+(OTHER_COMMAND)237 5073 y(PRINT_CONTROL=)c(NO_PRINT)150
+5173 y(END_TYPE)1905 5531 y Fs(79)p eop
+%%Page: 80 84
+80 83 bop 150 573 a Fh(TYPE=)42 b(OTHER_BEGIN)237 672
+y(PRINT_CONTROL=)c(NO_PRINT)150 772 y(END_TYPE)150 971
+y(TYPE=)k(OTHER_END)237 1071 y(PRINT_CONTROL=)c(NO_PRINT)150
+1171 y(END_TYPE)150 1370 y(C=)304 b(throw)42 b(away)g(naked)f(braces)
+150 1469 y(TYPE=)h(LBRACE)150 1569 y(END_TYPE)150 1768
+y(TYPE=)g(RBRACE)150 1868 y(END_TYPE)150 2067 y(C=)86
+b(Pretty)41 b(printing)g(will)h(probably)e(be)j(applied.)d(Indent)h
+(start)h(of)g(paragraphs)150 2167 y(TYPE=)g(PARAGRAPH)237
+2267 y(START_TAG=)e("?n?n)172 b(")150 2366 y(END_TYPE)150
+2565 y(C=)43 b(----------------)o(--)o(--)o(---)o(--)o(---)o(--)o(---)o
+(--)o(--)o(\(La)o(\)T)o(eX)37 b(special)k(characters)150
+2765 y(C=)i(hash)f(\(for)g(use)g(in)h(\\def)f(s)h(\))150
+2864 y(TYPE=)f(TEX_CHAR)150 2964 y(NAME=)g(#)150 3064
+y(END_TYPE)150 3263 y(C=)h(ampersand)d(\(tabular)g(column)h(delimiter,)
+e(replace)i(by)i(some)f(spaces\))150 3362 y(TYPE=)g(TEX_CHAR)150
+3462 y(NAME=)g(&)237 3562 y(START_TAG=)e(")130 b(")150
+3661 y(END_TYPE)150 3861 y(C=)43 b(twiddle)d(\(unbreakable)f(space\))
+150 3960 y(TYPE=)j(TEX_CHAR)150 4060 y(NAME=)g(~)237
+4159 y(START_TAG=)e(")j(")150 4259 y(END_TYPE)150 4458
+y(C=)g(underscore)c(\(math)j(subscript\))150 4558 y(TYPE=)g(TEX_CHAR)
+150 4658 y(NAME=)g(_)237 4757 y(START_TAG=)e("_")150
+4857 y(END_TYPE)150 5056 y(C=)j(caret)e(\(math)h(superscript\))150
+5156 y(TYPE=)g(TEX_CHAR)150 5255 y(NAME=)g(^)1905 5531
+y Fs(80)p eop
+%%Page: 81 85
+81 84 bop 237 573 a Fh(START_TAG=)40 b("^")150 672 y(END_TYPE)150
+872 y(C=)j(at)150 971 y(TYPE=)f(TEX_CHAR)150 1071 y(NAME=)g(@)237
+1171 y(START_TAG=)e("@")150 1270 y(END_TYPE)150 1469
+y(C=)j(----------------)o(--)o(--)o(---)o(--)37 b(default)k(single)g
+(character)f(commands)150 1569 y(C=)348 b(\(replace)40
+b(by)j(appropriate)c(character\))150 1768 y(C=)k(LaTeX)e(start)h(a)h
+(new)f(line)150 1868 y(TYPE=)g(CHAR_COMMAND)150 1968
+y(NAME=)g(\\\\)237 2067 y(START_TAG=)e("?n")150 2167
+y(END_TYPE)150 2366 y(C=)j(small)e(space)150 2466 y(TYPE=)h
+(CHAR_COMMAND)237 2565 y(NAME=)g(\\,)150 2665 y(START_TAG=)d(")44
+b(")150 2765 y(END_TYPE)150 2964 y(C=)f(end)f(of)h(sentence)d(space)150
+3064 y(TYPE=)i(CHAR_COMMAND)150 3163 y(NAME=)g(\\@)237
+3263 y(START_TAG=)e(")j(")150 3362 y(END_TYPE)150 3562
+y(C=)g(hash)150 3661 y(TYPE=)f(CHAR_COMMAND)150 3761
+y(NAME=)g(\\#)237 3861 y(START_TAG=)e("#")150 3960 y(END_TYPE)150
+4159 y(C=)j(dollar)150 4259 y(TYPE=)f(CHAR_COMMAND)150
+4359 y(NAME=)g(\\$)237 4458 y(START_TAG=)e("$")150 4558
+y(END_TYPE)150 4757 y(C=)j(ampersand)150 4857 y(TYPE=)f(CHAR_COMMAND)
+150 4956 y(NAME=)g(\\&)237 5056 y(START_TAG=)e("&")150
+5156 y(END_TYPE)1905 5531 y Fs(81)p eop
+%%Page: 82 86
+82 85 bop 150 573 a Fh(C=)43 b(underscore)150 672 y(TYPE=)f
+(CHAR_COMMAND)150 772 y(NAME=)g(\\_)237 872 y(START_TAG=)e("_")150
+971 y(END_TYPE)150 1171 y(C=)j(percent)150 1270 y(TYPE=)f(CHAR_COMMAND)
+150 1370 y(NAME=)g(\\\045)237 1469 y(START_TAG=)e("\045")150
+1569 y(END_TYPE)150 1768 y(C=)j(left)f(brace)150 1868
+y(TYPE=)g(CHAR_COMMAND)150 1968 y(NAME=)g(\\{)237 2067
+y(START_TAG=)e("{")150 2167 y(END_TYPE)150 2366 y(C=)j(right)e(brace)
+150 2466 y(TYPE=)h(CHAR_COMMAND)150 2565 y(NAME=)g(\\})237
+2665 y(START_TAG=)e("}")150 2765 y(END_TYPE)150 2964
+y(C=)j(optional)d(hyphenation)150 3064 y(TYPE=)i(CHAR_COMMAND)150
+3163 y(NAME=)g(\\-)237 3263 y(START_TAG=)e("")150 3362
+y(END_TYPE)150 3562 y(C=)j(----------------)o(--)o(--)o(---)o(--)o(---)
+o(-)37 b(General)k(LaTeX)150 3761 y(TYPE=)h(COMMAND)150
+3861 y(NAME=)g(\\caption)237 3960 y(START_TAG=)e("?n)173
+b(CAPTION:)40 b(")237 4060 y(OPT_PARAM=)g(FIRST)237 4159
+y(PRINT_OPT=)g(NO_PRINT)237 4259 y(REQPARAMS=)g(1)150
+4359 y(END_TYPE)150 4558 y(TYPE=)i(BEGIN_LIST_ENV)150
+4658 y(NAME=)g(itemize)237 4757 y(START_TAG=)e("?n")237
+4857 y(START_ITEM=)f("?n)130 b(o)43 b(")150 4956 y(END_TYPE)150
+5156 y(TYPE=)f(END_LIST_ENV)150 5255 y(NAME=)g(itemize)1905
+5531 y Fs(82)p eop
+%%Page: 83 87
+83 86 bop 237 573 a Fh(START_TAG=)40 b("?n")150 672 y(END_TYPE)150
+872 y(TYPE=)i(BEGIN_LIST_ENV)150 971 y(NAME=)g(enumerate)237
+1071 y(START_TAG=)e("?n")237 1171 y(START_ITEM=)f("?n)130
+b(--)42 b(")150 1270 y(END_TYPE)150 1469 y(TYPE=)g(END_LIST_ENV)150
+1569 y(NAME=)g(enumerate)237 1669 y(START_TAG=)e("?n")150
+1768 y(END_TYPE)150 1968 y(TYPE=)i(BEGIN_LIST_ENV)150
+2067 y(NAME=)g(description)237 2167 y(START_TAG=)e("?n")237
+2267 y(START_ITEM=)f("?n)173 b(")237 2366 y(END_ITEM_PARAM=)38
+b(")43 b(:)g(")150 2466 y(END_TYPE)150 2665 y(TYPE=)f(END_LIST_ENV)237
+2765 y(NAME=)g(description)150 2864 y(START_TAG=)d("?n")150
+2964 y(END_TYPE)150 3163 y(C=)304 b(replace)41 b(\\footnote)f(with)i
+(parenthesized)c(text)150 3263 y(TYPE=)k(COMMAND)150
+3362 y(NAME=)g(\\footnote)237 3462 y(START_TAG=)e(")j(\(")237
+3562 y(END_TAG=)d("\))j(")237 3661 y(OPT_PARAM=)d(FIRST)237
+3761 y(PRINT_OPT=)g(NO_PRINT)237 3861 y(REQPARAMS=)g(1)150
+3960 y(END_TYPE)150 4159 y(C=)435 b(----------------)o(---)o(--)o(--)37
+b(sectioning)j(\(keep)h(headers)g(only\))150 4359 y(C=)479
+b(repeat)41 b(for)h(all)g(the)h(other)e(sectioning)f(commands)150
+4458 y(TYPE=)i(SECTIONING)150 4558 y(NAME=)g(\\section)237
+4658 y(SECTIONING_LEVEL=)37 b(SECT)237 4757 y(START_TAG=)j("?n?n")237
+4857 y(OPT_PARAM=)g(FIRST)237 4956 y(PRINT_OPT=)g(NO_PRINT)237
+5056 y(REQPARAMS=)g(1)237 5156 y(END_TAG_1=)g("?n?n")150
+5255 y(END_TYPE)1905 5531 y Fs(83)p eop
+%%Page: 84 88
+84 87 bop 150 672 a Fh(C=)391 b(repeat)42 b(for)g(all)g(the)h(other)e
+(starred)g(sectioning)e(commands)150 772 y(TYPE=)j(SECTIONING)150
+872 y(NAME=)g(\\section*)237 971 y(SECTIONING_LEVEL=)37
+b(SECT)237 1071 y(START_TAG=)j("?n?n")237 1171 y(REQPARAMS=)g(1)237
+1270 y(END_TAG_1=)g("?n?n")150 1370 y(END_TYPE)150 1569
+y(C=)348 b(and)42 b(whatever)e(else)i(is)h(interesting)150
+1669 y(END_CTFILE=)150 1955 y Fu(B)134 b(LaT)-11 b(eX)44
+b(to)i(HTML)e(translation)150 2158 y Fs(The)g(command)g(table)h(\014le)
+f Fn(l2h.ct)f Fs(con)m(tains)h(a)h(set)h(of)e(commands)h(that)g(enable)
+f(simple)e(L)3541 2141 y Fr(A)3580 2158 y Fs(T)3631 2178
+y(E)3682 2158 y(X)150 2271 y(do)s(cumen)m(ts)30 b(to)h(b)s(e)f
+(translated)g(in)m(to)g(HTML)g(tagged)i(do)s(cumen)m(ts)e(for)g(displa)
+m(y)f(using)g(a)h(W)-8 b(orld)30 b(Wide)150 2384 y(W)-8
+b(eb)31 b(bro)m(wser.)40 b(A)m(t)31 b(a)f(min)m(um)m(um)e(this)g
+(command)i(table)g(can)g(b)s(e)f(used)g(for)h(con)m(v)m(ersion)g(of)g
+(the)g(L)3541 2367 y Fr(A)3580 2384 y Fs(T)3631 2404
+y(E)3682 2384 y(X)150 2497 y(source)g(of)g(this)e(man)m(ual.)40
+b(It)30 b(can)g(also)f(handle)g(some)h(v)m(ery)g(simple)d(mathematics)k
+(but)e(not)g(pictures.)3711 2464 y Fr(8)150 2610 y Fs(The)h(sp)s
+(eci\014cation)f(for)h(the)h(HTML)f(tags)h(w)m(as)g(tak)m(en)h(from)e
+(Musciano)g(and)f(Kennedy)h([5].)291 2723 y(Generally)42
+b(sp)s(eaking)g(and)h(sub)5 b(ject)43 b(to)h(the)f(ab)s(o)m(v)m(e)h
+(limitations,)g(a)g(L)2794 2706 y Fr(A)2833 2723 y Fs(T)2884
+2742 y(E)2934 2723 y(X)f(do)s(cumen)m(t)g(can)h(b)s(e)150
+2836 y(translated)27 b(to)h(HTML)g(without)e(the)i(do)s(cumen)m(t)f(ha)
+m(ving)g(b)s(een)g(planned)e(for)j(this)e(purp)s(ose,)g(with)h(one)150
+2948 y(exception.)53 b(The)34 b(exception)h(is)e(that)i(a)g(new)f(L)
+1797 2932 y Fr(A)1836 2948 y Fs(T)1887 2968 y(E)1938
+2948 y(X)g(command)g(should)f(b)s(e)h(used)f(in)g(the)i(do)s(cumen)m(t)
+150 3061 y(pream)m(ble.)71 b(I)41 b(ha)m(v)m(e)h(called)e(this)g
+Fn(\\mltitle)e Fs(and)j(its)f(purp)s(ose)f(to)j(to)f(de\014ne)f(the)h
+(con)m(ten)m(ts)i(of)e(the)150 3174 y(header)30 b(for)g(the)h(HTML)f
+(text.)42 b(The)30 b(de\014nition)e(of)i(this)g(command)g(is:)150
+3362 y Fn(\\newcommand{\\mltitle}[1])o({})150 3550 y
+Fs(That)f(is,)f(as)i(far)e(as)i(L)874 3533 y Fr(A)913
+3550 y Fs(T)964 3569 y(E)1014 3550 y(X)f(is)f(concerned,)i(the)f
+(argumen)m(t)g(to)h(the)f(command)g(is)f(thro)m(wn)h(a)m(w)m(a)m(y)i
+(and)d(is)150 3662 y(a)i(non-ev)m(en)m(t.)41 b(As)29
+b(far)g(as)h(the)f Fn(l2h.ct)e Fs(command)i(table)g(is)f(concerned)i
+(the)f(argumen)m(t)h(is)e(the)h(header)150 3775 y(title.)40
+b(As)31 b(an)f(example,)g(this)f(man)m(ual)h(starts)h(with:)150
+3963 y Fn(...)150 4076 y(\\mltitle{LaTeX)44 b(to)j(X)h(translator})150
+4189 y(\\begin{document})150 4302 y(\\title{\\lx:)d(A)i(\\LaTeX{})f(to)
+h(X)g(Auto-tagger})150 4415 y(...)150 4602 y Fs(whic)m(h)29
+b(gets)i(con)m(v)m(erted)h(in)m(to:)150 4790 y Fn(<html>)150
+4903 y(<head>)150 5016 y(<title>LaTeX)44 b(to)k(X)f(translator</title>)
+p 150 5085 1440 4 v 254 5139 a Fl(8)288 5170 y Fp(HTML)25
+b(itself)g(cannot)f(handle)g(pictures)g(directly)h(\(i.e.,)g(there)f
+(is)h(no)f(equiv)l(alen)n(t)f(to)h(the)g(L)2947 5153
+y Fl(A)2980 5170 y Fp(T)3022 5186 y(E)3066 5170 y(X)g
+Fh(picture)d Fp(en)n(viron-)150 5262 y(men)n(t\),)j(and)i(can)f(only)h
+(handle)f(simple)h(mathematics.)1905 5531 y Fs(84)p eop
+%%Page: 85 89
+85 88 bop 150 573 a Fn(</head>)150 686 y(<body>)150 912
+y(<h1)47 b(align=center>)198 1024 y(LTX2X:)f(A)h(LaTeX)g(to)g(X)g
+(Auto-tagger)150 1137 y(</h1>)150 1250 y(...)150 1438
+y Fs(If)31 b(the)h Fn(\\mltitle)e Fs(command)h(is)g(not)h(used,)f(then)
+h(the)f(e\013ect)j(is)c(to)j(ha)m(v)m(e)g(an)e(empt)m(y)j
+Fn(<title>)29 b Fs(in)i(the)150 1551 y Fn(<head>)e Fs(of)h(the)h(HTML)f
+(do)s(cumen)m(t.)291 1664 y(Sev)m(eral)d(asp)s(ects)f(of)h(the)f
+(design)g(of)33 b Fn(l2h.ct)25 b Fs(in)g(the)i(con)m(text)h(of)f(the)f
+(con)m(v)m(ersion)h(of)f(t)m(ypical)g(L)3541 1647 y Fr(A)3580
+1664 y Fs(T)3631 1683 y(E)3682 1664 y(X)150 1777 y(do)s(cumen)m(ts)i
+(ha)m(v)m(e)h(b)s(een)e(discussed)f(as)i(examples)f(in)g(the)h(b)s(o)s
+(dy)e(of)i(the)h(man)m(ual.)39 b(Ho)m(w)m(ev)m(er,)30
+b(there)f(are)150 1890 y(some)f(asp)s(ects)h(sp)s(eci\014c)e(to)h(the)h
+(translation)e(of)h(this)f(do)s(cumen)m(t)h(should)e(b)s(e)h(men)m
+(tioned.)40 b(These)28 b(stem)150 2002 y(from)35 b(the)h(fact)g(that)g
+(HTML)g(has)f(no)g(tags)i(corresp)s(onding)c(to)k(to)f(the)g(L)2732
+1986 y Fr(A)2771 2002 y Fs(T)2822 2022 y(E)2872 2002
+y(X)g Fn(\\verb)e Fs(command)h(or)150 2115 y Fn(verbatim)28
+b Fs(en)m(vironmen)m(t)i(whic)m(h)f(switc)m(h)h(o\013)h(the)f(meanings)
+g(of)g(sp)s(ecial)f(c)m(haracters.)291 2228 y(HTML)42
+b(treats)g(the)g(c)m(haracters)i Fn(<)p Fs(,)g Fn(>)p
+Fs(,)g(&)e(and)f(#)g(sp)s(ecially)-8 b(.)73 b(Within)40
+b(a)i Fn(<pre>)p Fs(...)p Fn(</pre>)e Fs(the)150 2341
+y(bro)m(wser)27 b(honours)g(the)h(line)f(breaks)g(but)h(do)s(es)f(not)i
+(switc)m(h)e(o\013)h(the)g(meanings)g(of)g(the)g(sp)s(ecial)e(c)m
+(harac-)150 2454 y(ters.)39 b(In)25 b(L)494 2437 y Fr(A)533
+2454 y Fs(T)584 2474 y(E)635 2454 y(X,)i(the)f Fn(\\verb)e
+Fs(command)i(switc)m(hes)f(o\013)i(all)d(sp)s(ecial)h(c)m(haracters)i
+(but)e(prohibits)e(an)m(y)k(line)150 2567 y(breaking.)40
+b(The)30 b Fn(verbatim)e Fs(en)m(vironmen)m(t)i(b)s(oth)f(honours)h
+(line)e(breaks)i(and)g(switc)m(hes)g(o\013)h(all)e(sp)s(ecial)150
+2680 y(c)m(haracters.)70 b(The)39 b(di\016cult)m(y)f(with)h(this)f
+(particular)g(do)s(cumen)m(t)i(is)f(that)h(I)f(w)m(an)m(t)i(to)f(sho)m
+(w)g(author-)150 2793 y(formatted)34 b(HTML)g(source,)h(and)e(that)h
+(is)f(not)g(easly)h(p)s(ossible,)e(unlik)m(e)g(using)g(the)i(L)3126
+2776 y Fr(A)3165 2793 y Fs(T)3216 2812 y(E)3266 2793
+y(X)g Fn(verbatim)150 2906 y Fs(en)m(vironmen)m(t)c(for)g(sho)m(wing)g
+(user-formatted)g(L)1797 2889 y Fr(A)1836 2906 y Fs(T)1887
+2925 y(E)1938 2906 y(X)g(source.)291 3019 y(The)g(problem)f(w)m(as)i
+(solv)m(ed)f(through)f(the)i(use)f(of)h(t)m(w)m(o)g(L)2236
+3002 y Fr(A)2275 3019 y Fs(T)2326 3038 y(E)2377 3019
+y(X)f(en)m(vironmen)m(ts.)40 b(The)30 b(\014rst)g(of)g(these)150
+3132 y(is)d Fh(latexonly)d Fs(whic)m(h)i(is)h(used)g(for)h(input)d
+(that)k(is)e(to)h(b)s(e)f(pro)s(cessed)g(normally)f(b)m(y)i(L)3031
+3115 y Fr(A)3070 3132 y Fs(T)3121 3151 y(E)3171 3132
+y(X)g(but)f(whic)m(h)g(is)150 3245 y(to)34 b(b)s(e)e(totally)h(ignored)
+g(b)m(y)g Fy(L)-7 b(TX2X)p Fs(.)33 b(The)g(other)g(en)m(vironmen)m(t)g
+(is)f Fh(htmlverbatim)c Fs(whic)m(h)k(is)g(used)g(for)150
+3357 y(input)26 b(that)j(is)f(to)h(b)s(e)e(totally)i(ignored)e(b)m(y)h
+(L)1663 3341 y Fr(A)1702 3357 y Fs(T)1753 3377 y(E)1804
+3357 y(X)g(but)g(whic)m(h)f(is)g(to)i(b)s(e)f(pro)s(cessed)f(b)m(y)i
+Fy(L)-7 b(TX2X)28 b Fs(in)m(to)g(an)150 3470 y(HTML)i
+Fn(<pre>)f Fs(en)m(vironmen)m(t.)291 3570 y(A)g(pac)m(k)-5
+b(age)30 b(\014le)e(has)h(b)s(een)e(written)h(whic)m(h)f(pro)m(vides)h
+(some)h(addtional)e(commands)i(and)f(en)m(viron-)150
+3670 y(men)m(ts.)150 3844 y Fh(\045)43 b(ltx2html.sty)82
+b(---)43 b(Some)f(useful)f(commands)f(and)i(environments)d(when)j
+(using)150 3944 y(\045)828 b(ltx2x)41 b(to)i(convert)e(from)h(LaTeX)f
+(to)i(HTML)f(tagging.)150 4043 y(\045)150 4143 y(\045)h(Author:)e
+(Peter)g(Wilson)172 b(August)41 b(1996)150 4242 y(\045)150
+4342 y(\\ProvidesPackage)o({lt)o(x2)o(ht)o(ml})o([1)o(996)o(/0)o(8/2)o
+(9)c(ltx2x)42 b(HTMLing])150 4442 y(\\RequirePackage{)o(htm)o(l})80
+b(\045)44 b(the)e(package)f(file)h(for)g(the)g(Perl)g(program)1196
+4541 y(\045)h(latex2html)150 4741 y(\045)g(The)g(document)d(title)h
+(for)i(the)f(WWW)g(browser.)150 4840 y(\045)h(If)g(used,)e(must)h(be)h
+(placed)e(in)i(the)f(preamble.)150 4940 y(\\newcommand{\\mlt)o(itl)o
+(e})o([1)o(]{})150 5139 y(\045)h(argument)d(is)j(for)g(processing)c(by)
+k(LaTeX)e(only)150 5239 y(\\providecommand{)o(\\la)o(te)o(x})o([1])o
+({#)o(1})1905 5531 y Fs(85)p eop
+%%Page: 86 90
+86 89 bop 150 672 a Fh(\045)43 b(argument)d(is)j(for)g(HTML)e
+(processing)f(only)150 772 y(\\providecommand{)o(\\ht)o(ml)o(}[)o(1]{)o
+(})150 971 y(\045)j(print)f(argument)e(as)j(an)f(SGML/HTML)e(start)i
+(tag)150 1071 y(\\newcommand{\\ST})o([1])o({\\)o(te)o(xtt)o(t{)o(<#1)o
+(>})o(})150 1270 y(\045)h(print)f(argument)e(as)j(an)f(SGML/HTML)e(end)
+j(tag)150 1370 y(\\newcommand{\\ET})o([1])o({\\)o(te)o(xtt)o(t{)o(</#)o
+(1>)o(}})150 1569 y(\045)g(print)f(HTML)g(special)e(characters)150
+1669 y(\\newcommand{\\Amp)o(}{\\)o(&})150 1768 y(\\newcommand{\\GT})o
+({\\t)o(ex)o(tt)o(t{>)o(}})150 1868 y(\\newcommand{\\LT})o({\\t)o(ex)o
+(tt)o(t{<)o(}})150 1968 y(\\newcommand{\\HAS)o(H}{)o(\\#)o(})150
+2167 y(\045)j(treat)f(contents)e(as)j(a)g(LaTeX)e(comment)g(but)150
+2267 y(\045)i(translate)d(contents)g(into)i(an)h(HTML)f("verbatim")d
+(environment)150 2366 y(\045)k(Use)g(as:)f(\\begin{htmlverba)o(ti)o(m})
+37 b(...)43 b(\\end{htmlverbat)o(im)o(})150 2466 y(\\excludecomment{)o
+(htm)o(lv)o(er)o(bat)o(im)o(})150 2665 y(\\endinput)291
+2828 y Fs(The)30 b(command)g(table)g(en)m(tries)h(for)f(some)h(of)f
+(these)h(are:)150 2990 y Fh(TYPE=)42 b(COMMAND)150 3090
+y(NAME=)g(\\Amp)237 3189 y(START_TAG=)e("&amp;")150 3289
+y(END_TYPE)150 3488 y(TYPE=)i(COMMAND)150 3588 y(NAME=)g(\\GT)237
+3688 y(START_TAG=)e("&gt;")150 3787 y(END_TYPE)150 3986
+y(TYPE=)i(COMMAND)150 4086 y(NAME=)g(\\LT)237 4186 y(START_TAG=)e
+("&lt;")150 4285 y(END_TYPE)150 4485 y(TYPE=)i(COMMAND)150
+4584 y(NAME=)g(\\HASH)237 4684 y(START_TAG=)e("&#035;")150
+4783 y(END_TYPE)150 4983 y(TYPE=)i(COMMAND)150 5082 y(NAME=)g(\\ST)237
+5182 y(START_TAG=)e("&lt;")237 5282 y(END_TAG=)g("&gt;")1905
+5531 y Fs(86)p eop
+%%Page: 87 91
+87 90 bop 237 573 a Fh(REQPARAMS=)40 b(1)150 672 y(END_TYPE)150
+872 y(TYPE=)i(COMMAND)150 971 y(NAME=)g(\\ET)237 1071
+y(START_TAG=)e("&lt;/")237 1171 y(END_TAG=)g("&gt;")237
+1270 y(REQPARAMS=)g(1)150 1370 y(END_TYPE)291 1557 y
+Fs(Finally)-8 b(,)32 b(as)h(an)g(example,)g(this)e(is)h(ho)m(w)h(some)g
+(of)g(the)g(prior)e(example)h(text)i(could)d(b)s(e)h(written)g(in)150
+1670 y(the)f(source)f(of)h(this)e(do)s(cumen)m(t.)150
+1858 y Fn(\\begin{latexonly})150 1971 y(\\begin{verbatim})150
+2084 y(<html>)150 2197 y(<head>)150 2310 y(<title>LaTeX)44
+b(to)k(X)f(translator</title>)150 2423 y(</head>)150
+2535 y(<body>)150 2761 y(<h1)g(align=center>)198 2874
+y(LTX2X:)f(A)h(LaTeX)g(to)g(X)g(Auto-tagger)150 2987
+y(</h1>)150 3100 y(...)150 3288 y(\\end{verbatim})150
+3401 y(\\end{latexonly})150 3701 y(\\begin{htmlverbatim})150
+3814 y(<html>)150 3927 y(<head>)150 4040 y(<title>LaTeX)d(to)k(X)f
+(translator\\ET{title})150 4153 y(\\ET{head})150 4266
+y(<body>)150 4491 y(<h1)g(align=center>)198 4604 y(LTX2X:)f(A)h(LaTeX)g
+(to)g(X)g(Auto-tagger)150 4717 y(\\ET{h1})150 4830 y(...)150
+4943 y(\\end{htmlverbatim})291 5131 y Fs(Reading)32 b(the)g(L)830
+5114 y Fr(A)869 5131 y Fs(T)920 5150 y(E)971 5131 y(X)g(source)h(of)f
+(this)g(do)s(cumen)m(t)g(will)d(rev)m(eal)k(some)g(other)g(details.)45
+b(Admittedly)150 5244 y(the)35 b(problem)f(w)m(as)i(comp)s(ounded)e(b)m
+(y)h(the)g(fact)i(that)e(this)g(do)s(cumen)m(t)g(con)m(tains)g
+(demonstrations)g(of)1905 5531 y(87)p eop
+%%Page: 88 92
+88 91 bop 150 573 a Fs(b)s(oth)26 b(L)385 556 y Fr(A)424
+573 y Fs(T)475 592 y(E)526 573 y(X)h(and)f(HTML)h(commands)g(whic)m(h)e
+(will)g(b)s(e)h(pro)s(cessed)h(through)f(b)s(oth)g(L)3067
+556 y Fr(A)3106 573 y Fs(T)3157 592 y(E)3207 573 y(X)i(and)e(HTML)150
+686 y(bro)m(wsers,)33 b(th)m(us)f(a)h(mo)s(dicum)e(of)i(care)g(is)f
+(required)f(to)i(appropriately)e(pro)s(cess)h(b)s(oth)g(sets)i(of)e(sp)
+s(ecial)150 799 y(c)m(haracters.)150 1085 y Fu(C)135
+b(Kno)l(wn)45 b(limitations)150 1288 y Fy(L)-7 b(TX2X)33
+b Fs(do)s(es)f(not)h(do)g(ev)m(erything)g(that)g(it)g(migh)m(t)f(\(and)
+h(probably)e(nev)m(er)i(will\).)46 b(The)32 b(follo)m(wing)g(are)150
+1401 y(some)f(of)f(the)h(things)e(that)i(it)f(do)s(es)g(not)h(do.)286
+1613 y Fm(\017)46 b Fs(It)28 b(do)s(es)g(not)g(understand)e(the)i(L)
+1486 1597 y Fr(A)1525 1613 y Fs(T)1576 1633 y(E)1627
+1613 y(X)g Fn(\\input)e Fs(or)i Fn(\\include)e Fs(commands)h(|)h(it)g
+(just)f(reads)h(the)377 1726 y(source)g(\014le)f(as)h(giv)m(en.)40
+b(It)28 b(ma)m(y)h(b)s(e)e(useful)f(to)j(pre-pro)s(cess)e(the)h(source)
+g(\014le)f(through)g(a)h(program)377 1839 y(that)j(will)d
+(automatically)i(incorp)s(orate)g(included)e(\014les)h(in)m(to)h(a)h(L)
+2632 1823 y Fr(A)2671 1839 y Fs(T)2722 1859 y(E)2772
+1839 y(X)g(ro)s(ot)g(\014le)e([13)q(].)286 2027 y Fm(\017)46
+b Fs(The)e Fn(\\newcommand)e Fs(and)i(friends)f(do)h(not)h(readily)e
+(\014t)i(in)m(to)f(the)h(command)g(patterns)f(that)377
+2140 y Fy(L)-7 b(TX2X)36 b Fs(can)h(deal)e(with.)57 b(In)35
+b(particular,)h(if)f(it)h(comes)h(across)g(a)f Fn(\\newcommand)d
+Fs(sp)s(eci\014cation)377 2253 y(for)26 b(a)h(command)f(that)h(is)e(sp)
+s(eci\014ed)g(in)g(the)h(command)g(table,)h(in)m(teresting)f(results)f
+(migh)m(t)h(o)s(ccur)377 2366 y(\(for)38 b(example,)h(all)d(the)h
+(follo)m(wing)f(output)h(could)f(b)s(e)h(thro)m(wn)g(a)m(w)m(a)m(y)i
+(if)d(the)h(command)g(tak)m(es)377 2479 y(an)m(y)31 b(argumen)m(ts\).)
+377 2616 y(F)-8 b(or)31 b(instance,)g(if)e(the)i(do)s(cumen)m(t)f(and)g
+(the)g(command)g(table)h(con)m(tain:)377 2827 y Fh(\\newcommand{\\lx}{)
+o(LT)o(X2X)o(})377 2927 y(....)377 3027 y(The)43 b(\\lx\\)f(program)e
+(...)377 3226 y(TYPE=)i(COMMAND)377 3325 y(NAME=)g(\\lx)464
+3425 y(START_TAG=)e("LTX2X")377 3525 y(END_TYPE)377 3736
+y Fs(then)32 b(there)h(is)e(usually)f(no)i(problem.)45
+b(On)31 b(the)i(other)f(hand,)g(if)f(the)i(do)s(cumen)m(t)f(and)g(the)g
+(com-)377 3836 y(mand)e(table)g(con)m(tain:)377 4048
+y Fh(\\newcommand{\\fd}[)o(1])o({\\t)o(ex)o(ttt)o({#)o(1})o(})377
+4147 y(....)377 4247 y(where)42 b(\\fd{InputFile})c(is)k(the)h(name)f
+(...)377 4446 y(TYPE=)g(COMMAND)377 4546 y(NAME=)g(\\fd)464
+4645 y(REQPARAMS=)e(1)377 4745 y(END_TYPE)377 4970 y
+Fs(then)30 b(there)g(ma)m(y)h(b)s(e)e(a)i(problem,)e(whic)m(h)f(migh)m
+(t)i(b)s(e)g(as)g(`minor')f(as)h Fy(L)-7 b(TX2X)30 b
+Fs(rep)s(orting)f(a)h(parse)377 5083 y(error)i(when)f(it)g(has)h(reac)m
+(hed)h Fn(\\newcommand{\\fd})27 b Fs(in)k(the)h(input)e(\014le)h(and)h
+(then)g(carrying)f(on,)377 5196 y(or)g(it)f(ma)m(y)h(b)s(e)e(more)i
+(serious.)1905 5531 y(88)p eop
+%%Page: 89 93
+89 92 bop 286 573 a Fm(\017)46 b Fs(There)26 b(is)f(a)i(sligh)m(t)e
+(problem)g(with)f(optional)i(argumen)m(ts.)39 b Fy(L)-7
+b(TX2X)26 b Fs(alw)m(a)m(ys)h(tak)m(es)h(the)e(\014rst)g(close)377
+686 y(brac)m(k)m(et)j(\()p Fn(])p Fs(\))e(after)h(the)f(op)s(ening)f
+(brac)m(k)m(et)j(as)e(signalling)d(the)k(end)e(of)h(the)h(argumen)m(t)f
+(text.)41 b(This)377 799 y(o)s(ccurs)e(ev)m(en)g(if)f(the)h(close)g
+(brac)m(k)m(et)h(is)e(enclosed)g(in)g(braces)h(\(i.e.)66
+b Fn({]})p Fs(\).)f(Op)s(ening)36 b(brac)m(k)m(ets)377
+912 y(within)28 b(optional)i(argumen)m(t)g(text)i(are)f(handled)d
+(correctly)-8 b(.)286 1099 y Fm(\017)46 b Fs(It)36 b(cannot)h(sensibly)
+c(handle)i(L)1455 1082 y Fr(A)1494 1099 y Fs(T)1545 1119
+y(E)1595 1099 y(X)h(constructs)h(of)f(the)g(form)f Fn({\\em)47
+b(emph)g(text})p Fs(.)56 b(That)36 b(is,)377 1212 y(except)30
+b(for)f(command)g(argumen)m(ts,)h(it)e(do)s(es)h(not)g(recognize)h
+Fn({...})e Fs(as)h(a)h(grouping)d(construct,)377 1325
+y(so)37 b(cannot)h(successfully)c(tag)k(the)f(end)g(of)f(the)h
+Fn(emph)47 b(text)36 b Fs(in)f(the)i(example.)60 b(On)36
+b(the)h(other)377 1438 y(hand,)45 b(if)d(constructs)h(lik)m(e)f
+Fn(\\emph{emph)j(text})c Fs(or)h Fn(\\begin{em}emph)i(text\\end{em})c
+Fs(are)377 1551 y(used)28 b(instead,)h(start)g(and)f(end)g(tags)h(can)g
+(b)s(e)f(generated,)j(giv)m(en)d(appropriate)g(sp)s(eci\014cations)f
+(in)377 1664 y(the)k(command)f(table.)286 1851 y Fm(\017)46
+b Fs(It)27 b(assumes)g(that)g(all)f(commands)h(that)g(tak)m(e)h
+(argumen)m(ts)g(are)f(written)f(so)h(that)g(eac)m(h)h(argumen)m(t)377
+1964 y(is)g(enclosed)h(in)f(braces.)40 b(F)-8 b(or)30
+b(example,)f(the)h(sup)s(erscripting)25 b(command)k(should)e(b)s(e)i
+(written)f(as)377 2077 y Fn(^{2})33 b Fs(and)g(not)h(as)g
+Fn(^2)p Fs(.)50 b(Similarly)-8 b(,)32 b(accen)m(t)k(commands)d(should)f
+(b)s(e)h(written)g(as)h Fn(\\={o})e Fs(rather)377 2190
+y(than)e Fn(\\=o)p Fs(,)g(and)g(so)h(on.)286 2364 y Fm(\017)46
+b Fs(There)22 b(has)g(not)g(b)s(een)g(time)f(to)i(test)g(all)e(asp)s
+(ects)i(of)f(the)h Fo(Express-A)e Fs(in)m(terpreter.)37
+b(It)22 b(is)f(p)s(ossible)377 2464 y(that)28 b(this)d(ma)m(y)j(not)f
+(p)s(erform)e(quite)i(as)g(adv)m(ertised.)39 b(In)26
+b(particular)f(dynamic)h(aggregates)k(ha)m(v)m(e)377
+2564 y(not)h(b)s(een)f(fully)e(implemen)m(ted.)39 b(F)-8
+b(or)31 b(example:)377 2775 y Fh(LIST)42 b(OF)h(INTEGER;)377
+2987 y Fs(app)s(ears)h(to)h(b)s(e)e(handled)g(correctly)-8
+b(.)83 b(More)45 b(complicated)f(constructs)g(in)m(v)m(olving)f
+(dynamic)377 3087 y(aggregates,)34 b(suc)m(h)c(as)377
+3298 y Fh(ARRAY)42 b([1:7])f(OF)i(LIST)f(OF)h(ARRAY)e([-21:21])g(OF)h
+(INTEGER;)377 3523 y Fs(ha)m(v)m(e)31 b(not)e(b)s(een)g(tested.)41
+b(It)30 b(is)e(improbable)f(that)j Fh(BAG)e Fs(will)e(w)m(ork;)31
+b(the)e(status)h(of)36 b Fh(SET)28 b Fs(is)h(similar)377
+3636 y(and)h(additionally)e(the)i(uniqueness)e(test)j(for)g(set)g(mem)m
+(b)s(ership)c(has)k(not)f(b)s(een)g(implemen)m(ted.)286
+3824 y Fm(\017)46 b Fs(No)32 b(doubt)e(other)i(limitations)d(will)f
+(come)k(to)g(ligh)m(t)e(as)i Fy(L)-7 b(TX2X)31 b Fs(gets)h(more)f(use.)
+43 b(On)30 b(the)i(other)377 3937 y(hand,)h Fy(L)-7 b(TX2X)33
+b Fs(has)g(b)s(een)f(able)h(to)g(handle)f(a)h(broader)g(range)g(of)g
+(cases)h(than)f(it)g(w)m(as)g(designed)377 4050 y(to)e(address.)150
+4336 y Fu(D)135 b(Command)45 b(table)h(summary)150 4539
+y Fs(This)24 b(section)h(summarizes)f(the)i(commands)f(and)f(sp)s
+(eci\014cations)g(a)m(v)-5 b(ailable)25 b(for)g(de\014ning)e(a)j
+(command)150 4652 y(table.)150 4896 y Fj(D.1)112 b(Sp)s(ecial)37
+b(prin)m(t)f(c)m(haracters)150 5067 y Fs(The)22 b(com)m(bination)g(of)h
+(an)g(escap)s(e)g(c)m(haracter)h(and)e(another)h(c)m(haracter)h(can)f
+(b)s(e)f(used)g(to)i(sp)s(ecify)d(certain)150 5180 y(non-visible)28
+b(c)m(haracters)j(within)d(a)j(tag)h(string.)39 b(The)30
+b(commands)g(are)h(giv)m(en)f(in)f(T)-8 b(able)30 b(5.)1905
+5531 y(89)p eop
+%%Page: 90 94
+90 93 bop 1081 628 a Fs(T)-8 b(able)30 b(5:)41 b(Sp)s(ecial)28
+b(prin)m(t)h(c)m(haracter)j(commands.)p 1258 657 1385
+4 v 1256 770 4 113 v 1308 736 a(Command)p 2247 770 V
+580 w(Default)p 2641 770 V 1258 773 1385 4 v 1256 886
+4 113 v 1308 852 a Fh(AUDIBLE)p 1621 852 27 4 v 28 w(ALERT)p
+1869 852 V 29 w(CHAR=)p 2247 886 4 113 v 308 w Fn(a)p
+2641 886 V 1256 999 V 1308 965 a Fh(BACKSPACE)p 1709
+965 27 4 v 27 w(CHAR=)p 2247 999 4 113 v 470 w Fn(b)p
+2641 999 V 1256 1112 V 1308 1078 a Fh(CARRIAGE)p 1665
+1078 27 4 v 28 w(RETURN)p 1957 1078 V 29 w(CHAR=)p 2247
+1112 4 113 v 220 w Fn(r)p 2641 1112 V 1256 1225 V 1308
+1191 a Fh(ESCAPE)p 1577 1191 27 4 v 29 w(CHAR=)p 2247
+1225 4 113 v 600 w Fn(\\)p 2641 1225 V 1256 1338 V 1308
+1304 a Fh(FORMFEED)p 1665 1304 27 4 v 28 w(CHAR=)p 2247
+1338 4 113 v 513 w Fn(f)p 2641 1338 V 1256 1451 V 1308
+1417 a Fh(HEX)p 1445 1417 27 4 v 30 w(CHAR=)p 2247 1451
+4 113 v 731 w Fn(x)p 2641 1451 V 1256 1564 V 1308 1530
+a Fh(HORIZONTAL)p 1753 1530 27 4 v 27 w(TAB)p 1912 1530
+V 30 w(CHAR=)p 2247 1564 4 113 v 264 w Fn(t)p 2641 1564
+V 1256 1676 V 1308 1643 a Fh(NEWLINE)p 1621 1643 27 4
+v 28 w(CHAR=)p 2247 1676 4 113 v 557 w Fn(n)p 2641 1676
+V 1256 1789 V 1308 1756 a Fh(VERTICAL)p 1665 1756 27
+4 v 28 w(TAB)p 1825 1756 V 30 w(CHAR=)p 2247 1789 4 113
+v 351 w Fn(v)p 2641 1789 V 1258 1793 1385 4 v 291 2042
+a Fs(These)e(commands)g(tak)m(e)i(one)e(c)m(haracter)i(as)f(their)e(v)
+-5 b(alue.)40 b(If)30 b(an)m(y)g(commands)g(are)h(not)f(sp)s
+(eci\014ed,)150 2155 y(then)42 b(the)g(default)f(v)-5
+b(alue)41 b(is)g(used.)74 b(These)42 b(commands,)i(if)d(used,)j(m)m
+(ust)e(b)s(e)f(at)i(the)f(b)s(eginning)d(of)150 2268
+y(the)32 b(command)g(table)g(b)s(efore)g(an)m(y)i Fh(TYPE=)c
+Fs(commands,)j(although)e(their)g(ordering)g(is)h(not)g(signi\014can)m
+(t)150 2381 y(among)f(themselv)m(es.)150 2622 y Fj(D.2)112
+b Fd(Express-A)36 b Fj(co)s(de)h(initialization)150 2794
+y Fs(The)30 b(k)m(eyw)m(ord)h Fh(CODE)p 877 2794 27 4
+v 29 w(SETUP=)d Fs(indicates)i(that)h(the)f(follo)m(wing)f(part)h(of)h
+(the)g(command)f(table,)g(up)g(un)m(til)150 2907 y(the)j
+Fh(END)p 446 2907 V 30 w(CODE)e Fs(k)m(eyw)m(ord,)j(con)m(tains)f
+Fo(Express-A)f Fs(co)s(de)h(declarations)f(and/or)h(statemen)m(ts.)49
+b(If)32 b(used,)150 3020 y(this)d(blo)s(c)m(k)h(m)m(ust)g(come)i(b)s
+(efore)e(an)m(y)g(of)h(the)g Fh(TYPE=)d Fs(commands.)150
+3261 y Fj(D.3)112 b(Commen)m(ts)36 b(and)j(\014le)e(inclusion)150
+3433 y Fs(A)30 b(commen)m(t)i(within)c(a)i(command)h(table)f(\014le)f
+(is)h(an)m(y)g(line)f(starting)h(with)f Fh(C=)43 b Fs(.)291
+3546 y(A)31 b(\014le)e(can)i(b)s(e)e(included)f(within)g(another)j
+(command)f(table)g(\014le)f(with)g(the)i(command)f(line)150
+3723 y Fn(INCLUDE=)46 b(FileName)150 3901 y Fs(where)41
+b Fh(FileName)d Fs(is)j(the)h(name)f(of)h(the)g(\014le)f(to)h(b)s(e)f
+(included.)72 b(The)41 b Fh(INCLUDE=)d Fs(command)j(cannot)150
+4013 y(app)s(ear)30 b(b)s(et)m(w)m(een)h(the)f(command)g(pair)g
+Fh(TYPE=)e Fs(and)i(its)f(follo)m(wing)h Fh(END)p 2633
+4013 V 31 w(TYPE)p Fs(.)291 4126 y(The)j(end)f(of)i(a)f(command)g
+(table)g(\014le)g(is)f(either)h(the)g(ph)m(ysical)f(end)g(of)i(the)f
+(\014le)g(or)g(the)g(command)150 4239 y Fh(END)p 287
+4239 V 30 w(CTFILE=)p Fs(,)28 b(whic)m(hev)m(er)i(o)s(ccurs)g(\014rst.)
+150 4481 y Fj(D.4)112 b(Command)37 b(t)m(yp)s(es)150
+4652 y Fs(All)29 b(command)h(t)m(yp)s(e)h(sp)s(eci\014cations)e(ha)m(v)
+m(e)i(the)g(general)f(form:)150 4830 y Fn(TYPE=)46 b(CommandType)150
+4943 y(NAME=)g(CommandName)293 5056 y(C=)h(a)h(possibly)d(empty)i(list)
+f(of)i(mode-independent)43 b(commands)293 5169 y(C=)k(possibly)f(sets)h
+(of)g(mode-dependent)d(commands)150 5282 y(END_TYPE)1905
+5531 y Fs(90)p eop
+%%Page: 91 95
+91 94 bop 150 573 a Fs(where)48 b Fh(CommandType)43 b
+Fs(is)k(a)i(k)m(eyw)m(ord)f(iden)m(tifying)e(the)i(kind)e(of)j(command)
+f(b)s(eing)e(sp)s(eci\014ed)h(and)150 686 y Fh(CommandName)36
+b Fs(is)j(the)i(iden)m(ti\014er)d(of)i(a)h(L)1552 669
+y Fr(A)1591 686 y Fs(T)1642 705 y(E)1692 686 y(X)g(command)f(or)g(en)m
+(vironmen)m(t.)70 b(The)40 b(p)s(oten)m(tial)g(set)h(of)150
+799 y(commands)d(that)h(can)f(b)s(e)g(used)f(b)s(et)m(w)m(een)i(the)f
+Fh(TYPE=)e Fs(and)i Fh(END)p 2435 799 27 4 v 30 w(TYPE)f
+Fs(commands)g(dep)s(ends)g(on)h(the)150 912 y(kind)31
+b(of)h(command)g(b)s(eing)f(sp)s(eci\014ed,)g(but)h(the)h(sp)s(ecial)d
+(prin)m(t)h(c)m(haracter)j(commands,)f(T)-8 b(able)32
+b(5,)i(and)150 1024 y(the)d Fh(INCLUDE=)d Fs(command)j(cannot)h(app)s
+(ear)e(within)f(a)i(t)m(yp)s(e)h(sp)s(eci\014cation.)42
+b(All)29 b(command)i(sp)s(eci\014ca-)150 1137 y(tions,)k(except)h(for)e
+(the)h(built)d(in)h(command)i(t)m(yp)s(es)f(\(see)i(T)-8
+b(able)34 b(6\),)i(m)m(ust)f(include)d(at)j(least)g(a)g
+Fh(NAME=)150 1250 y Fs(command.)58 b(The)35 b(ordering)g(of)i(commands)
+e(within)f(a)j(t)m(yp)s(e)f(sp)s(eci\014cation)f(is)g(not)h
+(signi\014can)m(t.)57 b(The)150 1363 y(ordering)29 b(of)i(t)m(yp)s(e)f
+(sp)s(eci\014cations)f(within)f(a)j(command)f(table)g(\014le)g(is)f
+(not)i(signi\014can)m(t.)291 1476 y(The)g Fh(NAME=)f
+Fs(command)h(tak)m(es)j(as)e(its)f(v)-5 b(alue)31 b(the)h(name)g(of)g
+(a)g(L)2464 1459 y Fr(A)2503 1476 y Fs(T)2554 1496 y(E)2604
+1476 y(X)g(command)f(or)h(en)m(vironmen)m(t.)150 1589
+y(The)41 b(name)h(m)m(ust)f(b)s(e)g(written)g(exactly)i(as)e(it)h(w)m
+(ould)e(app)s(ear)h(in)f(a)j(L)2670 1572 y Fr(A)2709
+1589 y Fs(T)2760 1609 y(E)2810 1589 y(X)f(source)f(\014le.)74
+b(That)42 b(is,)150 1702 y Fn(\\command)35 b Fs(for)i(an)m(y)h(command)
+f(except)h Fn(\\begin{})d Fs(or)j Fn(\\end{})p Fs(,)f(and)g(as)h
+Fn(env)e Fs(for)h(an)g(en)m(vironmen)m(t)150 1815 y(b)s(egun)29
+b(as)i Fn(\\begin{env})c Fs(or)j(ended)g(b)m(y)g Fn(\\end{env})p
+Fs(.)150 2048 y Ft(D.4.1)105 b(Built)35 b(in)g(command)f(t)m(yp)s(es)
+150 2220 y Fs(T)-8 b(able)30 b(6)h(lists)e(the)h(k)m(eyw)m(ords)h(for)f
+(the)h(built)d(in)h(command)h(t)m(yp)s(es.)1097 2468
+y(T)-8 b(able)30 b(6:)41 b(Built)29 b(in)g(command)h(t)m(yp)s(e)h(k)m
+(eyw)m(ords.)p 585 2498 2731 4 v 583 2611 4 113 v 635
+2577 a(Keyw)m(ord)p 1281 2611 V 986 w(L)1999 2560 y Fr(A)2038
+2577 y Fs(T)2089 2596 y(E)2140 2577 y(X)f(command)p 3314
+2611 V 585 2614 2731 4 v 583 2727 4 113 v 635 2693 a
+Fh(BEGIN)p 860 2693 27 4 v 29 w(DOCUMENT)p 1281 2727
+4 113 v 681 w Fn(\\begin{document})p 3314 2727 V 583
+2840 V 635 2806 a Fh(BEGIN)p 860 2806 27 4 v 29 w(DOLLAR)p
+1281 2840 4 113 v 644 w Fn($)g Fs(at)h(start)g(of)g(in-text)f(math)p
+3314 2840 V 583 2953 V 635 2919 a Fh(BEGIN)p 860 2919
+27 4 v 29 w(VERB)p 1281 2953 4 113 v 363 w Fn(\\verb)f
+Fs(or)i Fn(\\verb*)d Fs(and)i(its)g(follo)m(wing)f(c)m(haracter)p
+3314 2953 V 583 3066 V 635 3032 a Fh(BEGIN)p 860 3032
+27 4 v 29 w(VERBATIM)p 1281 3066 4 113 v 204 w Fn(\\begin{verbatim})d
+Fs(or)31 b Fn(\\begin{verbatim*})p 3314 3066 V 583 3179
+V 635 3145 a Fh(END)p 772 3145 27 4 v 30 w(DOCUMENT)p
+1281 3179 4 113 v 816 w Fn(\\end{document})p 3314 3179
+V 583 3291 V 635 3258 a Fh(END)p 772 3258 27 4 v 30 w(DOLLAR)p
+1281 3291 4 113 v 754 w Fn($)f Fs(at)h(end)f(of)h(in-text)f(math)p
+3314 3291 V 583 3404 V 635 3370 a Fh(END)p 772 3370 27
+4 v 30 w(VERB)p 1281 3404 4 113 v 500 w Fs(the)g(ending)f(c)m(haracter)
+j(for)e Fn(\\verb)f Fs(or)i Fn(\\verb*)p 3314 3404 V
+583 3517 V 635 3483 a Fh(END)p 772 3483 27 4 v 30 w(VERBATIM)p
+1281 3517 4 113 v 387 w Fn(\\end{verbatim})26 b Fs(or)31
+b Fn(\\end{verbatim*})p 3314 3517 V 583 3630 V 635 3596
+a Fh(LBRACE)p 1281 3630 V 1376 w Fn({)p 3314 3630 V 583
+3743 V 635 3709 a Fh(OTHER)p 860 3709 27 4 v 29 w(BEGIN)p
+1281 3743 4 113 v 228 w Fs(of)g(the)f(form)g Fn(\\begin{env})e
+Fs(not)i(sp)s(eci\014ed)f(elsewhere)p 3314 3743 V 583
+3856 V 635 3822 a Fh(OTHER)p 860 3822 27 4 v 29 w(COMMAND)p
+1281 3856 4 113 v 283 w Fs(of)i(the)g(form)e Fn(\\comm)g
+Fs(not)i(sp)s(eci\014ed)e(elsewhere)p 3314 3856 V 583
+3969 V 635 3935 a Fh(OTHER)p 860 3935 27 4 v 29 w(END)p
+1281 3969 4 113 v 364 w Fs(of)i(the)f(form)g Fn(\\end{env})e
+Fs(not)i(sp)s(eci\014ed)f(elsewhere)p 3314 3969 V 583
+4082 V 635 4048 a Fh(PARAGRAPH)p 1281 4082 V 933 w Fs(blank)g(source)h
+(line)p 3314 4082 V 583 4195 V 635 4161 a Fh(RBRACE)p
+1281 4195 V 1376 w Fn(})p 3314 4195 V 583 4308 V 635
+4274 a Fh(SLASH)p 860 4274 27 4 v 29 w(SPACE)p 1281 4308
+4 113 v 1147 w Fn(\\ )p 3314 4308 V 585 4311 2731 4 v
+291 4491 a Fs(The)39 b(built)e(in)h(command)h(t)m(yp)s(e)h(sp)s
+(eci\014cations)e(can)i(only)e(sensibly)f(use)i(t)m(w)m(o)i(kinds)c(of)
+j(actions)150 4604 y(|)32 b(those)g(sp)s(eci\014ed)e(at)j(the)f(start)g
+(of)g(the)g(command)g(\(e.g.,)i Fh(PC)p 2371 4604 27
+4 v 30 w(AT)p 2489 4604 V 31 w(START=)29 b Fs(and)i Fh(START)p
+3211 4604 V 30 w(TAG=)p Fs(\))f(and/or)150 4717 y(actions)38
+b(at)h(the)g(end)e(of)i(the)f(command)g(\(e.g.,)k Fh(PC)p
+1957 4717 V 31 w(AT)p 2076 4717 V 30 w(END)37 b Fs(and)h
+Fh(END)p 2592 4717 V 30 w(TAG=)p Fs(\).)62 b(The)38 b
+Fh(NAME=)e Fs(command)150 4830 y(m)m(ust)30 b(not)h(b)s(e)f(used.)291
+4943 y(The)f Fh(OTHER)p 702 4943 V 59 w Fs(t)m(yp)s(es)h(are)g(an)f
+(exception)h(to)h(the)e(ab)s(o)m(v)m(e,)j(in)c(that)i(they)g(can)g
+(include)d(the)j(command)150 5056 y(line)f Fh(PRINT)p
+547 5056 V 29 w(CONTROL=)40 b(NO)p 1056 5056 V 31 w(PRINT)p
+Fs(.)291 5169 y Fy(L)-7 b(TX2X)37 b Fs(c)m(hec)m(ks)i(the)f(command)f
+(table)g(for)g(the)h(presence)f(of)g(these)h(required)e(t)m(yp)s(es.)61
+b(If)37 b(one)h(or)150 5282 y(more)24 b(ha)m(v)m(e)g(not)g(b)s(een)f
+(sp)s(eci\014ed,)g(then)g(they)h(are)g(automatically)f(added)g(to)h
+(the)g(command)f(table)g(with)1905 5531 y(91)p eop
+%%Page: 92 96
+92 95 bop 150 573 a Fs(default)35 b(v)-5 b(alues)36 b(\(e.g.)60
+b(empt)m(y)36 b(strings\))g(for)g(the)g(tags,)j(and)d(a)h(w)m(arning)e
+(message)i(is)e(prin)m(ted)g(giving)150 686 y(the)c(default)e(v)-5
+b(alue\(s\).)150 926 y Ft(D.4.2)105 b(Optional)35 b(command)f(t)m(yp)s
+(es)150 1098 y Fs(F)-8 b(or)31 b(discussion)c(purp)s(oses,)h(the)i
+(optional)f(command)h(t)m(yp)s(es)g(ha)m(v)m(e)h(b)s(een)e(tabulated)h
+(in)e(di\013eren)m(t)h(cat-)150 1210 y(egories.)61 b(The)37
+b(basic)f(distinction)f(b)s(et)m(w)m(een)i(these)h(categories)g(is)e
+(the)i(sets)f(of)g(commands)g(that)h(are)150 1323 y(p)s(ermissible)26
+b(within)i(the)j(command)f(sp)s(eci\014cation.)291 1436
+y(A)m(t)45 b(a)e(minim)m(um,)i(all)d(the)i(sp)s(eci\014cations)e(m)m
+(ust)h(include)e(a)j Fh(NAME=)d Fs(command)j(and)e(m)m(ust)i(not)150
+1549 y(con)m(tain)25 b(an)m(y)g Fh(PRINT)p 856 1549 27
+4 v 30 w(CONTROL=)20 b Fs(or)25 b Fh(INCLUDE=)20 b Fs(commands)k(or)g
+(the)h(sp)s(ecial)e(prin)m(t)g(c)m(haracter)i(commands)150
+1662 y(listed)k(in)g(T)-8 b(able)30 b(5.)291 1775 y(The)g(k)m(eyw)m
+(ords)h(for)f(the)g(general)h(command)f(t)m(yp)s(es)g(are)h(giv)m(en)f
+(T)-8 b(able)30 b(7.)1096 2038 y(T)-8 b(able)30 b(7:)41
+b(General)30 b(command)g(t)m(yp)s(e)h(k)m(eyw)m(ords.)p
+545 2068 2811 4 v 543 2181 4 113 v 594 2147 a(Keyw)m(ord)p
+1153 2181 V 876 w(L)1848 2130 y Fr(A)1887 2147 y Fs(T)1938
+2166 y(E)1989 2147 y(X)f(command)g(form)p 3354 2181 V
+545 2184 2811 4 v 543 2297 4 113 v 594 2263 a Fh(TEX)p
+731 2263 27 4 v 31 w(CHAR)p 1153 2297 4 113 v 529 w Fs(L)1486
+2246 y Fr(A)1525 2263 y Fs(T)1576 2283 y(E)1626 2263
+y(X)h(sp)s(ecial)e(c)m(haracters)j(\(except)f Fn({)48
+b(})f($)p Fs(\))p 3354 2297 V 543 2410 V 594 2376 a Fh(CHAR)p
+775 2376 27 4 v 30 w(COMMAND)p 1153 2410 4 113 v 561
+w Fn(\\c)p Fs(,)30 b(where)g Fn(c)g Fs(is)g(non-alphab)s(etic)p
+3354 2410 V 543 2523 V 594 2489 a Fh(COMMAND)p 1153 2523
+V 303 w Fn(\\command)e Fs(except)j(for)f(sectioning)g(or)h(picture)e
+(commands)p 3354 2523 V 543 2636 V 594 2602 a Fh(BEGIN)p
+819 2602 27 4 v 30 w(ENV)p 1153 2636 4 113 v 576 w Fn(\\begin{env})e
+Fs(except)32 b(for)e Fn(\\item)f Fs(lists)p 3354 2636
+V 543 2748 V 594 2715 a Fh(END)p 731 2715 27 4 v 31 w(ENV)p
+1153 2748 4 113 v 711 w Fn(\\end{env})f Fs(except)j(for)f
+Fn(\\item)f Fs(lists)p 3354 2748 V 543 2861 V 594 2828
+a Fh(VCOMMAND)p 1153 2861 V 862 w Fs(a)h Fn(\\verb)p
+Fs(-lik)m(e)f(command)p 3354 2861 V 543 2974 V 594 2940
+a Fh(BEGIN)p 819 2940 27 4 v 30 w(VENV)p 1153 2974 4
+113 v 501 w Fs(start)i(of)f(a)h Fn(verbatim)p Fs(-lik)m(e)d(en)m
+(vironmen)m(t)p 3354 2974 V 543 3087 V 594 3053 a Fh(END)p
+731 3053 27 4 v 31 w(VENV)p 1153 3087 4 113 v 611 w Fs(end)i(of)g(a)h
+Fn(verbatim)p Fs(-lik)m(e)d(en)m(vironmen)m(t)p 3354
+3087 V 545 3091 2811 4 v 291 3285 a(A)k(general)g(command)g(t)m(yp)s(e)
+g(sp)s(eci\014cation)f(can)h(include)e(an)m(y)i(of)g(the)h(tagging)f
+(and)g(prin)m(t)e(option)150 3398 y(commands.)44 b(They)32
+b(cannot)g(con)m(tain)g(a)g Fh(SECTION)p 1887 3398 27
+4 v 28 w(LEVEL=)e Fs(command,)i(nor)f(can)h(they)g(con)m(tain)g(an)m(y)
+g(of)150 3511 y(the)p 312 3511 V 62 w Fh(ITEM)p 519 3511
+V 60 w Fs(commands.)291 3624 y(The)e(k)m(eyw)m(ords)h(for)f(the)g(sp)s
+(eci\014c)g(command)g(t)m(yp)s(es)g(are)h(giv)m(en)f(in)f(T)-8
+b(able)30 b(8.)291 3737 y(A)41 b Fh(BEGIN)p 625 3737
+V 29 w(LIST)p 830 3737 V 30 w(ENV)e Fs(sp)s(eci\014cation)g(should)g
+(include)f(at)j(least)g(a)g Fh(START)p 2831 3737 V 29
+w(ITEM=)e Fs(command.)70 b(The)150 3850 y(other)p 405
+3850 V 75 w Fh(ITEM)p 613 3850 V 72 w Fs(commands)43
+b(are)g(optional.)77 b(Other)43 b(commands)f(follo)m(w)h(the)g(rules)e
+(for)i(the)g(general)150 3963 y(command)30 b(t)m(yp)s(es.)291
+4076 y(The)35 b(p)s(oten)m(tial)g(commands)g(for)h(the)p
+1639 4076 V 67 w Fh(PICTURE)p 1978 4076 V 64 w Fs(commands)f(are)h(the)
+g(same)g(as)g(for)f(the)h(general)150 4189 y(commands,)28
+b(with)f(the)h(exception)g(that)h(commands)e(related)h(to)g(optional)g
+(argumen)m(t)g(pro)s(cessing)f(are)150 4302 y(not)k(a)m(v)-5
+b(ailable)29 b(for)h(use.)291 4415 y(A)21 b Fh(SECTIONING)16
+b Fs(command)k(sp)s(eci\014cation)f(m)m(ust)h(include)e(a)j
+Fh(SECTIONING)p 2777 4415 V 27 w(LEVEL=)c Fs(command.)38
+b(Other)150 4527 y(commands)30 b(follo)m(w)g(the)g(rules)f(for)h(the)h
+(general)f(command)g(t)m(yp)s(es.)291 4640 y(The)g(k)m(eyw)m(ords)h
+(for)f(the)g(sp)s(ecial)f(command)i(t)m(yp)s(es)f(are)h(giv)m(en)f(in)f
+(T)-8 b(able)30 b(9.)291 4753 y(Apart)41 b(from)e(the)i(general)f
+(restrictions)f(on)i(the)f(allo)m(w)m(ed)g(commands)g(within)e(a)j(sp)s
+(eci\014cation,)150 4866 y(there)31 b(are)g(no)f(restrictions)g(on)g
+(the)h(commands)f(that)i(can)f(b)s(e)f(included)d(within)i(the)h(sp)s
+(eci\014cation)g(of)150 4979 y(a)k Fh(SPECIAL)p 542 4979
+V 62 w Fs(command.)51 b(It)34 b(is)f(up)g(to)h(the)g(creator)h(of)f
+(the)g(sp)s(ecial)e(to)j(decide)e(what)h(is)f(appropriate.)150
+5092 y(Ho)m(w)m(ev)m(er,)g(eac)m(h)e Fh(SPECIAL)p 1059
+5092 V 59 w Fs(sp)s(eci\014cation)e(m)m(ust)h(include)f(the)h(command)
+150 5280 y Fn(SPECIAL_TOKEN=)44 b(N)1905 5531 y Fs(92)p
+eop
+%%Page: 93 97
+93 96 bop 1100 930 a Fs(T)-8 b(able)30 b(8:)41 b(Sp)s(eci\014c)29
+b(command)h(t)m(yp)s(e)g(k)m(eyw)m(ords.)p 854 959 2192
+4 v 852 1072 4 113 v 904 1038 a(Keyw)m(ord)p 1625 1072
+V 648 w(L)1930 1021 y Fr(A)1969 1038 y Fs(T)2020 1058
+y(E)2070 1038 y(X)g(command)g(form)p 3044 1072 V 854
+1075 2192 4 v 852 1188 4 113 v 904 1154 a Fh(BEGIN)p
+1129 1154 27 4 v 29 w(LIST)p 1334 1154 V 30 w(ENV)p 1625
+1188 4 113 v 285 w Fn(\\begin{env})d Fs(for)j Fn(\\item)f
+Fs(lists)p 3044 1188 V 852 1301 V 904 1267 a Fh(BEGIN)p
+1129 1267 27 4 v 29 w(PICTURE)p 1466 1267 V 29 w(CC)p
+1625 1301 4 113 v 400 w Fn(\\begin{pic}\(\)\(\))p 3044
+1301 V 852 1414 V 904 1380 a Fh(END)p 1041 1380 27 4
+v 30 w(LIST)p 1247 1380 V 30 w(ENV)p 1625 1414 4 113
+v 420 w Fn(\\end{env})e Fs(for)k Fn(\\item)d Fs(lists)p
+3044 1414 V 852 1527 V 904 1493 a Fh(END)p 1041 1493
+27 4 v 30 w(PICTURE)p 1625 1527 4 113 v 748 w Fn(\\end{pic})p
+3044 1527 V 852 1640 V 904 1606 a Fh(PICTURE)p 1217 1606
+27 4 v 28 w(CCPP)p 1625 1640 4 113 v 634 w Fn(\\pic\(\)\(\){}{})p
+3044 1640 V 852 1753 V 904 1719 a Fh(PICTURE)p 1217 1719
+27 4 v 28 w(CO)p 1625 1753 4 113 v 817 w Fn(\\pic\(\)[])p
+3044 1753 V 852 1866 V 904 1832 a Fh(PICTURE)p 1217 1832
+27 4 v 28 w(COP)p 1625 1866 4 113 v 726 w Fn(\\pic\(\)[]{})p
+3044 1866 V 852 1978 V 904 1945 a Fh(PICTURE)p 1217 1945
+27 4 v 28 w(CP)p 1625 1978 4 113 v 817 w Fn(\\pic\(\){})p
+3044 1978 V 852 2091 V 904 2058 a Fh(PICTURE)p 1217 2058
+27 4 v 28 w(OCC)p 1625 2091 4 113 v 726 w Fn(\\pic[]\(\)\(\))p
+3044 2091 V 852 2204 V 904 2170 a Fh(PICTURE)p 1217 2170
+27 4 v 28 w(OCCC)p 1625 2204 4 113 v 634 w Fn(\\pic[]\(\)\(\)\(\))p
+3044 2204 V 852 2317 V 904 2283 a Fh(PICTURE)p 1217 2283
+27 4 v 28 w(OCO)p 1625 2317 4 113 v 726 w Fn(\\pic[]\(\)[])p
+3044 2317 V 852 2430 V 904 2396 a Fh(PICTURE)p 1217 2396
+27 4 v 28 w(PCOP)p 1625 2430 4 113 v 634 w Fn(\\pic{}\(\)[]{})p
+3044 2430 V 852 2543 V 904 2509 a Fh(SECTIONING)p 1625
+2543 V 333 w Fn(\\command)g Fs(for)i(a)h(do)s(cumen)m(t)f(section)p
+3044 2543 V 852 2656 V 904 2622 a Fh(COMMAND)p 1217 2622
+27 4 v 28 w(OOP)p 1625 2656 4 113 v 726 w Fn(\\com[][]{})p
+3044 2656 V 852 2769 V 904 2735 a Fh(COMMAND)p 1217 2735
+27 4 v 28 w(OOOPP)p 1625 2769 4 113 v 542 w Fn(\\com[][][]{}{})p
+3044 2769 V 852 2882 V 904 2848 a Fh(COMMAND)p 1217 2848
+27 4 v 28 w(OPO)p 1625 2882 4 113 v 726 w Fn(\\com[]{}[])p
+3044 2882 V 852 2995 V 904 2961 a Fh(COMMAND)p 1217 2961
+27 4 v 28 w(POOOP)p 1625 2995 4 113 v 542 w Fn(\\com{}[][][]{})p
+3044 2995 V 852 3108 V 904 3074 a Fh(COMMAND)p 1217 3074
+27 4 v 28 w(POOP)p 1625 3108 4 113 v 634 w Fn(\\com{}[][]{})p
+3044 3108 V 852 3220 V 904 3187 a Fh(COMMAND)p 1217 3187
+27 4 v 28 w(POOPP)p 1625 3220 4 113 v 542 w Fn(\\com{}[][]{}{})p
+3044 3220 V 854 3224 2192 4 v 1110 4040 a Fs(T)-8 b(able)30
+b(9:)41 b(Sp)s(ecial)29 b(command)h(t)m(yp)s(e)g(k)m(eyw)m(ords.)p
+761 4070 2378 4 v 759 4183 4 113 v 811 4149 a(Keyw)m(ord)p
+1631 4183 V 790 w(L)1979 4132 y Fr(A)2018 4149 y Fs(T)2069
+4168 y(E)2120 4149 y(X)g(command)g(form)p 3137 4183 V
+761 4186 2378 4 v 759 4299 4 113 v 811 4265 a Fh(SPECIAL)p
+1631 4299 V 651 w Fs(reserv)m(ed)g(for)g(p)s(ossible)e(future)i(use)p
+3137 4299 V 759 4412 V 811 4378 a Fh(SPECIAL)p 1124 4378
+27 4 v 28 w(BEGIN)p 1372 4378 V 30 w(ENV)p 1631 4412
+4 113 v 154 w Fn(\\begin{env})d Fs(except)k(for)g Fn(\\item)e
+Fs(lists)p 3137 4412 V 759 4525 V 811 4491 a Fh(SPECIAL)p
+1124 4491 27 4 v 28 w(BEGIN)p 1372 4491 V 30 w(LIST)p
+1631 4525 4 113 v 253 w Fn(\\begin{env})e Fs(for)j Fn(\\item)f
+Fs(lists)p 3137 4525 V 759 4637 V 811 4604 a Fh(SPECIAL)p
+1124 4604 27 4 v 28 w(COMMAND)p 1631 4637 4 113 v 740
+w Fn(\\command)p 3137 4637 V 759 4750 V 811 4717 a Fh(SPECIAL)p
+1124 4717 27 4 v 28 w(END)p 1284 4717 V 30 w(ENV)p 1631
+4750 4 113 v 290 w Fn(\\end{env})e Fs(except)32 b(for)e
+Fn(\\item)f Fs(lists)p 3137 4750 V 759 4863 V 811 4829
+a Fh(SPECIAL)p 1124 4829 27 4 v 28 w(END)p 1284 4829
+V 30 w(LIST)p 1631 4863 4 113 v 388 w Fn(\\end{env})f
+Fs(for)i Fn(\\item)f Fs(lists)p 3137 4863 V 759 4976
+V 811 4942 a Fh(SPECIAL)p 1124 4942 27 4 v 28 w(SECTIONING)p
+1631 4976 4 113 v 139 w Fn(\\command)f Fs(for)j(a)f(do)s(cumen)m(t)g
+(section)p 3137 4976 V 761 4980 2378 4 v 1905 5531 a(93)p
+eop
+%%Page: 94 98
+94 97 bop 150 573 a Fs(where)37 b Fh(N)f Fs(is)g(an)h(in)m(teger)h(n)m
+(um)m(b)s(er)e(\(with)g(10000)j Fm(\024)d Fe(N)46 b Fm(\024)36
+b Fs(32767)k(for)d(a)g(grammar)g(sp)s(ecial,)h(or)f Fe(N)46
+b(>)150 686 y Fs(50000)31 b(for)d(a)i(co)s(de)f(sp)s(ecial\))e(that)j
+(has)e(b)s(een)g(sp)s(eci\014ed)f(within)f Fy(L)-7 b(TX2X)29
+b Fs(as)g(b)s(eing)e(iden)m(ti\014ed)g(with)h(the)150
+799 y(grammar)i(and)g(actions)h(corresp)s(onding)d(to)j(the)g(v)-5
+b(alue)30 b(of)g(the)h Fh(NAME=)d Fs(command)i(for)g(the)h
+Fh(SPECIAL)p 3643 799 27 4 v 28 w Fs(.)150 1042 y Fj(D.5)112
+b(T)-9 b(ag)38 b(sp)s(eci\014cation)e(commands)150 1214
+y Ft(D.5.1)105 b(Argumen)m(ts)150 1385 y Fs(The)43 b(commands)g
+(relating)f(to)i(the)g(sp)s(eci\014cation)e(of)i(L)2125
+1369 y Fr(A)2164 1385 y Fs(T)2215 1405 y(E)2265 1385
+y(X)f(command)h(argumen)m(ts)f(are)h(giv)m(en)f(in)150
+1498 y(T)-8 b(able)30 b(10.)1309 1744 y(T)-8 b(able)30
+b(10:)42 b(Argumen)m(t)31 b(commands.)p 765 1773 2370
+4 v 763 1886 4 113 v 815 1852 a(Command)p 1299 1886 V
+882 w(V)-8 b(alue)p 3133 1886 V 765 1890 2370 4 v 763
+2002 4 113 v 815 1969 a Fh(OPT)p 952 1969 27 4 v 30 w(PARAM=)p
+1299 2002 4 113 v 710 w(FIRST)28 b Fs(or)i Fh(LAST)p
+3133 2002 V 763 2115 V 815 2082 a(REQPARAMS=)p 1299 2115
+V 96 w Fs(In)m(teger.)41 b(The)30 b(n)m(um)m(b)s(er)f(of)i(required)d
+(argumen)m(ts)p 3133 2115 V 765 2119 2370 4 v 291 2331
+a(The)20 b Fh(OPT)p 605 2331 27 4 v 30 w(PARAM=)e Fs(command)j(sp)s
+(eci\014es)e(that)i(the)g(L)2017 2315 y Fr(A)2056 2331
+y Fs(T)2107 2351 y(E)2157 2331 y(X)g(command)f(tak)m(es)i(one)f
+(optional)e(argumen)m(t)150 2444 y(and)30 b(it)g(is)f(the)i
+Fh(FIRST)d Fs(or)i Fh(LAST)f Fs(in)g(the)i(argumen)m(t)f(list.)291
+2557 y(The)37 b Fh(REQPARAMS=)c Fs(command)38 b(sp)s(eci\014es)e(that)i
+(the)g(L)2131 2540 y Fr(A)2170 2557 y Fs(T)2221 2577
+y(E)2271 2557 y(X)g(command)f(has)g Fn(Integer)f Fs(n)m(um)m(b)s(er)g
+(of)150 2670 y(required)29 b(argumen)m(ts.)41 b Fn(Integer)28
+b Fs(m)m(ust)i(b)s(e)g(b)s(et)m(w)m(een)h(one)g(and)e(nine)2560
+2637 y Fr(9)2629 2670 y Fs(inclusiv)m(e.)291 2783 y(Absence)c(of)g
+(these)g(commands)g(implies)c(that)26 b(the)f(relev)-5
+b(an)m(t)25 b(L)2419 2766 y Fr(A)2458 2783 y Fs(T)2509
+2802 y(E)2559 2783 y(X)g(command)g(has)f(no)h(argumen)m(ts)150
+2896 y(of)31 b(the)f(unsp)s(eci\014ed)e(kind.)150 3136
+y Ft(D.5.2)105 b(T)-9 b(ag)35 b(actions)150 3308 y Fs(The)42
+b(commands)h(for)f(sp)s(ecifying)f(the)i(tag)h(actions)f(are)g
+(summarized)e(in)h(T)-8 b(able)42 b(11.)79 b(The)p 3518
+3308 V 73 w Fh(ITEM)p 3725 3308 V 150 3420 a Fs(commands)30
+b(can)g(only)f(b)s(e)h(used)f(within)f(a)i Fh(BEGIN)p
+1879 3420 V 29 w(LIST)p 2084 3420 V 30 w(ENV)f Fs(or)h(a)g
+Fh(SPECIAL)p 2769 3420 V 59 w Fs(command)g(sp)s(eci\014cation.)1435
+3684 y(T)-8 b(able)30 b(11:)41 b(T)-8 b(ag)31 b(commands.)p
+702 3713 2497 4 v 700 3826 4 113 v 752 3792 a(Command)p
+1516 3826 V 965 w(Application)p 3197 3826 V 702 3829
+2497 4 v 700 3942 4 113 v 752 3908 a Fh(END)p 889 3908
+27 4 v 30 w(ITEM=)p 1516 3942 4 113 v 748 w Fs(actions)g(after)g
+Fn(\\item)e Fs(text)p 3197 3942 V 700 4055 V 752 4021
+a Fh(END)p 889 4021 27 4 v 30 w(ITEM)p 1095 4021 V 29
+w(PARAM=)p 1516 4055 4 113 v 214 w Fs(actions)h(after)h
+Fn(\\item)e Fs(optional)h(argumen)m(t)p 3197 4055 V 700
+4168 V 752 4134 a Fh(END)p 889 4134 27 4 v 30 w(OPT=)p
+1516 4168 4 113 v 641 w Fs(actions)h(after)g(optional)e(argumen)m(t)p
+3197 4168 V 700 4281 V 752 4247 a Fh(END)p 889 4247 27
+4 v 30 w(TAG=)p 1516 4281 4 113 v 533 w Fs(actions)i(after)g(all)e
+(argumen)m(ts)i(pro)s(cessed)p 3197 4281 V 700 4394 V
+752 4360 a Fh(END)p 889 4360 27 4 v 30 w(TAG)p 1051 4360
+V 30 w(n=)p 1516 4394 4 113 v 470 w Fs(actions)f(after)h(n'th)f
+(required)f(argumen)m(t)p 3197 4394 V 700 4507 V 752
+4473 a Fh(START)p 977 4473 27 4 v 29 w(ITEM=)p 1516 4507
+4 113 v 727 w Fs(actions)i(b)s(efore)f Fn(\\item)p 3197
+4507 V 700 4620 V 752 4586 a Fh(START)p 977 4586 27 4
+v 29 w(ITEM)p 1182 4586 V 30 w(PARAM=)p 1516 4620 4 113
+v 97 w Fs(actions)g(b)s(efore)g Fn(\\item)f Fs(optional)h(argumen)m(t)p
+3197 4620 V 700 4733 V 752 4699 a Fh(START)p 977 4699
+27 4 v 29 w(OPT=)p 1516 4733 4 113 v 525 w Fs(actions)h(b)s(efore)f
+(optional)f(argumen)m(t)p 3197 4733 V 700 4846 V 752
+4812 a Fh(START)p 977 4812 27 4 v 29 w(TAG=)p 1516 4846
+4 113 v 619 w Fs(actions)h(at)h(start)g(of)g(command)p
+3197 4846 V 700 4959 V 752 4925 a Fh(START)p 977 4925
+27 4 v 29 w(TAG)p 1138 4925 V 30 w(n=)p 1516 4959 4 113
+v 354 w Fs(actions)f(b)s(efore)g(n'th)g(required)f(argumen)m(t)p
+3197 4959 V 702 4962 2497 4 v 150 5023 1440 4 v 254 5077
+a Fl(9)288 5109 y Fp(Or)d(eigh)n(t)f(if)33 b Fh(OPT)p
+807 5109 27 4 v 30 w(PARAM=)23 b Fp(is)j(sp)r(eci\014ed.)1905
+5531 y Fs(94)p eop
+%%Page: 95 99
+95 98 bop 291 573 a Fs(Eac)m(h)33 b(of)g(these)g(commands)f(can)h(sp)s
+(ecify)e(a)i(list)f(of)g(actions)h(to)h(b)s(e)e(p)s(erformed;)g(t)m
+(ypically)f(this)h(is)150 686 y(just)27 b(to)h(prin)m(t)e(a)i(text)h
+(string.)38 b(A)28 b(string)e(is)h(an)m(y)h(set)g(of)g(c)m(haracters)h
+(enclosed)e(in)f(double)g(quote)i(marks.)150 799 y(The)j(string)g(can)h
+(include)d(an)m(y)j(sp)s(ecial)e(prin)m(ting)f(c)m(haracters.)46
+b(The)31 b(text)i(string)e(starts)h(immediately)150 912
+y(after)f(the)g(\014rst)e(double)g(quote)i(and)f(ends)g(immediately)f
+(b)s(efore)h(the)g(last)h(double)d(quote.)42 b(The)30
+b(string)150 1024 y(cannot)j(include)d(a)i(ph)m(ysical)f(linebreak)f
+(within)g(the)i(command)g(table)g(\014le.)45 b(If)32
+b(the)g(\014rst)g(action)g(is)f(to)150 1137 y(prin)m(t)e(a)i(string)e
+(then)h(the)h(string)e(ma)m(y)i(b)s(e)f(placed)g(on)g(the)g(same)h
+(line)e(as)i(the)f(k)m(eyw)m(ord.)291 1250 y(The)44 b(actions)h(are)g
+(listed)e(one)i(p)s(er)e(line)g(and)h(are)h(p)s(erformed)e(in)h(the)g
+(order)g(they)h(are)g(listed.)150 1363 y(T)-8 b(able)30
+b(12)h(lists)e(the)i(action)f(commands.)1505 1609 y(T)-8
+b(able)30 b(12:)42 b(T)-8 b(ag)31 b(actions.)p 438 1638
+3025 4 v 436 1751 4 113 v 488 1717 a(Keyw)m(ord)p 1252
+1751 V 462 w(V)-8 b(alue)p 1775 1751 V 300 w(Application)p
+3461 1751 V 438 1755 3025 4 v 436 1867 4 113 v 488 1834
+a Fh(STRING:)p 1252 1867 V 508 w Fs(text)31 b(string)p
+1775 1867 V 104 w(Prin)m(t)e(the)i(string)p 3461 1867
+V 436 1980 V 488 1946 a Fh(SOURCE:)p 1252 1980 V 508
+w(BUFFER)d(num)p 1775 1980 V 98 w Fs(Prin)m(t)h(the)i(con)m(ten)m(ts)h
+(of)f(bu\013er)e(n)m(um)m(b)s(er)g Fh(num)p 3461 1980
+V 436 2093 V 488 2059 a(SOURCE:)p 1252 2093 V 508 w(FILE)f(name)p
+1775 2093 V 142 w Fs(Prin)m(t)h(the)i(con)m(ten)m(ts)h(of)f(\014le)e
+Fh(name)p 3461 2093 V 436 2206 V 488 2172 a(SOURCE:)p
+1252 2206 V 508 w(SYSBUF)p 1775 2206 V 258 w Fs(Prin)m(t)g(the)i(con)m
+(ten)m(ts)h(of)f(the)f(system)h(bu\013er)p 3461 2206
+V 436 2319 V 488 2285 a Fh(RESET)p 713 2285 27 4 v 29
+w(BUFFER:)p 1252 2319 4 113 v 259 w(num)p 1775 2319 V
+390 w Fs(Reset)g(the)g(bu\013er)e Fh(num)p 3461 2319
+V 436 2432 V 488 2398 a(RESET)p 713 2398 27 4 v 29 w(FILE:)p
+1252 2432 4 113 v 347 w(name)p 1775 2432 V 346 w Fs(Reset)i(the)g
+(\014le)e Fh(name)p 3461 2432 V 436 2545 V 488 2511 a(RESET)p
+713 2511 27 4 v 29 w(SYSBUF:)p 1252 2545 4 113 v 1775
+2545 V 781 w Fs(Reset)i(the)g(system)f(bu\013er)p 3461
+2545 V 436 2658 V 488 2624 a Fh(SWITCH)p 757 2624 27
+4 v 29 w(TO)p 874 2624 V 30 w(BUFFER:)p 1252 2658 4 113
+v 97 w(num)p 1775 2658 V 390 w Fs(Prin)m(t)f(to)j(bu\013er)d(n)m(um)m
+(b)s(er)g Fh(num)p 3461 2658 V 436 2771 V 488 2737 a(SWITCH)p
+757 2737 27 4 v 29 w(TO)p 874 2737 V 30 w(FILE:)p 1252
+2771 4 113 v 185 w(name)p 1775 2771 V 346 w Fs(Prin)m(t)g(to)j(\014le)d
+(called)h Fh(name)p 3461 2771 V 436 2884 V 488 2850 a(SWITCH)p
+757 2850 27 4 v 29 w(TO)p 874 2850 V 30 w(SYSBUF:)p 1252
+2884 4 113 v 1775 2884 V 619 w Fs(Prin)m(t)f(to)j(the)e(system)h
+(bu\013er)p 3461 2884 V 436 2997 V 488 2963 a Fh(SWITCH)p
+757 2963 27 4 v 29 w(BACK:)p 1252 2997 4 113 v 1775 2997
+V 825 w Fs(Reset)g(the)g(prin)m(t)e(mo)s(de)p 3461 2997
+V 436 3109 V 488 3076 a Fh(SET)p 625 3076 27 4 v 30 w(MODE:)p
+1252 3109 4 113 v 434 w(name)p 1775 3109 V 346 w Fs(Set)i(the)f(mo)s
+(de)g(to)h Fh(name)p 3461 3109 V 436 3222 V 488 3188
+a(RESET)p 713 3188 27 4 v 29 w(MODE:)p 1252 3222 4 113
+v 1775 3222 V 869 w Fs(Reset)g(the)g(mo)s(de)f(to)h(its)f(prior)e(v)-5
+b(alue)p 3461 3222 V 436 3335 V 488 3301 a Fh(CODE:)p
+1252 3335 V 1775 3335 V 1118 w Fs(Start)31 b(of)f(a)h(set)g(of)f
+Fo(Express-A)g Fs(statemen)m(ts)p 3461 3335 V 438 3339
+3025 4 v 150 3678 a Ft(D.5.3)105 b(Prin)m(t)36 b(con)m(trol)150
+3850 y Fs(The)c(prin)m(t)f(con)m(trol)i(commands)f(are)h(summarized)e
+(in)g(T)-8 b(able)32 b(13.)48 b(These)32 b(are)h(used)e(to)j(set)f(the)
+f(prin)m(t)150 3963 y(mo)s(de)37 b(at)h(the)g(start)g(and)f(end)f(of)i
+(a)g(command,)h(and)e(for)g(eac)m(h)h(argumen)m(t.)63
+b(The)37 b(exception)g(is)g(the)150 4076 y Fh(PRINT)p
+375 4076 27 4 v 29 w(CONTROL=)29 b Fs(command)i(whic)m(h)g(can)h(only)f
+(b)s(e)g(used)g(within)e(an)j Fh(OTHER)p 2797 4076 V
+61 w Fs(command)f(t)m(yp)s(e)h(sp)s(eci\014-)150 4189
+y(cation,)f(and)f(whic)m(h)f(is)g(the)i(only)e(prin)m(t)g(con)m(trol)i
+(that)g(can)g(b)s(e)f(sp)s(eci\014ed)e(for)i(the)h Fh(OTHER)p
+3238 4189 V 59 w Fs(commands.)1253 4452 y(T)-8 b(able)30
+b(13:)42 b(Prin)m(t)29 b(con)m(trol)i(commands.)p 864
+4464 2173 4 v 862 4577 4 113 v 914 4543 a(Command)p 1560
+4577 V 287 w(Application)p 3034 4577 V 864 4580 2173
+4 v 862 4693 4 113 v 914 4659 a Fh(PRINT)p 1139 4659
+27 4 v 29 w(CONTROL=)p 1560 4693 4 113 v 96 w Fs(prin)m(ting)e(of)37
+b Fh(OTHER)p 2293 4659 27 4 v 60 w Fs(commands)p 3034
+4693 4 113 v 862 4806 V 914 4772 a Fh(PC)p 1007 4772
+27 4 v 30 w(AT)p 1125 4772 V 31 w(START=)p 1560 4806
+4 113 v 196 w Fs(set)31 b(prin)m(ting)e(at)i(start)g(of)f(command)p
+3034 4806 V 862 4919 V 914 4885 a Fh(PC)p 1007 4885 27
+4 v 30 w(AT)p 1125 4885 V 31 w(END=)p 1560 4919 4 113
+v 284 w Fs(set)h(prin)m(ting)e(at)i(end)e(of)i(command)p
+3034 4919 V 862 5032 V 914 4998 a Fh(PRINT)p 1139 4998
+27 4 v 29 w(OPT=)p 1560 5032 4 113 v 272 w Fs(prin)m(ting)e(of)h
+(optional)g(argumen)m(t)p 3034 5032 V 862 5145 V 914
+5111 a Fh(PRINT)p 1139 5111 27 4 v 29 w(Pn=)p 1560 5145
+4 113 v 316 w Fs(prin)m(ting)f(of)h(n'th)g(required)f(argumen)m(t)p
+3034 5145 V 864 5148 2173 4 v 1905 5531 a(95)p eop
+%%Page: 96 100
+96 99 bop 291 573 a Fs(The)35 b(v)-5 b(alues)34 b(that)h(these)h
+(commands)e(ma)m(y)i(tak)m(e)g(are)f(giv)m(en)g(in)f(T)-8
+b(able)34 b(14.)55 b(These)35 b(direct)f(where)150 686
+y(an)m(y)e(prin)m(t)f(output)h(is)f(to)i(b)s(e)e(directed.)46
+b(The)31 b(default)g(is)g(to)i(send)f(all)f(output)g(the)i(the)f
+(\014le)f(named)h(as)150 799 y(the)f(output)f(on)g(the)g(command)h
+(line)d(when)i(starting)g Fy(L)-7 b(TX2X)p Fs(.)1343
+1062 y(T)f(able)30 b(14:)41 b(Prin)m(t)30 b(con)m(trol)h(v)-5
+b(alues.)p 1045 1074 1811 4 v 1043 1187 4 113 v 1095
+1153 a(V)d(alue)p 1684 1187 V 419 w(Application)p 2853
+1187 V 1045 1190 1811 4 v 1043 1303 4 113 v 1095 1269
+a Fh(NO)p 1188 1269 27 4 v 30 w(PRINT)p 1684 1303 4 113
+v 303 w Fs(Do)31 b(not)f(prin)m(t)f(at)i(all)p 2853 1303
+V 1043 1416 V 1095 1382 a Fh(TO)p 1188 1382 27 4 v 30
+w(SYSBUF)p 1684 1416 4 113 v 259 w Fs(Prin)m(t)e(to)i(the)g(system)f
+(bu\013er)p 2853 1416 V 1043 1529 V 1095 1495 a Fh(TO)p
+1188 1495 27 4 v 30 w(BUFFER)e(num)p 1684 1529 4 113
+v 99 w Fs(Prin)m(t)h(to)i(bu\013er)e(n)m(um)m(b)s(er)g
+Fh(num)p 2853 1529 V 1043 1642 V 1095 1608 a(TO)p 1188
+1608 27 4 v 30 w(FILE)g(name)p 1684 1642 4 113 v 142
+w Fs(Prin)m(t)g(to)i(\014le)e(called)h Fh(name)p 2853
+1642 V 1043 1755 V 1095 1721 a(NO)p 1188 1721 27 4 v
+30 w(OP)p 1684 1755 4 113 v 435 w Fs(Do)h(not)f(do)h(an)m(y)f(pro)s
+(cessing)p 2853 1755 V 1043 1867 V 1095 1834 a Fh(RESET)p
+1684 1867 V 421 w Fs(Reset)h(the)f(prin)m(t)f(mo)s(de)p
+2853 1867 V 1045 1871 1811 4 v 291 2066 a Fh(NO)p 384
+2066 27 4 v 31 w(PRINT)37 b Fs(and)h Fh(NO)p 945 2066
+V 31 w(OP)g Fs(b)s(oth)g(pro)s(duce)g(no)i(prin)m(ted)d(output.)67
+b(Ho)m(w)m(ev)m(er,)44 b(in)37 b(the)j Fh(NO)p 3271 2066
+V 30 w(OP)f Fs(case)h(the)150 2179 y(lexer)33 b(handles)g(all)f(the)i
+(pro)s(cessing,)g(and)f(e\013ectiv)m(ely)i(just)e(ignores)h(the)g
+(source)g(do)s(cumen)m(t)f(text.)53 b(In)150 2291 y(the)32
+b Fh(NO)p 401 2291 V 31 w(PRINT)d Fs(case,)34 b(the)e(source)g(text)h
+(is)d(pro)s(cessed)i(as)g(normal,)f(but)g(the)h(prin)m(ting)e(is)h
+(directed)g(to)i(a)150 2404 y(blac)m(k)d(hole.)150 2644
+y Ft(D.5.4)105 b(Sectioning)150 2816 y Fh(SECTIONING)20
+b Fs(command)25 b(sp)s(eci\014cations)e(require)g(a)i
+Fh(SECTIONING)p 2382 2816 V 27 w(LEVEL=)d Fs(command.)39
+b(The)24 b(v)-5 b(alues)23 b(that)150 2929 y(this)29
+b(can)i(tak)m(e)h(are)f(listed)e(in)g(T)-8 b(able)30
+b(15.)1291 3175 y(T)-8 b(able)30 b(15:)41 b(Sectioning)30
+b(lev)m(el)g(v)-5 b(alues.)p 815 3204 2271 4 v 813 3317
+4 113 v 864 3283 a(V)d(alue)p 1348 3317 V 314 w(Application)p
+3084 3317 V 815 3320 2271 4 v 813 3433 4 113 v 864 3399
+a Fh(PART)p 1348 3433 V 360 w Fs(sectioning)30 b(equiv)-5
+b(alen)m(t)29 b(to)i Fn(\\part)p 3084 3433 V 813 3546
+V 864 3512 a Fh(CHAPTER)p 1348 3546 V 228 w Fs(sectioning)f(equiv)-5
+b(alen)m(t)29 b(to)i Fn(\\chapter)p 3084 3546 V 813 3659
+V 864 3625 a Fh(SECT)p 1348 3659 V 360 w Fs(sectioning)f(equiv)-5
+b(alen)m(t)29 b(to)i Fn(\\section)p 3084 3659 V 813 3772
+V 864 3738 a Fh(SUBSECT)p 1348 3772 V 228 w Fs(sectioning)f(equiv)-5
+b(alen)m(t)29 b(to)i Fn(\\subsection)p 3084 3772 V 813
+3885 V 864 3851 a Fh(SUBSUBSECT)p 1348 3885 V 96 w Fs(sectioning)f
+(equiv)-5 b(alen)m(t)29 b(to)i Fn(\\subsubsection)p 3084
+3885 V 813 3998 V 864 3964 a Fh(PARA)p 1348 3998 V 360
+w Fs(sectioning)f(equiv)-5 b(alen)m(t)29 b(to)i Fn(\\paragraph)p
+3084 3998 V 813 4111 V 864 4077 a Fh(SUBPARA)p 1348 4111
+V 228 w Fs(sectioning)f(equiv)-5 b(alen)m(t)29 b(to)i
+Fn(\\subprargraph)p 3084 4111 V 815 4114 2271 4 v 291
+4327 a Fs(A)j(sectioning)f(command)h(sp)s(eci\014cation)e(uses)i(the)f
+Fh(END)p 2253 4327 27 4 v 31 w(TAG=)f Fs(text)i(tag)h(di\013eren)m(tly)
+e(from)g(its)g(use)150 4439 y(b)m(y)27 b(an)m(y)h(other)g(sp)s
+(eci\014cation.)39 b(In)27 b(this)f(case,)k(the)d(tag)i(is)e(prin)m
+(ted)f(at)i(the)g(closure)f(of)h(the)g(text)g(forming)150
+4552 y(the)37 b(b)s(o)s(dy)e(of)h(the)h(section)g(of)g(the)f(do)s
+(cumen)m(t.)59 b(A)37 b(do)s(cumen)m(t)f(section)h(is)f(considered)f
+(to)i(b)s(e)f(closed)150 4665 y(when)27 b(it)h(is)g(follo)m(w)m(ed)g(b)
+m(y)g(a)g(higher)f(lev)m(el)h(sectioning)g(command.)40
+b(The)28 b(v)-5 b(alues)28 b(in)f(T)-8 b(able)27 b(15)j(are)e(listed)
+150 4778 y(in)h(decreasing)h(lev)m(el.)40 b(That)31 b(is,)e(a)i
+(section)f(at)i(lev)m(el)e Fh(CHAPTER)d Fs(is)i(at)i(a)g(higher)e(lev)m
+(el)h(than)g(a)h(section)f(at)150 4891 y(lev)m(el)g Fh(PARA)p
+Fs(.)150 5104 y Ft(NOTE)44 b Fs(F)-8 b(or)32 b(the)e(use)h(of)f
+(writers)g(of)37 b Fh(SPECIAL)p 1806 5104 V 59 w Fs(command)31
+b(sp)s(eci\014cations,)e Fh(SECTIONING)p 3299 5104 V
+28 w(LEVEL=)f Fs(can)377 5217 y(b)s(e)k(giv)m(en)g(some)h(additional)d
+(v)-5 b(alues.)45 b(These)32 b(are)h Fh(PARTm2)d Fs(and)h
+Fh(PARTm1)f Fs(for)i(lev)m(els)g(resp)s(ectiv)m(ely)1905
+5531 y(96)p eop
+%%Page: 97 101
+97 100 bop 377 573 a Fs(t)m(w)m(o)40 b(and)d(one)h(higher)f(than)h
+Fh(PART)p Fs(,)e(and)i Fh(SUBPARAp1)c Fs(and)j Fh(SUBPARAp2)d
+Fs(for)k(lev)m(els)g(resp)s(ectiv)m(ely)377 686 y(one)31
+b(and)f(t)m(w)m(o)h(lo)m(w)m(er)g(than)f Fh(SUBPARA)p
+Fs(.)150 972 y Fu(E)135 b(System)45 b(installation)150
+1175 y Fs(This)23 b(section)h(describ)s(es)f(ho)m(w)h(to)h(install)d
+(the)j Fy(L)-7 b(TX2X)24 b Fs(program)g(and)g(some)h(of)f(the)h(in)m
+(ternal)e(size)h(limits)150 1288 y(within)k Fy(L)-7 b(TX2X)p
+Fs(.)291 1401 y(The)30 b(basic)g Fy(L)-7 b(TX2X)30 b
+Fs(system)h(requires)d(the)j(follo)m(wing)e(source)h(\014les:)150
+1589 y Fn(l2x.l)44 b Fs(the)31 b(lexer)f(source.)150
+1776 y Fn(l2x.y)44 b Fs(the)31 b(parser)e(source.)150
+1964 y Fn(l2xlib.c)p Ft(,)k Fn(l2xlib.h)43 b Fs(main)29
+b(program)h(and)g(supp)s(ort)f(functions.)150 2151 y
+Fn(l2xlibtc.h)43 b Fs(header)30 b(\014le)f(con)m(taining)h(k)m(eyw)m
+(ords)h(and)f(their)f(represen)m(tations)h(as)h(strings.)150
+2339 y Fn(l2xcom.h)43 b Fs(header)32 b(\014le)g(for)g(all)f(system)h
+(comp)s(onen)m(ts)h(\(except)g(for)f(getopt,)j(src)m(hen)m(v)d(and)g
+(the)g(in)m(ter-)377 2452 y(preter\).)150 2640 y Fn(l2xacts.c)p
+Ft(,)g Fn(l2xacts.h)43 b Fs(standard)30 b(action)h(functions.)150
+2827 y Fn(l2xusrlb.c)p Ft(,)h Fn(l2xusrlb.h)43 b Fs(sp)s(ecial)29
+b(actions)h(and)g(user-de\014ned)f(functions.)150 3015
+y Fn(strtypes.h)43 b Fs(header)30 b(\014le)f(with)g(some)i(t)m(yp)s(e)g
+(de\014nitions.)150 3203 y Fn(getopt.c)p Ft(,)i Fn(getopt.h)43
+b Fs(functions)29 b(for)h(handling)e(command)i(line)f(options)g([14)q
+(,)i(Chapter)f(6].)150 3390 y Fn(srchenv.c)p Ft(,)i Fn(srchenv.h)43
+b Fs(functions)29 b(for)h(searc)m(hing)h(directories)e(for)h(\014les)g
+([15)q(,)g(page)h(747].)291 3578 y(The)f Fo(Express-A)f
+Fs(in)m(terpreter)h(also)g(requires)f(the)i(follo)m(wing)e(\014les:)150
+3765 y Fn(l2xistup.c)43 b Fs(the)30 b(in)m(terface)h(b)s(et)m(w)m(een)g
+(the)g(main)e(part)h(of)h Fy(L)-7 b(TX2X)30 b Fs(and)g(the)g(in)m
+(terpreter.)150 3953 y Fn(l2xicmon.h)43 b Fs(header)30
+b(\014le)f(for)i(the)f(in)m(terface.)150 4141 y Fn(l2xirtne.c)p
+Ft(,)i Fn(l2xistd.c)p Ft(,)h Fn(l2xidecl.c)p Ft(,)f Fn(l2xistmt.c)p
+Ft(,)g Fn(l2xiexpr.c)43 b Fs(the)25 b(\014les)e(that)j(con)m(tain)f
+(the)377 4254 y(co)s(de)34 b(for)e(parsing)g Fo(Express-A)p
+Fs(.)g(Resp)s(ectiv)m(ely)h(they)g(deal)f(with)g(functions)g(and)g(pro)
+s(cedures,)377 4366 y(the)f(built-in)c(functions,)i(declarations,)h
+(statemen)m(ts,)j(and)c(expressions.)150 4554 y Fn(l2xiprse.h)43
+b Fs(header)30 b(\014le)f(for)i(parsing.)150 4742 y Fn(l2xixutl.c)p
+Ft(,)h Fn(l2xiexec.h)43 b Fs(utilit)m(y)24 b(routines)h(supp)s(orting)e
+(the)j(execution)g(mo)s(dule)e(and)h(for)h(manag-)377
+4855 y(ing)k(the)g(in)m(terpreter's)g(stac)m(k.)150 5042
+y Fn(l2xixstd.c)p Ft(,)i Fn(l2xixstm.c)p Ft(,)g Fn(l2xixxpr.c)43
+b Fs(functions)k(for)h(executing)g(the)g Fo(Express-A)f
+Fs(built)f(in)377 5155 y(functions,)29 b(statemen)m(ts)k(and)c
+(expressions.)1905 5531 y(97)p eop
+%%Page: 98 102
+98 101 bop 150 573 a Fn(l2xirexp.c)p Ft(,)32 b Fn(l2xirexpr.h)43
+b Fs(general)35 b(functions)e(for)i(pro)s(cessing)f(and)g(executing)i
+(regular)e(expres-)377 686 y(sions.)150 873 y Fn(listsetc.c)p
+Ft(,)e Fn(listsetc.h)43 b Fs(general)30 b(functions)f(for)h(pro)s
+(cessing)f(lists.)150 1061 y Fn(l2xiscan.c)p Ft(,)j Fn(l2xiscan.h)43
+b Fs(lexing)29 b(routines)g(for)h(the)h(in)m(terpreter.)150
+1249 y Fn(l2xisymt.c)p Ft(,)h Fn(l2xisymt.h)43 b Fs(routines)29
+b(for)h(managing)g(the)h(in)m(terpreter's)f(sym)m(b)s(ol)f(tables.)150
+1436 y Fn(l2xidbug.c)43 b Fs(the)30 b(source)h(lev)m(el)f(debugger.)150
+1624 y Fn(l2xierr.c)p Ft(,)i Fn(l2xierr.h)43 b Fo(Express-A)28
+b Fs(language)h(error)f(handling)e(and)h(diagnostic)h(output)g(for)h
+(the)377 1737 y(user.)150 1924 y Fn(l2xiidbg.c)p Ft(,)j
+Fn(l2xiidbg.h)p Ft(,)g Fn(l2xisdcl.c)43 b Fs(diagnostics)30
+b(for)g(a)h(dev)m(elop)s(er)e(of)i(the)g(in)m(terpreter.)150
+2112 y Fn(licomsym.h)43 b Fs(general)30 b(header)g(\014le)g(for)g(the)g
+(in)m(terpreter)g(mo)s(dules.)150 2300 y Fn(l2xidftc.h)p
+Ft(,)i Fn(l2xiertc.h)p Ft(,)g Fn(l2xisctc.h)p Ft(,)g
+Fn(l2xisftc.h)43 b Fs(header)29 b(\014les)f(con)m(taining)h(k)m(eyw)m
+(ords)h(and)377 2413 y(their)g(represen)m(tations)g(as)h(strings.)291
+2600 y(The)f(follo)m(wing)f(\014les)g(ma)m(y)i(b)s(e)f(useful:)150
+2788 y Fn(man)45 b Fs(the)30 b(manpage)150 2976 y Fn(printct.c)43
+b Fs(a)31 b(program)f(to)h(prin)m(t)e(and)h(up)s(date)f(command)h
+(table)h(\014les;)150 3163 y Fn(ltx2html.sty)42 b Fs(a)33
+b(L)870 3146 y Fr(A)909 3163 y Fs(T)960 3183 y(E)1010
+3163 y(X)g(pac)m(k)-5 b(age)35 b(\014le)c(to)j(assist)e(in)f(retagging)
+j(a)f(L)2572 3146 y Fr(A)2611 3163 y Fs(T)2662 3183 y(E)2712
+3163 y(X)g(do)s(cumen)m(t)f(to)i(an)e(HTML)377 3276 y(do)s(cumen)m(t.)
+291 3464 y(Essen)m(tially)-8 b(,)33 b(installing)d Fy(L)-7
+b(TX2X)33 b Fs(consists)g(of)g(pro)s(cessing)f(the)i(\014le)e
+Fn(l2x.l)g Fs(through)g(a)i(lexer)e(gen-)150 3577 y(erator,)d(pro)s
+(cessing)d(the)h(\014le)g Fn(l2x.y)e Fs(through)i(a)g(parser)g
+(generator,)i(and)e(then)g(compiling)e(the)i(results)150
+3689 y(together)32 b(with)d(the)h(other)h(supplied)c(source)k(\014les.)
+291 3802 y(The)37 b(lexer)g(source)h(\014le)f Fn(l2x.l)f
+Fs(and)h(the)h(parser)f(source)h(\014le)f Fn(l2x.y)f
+Fs(ha)m(v)m(e)j(to)f(b)s(e)f(pro)s(cessed)g(b)m(y)150
+3915 y(\015ex)e(\(or)g(equiv)-5 b(alen)m(t\))34 b(and)g(bison)f(\(or)i
+(equiv)-5 b(alen)m(t\))35 b(resp)s(ectiv)m(ely)f(to)h(generate)h(C)f
+(co)s(de.)54 b(This)32 b(co)s(de,)150 4028 y(together)i(with)c(the)i
+(co)s(de)h(in)d(the)j(other)f(source)g(\014les)f(m)m(ust)h(then)g(b)s
+(e)f(compiled)g(and)g(link)m(ed)g(to)h(form)150 4141
+y(the)f(executable.)291 4254 y(The)39 b(executable)g(m)m(ust)g(then,)i
+(after)f(suitable)d(testing,)42 b(b)s(e)c(mo)m(v)m(ed)i(to)g(its)f
+(\014nal)e(place)i(in)f(y)m(our)150 4367 y(system)21
+b(and)f(the)h(manpage)g(\(\014le)f Fn(man)p Fs(\))g(also)h(copied)f(to)
+h(its)f(\014nal)f(p)s(osition)g(in)g(y)m(our)i(directory)f(structure.)
+291 4480 y(Included)32 b(in)h(the)h Fy(L)-7 b(TX2X)34
+b Fs(distribution)d(are)k(sev)m(eral)f(command)g(table)g(\014les.)51
+b(One)34 b(is)f Fn(detex.ct)150 4593 y Fs(whic)m(h)19
+b(pro)m(vides)g(an)h(example)g(of)h(commands)f(for)g(de-T)2046
+4612 y(E)2096 4593 y(Xing)g(a)g(do)s(cumen)m(t.)2785
+4560 y Fr(10)2897 4593 y Fs(Another)g(is)g Fn(remcom.ct)150
+4706 y Fs(whic)m(h)j(pro)m(vides)h(an)h(example)f(of)h(commands)g(to)g
+(remo)m(v)m(e)h(commen)m(ts)g(from)e(a)i(L)2908 4689
+y Fr(A)2947 4706 y Fs(T)2998 4725 y(E)3048 4706 y(X)f(do)s(cumen)m(t.)
+38 b(The)150 4819 y(command)31 b(table)h(\014le)e Fn(bye.ct)g
+Fs(replaces)h(a)h(L)1705 4802 y Fr(A)1744 4819 y Fs(T)1795
+4838 y(E)1845 4819 y(X)g(do)s(cumen)m(t)f(b)m(y)g("Go)s(o)s(db)m(y)m(e)
+i(do)s(cumen)m(t".)44 b(Another)150 4932 y(is)35 b Fn(ltx2x.ct)f
+Fs(whic)m(h)h(do)s(es)h(nothing)f(except)j(try)e(and)f(include)f
+(another)j(\014le)e(named)h Fn(ZiLcH)p Fs(,)f(whic)m(h)p
+150 5011 1440 4 v 223 5064 a Fl(10)288 5096 y Fp(Y)-6
+b(ou)30 b(ma)n(y)f(wish)j(to)f(try)f(using)i Fa(detex.ct)g
+Fp(on)f(the)f(L)1853 5079 y Fl(A)1886 5096 y Fp(T)1928
+5112 y(E)1972 5096 y(X)g(source)i(of)f(this)g(do)r(cumen)n(t)e(to)i
+(see)g(what)g(the)f(e\013ect)h(is.)150 5187 y(This)26
+b(can)g(also)h(serv)n(e)f(as)g(a)g(c)n(hec)n(k)f(on)h(the)f(system)g
+(installation.)1905 5531 y Fs(98)p eop
+%%Page: 99 103
+99 102 bop 150 573 a Fs(presumably)32 b(is)i(not)h(on)f(an)m(y)m(one's)
+i(system.)53 b(Running)32 b Fy(L)-7 b(TX2X)35 b Fs(with)e(this)g
+(\014le)h(will)e(prompt)h(for)i(an-)150 686 y(other)j(name)f(of)h(a)g
+(\014le)e(if)g(it)h(cannot)h(\014nd)e Fn(ZiLcH)p Fs(;)h(en)m(ter)h(an)f
+(existing)f(\014le)h(\(lik)m(e)g Fn(detex.ct)p Fs(\))f(at)i(the)150
+799 y(prompt.)469 766 y Fr(11)291 912 y Fs(The)h(command)g(table)h
+(\014le)e Fn(l2h.ct)g Fs(has)h(pro)m(v)m(en)h(to)g(b)s(e)f(adequate)h
+(for)g(con)m(v)m(erting)g(the)f(L)3541 895 y Fr(A)3580
+912 y Fs(T)3631 931 y(E)3682 912 y(X)150 1024 y(source)27
+b(of)h(this)e(man)m(ual,)h(and)f(other)i(L)1475 1008
+y Fr(A)1514 1024 y Fs(T)1565 1044 y(E)1615 1024 y(X)f(do)s(cumen)m(ts)g
+(without)f(pictures)g(and)h(only)f(limited)f(math-)150
+1137 y(ematics,)31 b(in)m(to)f(an)h(ASCI)s(I)d(\014le)i(with)f(HTML)h
+(tags)i(instead.)291 1250 y(The)h(\014le)f Fn(fun.ct)f
+Fs(con)m(tains)i(some)h(test)g(co)s(de)f(for)g(the)g
+Fo(Express-A)f Fs(in)m(terpreter.)48 b(The)32 b(con)m(ten)m(ts)150
+1363 y(are)f(similar)d(to)j(the)f(example)g(sho)m(wn)g(at)h(the)g(end)e
+(of)i(section)f(4.)291 1476 y(The)25 b Fn(l2xusrlb)d
+Fs(\014les)i(are)i(sk)m(eletons.)39 b(The)24 b(system)i(do)s(es)e
+(include)f(the)i(functions)f(and)g(parser)g(con-)150
+1589 y(structs)29 b(for)h(the)f Fn(\\GRAMMspecial)d Fs(and)j
+Fn(\\CODEspecial)d Fs(commands)j(used)g(as)h(examples)f(previously)-8
+b(.)150 1702 y(The)28 b(last)h(t)m(w)m(o)i(en)m(tries)d(in)g
+Fn(remcom.ct)e Fs(are)k(the)f(sp)s(eci\014cation)f(of)h(these,)h(and)e
+(the)h(implemen)m(tation)f(is)150 1815 y(as)j(describ)s(ed)d
+(previously)-8 b(.)150 2058 y Fj(E.1)112 b(Command)37
+b(table)g(prin)m(ting)150 2230 y Fs(The)e(grammar)g(of)g(the)g(command)
+g(table)g(has)g(b)s(een)g(c)m(hanged)h(sligh)m(tly)d(since)i(the)g
+(initial)d(release)k(of)150 2343 y Fy(L)-7 b(TX2X)p Fs(.)31
+b(The)e(utilit)m(y)g(C)h(program)g(in)f Fn(printct.c)f
+Fs(ma)m(y)j(b)s(e)f(used)f(to:)286 2530 y Fm(\017)46
+b Fs(Prett)m(y-prin)m(t)31 b(a)f(command)h(table;)286
+2718 y Fm(\017)46 b Fs(Con)m(v)m(ert)31 b(an)g(original)d(command)i
+(table)h(to)g(one)f(that)h(conforms)g(to)g(the)f(new)g(grammar.)291
+2906 y(The)g(syn)m(tax)h(for)f(running)f Fn(printct)f
+Fs(is:)150 3093 y Fn(printct)46 b([-D)h(dir_cat_char])d([-P)j
+(path_seperators])c([-f)k(table_file])e([-t])150 3281
+y Fs(where)38 b(elemen)m(ts)g(in)f(square)h(brac)m(k)m(ets)h(are)g
+(options.)63 b(These)37 b(options)h(are)g(iden)m(tical)f(to)i(the)f
+(corre-)150 3394 y(sp)s(onding)28 b(ones)i(for)h Fy(L)-7
+b(TX2X)30 b Fs(and)g(are)g(as)h(follo)m(ws:)150 3582
+y Fn(-f)45 b Fs(By)g(default,)k Fn(printct)43 b Fs(reads)i(the)g
+(command)g(table)g(from)g(a)g(\014le)g(called)f Fn(ltx2x.ct)p
+Fs(.)83 b(If)45 b(the)377 3694 y(required)31 b(command)h(table)h(is)e
+(in)g(a)i(\014le)f(with)f(another)i(name)f(this)f(option)h(is)g(used)g
+(to)h(c)m(hange)377 3807 y(from)d(the)h(default)e(\014le.)40
+b(F)-8 b(or)31 b(example,)377 4032 y Fn(>)48 b(printct)377
+4257 y Fs(reads)30 b(a)h(command)f(table)h(from)e Fn(ltx2x.ct)p
+Fs(,)g(while)377 4482 y Fn(>)48 b(printct)e(-f)h(detex.ct)377
+4707 y Fs(reads)30 b(a)h(command)f(table)h(from)e(\014le)h
+Fn(detex.ct)p Fs(.)150 4895 y Fn(-t)45 b Fs(This)28 b(generates)k(some)
+f(diagnostics)f(related)g(to)h(the)g(pro)s(cessing)e(of)h(the)h
+(command)f(table)g(\014le.)p 150 4974 1440 4 v 223 5028
+a Fl(11)288 5060 y Fp(This)d(is)f(one)g(w)n(a)n(y)f(of)i(setting)f(up)f
+Fy(L)-7 b(TX2X)25 b Fp(for)i(in)n(teractiv)n(e)f(sp)r(eci\014cation)h
+(of)f(the)f(desired)h(command)e(table)i(\014le\(s\).)1905
+5531 y Fs(99)p eop
+%%Page: 100 104
+100 103 bop 150 573 a Fn(-D)45 b Fs(The)39 b(v)-5 b(alue)39
+b(of)h(this)e(option)i(is)e(the)i(c)m(haracter)h(that)f(the)g(op)s
+(erating)f(system)h(uses)f(to)i(catenate)377 686 y(directory)31
+b(names)f(to)i(form)e(a)h(path)g(\(see)g(3.1.1\).)44
+b(The)31 b(default)f(v)-5 b(alue)30 b(is)g(a)h(slash)e(\(i.e.)43
+b Fn(/)p Fs(\).)e(The)377 799 y(default)30 b(could)f(b)s(e)h(c)m
+(hanged)h(to)g(a)g(bac)m(kslash,)f(for)g(example,)h(b)m(y)f
+Fn(-D)47 b(\\)p Fs(.)150 986 y Fn(-P)e Fs(The)33 b(en)m(vironmen)m(t)h
+(v)-5 b(ariable)33 b(\(see)h(3.1.1\))i(con)m(tains)f(a)f(list)e(of)i
+(directories)f(\(also)i(kno)m(wn)e(as)h(path)377 1099
+y(names\).)73 b(In)40 b(the)h(op)s(erating)f(system)h(that)g(I)g(use,)i
+(these)f(are)f(separated)g(b)m(y)g(the)g(colon)g(\()p
+Fn(:)p Fs(\))377 1212 y(c)m(haracter)32 b(whic)m(h,)e(together)i(with)e
+(the)g(semi-colon)h(and)f(space)h(c)m(haracters,)h(form)e(the)h
+Fy(L)-7 b(TX2X)377 1325 y Fs(default)34 b(separators.)56
+b(The)34 b(path)h(separator)h(c)m(haracters)g(can)f(b)s(e)g(c)m(hanged)
+h(with)d(this)h(option.)377 1438 y(F)-8 b(or)30 b(example,)f
+Fn(-P)47 b(:)29 b Fs(will)e(mak)m(e)j(the)f(separators)g(b)s(e)g(a)g
+(colon)g(or)g(a)h(space)f(\(space)h(is)e(automati-)377
+1551 y(cally)i(included)e(in)h(the)h(separator)h(list\).)291
+1738 y Fn(printct)40 b Fs(only)h(reads)h(a)g(single)e(command)i(table)g
+(\014le)f(and)g(outputs)g(the)h(prett)m(y-prin)m(ted)g(and)150
+1851 y(up)s(dated)31 b(v)m(ersion)h(to)h(\014le)f Fn(printct.lis)p
+Fs(.)44 b(It)33 b(p)s(erforms)e(a)h(v)m(ery)h(limited)d(amoun)m(t)j(of)
+g(error)f(c)m(hec)m(king)150 1964 y(and)e(writes)f(error)h(messages)i
+(and)d(statistics)i(to)g(the)f(\014le)g Fn(printct.err)p
+Fs(.)150 2208 y Fj(E.2)112 b(A)37 b FA(make)h Fj(\014le)150
+2379 y Fs(Here)31 b(is)e(a)i(UNIX)g Fn(make)e Fs(\014le)g([16)r(])h
+(for)g(the)h Fy(L)-7 b(TX2X)30 b Fs(system.)150 2579
+y Fh(#)43 b(makefile)d(for)j(program)d(ltx2x)i(---)g(LaTeX)g(to)h(X)g
+(autotagger)150 2678 y(#)150 2778 y(################)o(###)o(##)37
+b(Change)k(the)h(following)e(for)j(your)e(setup)150 2877
+y(#)i(The)g(compiler)150 2977 y(CC)g(=)g(cc)150 3176
+y(#)g(We)g(use)f(flex)g(\(or)h(equivalent,)c(but)j(not)g(lex\))g(to)h
+(generate)d(the)j(lexer)150 3276 y(LEX)f(=)i(flex)150
+3376 y(#)f(and)g(the)f(options)150 3475 y(LEXFLAGS)e(=)j(-v)150
+3675 y(#)g(We)g(use)f(bison)g(\(or)g(equivalent\))d(to)k(generate)d
+(the)j(parser)150 3774 y(YACC)f(=)h(bison)150 3874 y(#)g(and)g(the)f
+(options)150 3973 y(YACCFLAGS)e(=)j(-y)g(-d)g(-v)150
+4173 y(#)g(Libraries)d(to)j(be)g(used)150 4272 y(LIBS)f(=)h(-ly)f(-ll)h
+(-lm)150 4472 y(#)g(The)g(root)e(directory)f(for)j(the)f(installation)d
+(\(e.g.,)i(/usr/local)e(\))150 4571 y(ROOTDIR)i(=)i(/proj/ltx/teTeX0)o
+(33)150 4770 y(#)g(Where)f(to)g(place)g(the)g(running)f(code)h(\(e.g.)f
+(/usr/local/bin)d(\))150 4870 y(BINDIR)j(=)i(${ROOTDIR}/bin)150
+5069 y(#)g(Where)f(to)g(place)g(the)g(manpage)f(\(e.g.,)g
+(/usr/local/man/m)o(an1)c(\))150 5169 y(MANEXT)k(=)i(1)150
+5269 y(MANDIR)e(=)i(${ROOTDIR}/man/ma)o(n$)o({MA)o(NE)o(XT})1882
+5531 y Fs(100)p eop
+%%Page: 101 105
+101 104 bop 150 672 a Fh(#)43 b(Just)f(in)h(case)f(you)g(want)g(to)h
+(change)e(the)h(name)g(of)h(the)f(binary)150 772 y(#)h(\(and)f(then)g
+(you)g(should)f(also)h(change)g(the)g(man)g(page)g(and)g
+(documentation\).)150 872 y(#)h(So,)g(do)f(not)h(change)e(this.)150
+971 y(PROG)h(=)h(ltx2x)150 1171 y(#)g(Where)f(to)g(place)g(the)g(user)g
+(documentation)c(\(e.g.,)k(/usr/local/doc/)o(ltx)o(2x)37
+b(\))150 1270 y(DOCDIR)k(=)i(${ROOTDIR}/doc/${)o(PR)o(OG})150
+1469 y(#)g(Where)f(to)g(place)g(the)g(example)f(command)g(tables)g
+(\(e.g.,)g(/usr/local/lib/c)o(on)o(fig)o(/l)o(tx2)o(x)c(\))150
+1569 y(CTDIR)42 b(=)h(${ROOTDIR}/lib/)o(con)o(fi)o(g/$)o({P)o(ROG)o(})
+150 1768 y(#)g(The)g(file)e(copy)h(command)f(\(copy)h(but)g(do)h(not)f
+(delete)f(original\))150 1868 y(COPY)h(=)h(cp)150 2067
+y(#)g(The)g(file)e(move)h(command)f(\(move)h(and)g(delete)f(original\))
+150 2167 y(MOVE)h(=)h(mv)150 2366 y(#)g(The)g(file)e(delete)h(command)
+150 2466 y(DELETE)f(=)i(rm)150 2665 y(#)g(The)g(make)e(directory)f
+(\(hierarchy\))f(command)150 2765 y(MAKEDIR)i(=)i(mkdirhier)150
+2964 y(#)g(The)g(stream)e(editor)g(command)150 3064 y(SED)h(=)i(sed)150
+3263 y(#)f(Command)e(to)i(write)e(to)i(the)f(terminal)f(\(stdout\))150
+3362 y(ECHO)h(=)h(echo)150 3562 y(################)o(###)37
+b(You)42 b(should)f(not)i(have)e(to)i(change)e(anything)g(after)g(this)
+150 3761 y(#)i(The)g(source)e(modules)150 3861 y(L2XSRCS)g(=)i
+(l2xytab.c)d(l2xlexyy.c)f(l2xlib.c)h(l2xacts.c)g(l2xusrlb.c)150
+3960 y(getopt.c)g(srchenv.c)150 4159 y(INTSRCS)h(=)i(l2xirtne.c)c
+(l2xistd.c)h(l2xidecl.c)g(l2xistmt.c)f(l2xiexpr.c)150
+4259 y(l2xiscan.c)g(l2xisymt.c)h(l2xierr.c)g(l2xiidbg.c)f(l2xistup.c)h
+(l2xistm.c)150 4359 y(l2xixxpr.c)f(l2xixstd.c)h(l2xidbug.c)f
+(l2xisdcl.c)h(l2xirexp.c)f(listsetc.c)150 4558 y(#)k(The)g(object)e
+(modules)150 4658 y(L2XOBJS)g(=)i(l2xytab.o)d(l2xlexyy.o)f(l2xlib.o)h
+(l2xacts.o)g(l2xusrlb.o)586 4757 y(getopt.o)g(srchenv.o)150
+4956 y(INTSRCS)h(=)i(l2xirtne.o)c(l2xistd.o)h(l2xidecl.o)g(l2xistmt.o)f
+(l2xiexpr.o)150 5056 y(l2xiscan.o)g(l2xisymt.o)h(l2xierr.o)g
+(l2xiidbg.o)f(l2xistup.o)h(l2xistm.o)150 5156 y(l2xixxpr.o)f
+(l2xixstd.o)h(l2xidbug.o)f(l2xisdcl.o)h(l2xirexp.o)f(listsetc.o)1882
+5531 y Fs(101)p eop
+%%Page: 102 106
+102 105 bop 150 573 a Fh(OBJS)42 b(=)h(${L2XOBJS})d(${INTOBJS})150
+772 y(#)j(Link)f(object)f(code)h(together)e(into)i(PROG)150
+872 y(ltx2x)g(:)h(${OBJS})499 971 y(${CC})e(-o)i(${PROG})e(${OBJS})f
+(${LIBS})150 1171 y(#)j(Compile)e(C)i(source)e(code)h(into)g(object)f
+(code)150 1270 y(getopt.o)f(:)j(getopt.c)e(getopt.h)499
+1370 y(${CC})g(-c)i(getopt.c)150 1469 y(l2xytab.o)d(:)j(l2xytab.c)d
+(l2xlib.h)g(l2xusrlb.h)83 b(l2xacts.h)40 b(strtypes.h)g(l2xcom.h)499
+1569 y(${CC})h(-c)i(l2xytab.c)150 1669 y(l2xlexyy.o)c(:)44
+b(l2xlexyy.c)39 b(l2xytab.h)h(l2xlib.h)84 b(l2xusrlb.h)39
+b(l2xcom.h)499 1768 y(${CC})i(-c)i(l2xlexyy.c)150 1868
+y(l2xlib.o)d(:)j(l2xlib.c)e(getopt.h)f(l2xytab.h)g(strtypes.h)f
+(l2xcom.h)499 1968 y(${CC})i(-c)i(l2xlib.c)150 2067 y(l2xusrlb.o)c(:)44
+b(l2xusrlb.c)39 b(l2xlib.h)h(l2xytab.h)g(strtypes.h)g(l2xcom.h)499
+2167 y(${CC})h(-c)i(l2xusrlb.c)150 2267 y(l2xacts.o)d(:)j(l2xacts.c)d
+(l2xusrlb.h)f(l2xlib.h)i(l2xytab.h)e(strtypes.h)h(l2xcom.h)499
+2366 y(${CC})h(-c)i(l2xacts.c)150 2466 y(srchenv.o)d(:)j(srchenv.c)d
+(srchenv.h)499 2565 y(${CC})h(-c)i(srchenv.c)150 2765
+y(#)g(Generate)d(C)k(code)e(for)g(parsing)150 2864 y(l2xytab.c)e
+(l2xytab.h:)f(l2x.y)499 2964 y(@)k(${ECHO})e("Expect)f(10)j
+(shift/reduce)c(conflicts)g(to)k(be)g(reported")499 3064
+y(${YACC})d(${YACCFLAGS})f(l2x.y)499 3163 y(${MOVE})h(y.tab.c)h
+(l2xytab.c)499 3263 y(${MOVE})f(y.tab.h)h(l2xytab.h)150
+3462 y(#)i(Generate)d(C)k(code)e(for)g(lexing)150 3562
+y(l2xlexyy.c)d(:)44 b(l2x.l)499 3661 y(${LEX})d(${LEXFLAGS})e(l2x.l)499
+3761 y(${MOVE})h(lex.yy.c)h(l2xlexyy.c)150 3960 y(#)i(the)g
+(interpreter)c(modules)150 4159 y(#)k(compiler)d(flags)i(for)g(analyze)
+f(and)h(execute)f(modules)150 4259 y(ANLFLAG)g(=)i(-Danalyze)150
+4359 y(RUNFLAG)e(=)i(-Dtrace)150 4558 y(#)g(interpreter)c(header)i
+(files)150 4658 y(SOMEH)h(=)h(l2xicmon.h)c(l2xierr.h)h(l2xiscan.h)f
+(l2xisymt.h)h(licomsym.h)f(l2xiidbg.h)150 4757 y(MOSTH)j(=)h(${SOMEH})d
+(l2xiprse.h)150 4857 y(ALLH)i(=)h(${MOSTH})d(l2xicpr.h)g(l2xiexec.h)150
+5056 y(#)j(interpreter)c(interface)150 5255 y(l2xistup.o)g(:)44
+b(l2xistup.c)39 b(${ALLH})1882 5531 y Fs(102)p eop
+%%Page: 103 107
+103 106 bop 499 573 a Fh(${CC})41 b(-c)i(${ANLFLAG})c(${RUNFLAG})h
+(l2xistup.c)150 772 y(#)j(the)g(parser)e(module)150 971
+y(l2xirtne.o)e(:)44 b(l2xirtne.c)39 b(${ALLH})499 1071
+y(${CC})i(-c)i(${ANLFLAG})c(l2xirtne.c)150 1270 y(l2xistd.o)h(:)j
+(l2xistd.c)d(${MOSTH})499 1370 y(${CC})h(-c)i(${ANLFLAG})c(${RUNFLAG})h
+(l2xistup.c)150 1569 y(l2xistup.o)f(:)44 b(l2xistup.c)39
+b(${ALLH})499 1669 y(${CC})i(-c)i(l2xistd.c)150 1868
+y(l2xidecl.o)c(:)44 b(l2xidecl.c)39 b(${MOSTH})h(l2xicpr.h)499
+1968 y(${CC})h(-c)i(${ANLFLAG})c(l2xisdecl.c)150 2167
+y(l2xistmt.o)g(:)44 b(l2xistmt.c)39 b(${ALLH})499 2267
+y(${CC})i(-c)i(${ANLFLAG})c(l2xistmt.c)150 2466 y(l2xiexpr.o)g(:)44
+b(l2xiexpr.c)39 b(${MOSTH})h(l2xicpr.h)499 2565 y(${CC})h(-c)i
+(${ANLFLAG})c(l2xiexpr.c)150 2765 y(#)k(the)g(scanner)d(module)150
+2964 y(l2xiscan.o)f(:)44 b(l2xiscan.c)39 b(${SOMEH})h(l2xicpr.h)499
+3064 y(${CC})h(-c)i(${ANLFLAG})c(l2xiscan.c)150 3263
+y(#)k(symbol)e(table)h(module)150 3462 y(l2xisymt.o)d(:)44
+b(l2xisymt.c)39 b(l2xicmon.h)h(l2xierr.h)f(l2xisymt.h)h(licomsym.h)f
+(l2xiidbg.h)499 3562 y(${CC})i(-c)i(l2xisymt.c)150 3761
+y(#)g(executor)d(module)150 3960 y(l2xixutl.o)f(:)44
+b(l2xixutl.c)39 b(${MOSTH})h(l2xiexec.h)g(listsetc.h)499
+4060 y(${CC})h(-c)i(${RUNFLAG})c(l2xixutl.c)150 4259
+y(l2xixstm.o)g(:)44 b(l2xixstm.c)39 b(${MOSTH})h(l2xiexec.h)g
+(listsetc.h)499 4359 y(${CC})h(-c)i(${RUNFLAG})c(l2xixstm.c)150
+4558 y(l2xixxpr.o)g(:)44 b(l2xixxpr.c)39 b(${MOSTH})h(l2xiexec.h)g
+(listsetc.h)499 4658 y(${CC})h(-c)i(${RUNFLAG})c(l2xixxpr.c)150
+4857 y(l2xixstd.o)g(:)44 b(l2xixstd.c)39 b(${MOSTH})h(l2xiexec.h)g
+(listsetc.h)499 4956 y(${CC})h(-c)i(${RUNFLAG})c(l2xixstd.c)150
+5156 y(l2xidbug.o)g(:)44 b(l2xidbug.c)39 b(${SOMEH})h(l2xiexec.h)g
+(listsetc.h)499 5255 y(${CC})h(-c)i(${RUNFLAG})c(l2xidbug.c)1882
+5531 y Fs(103)p eop
+%%Page: 104 108
+104 107 bop 150 672 a Fh(#)43 b(error)f(and)g(miscellaneous)150
+872 y(l2xisdcl.o)d(:)44 b(l2xisdcl.c)39 b(${SOMEH})499
+971 y(${CC})i(-c)i(${ANLFLAG})c(${RUNFLAG})h(l2xisdcl.c)150
+1171 y(l2xiidbg.o)f(:)44 b(l2xiidbg.c)39 b(${SOMEH})h(l2xiexec.h)499
+1270 y(${CC})h(-c)i(l2xiidbg.c)150 1469 y(l2xirexp.o)c(:)44
+b(l2xirexp.c)39 b(l2xirexp.h)499 1569 y(${CC})i(-c)i(l2xirexp.c)150
+1768 y(listsetc.o)c(:)44 b(listsetc.c)39 b(listsetc.h)499
+1868 y(${CC})i(-c)i(listsetc.c)150 2067 y(#)g(only)f(call)g(make)g
+(install)f(if)h(BINDIR)g(has)g(been)g(set)150 2167 y(install)f(:)i
+(ltx2x)499 2267 y(${MAKEDIR})c(${BINDIR})499 2366 y(${MOVE})h(${PROG})h
+(${BINDIR})150 2565 y(#)i(Edit)f(the)g(file)g(man)h(to)f(replace)f
+(DOCUMENTDIR)e(by)k(the)f(actual)f(directory)150 2665
+y(#)i(where)f(the)g(user)g(manual)f(is)i(to)g(be)f(placed,)f(and)h
+(CTDIR)g(by)h(the)f(location)150 2765 y(#)h(of)g(the)f(example)f
+(command)g(table)g(files.)150 2864 y(#)i(Then)f(copy)g(the)g(manpage)f
+(to)i(the)f(proper)f(place)150 2964 y(manpage)g(:)499
+3064 y(${SED})g('s!DOCUMENTDIR!$)o({D)o(OCD)o(IR)o(}!)o(;)d
+(s!CTDIR!${CTDIR)o(}!')f(man)42 b(>)h(tman)499 3163 y(${MAKEDIR})c
+(${MANDIR})499 3263 y(${COPY})h(tman)i(${MANDIR}/${PROG})o(.$)o({MA)o
+(NE)o(XT})150 3462 y(#)h(Copy)f(the)g(user)g(manuals)f(to)i(the)f
+(proper)f(place)150 3562 y(doc)h(:)499 3661 y(${MAKEDIR})d(${DOCDIR})
+499 3761 y(${COPY})h(ltx2x.tex)g(${DOCDIR}/${PROG})o(.t)o(ex)499
+3861 y(${COPY})g(ltx2x.ps)h(${DOCDIR}/${PRO)o(G}.)o(ps)499
+3960 y(${COPY})f(ltx2x.txt)g(${DOCDIR}/${PROG})o(.t)o(xt)499
+4060 y(${COPY})g(ltx2x.html)g(${DOCDIR}/${PROG)o(}.)o(htm)o(l)150
+4259 y(#)j(Copy)f(the)g(example)f(command)g(tables)g(to)i(their)e
+(final)h(location)150 4359 y(ctables)f(:)499 4458 y(${MAKEDIR})e
+(${CTDIR})499 4558 y(${COPY})h(ltx2x.ct)h(${CTDIR}/ltx2x.)o(ct)499
+4658 y(${COPY})f(detex.ct)h(${CTDIR}/detex.)o(ct)499
+4757 y(${COPY})f(remcom.ct)g(${CTDIR}/remcom.c)o(t)499
+4857 y(${COPY})g(l2h.ct)h(${CTDIR}/l2h.ct)499 4956 y(${COPY})f(bye.ct)h
+(${CTDIR}/bye.ct)499 5056 y(${COPY})f(fun.ct)h(${CTDIR}/fun.ct)150
+5255 y(#)i(Do)g(almost)e(everything)e(except)j(clean)f(up)1882
+5531 y Fs(104)p eop
+%%Page: 105 109
+105 108 bop 150 573 a Fh(all)42 b(:)i(ltx2x)d(install)g(manpage)f(doc)j
+(ctables)150 772 y(#)g(call)f(make)g(clean)g(to)g(remove)f(the)i
+(object)e(files,)g(info)h(from)g(YACC,)150 872 y(#)h(and)g(the)f
+(edited)f(version)g(of)h(the)h(manpage)150 971 y(clean)f(:)499
+1071 y(${DELETE})83 b(*.o)499 1171 y(${DELETE})40 b(y.output)499
+1270 y(${DELETE})g(tman)150 1469 y(#)j(Compile)e(the)h(command)f(table)
+g(printer)150 1569 y(printct)g(:)i(printct.o)d(getopt.o)g(srchenv.o)499
+1669 y(${CC})h(-o)i(printct)e(printct.o)f(getopt.o)g(srchenv.o)150
+1868 y(printct.o)g(:)j(printct.c)d(getopt.h)g(strtypes.h)g(l2xcom.h)499
+1968 y(${CC})h(-c)i(printct.c)291 2180 y Fs(If)25 b(y)m(ou)g(use)g(the)
+g(ab)s(o)m(v)m(e)h(mak)m(e\014le)f(then)g(the)g(\014rst)g(part)g
+(should)e(b)s(e)h(edited)g(to)i(re\015ect)g(y)m(our)f(system's)150
+2293 y(con\014guration.)77 b(Y)-8 b(ou)44 b(could)d(do)i
+Fn(make)k(all)41 b Fs(whic)m(h)h(should)f(do)h(ev)m(erything)h(for)g(y)
+m(ou,)j(except)e(the)150 2406 y(cleaning)29 b(up.)40
+b(A)30 b(more)g(conserv)-5 b(ativ)m(e)31 b(approac)m(h)f(is)f
+(recommended.)40 b(First)30 b(just)f(do)h Fn(make)f Fs(whic)m(h)g(will)
+150 2519 y(generate)34 b(the)g(executable.)48 b(This)32
+b(can)h(then)f(b)s(e)h(tested.)49 b(When)33 b(all)e(is)h(w)m(ell)g(do)h
+Fn(make)47 b(install)31 b Fs(and)150 2632 y Fn(make)47
+b(manpage)36 b Fs(whic)m(h)h(will)f(put)i(the)g(executable)h(and)f(the)
+h(manpage)g(in)m(to)f(their)g(\014nal)f(p)s(ositions.)150
+2745 y(Finally)-8 b(,)29 b Fn(make)47 b(clean)29 b Fs(will)e(remo)m(v)m
+(e)32 b(the)f(in)m(termediate)f(\014les)f(generated)i(during)e(the)h
+(build)e(pro)s(cess.)291 2858 y(The)40 b(ab)s(o)m(v)m(e)i
+Fn(make)d Fs(\014le)h(uses)g(\015ex)h(as)g(the)f(lexer)h(generator.)72
+b(Y)-8 b(ou)41 b(can)g(use)f(y)m(our)h(fa)m(v)m(orite)h(one)150
+2971 y(instead)30 b(but)g(it)g(m)m(ust,)h(unlik)m(e)e(lex,)h(supp)s
+(ort)f(exclusiv)m(e)h(start)i(states.)42 b(Also,)31 b(bison)e(is)h
+(used)g(ab)s(o)m(v)m(e)i(as)150 3083 y(the)g(parser)f(generator.)46
+b(Again,)32 b(y)m(ou)g(can)g(use)g(y)m(our)f(fa)m(v)m(orite)i(one.)46
+b(As)31 b(far)h(as)g(I)f(am)h(a)m(w)m(are,)i(there)e(is)150
+3196 y(nothing)g(remark)-5 b(able)32 b(ab)s(out)h(the)g(grammar,)h
+(except)h(that)e(during)e(early)i(dev)m(elopmen)m(t)g(I)g(exceeded)150
+3309 y(the)e(size)f(limits)f(of)h(y)m(acc.)44 b(The)30
+b(grammar)g(has)h(b)s(een)f(simpli\014ed)d(since)i(then,)i(so)g(this)f
+(ma)m(y)h(no)f(longer)150 3422 y(b)s(e)g(a)g(problem.)150
+3535 y(NOTE:)j(If)f(bison)g(is)g(used)g(it)h(rep)s(orts)f(that)i(there)
+f(are)g(10)h(shift/reduce)e(con\015icts.)49 b(It)33 b(app)s(ears)f
+(that)150 3648 y(these)f(can)f(b)s(e)g(safely)g(ignored.)291
+3761 y(One)25 b(compilation)f(problem)g(has)h(b)s(een)f(noted)i(b)m(y)f
+(Uw)m(e)h(Sassen)m(b)s(erg)2680 3728 y Fr(12)2779 3761
+y Fs(on)f(AIX)h(3.2)g(and)f(IRIX)g(5.3)150 3874 y(systems,)40
+b(but)e(I)g(could)f(not)h(repro)s(duce)f(it)h(on)g(a)g(SunOS)e(4.1.3)k
+(system.)64 b(This)36 b(is)i(when)f(the)h(main)150 3987
+y(pro)s(cedure)31 b(of)h Fy(L)-7 b(TX2X)32 b Fs(is)g(pro)s(cessing)f
+(the)h(optional)f(command)h(line)f(argumen)m(ts.)46 b(F)-8
+b(or)33 b(some)g(reason)150 4100 y(it)d(had)g(di\016culties)f(with)g
+(the)i(C)f Fn(EOF)p Fs(.)g(The)h(symptom)f(w)m(as)h(that)g(the)g
+(program)g(compiled)e(but)h(when)150 4213 y(it)25 b(w)m(as)h(run)e(it)h
+(sat)h(there)g(absorbing)e(CPU)i(cycles)f(and)g(doing)g(nothing)g(as)g
+(it)g(had)g(got)i(in)m(to)f(an)f(in\014nite)150 4325
+y Fn(while)k Fs(lo)s(op.)40 b(The)30 b(cure)g(w)m(as)h(to)g(insert)e
+(the)i(follo)m(wing)d(line)h(of)i(co)s(de)f(in)f(\014le)h
+Fn(l2xlib.c)p Fs(:)150 4513 y Fn(main\(argc,argv\))150
+4626 y(...)245 4739 y(/*)48 b(get)f(command)e(line)i(optional)f
+(parameters)f(*/)245 4852 y(opterr)i(=)g(1;)334 b(/*)47
+b(getopt)f(prints)g(errors)g(if)h(opterr)f(is)h(1)h(*/)245
+4965 y(while)f(\(EOF)f(!=)i(\(optchar)d(=)532 5078 y
+(getopt\(argc,argv,)e("l:ty:f:cp:wE:P:D:"\)\)\))f({)p
+150 5159 1440 4 v 223 5213 a Fl(12)288 5245 y Fa
+(<sassen@hal1.physik.uni-dort)q(mund)q(.de>)1882 5531
+y Fs(105)p eop
+%%Page: 106 110
+106 109 bop 150 573 a Fn(/*)47 b(insert)f(this)h(line)g(of)g(code:)94
+b(if)47 b(\(optchar)f(==)h(255\))f(break;)94 b(end)47
+b(insert)f(*/)532 686 y(switch\(optchar\))d({)150 799
+y(...)150 986 y Fs(This)33 b(co)s(de)j(line)e(whic)m(h)g(y)m(ou)h(ma)m
+(y)h(need)f(to)h(insert)f(is)f(supplied)e(as)j(a)h(commen)m(t)g(in)e
+(the)i(distributed)150 1099 y(source.)150 1343 y Fj(E.3)112
+b(Limits)35 b(and)j(errors)150 1514 y Fs(The)32 b Fy(L)-7
+b(TX2X)32 b Fs(system)g(has)g(some)g(built-in)d(limits)h(whic)m(h)g
+(are)j(de\014ned)e(in)f Fn(l2xlib.c)p Fs(.)44 b(The)31
+b(follo)m(wing)150 1627 y(is)e(a)i(listing)d(of)j(the)g(relev)-5
+b(an)m(t)30 b(sizes.)150 1840 y Fh(CLAUSE)p 419 1840
+27 4 v 29 w(STACK)p 668 1840 V 29 w(SIZE)44 b Fs(The)30
+b(maxim)m(um)g(nesting)g(depth)g(of)h(do)s(cumen)m(t)f(sectioning.)41
+b(This)29 b(is)h(set)h(some-)377 1953 y(what)42 b(larger)g(than)g(the)g
+(n)m(um)m(b)s(er)f(of)h(standard)f(L)2151 1936 y Fr(A)2190
+1953 y Fs(T)2241 1972 y(E)2291 1953 y(X)i(sectioning)e(command)h(t)m
+(yp)s(es.)75 b(\(De-)377 2066 y(fault)30 b(10\))150 2253
+y Fh(EVERY)p 375 2253 V 29 w(N)p 448 2253 V 31 w(LINES)44
+b Fs(Con)m(trols)35 b(the)h(frequency)f(of)h(prin)m(ting)e(pro)s
+(cessed)h(line)f(n)m(um)m(b)s(ers)h(to)h(the)g(terminal.)377
+2366 y(\(Default)31 b(100\))150 2554 y Fh(LIST)p 331
+2554 V 30 w(STACK)p 581 2554 V 29 w(SIZE)44 b Fs(The)35
+b(maxim)m(um)f(nesting)g(depth)g(of)i(list)e(en)m(vironmen)m(ts.)54
+b(This)34 b(is)g(set)i(somewhat)377 2667 y(larger)30
+b(than)g(the)h(standard)f(L)1408 2650 y Fr(A)1447 2667
+y Fs(T)1498 2686 y(E)1548 2667 y(X)g(nesting)g(depth.)40
+b(\(Default)31 b(10\))150 2854 y Fh(MAX)p 287 2854 V
+30 w(BUFFER)43 b Fs(The)28 b(maxim)m(um)f(n)m(um)m(b)s(er)g(of)h(c)m
+(haracters)i(that)e(can)h(b)s(e)e(held)g(in)g(the)h(system)h(bu\013er,)
+f(and)377 2967 y(also)21 b(the)g(maxim)m(um)e(n)m(um)m(b)s(er)g(of)i(c)
+m(haracters)h(in)e(a)h(prett)m(y-prin)m(ted)f(output)g(line.)36
+b(\(Default)21 b(2000\))150 3155 y Fh(MAX)p 287 3155
+V 30 w(CT)p 405 3155 V 31 w(STACK)43 b Fs(The)30 b(maxim)m(um)f
+(nesting)h(depth)f(for)i(included)c(command)j(table)h(\014les.)39
+b(\(Default)31 b(20\))150 3342 y Fh(MAX)p 287 3342 V
+30 w(ERRORS)43 b Fs(The)24 b(maxim)m(um)f(n)m(um)m(b)s(er)g(of)h
+(non-fatal)g(errors)g(disco)m(v)m(ered)g(in)f(command)h(table)g(pro)s
+(cess-)377 3455 y(ing)30 b(or)g(in)f(source)i(\014le)e(pro)s(cessing)g
+(b)s(efore)h Fy(L)-7 b(TX2X)31 b Fs(quits.)39 b(\(Default)31
+b(10\))150 3643 y Fh(MAX)p 287 3643 V 30 w(LINE)44 b
+Fs(The)23 b(maxim)m(um)f(n)m(um)m(b)s(er)g(of)i(c)m(haracters)g(in)e(a)
+i(line)e(of)h(a)h(L)2497 3626 y Fr(A)2536 3643 y Fs(T)2587
+3663 y(E)2638 3643 y(X)f(source)h(\014le.)37 b(\(Default)24
+b(2000\))150 3831 y Fh(MAX)p 287 3831 V 30 w(PRINT)p
+537 3831 V 29 w(STACK)44 b Fs(The)30 b(maxim)m(um)f(nesting)h(depth)f
+(for)h(prin)m(t)f(con)m(trol)i(commands.)40 b(\(Default)31
+b(100\))150 4018 y Fh(MAX)p 287 4018 V 30 w(TABLE)p 537
+4018 V 29 w(ENTRIES)43 b Fs(The)36 b(maxim)m(um)f(n)m(um)m(b)s(er)h(of)
+44 b Fh(TYPE)34 b Fs(sp)s(eci\014cations)i(in)f(a)i(command)f(table)h
+(\(in-)377 4131 y(cluding)28 b(the)j(built)d(in)h(t)m(yp)s(e)i(sp)s
+(eci\014cations\).)40 b(\(Default)30 b(1000\))150 4319
+y Fh(MAX)p 287 4319 V 30 w(TABLE)p 537 4319 V 29 w(LINE)44
+b Fs(The)g(maxim)m(um)g(n)m(um)m(b)s(er)f(of)i(c)m(haracters)h(in)e(a)h
+(line)e(in)g(a)i(command)g(table)g(\014le.)377 4432 y(\(Default)31
+b(254\))150 4619 y Fh(MAX)p 287 4619 V 30 w(USER)p 493
+4619 V 30 w(BUFFS)43 b Fs(The)30 b(maxim)m(um)f(n)m(um)m(b)s(er)g(of)i
+(user)f(bu\013ers.)39 b(\(Default)31 b(20\))150 4807
+y Fh(MAX)p 287 4807 V 30 w(UBUFF)p 537 4807 V 29 w(LEN)45
+b Fs(The)c(maxim)m(um)h(n)m(um)m(b)s(er)f(of)h(c)m(haracters)i(that)f
+(can)f(b)s(e)g(stored)g(in)f(a)i(user)f(bu\013er.)377
+4920 y(\(Default)31 b(510\))150 5107 y Fh(MAX)p 287 5107
+V 30 w(USER)p 493 5107 V 30 w(FILES)43 b Fs(The)30 b(maxim)m(um)f(n)m
+(um)m(b)s(er)g(of)i(user)f(\014les.)39 b(\(Default)31
+b(16\))1882 5531 y(106)p eop
+%%Page: 107 111
+107 110 bop 291 573 a Fy(L)-7 b(TX2X)37 b Fs(prin)m(ts)e(out)i(a)g
+(summary)e(of)i(the)g(program)f(statistices)h(at)h(the)f(end)f(of)h
+(the)f Fn(ltx2x.err)150 686 y Fs(\014le.)61 b(If)37 b(the)h(limits)d
+(are)j(not)g(suitable)e(for)h(y)m(our)g(purp)s(oses,)h(then)f(they)h
+(ma)m(y)g(b)s(e)f(c)m(hanged)h(and)f(the)150 799 y(system)31
+b(rebuilt.)291 912 y Fy(L)-7 b(TX2X)41 b Fs(can)f(pro)s(duce)g(a)h(v)-5
+b(ariet)m(y)40 b(of)h(error)f(and)g(w)m(arning)f(messages,)45
+b(for)40 b(example)g(when)g(an)m(y)150 1024 y(of)j(the)g(ab)s(o)m(v)m
+(e)g(limits)e(are)i(exceeded.)78 b(Some)43 b(of)f(the)h(messages)h(are)
+f(related)f(to)i(command)e(table)150 1137 y(pro)s(cessing,)f(while)d
+(others)h(are)h(related)g(to)g(L)1772 1121 y Fr(A)1811
+1137 y Fs(T)1862 1157 y(E)1912 1137 y(X)g(do)s(cumen)m(t)g(pro)s
+(cessing.)67 b(Both)40 b(these)g(kinds)e(of)150 1250
+y(messages)f(are)f(targeted)h(to)g(the)e(normal)g(end)g(user.)56
+b(There)36 b(is)e(another)i(set)h(of)e(messages)i(that)g(are)150
+1363 y(aimed)26 b(at)i(the)f(implemen)m(tor)f(of)h(new)g
+Fh(SPECIAL)p 1797 1363 27 4 v 56 w Fs(commands.)39 b(An)26
+b(implemen)m(tor)g(ma)m(y)h(also)g(\014nd)f(some)150
+1476 y(of)31 b(the)f(debugging)f(options)h(useful)f(if)g(things)g
+(really)h(fall)f(apart.)150 1720 y Fj(E.4)112 b(Av)-6
+b(ailabilit)m(y)150 1891 y Fs(Source)25 b(co)s(de)g(and)g(do)s(cumen)m
+(tation)g(for)f Fy(L)-7 b(TX2X)25 b Fs(is)g(a)m(v)-5
+b(ailable)24 b(from)h(the)g(NIST)f(SOLIS)g(\(SC4)h(On-Line)150
+2004 y(Information)k(Service\))h(system)h([17)q(])g(in)e(directory)150
+2117 y Fn(/subject/sc4/editing/lat)o(ex/p)o(rogr)o(ams)o(/ltx)o(2x)p
+Fs(.)150 2230 y(SOLIS)g(can)h(b)s(e)g(accessed)i(b)m(y:)286
+2418 y Fm(\017)46 b Fs(Anon)m(ymous)30 b(ftp)g(to)h Fn
+(ftp.cme.nist.gov)26 b Fs(\()p Fn(cd)k Fs(to)h Fn(/pub/subject/sc4...)p
+Fs(\))286 2605 y Fm(\017)46 b Fs(URL)30 b Fn(http://www.nist.gov/sc4)
+291 2793 y Fs(An)m(y)h(commen)m(ts)g(should)d(b)s(e)i(directed)g(to)h
+Fn(apde@cme.nist.gov)p Fs(.)150 3033 y Ft(E.4.1)105 b(Cop)m(yrigh)m(t)
+150 3205 y Fs(Dev)m(elopmen)m(t)45 b(of)e(this)f(soft)m(w)m(are)j(w)m
+(as)f(funded)d(b)m(y)i(the)h(United)e(States)j(Go)m(v)m(ernmen)m(t)g
+(and)d(is)h(not)150 3317 y(sub)5 b(ject)30 b(to)h(cop)m(yrigh)m(t.)41
+b(It)30 b(w)m(as)g(dev)m(elop)s(ed)g(b)m(y)g(the)g(Man)m(ufacturing)g
+(Systems)f(In)m(tegration)i(Division)150 3430 y(\(MSID\))j(of)f(the)h
+(Man)m(ufacturing)f(Engineering)e(Lab)s(oratory)i(\(MEL\))h(of)g(the)f
+(National)g(Institute)g(of)150 3543 y(Standards)c(and)h(T)-8
+b(ec)m(hnology)31 b(\(NIST\).)150 3783 y Ft(E.4.2)105
+b(Disclaimer)150 3955 y Fs(There)24 b(is)g(no)g(w)m(arran)m(t)m(y)i
+(for)e(the)h Fy(L)-7 b(TX2X)25 b Fs(soft)m(w)m(are.)40
+b(If)24 b(the)h Fy(L)-7 b(TX2X)24 b Fs(soft)m(w)m(are)j(is)c(mo)s
+(di\014ed)g(b)m(y)h(someone)150 4068 y(else)29 b(and)f(passed)h(on,)g
+(NIST)f(requests)h(that)h(the)f(soft)m(w)m(are's)i(recipien)m(ts)d(b)s
+(e)g(noti\014ed)g(that)i(what)f(they)150 4181 y(ha)m(v)m(e)j(is)d(not)i
+(what)f(NIST)f(distributed.)150 4393 y Ft(P)m(olicies)461
+4581 y Fs(1.)46 b(An)m(y)m(one)33 b(ma)m(y)f(cop)m(y)g(and)f
+(distribute)e(v)m(erbatim)i(copies)g(of)h(the)g(source)f(co)s(de)h(as)g
+(receiv)m(ed)577 4694 y(in)d(an)m(y)i(medium.)461 4840
+y(2.)46 b(An)m(y)m(one)26 b(ma)m(y)f(mo)s(dify)e(y)m(our)h(cop)m(y)i
+(or)e(copies)h(of)g(the)g Fy(L)-7 b(TX2X)24 b Fs(source)h(co)s(de)g(or)
+f(an)m(y)h(p)s(ortion)577 4953 y(of)k(it,)g(and)f(cop)m(y)i(and)e
+(distribute)f(suc)m(h)h(mo)s(di\014cations)f(pro)m(vided)h(that)h(all)f
+(mo)s(di\014cations)577 5066 y(are)j(clearly)f(asso)s(ciated)h(with)e
+(the)h(en)m(tit)m(y)h(that)g(p)s(erforms)e(the)i(mo)s(di\014cations.)
+1882 5531 y(107)p eop
+%%Page: 108 112
+108 111 bop 150 573 a Ft(NO)34 b(W)-12 b(ARRANTY)377
+723 y Fs(NIST)48 b(PR)m(O)m(VIDES)h(ABSOLUTEL)-8 b(Y)49
+b(NO)g(W)-10 b(ARRANTY.)49 b(THE)g Fy(L)-7 b(TX2X)48
+b Fs(SOFTW)-10 b(ARE)377 836 y(IS)40 b(PR)m(O)m(VIDED)h(`AS)f(IS')g
+(WITHOUT)g(W)-10 b(ARRANTY)41 b(OF)f(ANY)h(KIND,)f(EITHER)g(EX-)377
+949 y(PRESSED)29 b(OR)g(IMPLIED,)h(INCLUDING,)h(BUT)f(NOT)f(LIMITED)g
+(TO,)h(THE)f(IMPLIED)377 1062 y(W)-10 b(ARRANTIES)31
+b(OF)h(MER)m(CHANT)-8 b(ABILITY)32 b(AND)g(FITNESS)e(F)m(OR)i(A)g(P)-8
+b(AR)g(TICULAR)377 1175 y(PURPOSE.)34 b(THE)h(ENTIRE)f(RISK)f(AS)i(TO)f
+(THE)g(QUALITY)g(AND)i(PERF)m(ORMANCE)377 1288 y(OF)e(THE)f(PR)m(OGRAM)
+i(IS)e(WITH)g(YOU.)h(SHOULD)g(ANY)g(POR)-8 b(TION)33
+b(OF)h(THE)f Fy(L)-7 b(TX2X)377 1401 y Fs(SOFTW)d(ARE)29
+b(PR)m(O)m(VE)g(DEFECTIVE,)g(YOU)h(ASSUME)e(THE)h(COST)f(OF)h(ALL)g
+(NECES-)377 1513 y(SAR)-8 b(Y)31 b(SER)-10 b(VICING,)30
+b(REP)-8 b(AIR)30 b(OR)g(CORRECTION.)377 1664 y(IN)46
+b(NO)g(EVENT)f(WILL)h(NIST)f(BE)h(LIABLE)f(F)m(OR)h(D)m(AMA)m(GES,)i
+(INCLUDING)e(ANY)377 1777 y(LOST)23 b(PR)m(OFITS,)g(LOST)f(MONIES,)i
+(OR)f(OTHER)g(SPECIAL,)g(INCIDENT)-8 b(AL)24 b(OR)f(CON-)377
+1890 y(SEQUENTIAL)h(D)m(AMA)m(GES)k(ARISING)d(OUT)g(OF)g(THE)g(USE)g
+(OR)g(INABILITY)h(TO)e(USE)377 2002 y(\(INCLUDING)31
+b(BUT)g(NOT)e(LIMITED)h(TO)g(LOSS)f(OF)h(D)m(A)-8 b(T)g(A)32
+b(OR)e(D)m(A)-8 b(T)g(A)32 b(BEING)f(REN-)377 2115 y(DERED)43
+b(INA)m(CCURA)-8 b(TE)43 b(OR)f(LOSSES)e(SUST)-8 b(AINED)42
+b(BY)h(THIRD)g(P)-8 b(AR)g(TIES)42 b(OR)g(A)377 2228
+y(F)-10 b(AILURE)43 b(OF)g(THE)g(PR)m(OGRAM)g(TO)f(OPERA)-8
+b(TE)43 b(WITH)f(PR)m(OGRAMS)i(NOT)e(DIS-)377 2341 y(TRIBUTED)25
+b(BY)g(NIST\))f(THE)g(PR)m(OGRAMS,)h(EVEN)f(IF)h(YOU)g(HA)-10
+b(VE)24 b(BEEN)h(AD)m(VISED)377 2454 y(OF)37 b(THE)f(POSSIBILITY)f(OF)i
+(SUCH)f(D)m(AMA)m(GES,)j(OR)d(F)m(OR)h(ANY)h(CLAIM)e(BY)h(ANY)377
+2567 y(OTHER)30 b(P)-8 b(AR)g(TY.)150 2853 y Fu(F)134
+b(A)44 b(grammar)i(for)f(the)h(command)e(table)150 3060
+y Fj(F.1)113 b(Notation)150 3231 y Fs(The)35 b(syn)m(tactical)h
+(constructs)g(used)e(corresp)s(ond)h(to)h(a)g(deriv)-5
+b(ativ)m(e)35 b(of)g(the)h(Wirth)e(Syn)m(tax)i(Notation)150
+3344 y(\(WSN\))31 b([18)q(].)41 b(The)30 b(seman)m(tics)h(of)f(the)h
+(enclosing)e(braces)i(are:)286 3532 y Fm(\017)46 b Fs(curly)29
+b(braces)i(`)p Fm(f)48 b(g)p Fs(')31 b(indicate)f(xero)g(or)h(more)f
+(rep)s(etitions;)286 3720 y Fm(\017)46 b Fs(square)30
+b(brac)m(k)m(ets)i(`)p Fn([)48 b(])p Fs(')30 b(indicate)g(an)g
+(optional)f(elemen)m(t;)286 3907 y Fm(\017)46 b Fs(paren)m(thesis)30
+b(`)p Fn(\()47 b(\))p Fs(')31 b(indicates)e(a)i(group;)286
+4095 y Fm(\017)46 b Fs(v)m(ertical)e(bar)f(`)p Fn(|)p
+Fs(')g(indicates)g(that)h(exactly)g(one)g(of)f(the)h(terms)f(in)f(the)i
+(expression)e(shall)g(b)s(e)377 4208 y(c)m(hosen.)291
+4382 y(Here)31 b(is)e(the)i(grammar)f(for)h(WSN)f(de\014ned)f(in)g
+(itself.)150 4556 y Fh(syntax)215 b(=)44 b({)f(production)c(})k(.)150
+4656 y(production)c(=)44 b(identifier)39 b('=')j(expression)e('.')i(.)
+150 4756 y(expression)d(=)44 b(term)e({)h('|')f(term)g(})h(.)150
+4855 y(term)303 b(=)44 b(factor)d({)i(factor)e(})i(.)150
+4955 y(factor)215 b(=)44 b(identifier)39 b(|)k(literal)e(|)i(group)f(|)
+h(option)e(|)i(repetition)d(.)150 5055 y(identifier)f(=)44
+b(character)39 b({)44 b(character)c(})j(.)150 5154 y(literal)171
+b(=)44 b('''')e(character)d({)44 b(character)39 b(})44
+b('''')e(.)150 5254 y(group)259 b(=)44 b('\(')e(expression)d('\)')k(.)
+1882 5531 y Fs(108)p eop
+%%Page: 109 113
+109 112 bop 150 573 a Fh(option)215 b(=)44 b('[')e(expression)d(']')k
+(.)150 672 y(repetition)c(=)44 b('{')e(expression)d('}')k(.)291
+859 y Fs(W)-8 b(e)32 b(also)e(use)g(the)h(follo)m(wing)e(shorthand)g
+(notation)h(for)g(particular)f(c)m(haracters:)286 1045
+y Fm(\017)46 b Fn(\\c)30 b Fs(|)g(an)m(y)h(prin)m(table)e(c)m(haracter)
+286 1232 y Fm(\017)46 b Fn(\\n)30 b Fs(|)g(the)h(end)f(of)g(line)f(c)m
+(haracter\(s\))286 1419 y Fm(\017)46 b Fn(eof)30 b Fs(|)g(the)h(end)e
+(of)i(\014le)e(c)m(haracter\(s\))150 1662 y Fj(F.2)113
+b(Grammar)150 1821 y Fs(First,)30 b(the)h(k)m(eyw)m(ords.)41
+b(Note)31 b(that)g(these)g(are)g(case)g(insensitiv)m(e.)150
+1994 y Fh(AudibleAlertChar)37 b(=)43 b('AUDIBLE_ALERT_CH)o(AR)o(=')37
+b(.)150 2093 y(BackspaceChar)h(=)43 b('BACKSPACE_CHAR=')37
+b(.)150 2193 y(BeginDocument)h(=)43 b('BEGIN_DOCUMENT')37
+b(.)150 2293 y(BeginDollar)i(=)k('BEGIN_DOLAR')38 b(.)150
+2392 y(BeginEnv)i(=)j('BEGIN_ENV')c(.)150 2492 y(BeginListEnv)g(=)k
+('BEGIN_LIST_ENV')37 b(.)150 2592 y(BeginPictureCc)h(=)43
+b('BEGIN_PICTURE_C)o(C')37 b(.)150 2691 y(BeginVenv)j(=)j('BEGIN_VENV')
+c(.)150 2791 y(BeginVerb)h(=)j('BEGIN_VERB')c(.)150 2890
+y(BeginVerbatim)f(=)43 b('BEGIN_VERBATIM')37 b(.)150
+2990 y(Buffer)k(=)i('BUFFER')e(.)150 3090 y(CarriageReturnCh)o(ar)c(=)
+43 b('CARRIAGE_RETURN_)o(CH)o(AR=)o(')37 b(.)150 3189
+y(Chapter)k(=)i('CHAPTER')d(.)150 3289 y(CharCommand)f(=)k
+('CHAR_COMMAND')38 b(.)150 3389 y(Command)j(=)i('COMMAND')d(.)150
+3488 y(CommandOop)f(=)44 b('COMMAND_OOP')38 b(.)150 3588
+y(CommandOoopp)h(=)k('COMMAND_OOOPP')37 b(.)150 3688
+y(CommandOpo)i(=)44 b('COMMAND_OPO')38 b(.)150 3787 y(CommandPooop)h(=)
+k('COMMAND_POOOP')37 b(.)150 3887 y(CommandPoop)i(=)k('COMMAND_POOP')38
+b(.)150 3986 y(CommandPoopp)h(=)k('COMMAND_POOPP')37
+b(.)150 4086 y(Comment)k(=)i('C=')f(.)150 4186 y(EndCtfile)e(=)j
+('END_CTFILE=')38 b(.)150 4285 y(EndDocument)h(=)k('END_DOCUMENT')38
+b(.)150 4385 y(EndDollar)i(=)j('END_DOLAR')c(.)150 4485
+y(EndEnv)i(=)i('END_ENV')d(.)150 4584 y(EndItem)h(=)i('END_ITEM=')c(.)
+150 4684 y(EndItemParam)g(=)k('END_ITEM_PARAM=)o(')37
+b(.)150 4783 y(EndListEnv)i(=)44 b('END_LIST_ENV')37
+b(.)150 4883 y(EndMode)k(=)i('END_MODE')c(.)150 4983
+y(EndOpt)i(=)i('END_OPT=')d(.)150 5082 y(EndPicture)f(=)44
+b('END_PICTURE')38 b(.)150 5182 y(EndTag)j(=)i('END_TAG=')d(.)150
+5282 y(EndTag1)h(=)i('END_TAG_1=')38 b(.)1882 5531 y
+Fs(109)p eop
+%%Page: 110 114
+110 113 bop 150 573 a Fh(EndTag2)41 b(=)i('END_TAG_2=')38
+b(.)150 672 y(EndTag3)j(=)i('END_TAG_3=')38 b(.)150 772
+y(EndTag4)j(=)i('END_TAG_4=')38 b(.)150 872 y(EndTag5)j(=)i
+('END_TAG_5=')38 b(.)150 971 y(EndTag6)j(=)i('END_TAG_6=')38
+b(.)150 1071 y(EndTag7)j(=)i('END_TAG_7=')38 b(.)150
+1171 y(EndTag8)j(=)i('END_TAG_8=')38 b(.)150 1270 y(EndTag9)j(=)i
+('END_TAG_9=')38 b(.)150 1370 y(EndType)j(=)i('END_TYPE')c(.)150
+1469 y(EndVenv)i(=)i('END_VENV')c(.)150 1569 y(EndVerb)i(=)i
+('END_VERB')c(.)150 1669 y(EndVerbatim)g(=)k('END_VERBATIM')38
+b(.)150 1768 y(EscapeChar)h(=)44 b('ESCAPE_CHAR=')37
+b(.)150 1868 y(File)42 b(=)h('FILE')e(.)150 1968 y(First)h(=)h('FIRST')
+d(.)150 2067 y(FormfeedChar)f(=)k('FORMFEED_CHAR=')37
+b(.)150 2167 y(HexChar)k(=)i('HEX_CHAR=')c(.)150 2267
+y(HorizontalTabCha)o(r)f(=)43 b('HORIZONTAL_TAB_)o(CH)o(AR)o(=')37
+b(.)150 2366 y(Include)k(=)i('INCLUDE=')c(.)150 2466
+y(InMode)i(=)i('IN_MODE=')d(.)150 2565 y(Last)i(=)h('LAST')e(.)150
+2665 y(Lbrace)g(=)i('LBRACE')e(.)150 2765 y(Name)h(=)h('NAME=')e(.)150
+2864 y(NewlineChar)e(=)k('NEWLINE_CHAR=')38 b(.)150 2964
+y(NoOp)k(=)h('NO_OP')e(.)150 3064 y(NoPrint)g(=)i('NO_PRINT')c(.)150
+3163 y(OptParam)h(=)j('OPT_PARAM=')c(.)150 3263 y(OtherBegin)g(=)44
+b('OTHER_BEGIN')38 b(.)150 3362 y(OtherCommand)h(=)k('OTHER_COMMAND')37
+b(.)150 3462 y(OtherEnd)j(=)j('OTHER_END')c(.)150 3562
+y(Para)j(=)h('PARA')e(.)150 3661 y(Paragraph)f(=)j('PARAGRAPH')c(.)150
+3761 y(Part)j(=)h('PART')e(.)150 3861 y(Partm1)g(=)i('PARTm1')e(.)150
+3960 y(Partm2)g(=)i('PARTm2')e(.)150 4060 y(PcAtEnd)g(=)i('PC_AT_END=')
+38 b(.)150 4159 y(PcAtStart)i(=)j('PC_AT_START=')38 b(.)150
+4259 y(PictureCcpp)h(=)k('PICTURE_CCPP')38 b(.)150 4359
+y(PictureCo)i(=)j('PICTURE_CO')c(.)150 4458 y(PictureCop)g(=)44
+b('PICTURE_COP')38 b(.)150 4558 y(PictureCp)i(=)j('PICTURE_CP')c(.)150
+4658 y(PictureOcc)g(=)44 b('PICTURE_OCC')38 b(.)150 4757
+y(PictureOccc)h(=)k('PICTURE_OCCC')38 b(.)150 4857 y(PictureOco)h(=)44
+b('PICTURE_OCO')38 b(.)150 4956 y(PicturePcop)h(=)k('PICTURE_PCOP')38
+b(.)150 5056 y(PrintControl)h(=)k('PRINT_CONTROL=')37
+b(.)150 5156 y(PrintP1)k(=)i('PRINT_P1=')c(.)150 5255
+y(PrintP2)i(=)i('PRINT_P2=')c(.)1882 5531 y Fs(110)p
+eop
+%%Page: 111 115
+111 114 bop 150 573 a Fh(PrintP3)41 b(=)i('PRINT_P3=')c(.)150
+672 y(PrintP4)i(=)i('PRINT_P4=')c(.)150 772 y(PrintP5)i(=)i
+('PRINT_P5=')c(.)150 872 y(PrintP6)i(=)i('PRINT_P6=')c(.)150
+971 y(PrintP7)i(=)i('PRINT_P7=')c(.)150 1071 y(PrintP8)i(=)i
+('PRINT_P8=')c(.)150 1171 y(PrintP9)i(=)i('PRINT_P9=')c(.)150
+1270 y(PrintOpt)h(=)j('PRINT_OPT=')c(.)150 1370 y(Rbrace)i(=)i
+('RBRACE')e(.)150 1469 y(Reqparams)f(=)j('REQPARAMS=')c(.)150
+1569 y(Reset)j(=)h('RESET')d(.)150 1669 y(ResetBuffer)f(=)k
+('RESET_BUFFER:')38 b(.)150 1768 y(ResetMode)i(=)j('RESET_MODE:')38
+b(.)150 1868 y(Sect)k(=)h('SECT')e(.)150 1968 y(Sectioning)e(=)44
+b('SECTIONING')38 b(.)150 2067 y(SectioningLevel)f(=)44
+b('SECTIONING_LEV)o(EL=)o(')37 b(.)150 2167 y(SetMode)k(=)i
+('SET_MODE:')c(.)150 2267 y(SlashSpace)g(=)44 b('SLASH_SPACE')38
+b(.)150 2366 y(Source)j(=)i('SOURCE:')d(.)150 2466 y(Special)h(=)i
+('SPECIAL')d(.)150 2565 y(SpecialBeginEnv)d(=)44 b('SPECIAL_BEGIN_)o
+(ENV)o(')37 b(.)150 2665 y(SpecialBeginList)g(=)43 b('SPECIAL_BEGIN_LI)
+o(ST)o(')37 b(.)150 2765 y(SpecialCommand)h(=)43 b('SPECIAL_COMMAND)o
+(')38 b(.)150 2864 y(SpecialEndEnv)g(=)43 b('SPECIAL_END_ENV')37
+b(.)150 2964 y(SpecialEndList)h(=)43 b('SPECIAL_END_LIS)o(T')37
+b(.)150 3064 y(SpecialSectionin)o(g)h(=)43 b('SPECIAL_SECTION)o(IN)o
+(G')37 b(.)150 3163 y(StartItem)j(=)j('START_ITEM=')38
+b(.)150 3263 y(StartItemParam)g(=)43 b('START_ITEM_PARA)o(M=')37
+b(.)150 3362 y(StartOpt)j(=)j('START_OPT=')c(.)150 3462
+y(StartTag)h(=)j('START_TAG=')c(.)150 3562 y(StartTag1)h(=)j
+('START_TAG_1=')38 b(.)150 3661 y(StartTag2)i(=)j('START_TAG_2=')38
+b(.)150 3761 y(StartTag3)i(=)j('START_TAG_3=')38 b(.)150
+3861 y(StartTag4)i(=)j('START_TAG_4=')38 b(.)150 3960
+y(StartTag5)i(=)j('START_TAG_5=')38 b(.)150 4060 y(StartTag6)i(=)j
+('START_TAG_6=')38 b(.)150 4159 y(StartTag7)i(=)j('START_TAG_7=')38
+b(.)150 4259 y(StartTag8)i(=)j('START_TAG_8=')38 b(.)150
+4359 y(StartTag9)i(=)j('START_TAG_9=')38 b(.)150 4458
+y(String)j(=)i('STRING:')d(.)150 4558 y(SubPara)h(=)i('SUBPARA')d(.)150
+4658 y(SubParap1)g(=)j('SUBPARAp1')c(.)150 4757 y(SubParap2)h(=)j
+('SUBPARAp2')c(.)150 4857 y(SubSect)i(=)i('SUBSECT')d(.)150
+4956 y(SubSubSect)f(=)44 b('SUBSUBSECT')38 b(.)150 5056
+y(SwitchBack)h(=)44 b('SWITCH_BACL:)38 b(')43 b(.)150
+5156 y(SwitchToBuffer)38 b(=)43 b('SWITCH_TO_BUFFE)o(R:)37
+b(')43 b(.)150 5255 y(SwitchToFile)c(=)k('SWITCH_TO_FILE:)37
+b(')43 b(.)1882 5531 y Fs(111)p eop
+%%Page: 112 116
+112 115 bop 150 573 a Fh(SwitchToSysbuf)38 b(=)43 b('SWITCH_TO_SYSBU)o
+(F:)37 b(')43 b(.)150 672 y(Sysbuf)e(=)i('SYSBUF')e(.)150
+772 y(TexChar)g(=)i('TEX_CHAR')c(.)150 872 y(ToBuffer)h(=)j
+('TO_BUFFER')c(.)150 971 y(ToFile)i(=)i('TO_FILE')d(.)150
+1071 y(ToSysbuf)g(=)j('TO_SYSBUF')c(.)150 1171 y(Type)j(=)h('TYPE=')e
+(.)150 1270 y(Vcommand)f(=)j('VCOMMAND')d(.)150 1370
+y(VerticalTabChar)d(=)44 b('VERTICAL_TAB_C)o(HAR)o(=')37
+b(.)291 1544 y Fs(Some)31 b(utilit)m(y)d(pro)s(ductions.)150
+1719 y Fh(latex_id)40 b(=)j(\\c)g({)g(\\c)g(})g(.)150
+1818 y(name)f(=)h(\\c)g({)g(\\c)g(})g(.)150 1918 y(text)f(=)h('"')f({)i
+(\\c)e(})i('"')e(.)150 2017 y(Eol)g(=)i(\\n)e(.)150 2117
+y(digit)g(=)h('0')f(|)h('1')g(|)g('2')f(|)h('3')g(|)g('4')f(|)h('5')g
+(|)g('6')f(|)h('7')g(|)g('8')f(|)h('9')g(.)150 2217 y(integer)e(=)i
+(digit)e({)j(digit)d(})i(.)150 2316 y(ct_file_name)c(=)k(name)f(.)150
+2416 y(file_id)f(=)i(name)f(.)150 2516 y(buffer_id)e(=)j(integer)e(.)
+150 2615 y(mode_id)g(=)i(name)f(.)291 2790 y Fs(The)30
+b(starting)g(pro)s(duction.)150 2964 y Fh(table)42 b(=)h([)g
+(special_chars)38 b(])43 b({)g(specification)c(|)k(inclusion)d(|)j
+(comment)e(})i(eof)f(.)291 3138 y Fs(Pro)s(ductions)29
+b(for)h Fh(inclusion)c Fs(and)k Fh(comment)e Fs(and)h
+Fh(eof)p Fs(.)150 3313 y Fh(inclusion)40 b(=)j(Include)e(ct_file_name)d
+(Eol)43 b(.)150 3412 y(comment)e(=)i(Comment)e({)i(\\c)f(})i(Eol)e(.)
+150 3512 y(eof)g(=)i(EndCtfile)39 b({)44 b(\\c)e(})h(Eol)g(.)291
+3686 y Fs(Pro)s(ductions)29 b(for)h Fh(special)p 1253
+3686 27 4 v 28 w(chars)p Fs(.)150 3861 y Fh(special_chars)38
+b(=)43 b([)h(escape)d(])i([)g(alert)f(])h([)g(backspace)d(])j([)g
+(return)e(])i([)h(feed)d(])847 3960 y([)j(hex)e(])h([)g(htab)f(])h([)h
+(newline)c(])j([)h(vtab)d(])j({)f(comment)e(})i(.)150
+4060 y(escape)e(=)i(EscapeChar)d(\\c)i(Eol)h(Eol)f(.)150
+4159 y(alert)g(=)h(AudibleAlertCha)o(r)38 b(\\c)k(Eol)h(.)150
+4259 y(backspace)d(=)j(BackspaceChar)38 b(\\c)43 b(Eol)f(.)150
+4359 y(return)f(=)i(CarriageReturnCha)o(r)37 b(\\c)43
+b(Eol)g(.)150 4458 y(feed)f(=)h(FormfeedChar)c(\\c)j(Eol)h(.)150
+4558 y(hex)f(=)i(HexChar)c(\\c)j(Eol)f(.)150 4658 y(htab)g(=)h
+(HorizontalTabCha)o(r)38 b(\\c)k(Eol)h(.)150 4757 y(newline)e(=)i
+(NewlineChar)c(\\c)k(Eol)f(.)150 4857 y(vtab)g(=)h(VerticalTabChar)37
+b(\\c)43 b(Eol)g(.)291 5031 y Fs(Pro)s(ductions)29 b(for)h
+Fh(specification)p Fs(.)1882 5531 y(112)p eop
+%%Page: 113 117
+113 116 bop 150 573 a Fh(specification)38 b(=)43 b(built_in)e(|)i
+(normal)e(|)i(list)f(|)h(section)e(|)i(special)e(|)i(picture)e(|)i(odd)
+f(.)150 672 y(built_in)e(=)j(\(Type)f(built_in_type)c(Eol\))k([)h
+(built_in_body)38 b(])44 b(end_type)c(.)150 772 y(end_type)g(=)j
+(EndType)e(Eol)h(.)150 872 y(built_in_type)c(=)43 b(BeginDocument)c(|)k
+(BeginDollar)c(|)k(BeginVerb)d(|)j(BeginVerbatim)38 b(|)847
+971 y(EndDocument)h(|)44 b(EndDollar)39 b(|)44 b(EndVerb)c(|)j
+(EndVerbatim)d(|)847 1071 y(Lbrace)h(|)j(OtherBegin)39
+b(|)k(OtherCommand)c(|)k(OtherEnd)d(|)847 1171 y(Paragraph)g(|)j
+(Rbrace)f(|)h(SlashSpace)c(.)150 1270 y(normal)i(=)i(\(Type)f
+(normal_type)d(Eol\))j(type_name)e([)j(normal_body)c(])k(end_type)d(.)
+150 1370 y(type_name)g(=)j(Name)f(latex_id)e(Eol)j(.)150
+1469 y(normal_type)c(=)k(BeginEnv)d(|)k(BeginVenv)c(|)j(CharCommand)c
+(|)k(Command)e(|)760 1569 y(EndEnv)g(|)i(EndVenv)e(|)i(TexChar)e(|)i
+(Vcommand)d(.)150 1669 y(list)i(=)h(\(Type)f(list_type)d(Eol\))j
+(type_name)e([)j(list_body)d(])j(end_type)e(.)150 1768
+y(list_type)f(=)j(BeginListEnv)c(|)k(EndListEnv)c(.)150
+1868 y(section)i(=)i(\(Type)e(Sectioning)f(Eol\))i(type_name)e([)j
+(section_body)38 b(])44 b(end_type)c(.)150 1968 y(special)h(=)i(\(Type)
+e(special_type)e(Eol\))j(type_name)e([)j(special_body)c(])k(end_type)d
+(.)150 2067 y(special_type)f(=)k(Special)d(|)k(SpecialBeginEnv)37
+b(|)43 b(SpecialBeginList)37 b(|)804 2167 y(SpecialCommand)h(|)43
+b(SpecialEndEnv)38 b(|)43 b(SpecialEndList)38 b(|)804
+2267 y(SpecialSectionin)o(g)f(.)150 2366 y(picture)k(=)i(\(Type)e
+(picture_type)e(Eol\))j(type_name)e([)j(picture_body)c(])k(end_type)84
+b(.)150 2466 y(picture_type)39 b(=)k(BeginPictureCc)38
+b(|)43 b(EndPicture)c(|)k(PictureCcpp)c(|)44 b(PictureCo)39
+b(|)804 2565 y(PictureCop)g(|)k(PictureCp)d(|)j(PictureOcc)d(|)804
+2665 y(PictureOccc)f(|)k(PictureOco)c(|)44 b(PicturePcop)39
+b(.)150 2765 y(odd)j(=)i(\(Type)d(odd_type)f(Eol\))i(type_name)e([)j
+(odd_body)e(])i(end_type)d(.)150 2864 y(odd_type)g(=)j(CommandOop)d(|)j
+(CommandOoopp)c(|)k(CommandOpo)c(|)629 2964 y(CommandPooop)g(|)k
+(CommandPoop)c(|)k(CommandPoopp)c(.)291 3138 y Fs(The)30
+b Fh(X)p 527 3138 27 4 v 31 w(body)f Fs(pro)s(ductions.)150
+3313 y Fh(built_in_body)38 b(=)43 b([)h(basic_body)39
+b(])847 3412 y({)44 b(start_mode)39 b([)k(basic_body)d(])j(end_mode)d
+(})j(.)150 3512 y(start_mode)c(=)44 b(InMode)d(mode_id)f(Eol)j(.)150
+3611 y(end_mode)d(=)j(EndMode)e(Eol)h(.)150 3711 y(normal_body)d(=)k([)
+g(basic_norm_body)38 b(])760 3811 y({)43 b(start_mode)d([)j
+(basic_norm_body)37 b(])44 b(end_mode)c(})j(.)150 3910
+y(sect_body)d(=)j([)g(basic_sect_body)38 b(])673 4010
+y({)43 b(start_mode)d([)j(basic_sect_body)37 b(])43 b(end_mode)e(})i(.)
+150 4110 y(list_body)d(=)j([)g(basic_list_body)38 b(])673
+4209 y({)43 b(start_mode)d([)j(basic_list_body)37 b(])43
+b(end_mode)e(})i(.)150 4309 y(picture_body)c(=)k([)g(basic_defarg_bod)o
+(y)38 b(])804 4408 y({)43 b(start_mode)c([)44 b(basic_defarg_bo)o(dy)37
+b(])43 b(end_mode)e(})i(.)150 4508 y(odd_body)d(=)87
+b([)43 b(basic_defarg_body)37 b(])673 4608 y({)43 b(start_mode)d([)j
+(basic_defarg_bod)o(y)37 b(])44 b(end_mode)c(})j(.)150
+4707 y(special_body)c(=)k([)g(basic_special_bo)o(dy)37
+b(])804 4807 y({)43 b(start_mode)c([)44 b(basic_special_b)o(ody)37
+b(])43 b(end_mode)d(})j(.)291 4981 y Fs(Note:)k(the)33
+b(ordering)f(of)h(the)g(comp)s(onen)m(ts)g(of)g(the)g(follo)m(wing)g
+Fh(basic)p 2718 4981 V 29 w(X)p 2791 4981 V 31 w(body)e
+Fs(pro)s(ductions)g(is)h(im-)150 5081 y(material.)150
+5255 y Fh(basic_body)39 b(=)44 b([)f(start_it)d(])j([)g(end_it)f(])h(.)
+1882 5531 y Fs(113)p eop
+%%Page: 114 118
+114 117 bop 150 573 a Fh(basic_norm_body)37 b(=)44 b([)f(basic_body)c
+(])k([)h(no_req_arg)39 b(])k([)g(opt_arg_pos)c(])717
+672 y({)k(arg_print)d(})j({)g(arg_action)c(})44 b(.)150
+772 y(basic_sect_body)37 b(=)44 b(sect_level)39 b([)k(basic_norm_body)
+38 b(])43 b(.)150 872 y(sect_level)c(=)44 b(SectioningLevel)37
+b(div_level)j(Eol)i(.)150 971 y(div_level)e(=)j(Chapter)e(|)i(Para)f(|)
+h(Part)f(|)h(Partm1)e(|)i(Partm2)e(|)j(Sect)e(|)h(Subpara)d(|)673
+1071 y(Subparap1)g(|)j(Subparap2)d(|)j(Subsect)e(|)i(Subsubsect)c(.)150
+1171 y(basic_defarg_bod)o(y)f(=)43 b([)g(basic_body)c(])44
+b({)f(arg_print)d(})j({)g(arg_action)c(})44 b(.)150 1270
+y(basic_list_body)37 b(=)44 b([)f(basic_norm_body)37
+b(])43 b({)g(item_action)c(})44 b(.)150 1370 y(basic_special_bo)o(dy)37
+b(=)43 b([)g(sect_level)d(])j([)g(basic_list_body)38
+b(])43 b(.)150 1469 y(no_req_arg)c(=)44 b(Reqparams)39
+b(integer)i(Eol)i(.)150 1569 y(opt_arg_pos)c(=)k(OptParam)d(\()k(First)
+d(|)i(Last)f(\))h(Eol)g(.)291 1723 y Fs(The)30 b Fh(start)p
+703 1723 27 4 v 29 w(it)g Fs(and)g Fh(end)p 1159 1723
+V 30 w(it)f Fs(pro)s(ductions.)150 1877 y Fh(start_it)40
+b(=)j([)h(start_print)39 b(])k([start_action)38 b(])43
+b(.)150 1976 y(start_print)c(=)k(PcAtStart)d(\()j(basic_pc_kind)38
+b(|)44 b(Reset)d(\))i(Eol)g(.)150 2076 y(basic_pc_kind)38
+b(=)43 b(NoPrint)e(|)i(ToSysbuf)e(|)i(print_to_buffer)37
+b(|)43 b(print_to_file)38 b(.)150 2176 y(print_to_buffer)f(=)44
+b(ToBuffer)c(buffer_id)g(.)150 2275 y(print_to_file)e(=)43
+b(ToFile)e(file_id)g(.)150 2375 y(start_action)e(=)k(StartTag)d([)j
+(text)f(])h(Eol)g({)g(tag_action)c(})k(.)150 2474 y(tag_action)c(=)44
+b(\()f(String)e(text)h(|)804 2574 y(Source)f(\()i(Sysbuf)e(|)i
+(user_buffer)c(|)44 b(user_file)39 b(\))44 b(|)804 2674
+y(ResetBuffer)39 b(buffer_id)h(|)804 2773 y(ResetFile)g(file_id)g(|)804
+2873 y(ResetSysbuf)f(|)804 2973 y(SwitchToBuffer)f(buffer_id)h(|)804
+3072 y(SwitchToFile)f(file_id)j(|)804 3172 y(SwitchToSysbuf)d(|)804
+3272 y(SwitchBack)h(|)804 3371 y(SetMode)h(mode_id)h(|)804
+3471 y(ResetMode)f(\))804 3570 y(Eol)i(.)150 3670 y(user_buffer)d(=)k
+(Buffer)e(buffer_id)f(.)150 3770 y(user_file)g(=)j(File)f(file_id)f(.)
+150 3869 y(end_it)g(=)i([)g(end_print)d(])j([)h(end_action)39
+b(])k(.)150 3969 y(end_print)d(=)j(PcAtEnd)e(\(basic_pc_kind)d(|)43
+b(Reset\))e(Eol)h(.)150 4069 y(end_action)d(=)44 b(EndTag)d([)i(text)f
+(])h(Eol)f({)i(tag_action)39 b(})k(.)291 4222 y Fs(The)30
+b Fh(arg)p 615 4222 V 30 w(print)e Fs(pro)s(ductions.)150
+4376 y Fh(arg_print)40 b(=)j(print_arg_kind)38 b(\(basic_pc_kind)g(|)43
+b(NoOp)f(\))h(Eol)f(.)150 4476 y(print_arg_kind)c(=)43
+b(PrintOpt)d(|)j(PrintP1)e(|)i(PrintP2)e(|)i(PrintP3)e(|)i(PrintP4)e(|)
+935 4575 y(PrintP5)f(|)j(PrintP6)e(|)i(PrintP7)e(|)i(PrintP8)e(|)i
+(PrintP9)e(.)291 4729 y Fs(The)30 b Fh(arg)p 615 4729
+V 30 w(action)e Fs(pro)s(ductions.)150 4883 y Fh(arg_action)39
+b(=)44 b(arg_tag_kind)38 b([)43 b(text)f(])i(Eol)e({)h(tag_action)c(})
+44 b(.)150 4983 y(arg_tag_kind)39 b(=)k(EndOpt)e(|)i(EndTag1)e(|)i
+(EndTag2)e(|)i(EndTag3)d(|)k(EndTag4)c(|)760 5082 y(EndTag5)h(|)i
+(EndTag6)e(|)i(EndTag7)e(|)i(EndTag8)d(|)k(EndTag9)c(|)717
+5182 y(StartOpt)g(|)j(StartTag1)d(|)j(StartTag2)d(|)j(StartTag3)d(|)j
+(StartTag4)d(|)673 5282 y(StartTag5)g(|)j(StartTag6)d(|)j(StartTag7)d
+(|)j(StartTag8)d(|)j(StartTag9)d(.)1882 5531 y Fs(114)p
+eop
+%%Page: 115 119
+115 118 bop 291 573 a Fs(The)30 b Fh(item)p 659 573 27
+4 v 30 w(action)e Fs(pro)s(ductions.)150 719 y Fh(item_action)39
+b(=)k(item_tag_kind)38 b([)44 b(text)e(])h(Eol)f({)h(tag_action)d(})j
+(.)150 819 y(item_tag_kind)38 b(=)43 b(EndItem)e(|)i(EndItemParam)c(|)k
+(StartItem)d(|)j(StartItemParam)38 b(.)291 979 y Fs(The)k(parser)f(in)f
+Fy(L)-7 b(TX2X)42 b Fs(for)g(the)g(command)g(table)f(is)g(v)m(ery)h
+(simple.)74 b(F)-8 b(or)42 b(eac)m(h)h Fh(TYPE=)d Fs(in)h(the)150
+1092 y(command)34 b(table)h(it)f(creates)j(a)e Fh(struct)d
+Fs(to)j(hold)f(the)h(sp)s(eci\014cation)e(data.)55 b(If)34
+b(an)m(y)h(t)m(yp)s(e)g(is)f(m)m(ultiply)150 1205 y(de\014ned,)27
+b(then)g(whic)m(h)f(one)h(will)e(b)s(e)h(\014nally)f(used)i(is)f
+(somewhat)i(random)e(b)s(ecause)h(of)h(the)f(sorting)g(and)150
+1318 y(searc)m(hing)j(algorithms)e(emplo)m(y)m(ed)i(in)m(ternally)-8
+b(.)39 b(No)30 b(c)m(hec)m(ks)h(are)f(made)g(for)f(m)m(ultiply)e
+(de\014ned)i(en)m(tries.)291 1430 y(Eac)m(h)k(command)f(in)e(the)j
+(command)f(table)f(starts)i(on)f(a)g(sep)s(erate)h(line.)44
+b(The)32 b(parser)f(reads)h(only)150 1543 y(as)d(m)m(uc)m(h)g(of)h(a)f
+(table)g(line)e(as)i(is)g(necessary)g(to)h(parse)e(that)i(line)d
+(according)i(to)h(the)f(\014rst)g(tok)m(en)h(that)f(it)150
+1656 y(\014nds)f(on)h(the)g(line.)39 b(The)29 b(data)h(in)e(eac)m(h)j
+(line)c(after)j(parsing)e(is)g(added)h(to)h(the)g(curren)m(t)f
+Fh(struct)e Fs(for)i(the)150 1769 y(L)174 1752 y Fr(A)213
+1769 y Fs(T)264 1789 y(E)314 1769 y(X)35 b(command.)53
+b(If)34 b(an)m(y)g(of)h(the)g(command)f(lines)e(within)g(an)j(en)m(try)
+f(are)h(m)m(ultiply)d(de\014ned,)i(then)150 1882 y(the)d(latest)g(one)f
+(will)e(o)m(v)m(erwrite)j(an)m(y)g(earlier)e(ones.)291
+1995 y(This)d(line-based)f(parsing)h(means)i(that)g(e\013ectiv)m(ely)g
+(an)m(ything)e(b)s(et)m(w)m(een)i(the)g(end)f(of)g(the)h(required)150
+2108 y(data)33 b(on)f(the)g(line)f(is)g(ignored)g(b)m(y)h(the)g
+(parser,)h(and)e(so)h(could)g(b)s(e)f(treated)i(as)g(a)f(commen)m(t.)47
+b(There)32 b(is)150 2221 y(no)e(guaran)m(tee)i(that)f(this)e(b)s(eha)m
+(viour)g(will)f(b)s(e)i(main)m(tained)f(in)g(future)h(releases)g(of)h
+Fy(L)-7 b(TX2X)p Fs(.)150 2502 y Fu(G)134 b(A)45 b(grammar)g(for)h
+Ff(Express-A)150 2705 y Fs(The)26 b(same)g(WSN)g(notation)h(is)e(used)g
+(for)h(the)g(grammar)h(for)f Fo(Express-A)f Fs(as)h(for)g(the)g
+(command)g(table)150 2818 y(grammar.)291 2931 y(First)33
+b(the)h(k)m(eyw)m(ords.)52 b(Note)35 b(that)g(these)f(are)h(case)g
+(insensitiv)m(e.)49 b(Also)33 b(not)i(all)d(of)j(the)f(k)m(eyw)m(ords)
+150 3044 y(ha)m(v)m(e)i(b)s(een)d(used)h(in)f(this)g(implemen)m(tation)
+g(of)i Fo(Express-A)p Fs(;)e(those)i(that)g(ha)m(v)m(e)h(not)e(b)s(een)
+g(used)g(are)150 3157 y(reserv)m(ed)d(for)f(the)g(future.)194
+3322 y Fh(ABS)42 b(=)h('abs')f(.)194 3422 y(ABSTRACT)e(=)j('abstract')c
+(.)194 3522 y(ACOS)j(=)h('acos')e(.)194 3621 y(AGGREGATE)e(=)44
+b('aggregate')39 b(.)194 3721 y(ALIAS)i(=)i('alias')e(.)194
+3821 y(AND)h(=)h('and')f(.)194 3920 y(ANDOR)f(=)i('andor')e(.)194
+4020 y(ARRAY)g(=)i('array')e(.)194 4119 y(AS)h(=)i('as')d(.)194
+4219 y(ASIN)h(=)h('asin')e(.)194 4385 y(ATAN)h(=)h('atan')e(.)194
+4485 y(BAG)h(=)h('bag')f(.)194 4584 y(BEGIN)f(=)i('begin')e(.)194
+4684 y(BINARY)g(=)i('binary')d(.)194 4783 y(BLENGTH)g(=)j('blength')d
+(.)194 4883 y(BOOLEAN)g(=)j('boolean')d(.)194 4983 y(BY)i(=)i('by')d(.)
+194 5082 y(CALL)h(=)h('call')e(.)194 5182 y(CASE)h(=)h('case')e(.)194
+5282 y(CONSTANT)f(=)j('constant')c(.)1882 5531 y Fs(115)p
+eop
+%%Page: 116 120
+116 119 bop 194 573 a Fh(CONST_E)40 b(=)j('const_e')d(.)194
+672 y(CONTEXT)g(=)j('context')d(.)194 772 y(COS)i(=)h('cos')f(.)194
+872 y(CRITERIA)e(=)j('criteria')c(.)194 971 y(DERIVE)i(=)i('derive')d
+(.)194 1071 y(DIV)i(=)h('div')f(.)194 1171 y(ELSE)g(=)h('else')e(.)194
+1270 y(END)h(=)h('end')f(.)194 1370 y(END_ALIAS)d(=)44
+b('end_alias')39 b(.)194 1469 y(END_CALL)h(=)j('end_call')c(.)194
+1669 y(END_CASE)h(=)j('end_case')c(.)194 1768 y(END_CODE)h(=)j
+('end_code')c(.)194 1868 y(END_CONSTANT)f(=)43 b('end_constant')38
+b(.)194 1968 y(END_CONTEXT)h(=)k('end_context')38 b(.)194
+2067 y(END_CRITERIA)g(=)43 b('end_criteria')38 b(.)194
+2167 y(END_ENTITY)h(=)k('end_entity')c(.)194 2267 y(END_FUNCTION)f(=)43
+b('end_function')38 b(.)194 2366 y(END_IF)j(=)i('end_if')d(.)194
+2466 y(END_LOCAL)f(=)44 b('end_local')39 b(.)194 2565
+y(END_MODEL)g(=)44 b('end_model')39 b(.)194 2765 y(END_NOTES)g(=)44
+b('end_notes')39 b(.)194 2864 y(END_OBJECTIVE)f(=)43
+b('end_objective')37 b(.)194 2964 y(END_PARAMETER)h(=)43
+b('end_parameter')37 b(.)194 3064 y(END_PROCEDURE)h(=)43
+b('end_procedure')37 b(.)194 3163 y(END_PURPOSE)i(=)k('end_purpose')38
+b(.)194 3263 y(END_REALIZATION)f(=)43 b('end_realization')37
+b(.)194 3362 y(END_REFERENCES)g(=)44 b('end_references)o(')38
+b(.)194 3462 y(END_REPEAT)h(=)k('end_repeat')c(.)194
+3562 y(END_RULE)h(=)j('end_rule')c(.)194 3661 y(END_SCHEMA)g(=)k
+('end_schema')c(.)194 3861 y(END_SCHEMA_DATA)e(=)43 b
+('end_schema_data')37 b(.)194 3960 y(END_TEST_CASE)h(=)43
+b('end_test_case')37 b(.)194 4060 y(END_TYPE)j(=)j('end_type')c(.)194
+4159 y(ENTITY)i(=)i('entity')d(.)194 4259 y(ENUMERATION)f(=)k
+('enumeration')38 b(.)194 4359 y(EOF)k(=)h('eof')f(.)194
+4458 y(EOLN)g(=)h('eoln')e(.)194 4558 y(ESCAPE)g(=)i('escape')d(.)194
+4658 y(EXISTS)h(=)i('exists')d(.)194 4757 y(EXP)i(=)h('exp')f(.)194
+4857 y(FALSE)f(=)i('false')e(.)194 5056 y(FIXED)g(=)i('fixed')e(.)194
+5156 y(FOR)h(=)h('for')f(.)194 5255 y(FORMAT)f(=)i('format')d(.)1882
+5531 y Fs(116)p eop
+%%Page: 117 121
+117 120 bop 194 573 a Fh(FROM)42 b(=)h('from')e(.)194
+672 y(FUNCTION)f(=)j('function')c(.)194 772 y(GENERIC)h(=)j('generic')d
+(.)194 872 y(HIBOUND)g(=)j('hibound')d(.)194 971 y(HIINDEX)g(=)j
+('hiindex')d(.)194 1071 y(IF)i(=)i('if')d(.)194 1171
+y(IMPORT)g(=)i('import')d(.)194 1370 y(IN)i(=)i('in')d(.)194
+1469 y(INSERT)g(=)i('insert')d(.)194 1569 y(INTEGER)g(=)j('integer')d
+(.)194 1669 y(INVERSE)g(=)j('inverse')d(.)194 1768 y(LENGTH)h(=)i
+('length')d(.)194 1868 y(LIKE)i(=)h('like')e(.)194 1968
+y(LIST)h(=)h('list')e(.)194 2067 y(LOBOUND)f(=)j('lobound')d(.)194
+2167 y(LOINDEX)g(=)j('loindex')d(.)194 2267 y(LOCAL)h(=)i('local')e(.)
+194 2466 y(LOG)h(=)h('log')f(.)194 2565 y(LOG10)f(=)i('log10')e(.)194
+2665 y(LOG2)h(=)h('log2')e(.)194 2765 y(LOGICAL)f(=)j('logical')d(.)194
+2864 y(MOD)i(=)h('mod')f(.)194 2964 y(MODEL)f(=)i('model')e(.)194
+3064 y(NOT)h(=)h('not')f(.)194 3163 y(NOTES)f(=)i('notes')e(.)194
+3263 y(NUMBER)g(=)i('number')d(.)194 3362 y(NVL)i(=)h('nvl')f(.)194
+3562 y(OBJECTIVE)d(=)44 b('objective')39 b(.)194 3661
+y(ODD)j(=)h('odd')f(.)194 3761 y(OF)g(=)i('of')d(.)194
+3861 y(ONEOF)g(=)i('oneof')e(.)194 3960 y(OPTIONAL)f(=)j('optional')c
+(.)194 4060 y(OR)j(=)i('or')d(.)194 4159 y(ORD)h(=)h('ord')f(.)194
+4259 y(OTHERWISE)d(=)44 b('otherwise')39 b(.)194 4359
+y(PARAMETERi)g(=)k('parameter')c(.)194 4458 y(PI)j(=)i('pi')d(.)194
+4658 y(PRED)h(=)h('pred')e(.)194 4757 y(PROCEDURE)e(=)44
+b('procedure')39 b(.)194 4857 y(PURPOSE)h(=)j('purpose')d(.)194
+4956 y(QUERY)h(=)i('query')e(.)194 5056 y(READ)h(=)h('read')e(.)194
+5156 y(READLN)g(=)i('readln')d(.)194 5255 y(REAL)i(=)h('real')e(.)1882
+5531 y Fs(117)p eop
+%%Page: 118 122
+118 121 bop 194 573 a Fh(REALIZATION)39 b(=)k('realization')38
+b(.)194 672 y(REFERENCE)h(=)44 b('reference')39 b(.)194
+772 y(REFERENCES)g(=)k('references')c(.)194 971 y(REMOVE)i(=)i
+('remove')d(.)194 1071 y(REPEAT)h(=)i('repeat')d(.)194
+1171 y(RETURN)h(=)i('return')d(.)194 1270 y(REXPR)h(=)i('rexpr')e(.)194
+1370 y(ROLESOF)f(=)j('rolesof')d(.)194 1469 y(ROUND)h(=)i('round')e(.)
+194 1569 y(RULE)h(=)h('rule)e(.)194 1669 y(SCHEMA)g(=)i('schema')d(.)
+194 1768 y(SCHEMA_DATA)f(=)k('schema_data')38 b(.)194
+1868 y(SELECT)j(=)i('select')d(.)194 2067 y(SELF)i(=)h('self')e(.)194
+2167 y(SET)h(=)h('set')f(.)194 2267 y(SIN)g(=)h('sin')f(.)194
+2366 y(SIZEOF)f(=)i('sizeof')d(.)194 2466 y(SKIP)i(=)h('skip')e(.)194
+2565 y(SQRT)h(=)h('sqrt')e(.)194 2665 y(STRING)g(=)i('string')d(.)194
+2765 y(SUBOF)h(=)i('subof')e(.)194 2864 y(SUBTYPE)f(=)j('subtype')d(.)
+194 2964 y(SUCC)i(=)h('succ')e(.)194 3163 y(SUPERTYPE)e(=)44
+b('supertype')39 b(.)194 3263 y(SUPOF)i(=)i('supof')e(.)194
+3362 y(SYSTEM)g(=)i('system')d(.)194 3462 y(TAN)i(=)h('tan')f(.)194
+3562 y(TEST_CASE)d(=)44 b('test_case')39 b(.)194 3661
+y(THE_DAY)h(=)j('the_day')d(.)194 3761 y(THE_MONTH)f(=)44
+b('the_month')39 b(.)194 3861 y(THE_YEAR)h(=)j('the_year')c(.)194
+3960 y(THEN)j(=)h('then')e(.)194 4060 y(TO)h(=)i('to')d(.)194
+4259 y(TRUE)h(=)h('true')e(.)194 4359 y(TRUNC)g(=)i('trunc')e(.)194
+4458 y(TYPE)h(=)h('type')e(.)194 4558 y(TYPEOF)g(=)i('typeof')d(.)194
+4658 y(UNIQUE)h(=)i('unique')d(.)194 4757 y(UNKNOWN)g(=)j('unknown')d
+(.)194 4857 y(UNTIL)h(=)i('until')e(.)194 4956 y(USE)h(=)h('use')f(.)
+194 5056 y(USEDIN)f(=)i('usedin')d(.)194 5156 y(USING)h(=)i('using')e
+(.)1882 5531 y Fs(118)p eop
+%%Page: 119 123
+119 122 bop 194 573 a Fh(VALUE)41 b(=)i('value')e(.)194
+672 y(VALUE_IN)f(=)j('value_in')c(.)194 772 y(VALUE_UNIQUE)f(=)43
+b('value_unique')38 b(.)194 872 y(VAR)k(=)h('var')f(.)194
+971 y(WHERE)f(=)i('where')e(.)194 1071 y(WHILE)g(=)i('while')e(.)194
+1171 y(WITH)h(=)h('with')e(.)194 1270 y(WRITE)g(=)i('write')e(.)194
+1370 y(WRITELN)f(=)j('writeln')d(.)194 1469 y(XOR)i(=)h('xor')f(.)291
+1662 y Fs(The)35 b(follo)m(wing)e(rules)g(de\014ne)i(v)-5
+b(arious)33 b(classes)i(of)g(c)m(haracters)i(whic)m(h)c(are)j(used)e
+(in)f(constructing)150 1775 y(the)e(tok)m(ens.)194 1954
+y Fh(digit)41 b(=)i('0')g(|)g('1')f(|)h('2')g(|)g('3')f(|)h('4')g(|)g
+('5')f(|)h('6')g(|)g('7')f(|)h('8')g(|)g('9')f(.)194
+2054 y(digits)f(=)i(digit)e({)j(digit)d(})i(.)194 2153
+y(letter)e(=)i('a')f(|)h('b')g(|)g('c')f(|)h('d')g(|)g('e')f(|)h('f')g
+(|)g('g')f(|)h('h')g(|)g('i')f(|)i('j')e(|)h('k')f(|)847
+2253 y('l')h(|)g('m')f(|)h('n')g(|)g('o')f(|)h('p')g(|)g('q')f(|)h('r')
+g(|)g('s')f(|)i('t')e(|)h('u')f(|)i('v')e(|)847 2353
+y('w')h(|)g('x')f(|)h('y')g(|)g('z')f(.)194 2452 y(lparen_not_star)37
+b(=)43 b('\(')f(not_star)f(.)194 2552 y(not_lparen_star)c(=)43
+b(not_paren_star)38 b(|)43 b('\)')f(.)194 2652 y(not_paren_star)37
+b(=)44 b(letter)d(|)i(digit)e(|)j(not_paren_star_)o(sp)o(eci)o(al)37
+b(.)194 2751 y(not_paren_star_)o(quo)o(te)o(_s)o(pec)o(ia)o(l)h(=)43
+b('!')f(|)h('"')g(|)g('#')f(|)h('$')g(|)g('\045')f(|)h('&')g(|)g('+')f
+(|)1022 2851 y(',')g(|)h('-')g(|)g('.')f(|)h('/')g(|)g(':')f(|)h(';')g
+(|)g('<')f(|)h('=')g(|)g('>')f(|)h('?')g(|)1022 2951
+y('@')f(|)h('[')g(|)g('\\')f(|)h(']')g(|)g('^')f(|)h('_')g(|)g('`')f(|)
+h('{')g(|)g('|')f(|)h('}')g(|)1022 3050 y('~')f(.)194
+3150 y(not_paren_star_)o(spe)o(ci)o(al)37 b(=)43 b(not_paren_star_qu)o
+(ot)o(e_s)o(pe)o(ci)o(al)37 b(|)43 b('''')f(.)194 3249
+y(not_quote)d(=)44 b(not_paren_star_)o(quo)o(te)o(_sp)o(ec)o(ia)o(l)38
+b(|)43 b(letter)e(|)i(digit)f(|)h('\(')f(|)h('\)')g(|)g('*')f(.)194
+3349 y(not_rparen)d(=)k(not_paren_star)38 b(|)43 b('*')g(|)g('\(')f(.)
+194 3528 y(not_star)e(=)j(not_paren_star)38 b(|)43 b('\(')f(|)i('\)')e
+(.)194 3628 y(octet)f(=)i(hex_digit)d(hex_digit)g(.)194
+3728 y(special)g(=)j(not_paren_star_qu)o(ote)o(_s)o(pec)o(ia)o(l)37
+b(|)44 b('\(')e(|)h('\)')f(|)i('*')e(|)h('''')f(.)194
+3827 y(star_not_rparen)37 b(=)43 b('*')f(not_rparen)e(.)291
+4020 y Fs(The)e(follo)m(wing)e(rules)h(sp)s(ecify)g(ho)m(w)h(certain)g
+(com)m(binations)g(of)g(c)m(haracters)i(are)e(in)m(terpreted)g(as)150
+4133 y(lexical)29 b(elemen)m(ts)i(within)d(the)i(language.)194
+4312 y Fh(integer_literal)37 b(=)43 b(digits)e(.)194
+4412 y(real_literal)d(=)43 b(digits)e('.')i([)g(digits)e(])i([)g('e')g
+([)g(sign)f(])h(digits)e(])i(.)194 4511 y(simple_id)c(=)44
+b(letter)d({)i(letter)e(|)i(digit)f(|)h('_')f(})h(.)194
+4611 y(simple_string_l)o(ite)o(ra)o(l)37 b(=)44 b(\\q)e({)i(\()f(\\q)g
+(\\q)f(\))h(|)h(not_quote)39 b(|)44 b(\\s)e(|)i(\\o)e(})i(\\q)e(.)291
+4803 y Fs(The)30 b(follo)m(wing)f(rules)g(sp)s(ecify)g(the)h(syn)m(tax)
+h(of)g(commen)m(ts)g(in)e Fo(Express-A)p Fs(.)194 4983
+y Fh(embedded_remark)37 b(=)43 b('\(*')f({)h(not_lparen_star)38
+b(|)43 b(lparen_not_star)37 b(|)1109 5082 y(star_not_rparen)g(|)43
+b(embedded_remark)38 b(})43 b('*\)')f(.)194 5182 y(remark)f(=)i
+(embedded_remark)37 b(|)43 b(tail_remark)c(.)194 5282
+y(tail_remark)g(=)k('--')f({)h(\\a)g(|)g(\\s)g(|)g(\\o)g(})g(\\n)f(.)
+1882 5531 y Fs(119)p eop
+%%Page: 120 124
+120 123 bop 291 573 a Fs(The)31 b(follo)m(wing)f(rules)g(represen)m(t)h
+(iden)m(ti\014ers)e(whic)m(h)h(are)i(kno)m(wn)f(to)h(ha)m(v)m(e)g(a)g
+(particular)e(meaning)150 686 y(\(i.e.,)h(to)g(b)s(e)f(declared)g
+(elsewhere)g(as)g(t)m(yp)s(es)h(or)f(functions,)f(etc.\).)194
+880 y Fh(attribute_ref)38 b(=)43 b(attribute_id)c(.)194
+979 y(constant_ref)f(=)43 b(constant_id)c(.)194 1079
+y(entity_ref)g(=)k(entity_id)d(.)194 1179 y(enumeration_ref)d(=)43
+b(enumeration_id)38 b(.)194 1278 y(function_ref)g(=)43
+b(function_id)c(.)194 1378 y(parameter_ref)f(=)43 b(parameter_id)c(.)
+194 1477 y(procedure_ref)f(=)43 b(procedure_id)c(.)194
+1577 y(type_ref)h(=)j(type_id)e(.)194 1677 y(variable_ref)d(=)43
+b(variable_id)c(.)291 1884 y Fs(The)i(follo)m(wing)e(rules)h(sp)s
+(ecify)f(ho)m(w)j(the)f(previous)e(lexical)h(elemen)m(ts)i(ma)m(y)f(b)s
+(e)g(com)m(bined)f(in)m(to)150 1997 y(constructs)j(of)f
+Fo(Express-A)p Fs(.)g(White)g(space)h(and/or)g(remark\(s\))g(ma)m(y)g
+(app)s(ear)f(b)s(et)m(w)m(een)h(an)m(y)g(t)m(w)m(o)150
+2110 y(tok)m(ens)31 b(in)e(these)i(rules.)40 b(The)29
+b(primary)g(syn)m(tax)i(rule)e(for)h Fo(Express-A)f Fs(is)h
+Fn(express_a)p Fs(.)194 2303 y Fh(actual_paramete)o(r_l)o(is)o(t)37
+b(=)44 b('\(')e(parameter)e({)j(',')f(parameter)e(})j('\)')g(.)194
+2403 y(add_like_op)c(=)k('+')f(|)h('-')g(|)g(OR)g(|)g(XOR)f(.)194
+2503 y(aggregation_typ)o(es)37 b(=)43 b(array_type)d(|)j(bag_type)d(|)j
+(list_type)d(|)j(set_type)e(.)194 2602 y(algorithm_head)c(=)44
+b({)f(declaration)c(})k([)g(local_decl)d(])j(.)194 2702
+y(array_type)c(=)k(ARRAY)f(bound_spec)d(OF)k(base_type)d(.)194
+2802 y(assignment_stmt)d(=)43 b(general_ref)c({)k(qualifier)d(})j(':=')
+f(expression)e(';')i(.)194 2901 y(attribute_decl)37 b(=)44
+b(attribute_id)38 b(.)194 3001 y(attribute_id)g(=)43
+b(simple_id)d(.)194 3101 y(attribute_quali)o(fie)o(r)d(=)43
+b('.')g(attribute_ref)38 b(.)194 3200 y(bag_type)i(=)j(BAG)f([)i
+(bound_spec)39 b(])k(OF)g(base_type)d(.)194 3394 y(base_type)f(=)44
+b(aggregation_typ)o(es)37 b(|)43 b(simple_types)c(|)k(named_types)c(.)
+194 3494 y(boolean_type)f(=)43 b(BOOLEAN)e(.)194 3593
+y(bound_1)f(=)j(numeric_expressio)o(n)38 b(.)194 3693
+y(bound_2)i(=)j(numeric_expressio)o(n)38 b(.)194 3793
+y(bound_spec)h(=)k('[')g(bound_1)d(':')j(bound_2)d(']')j(.)194
+3892 y(built_in_consta)o(nt)37 b(=)43 b(CONST_E)e(|)i(PI)g(|)g(THE_DAY)
+e(|)i(THE_MONTH)d(|)j(THE_YEAR)d(|)j('?')g(.)194 3992
+y(built_in_functi)o(on)37 b(=)43 b(ABS)g(|)g(COS)f(|)h(EOF)g(|)g(EOLN)f
+(|)h(EXISTS)e(|)i(EXP)g(|)1065 4091 y(HIBOUND)e(|)i(HIINDEX)e(|)i
+(LENGTH)e(|)i(LOBOUND)e(|)i(LOINDEX)e(|)1065 4191 y(LOG)i(|)g(LOG2)f(|)
+h(LOG10)e(|)j(NVL)e(|)h(ODD)f(|)i(ORD)e(|)h(PRED)f(|)1065
+4291 y(REXPR)g(|)h(ROUND)f(|)h(SIN)f(|)h(SIZEOF)e(|)1065
+4390 y(SQRT)h(|)h(SUCC)f(|)i(TAN)e(|)h(TRUNC)f(.)194
+4490 y(built_in_proced)o(ure)37 b(=)43 b(INSERT)e(|)i(PRINT)f(|)h
+(PRINTLN)e(|)i(READ)f(|)h(READLN)e(|)i(REMOVE)e(|)1109
+4590 y(SYSTEM)g(|)i(WRITE)f(|)h(WRITELN)e(.)194 4689
+y(case_action)e(=)k(case_label)c({)k(',')g(case_label)c(})k(':')g(stmt)
+f(.)194 4789 y(case_label)d(=)k(expression)d(.)194 4983
+y(case_stmt)f(=)44 b(CASE)e(selector)e(OF)j({)g(case_action)c(})k([)g
+(OTHERWISE)d(':')i(stmt)g(])978 5082 y(END_CASE)e(';')j(.)194
+5182 y(compound_stmt)38 b(=)43 b(BEGIN)e(stmt)h({)i(stmt)e(})h(END)f
+(';')g(.)194 5282 y(constant_factor)37 b(=)43 b(built_in_constant)37
+b(.)1882 5531 y Fs(120)p eop
+%%Page: 121 125
+121 124 bop 194 573 a Fh(constructed_typ)o(es)37 b(=)43
+b(enumeration_type)37 b(.)194 672 y(declaration)i(=)k(entity_decl)c(|)k
+(function_decl)38 b(|)43 b(procedure_decl)38 b(|)43 b(type_decl)d(.)194
+772 y(entity_body)f(=)k({)g(explicit_attr)38 b(})43 b(.)194
+872 y(entity_decl)c(=)k(entity_head)c(entity_body)g(END_ENTITY)g(';')k
+(.)194 971 y(entity_head)c(=)k(ENTITY)e(entity_id)f(';')i(.)194
+1071 y(entity_id)d(=)44 b(simple_id)39 b(.)194 1171 y(enum_id)h(=)j
+(simple_id)d(.)194 1370 y(enumeration_ref)o(ere)o(nc)o(e)d(=)44
+b(enum_id)c(.)194 1469 y(enumeration_typ)o(e)e(=)43 b(ENUMERATION)c(OF)
+k('\(')f(enum_id)f({)i(',')f(enum_id)f(})i('\)')f(.)194
+1569 y(escape_stmt)d(=)k(ESCAPE)e(';')h(.)194 1669 y(explicit_attr)c(=)
+43 b(attribute_decl)38 b({)43 b(',')f(attribute_decl)c(})43
+b(':')g(base_type)c(';')k(.)194 1768 y(express_a)c(=)44
+b({)f(declaration)c(})k([)g(local_decl)d(])j({)g(stmt)f(})h(END_CODE)d
+(.)194 1868 y(expression)f(=)k(simple_expression)37 b([)43
+b(rel_op_extended)37 b(simple_expression)g(])43 b(.)194
+1968 y(factor)e(=)i(simple_factor)38 b([)43 b('**')f(simple_factor)c(])
+44 b(.)194 2067 y(formal_paramete)o(r)38 b(=)43 b(parameter_id)38
+b({)44 b(',')e(parameter_id)c(})44 b(':')e(parameter_type)c(.)194
+2167 y(function_call)g(=)43 b(\()g(built_in_function)37
+b(|)43 b(function_ref)38 b(\))1152 2267 y([)44 b(actual_paramete)o(r_l)
+o(is)o(t)38 b(])43 b(.)194 2366 y(function_decl)38 b(=)43
+b(function_head)38 b([)43 b(algorithm_head)38 b(])43
+b(stmt)f({)h(stmt)f(})1152 2466 y(END_FUNCTION)d(';')j(.)194
+2665 y(function_head)c(=)43 b(FUNCTION)d(function_id)f([)k('\(')g
+(formal_parameter)1152 2765 y({)h(';')e(formal_parameter)37
+b(})43 b('\)')f(])i(':')e(parameter_type)c(';')k(.)194
+2864 y(function_id)d(=)k(simple_id)d(.)194 2964 y(generalized_typ)o(es)
+d(=)43 b(general_aggregati)o(on)o(_ty)o(pe)o(s)38 b(.)194
+3064 y(general_aggrega)o(tio)o(n_)o(ty)o(pes)f(=)43 b(general_array_ty)
+o(pe)37 b(|)43 b(general_bag_type)37 b(|)1414 3163 y(general_list_typ)o
+(e)h(|)43 b(general_set_type)37 b(.)194 3263 y(general_array_t)o(ype)g
+(=)43 b(ARRAY)e([)j(bound_spec)39 b(])k(OF)g(parameter_type)38
+b(.)194 3362 y(general_bag_typ)o(e)g(=)43 b(BAG)f([)h(bound_spec)d(])j
+(OF)g(parameter_type)37 b(.)194 3462 y(general_list_ty)o(pe)g(=)43
+b(LIST)f([)h(bound_spec)d(])j(OF)g(parameter_type)38
+b(.)194 3562 y(general_ref)h(=)86 b(parameter_ref)39
+b(|)k(variable_ref)38 b(.)194 3661 y(general_set_typ)o(e)g(=)43
+b(SET)f([)h(bound_spec)d(])j(OF)g(parameter_type)37 b(.)194
+3761 y(if_stmt)j(=)j(IF)g(logical_expressio)o(n)37 b(THEN)42
+b(stmt)g({)h(stmt)f(})h([)h(ELSE)e(stmt)g({)h(stmt)f(})h(])891
+3861 y(END_IF)e(';')h(.)194 4060 y(increment)d(=)44 b(numeric_express)o
+(ion)37 b(.)194 4159 y(increment_contr)o(ol)g(=)43 b(variable_id)c
+(':=')j(bound_1)f(TO)i(bound_2)d([)k(BY)e(increment)e(])j(.)194
+4259 y(index)e(=)i(numeric_expressio)o(n)37 b(.)194 4359
+y(index_1)j(=)j(index)f(.)194 4458 y(index_2)e(=)j(index)f(.)194
+4558 y(index_qualifier)37 b(=)43 b('[')f(index_1)f([)i(':')g(index_2)d
+(])k(']')e(.)194 4658 y(integer_type)c(=)43 b(INTEGER)e(.)194
+4757 y(interval)f(=)j('{')f(interval_low)d(interval_op)g(interval_item)
+f(interval_op)847 4857 y(interval_high)h('}')j(.)194
+4956 y(interval_high)c(=)43 b(simple_expressio)o(n)38
+b(.)194 5056 y(interval_item)g(=)43 b(simple_expressio)o(n)38
+b(.)194 5255 y(interval_low)g(=)43 b(simple_expression)37
+b(.)1882 5531 y Fs(121)p eop
+%%Page: 122 126
+122 125 bop 194 573 a Fh(interval_op)39 b(=)k('<')f(|)h('<=')f(.)194
+672 y(list_type)d(=)44 b(LIST)e([)h(bound_spec)c(])k(OF)g(base_type)d
+(.)194 772 y(literal)g(=)j(integer_literal)38 b(|)43
+b(logical_literal)37 b(|)44 b(real_literal)38 b(|)891
+872 y(string_literal)g(.)194 971 y(local_decl)h(=)k(LOCAL)f
+(local_variable)c({)43 b(local_variable)37 b(})44 b(END_LOCAL)c(';')i
+(.)194 1071 y(local_variable)37 b(=)44 b(variable_id)39
+b({)k(',')f(variable_id)d(})k(':')g(parameter_type)37
+b(';')43 b(.)194 1171 y(logical_express)o(ion)37 b(=)43
+b(expression)c(.)194 1270 y(logical_literal)e(=)43 b(FALSE)f(|)h(TRUE)f
+(|)h(UNKNOWN)e(.)194 1370 y(logical_type)d(=)43 b(LOGICAL)e(.)194
+1469 y(multiplication_)o(lik)o(e_)o(op)c(=)43 b('*')g(|)g('/')f(|)h
+(DIV)g(|)g(MOD)f(|)h(AND)g(|)g('||')f(.)194 1644 y(named_types)d(=)k
+(entity_ref)c(|)k(type_ref)e(.)194 1744 y(null_stmt)e(=)44
+b(';')e(.)194 1844 y(numeric_express)o(ion)37 b(=)43
+b(simple_expressio)o(n)37 b(.)194 1943 y(parameter)i(=)44
+b(expression)39 b(.)194 2043 y(parameter_id)f(=)43 b(simple_id)d(.)194
+2142 y(parameter_type)d(=)44 b(generalized_typ)o(es)37
+b(|)43 b(named_types)c(|)k(simple_types)c(.)194 2242
+y(population)g(=)k(entity_ref)d(.)194 2342 y(primary)g(=)j(literal)e(|)
+i(\()g(qualifiable_facto)o(r)38 b({)43 b(qualifier)d(})j(\))g(.)194
+2441 y(procedure_call_)o(stm)o(t)37 b(=)43 b(\()h(built_in_proced)o
+(ure)37 b(|)43 b(procedure_ref)38 b(\))1414 2541 y([)43
+b(actual_parameter_)o(li)o(st)37 b(])43 b(';')g(.)194
+2641 y(procedure_decl)37 b(=)44 b(procedure_head)37 b([)44
+b(algorithm_head)37 b(])43 b({)h(stmt)e(})h(END_PROCEDURE)38
+b(';')k(.)194 2815 y(procedure_head)37 b(=)44 b(PROCEDURE)39
+b(procedure_id)g([)k('\(')g([)g(VAR)f(])h(formal_parameter)1196
+2915 y({)g(';')g([)g(VAR)f(])h(formal_parameter)37 b(})43
+b('\)')g(])g(';')f(.)194 3015 y(procedure_id)c(=)43 b(simple_id)d(.)194
+3114 y(qualifiable_fac)o(tor)d(=)43 b(attribute_ref)38
+b(|)43 b(constant_factor)38 b(|)43 b(function_call)38
+b(|)1370 3214 y(general_ref)h(|)44 b(population)39 b(.)194
+3313 y(qualifier)g(=)44 b(attribute_quali)o(fie)o(r)37
+b(|)44 b(index_qualifier)37 b(.)194 3413 y(real_type)i(=)44
+b(REAL)e(.)194 3513 y(referenced_attr)o(ibu)o(te)37 b(=)43
+b(attribute_ref)38 b(|)43 b(qualified_attribu)o(te)37
+b(.)194 3612 y(rel_op)k(=)i('<')f(|)h('>')g(|)g('<=')f(|)h('>=')f(|)h
+('<>')f(|)h('=')g(|)g(':<>:')e(|)i(':=:')f(.)194 3712
+y(rel_op_extended)37 b(=)43 b(rel_op)e(|)i(IN)g(|)g(LIKE)f(.)194
+3812 y(repeat_control)37 b(=)44 b([)f(increment_contro)o(l)37
+b(])43 b([)h(while_control)38 b(])43 b([)g(until_control)38
+b(])44 b(.)194 3911 y(repeat_stmt)39 b(=)k(REPEAT)e(repeat_control)d
+(';')k(stmt)g({)h(stmt)f(})h(END_REPEAT)d(';')i(.)194
+4086 y(return_stmt)d(=)k(RETURN)e([)i('\(')f(expression)e('\)')i(])h
+(';')g(.)194 4186 y(selector)d(=)j(expression)c(.)194
+4285 y(set_type)h(=)j(SET)f([)i(bound_spec)39 b(])k(OF)g(base_type)d(.)
+194 4385 y(sign)i(=)h('+')f(|)h('-')g(.)194 4485 y(simple_expressi)o
+(on)37 b(=)43 b(term)f({)h(add_like_op)c(term)j(})i(.)194
+4584 y(simple_factor)38 b(=)43 b(enumeration_refe)o(ren)o(ce)37
+b(|)43 b(interval)d(|)891 4684 y(\()j([)g(unary_op)e(])i(\()g('\(')f
+(expression)e('\)')i(|)h(primary)e(\))i(\))g(.)194 4783
+y(simple_types)38 b(=)43 b(integer_type)c(|)k(logical_type)c(|)k
+(real_type)d(|)j(string_type)c(.)194 4883 y(skip_stmt)g(=)44
+b(SKIP)e(';')g(.)194 4983 y(stmt)g(=)h(assignment_stmt)37
+b(|)43 b(case_stmt)d(|)j(compound_stmt)38 b(|)44 b(escape_stmt)39
+b(|)499 5082 y(if_stmt)h(|)k(null_stmt)39 b(|)44 b(procedure_call_)o
+(stm)o(t)37 b(|)43 b(repeat_stmt)d(|)j(return_stmt)c(|)499
+5182 y(skip_stmt)h(.)194 5282 y(string_literal)d(=)44
+b(simple_string_l)o(ite)o(ra)o(l)37 b(.)1882 5531 y Fs(122)p
+eop
+%%Page: 123 127
+123 126 bop 194 573 a Fh(string_type)39 b(=)k(STRING)e(.)194
+672 y(term)h(=)h(factor)e({)i(multiplication_l)o(ike)o(_o)o(p)37
+b(factor)42 b(})h(.)194 772 y(type_decl)c(=)44 b(TYPE)e(type_id)e('=')j
+(underlying_type)37 b(';')42 b(END_TYPE)f(';')h(.)194
+872 y(type_id)e(=)j(simple_id)d(.)194 971 y(unary_op)g(=)j('+')f(|)i
+('-')e(|)h(NOT)f(.)194 1071 y(underlying_type)37 b(=)43
+b(constructed_types)37 b(|)43 b(aggregation_type)o(s)37
+b(|)44 b(simple_types)38 b(|)978 1171 y(type_ref)i(.)194
+1270 y(until_control)e(=)43 b(UNTIL)e(logical_expressio)o(n)d(.)194
+1370 y(variable_id)h(=)k(simple_id)d(.)194 1469 y(while_control)e(=)43
+b(WHILE)e(logical_expressio)o(n)d(.)150 1856 y Fu(References)195
+2058 y Fs([1])47 b(Leslie)25 b(Lamp)s(ort.)34 b Fi(L)-5
+b(aT)e(eX:)29 b(A)g(Do)-5 b(cument)30 b(Pr)-5 b(ep)g(ar)g(ation)32
+b(System)p Fs(.)j(Addison-W)-8 b(esley)26 b(Publishing)337
+2171 y(Compan)m(y)-8 b(,)31 b(second)f(edition,)f(1994.)195
+2359 y([2])47 b(Donald)30 b(E.)g(Kn)m(uth.)40 b Fi(The)33
+b(T)-7 b(eXb)i(o)g(ok)p Fs(.)41 b(Addison-W)-8 b(esley)30
+b(Publishing)c(Compan)m(y)-8 b(,)31 b(1984.)195 2547
+y([3])47 b(ISO)33 b(10303.)55 b Fi(Industrial)38 b(automation)h
+(systems)e(and)g(inte)-5 b(gr)g(ation)38 b(|)e(Pr)-5
+b(o)g(duct)38 b(data)g(r)-5 b(epr)g(esen-)337 2660 y(tation)34
+b(and)f(exchange)p Fs(,)e(1994.)195 2847 y([4])47 b(C.)36
+b(A.)g(Goldfarb.)56 b Fi(The)37 b(SGML)h(Handb)-5 b(o)g(ok)p
+Fs(.)59 b(Oxford)35 b(Univ)m(ersit)m(y)g(Press,)i(1990.)59
+b(\(Edited)35 b(and)337 2960 y(with)29 b(a)i(forew)m(ord)f(b)m(y)g(Y)-8
+b(uri)29 b(Rubinsky\).)195 3148 y([5])47 b(Ch)m(uc)m(k)e(Musciano)f
+(and)g(Bill)f(Kennedy)-8 b(.)83 b Fi(HTML)45 b(|)h(The)g(De\014nitive)f
+(Guide)p Fs(.)84 b(O'Reilly)42 b(&)337 3261 y(Asso)s(ciates,)31
+b(Inc.,)g(1996.)195 3448 y([6])47 b(Brian)29 b(W.)i(Kernighan)d(and)h
+(Dennis)g(M.)h(Ritc)m(hie.)40 b Fi(The)32 b(C)g(Pr)-5
+b(o)g(gr)g(amming)35 b(L)-5 b(anguage)p Fs(.)41 b(Pren)m(tice)337
+3561 y(Hall,)30 b(second)g(edition,)f(1988.)195 3749
+y([7])47 b(Douglas)31 b(A.)g(Sc)m(henc)m(k)h(and)e(P)m(eter)i(R.)f
+(Wilson.)41 b Fi(Information)35 b(Mo)-5 b(deling)34 b(the)f(EXPRESS)f
+(Way)p Fs(.)337 3862 y(Oxford)d(Univ)m(ersit)m(y)h(Press)g(\(ISBN)g
+(0-19-308714-3\),)37 b(1994.)195 4049 y([8])47 b(ISO)21
+b(10303-11:1994.)34 b Fi(Industrial)27 b(automation)h(systems)e(and)h
+(inte)-5 b(gr)g(ation)27 b(|)f(Pr)-5 b(o)g(duct)26 b(data)i(r)-5
+b(ep-)337 4162 y(r)g(esentation)36 b(and)g(exchange)f(|)f(Part)h(11:)47
+b(Description)35 b(metho)-5 b(ds:)48 b(The)35 b(EXPRESS)e(language)337
+4275 y(r)-5 b(efer)g(enc)g(e)33 b(manual)p Fs(,)f(1994.)195
+4463 y([9])47 b(John)35 b(R.)g(Levine,)i(T)-8 b(on)m(y)36
+b(Mason,)h(and)e(Doug)i(Bro)m(wn.)56 b Fi(lex)38 b(&)f(yac)-5
+b(c)p Fs(.)56 b(O'Reilly)34 b(&)h(Asso)s(ciates,)337
+4576 y(Inc.,)30 b(second)h(edition,)e(1992.)150 4763
+y([10])47 b(M.)34 b(E.)g(Lesk)f(and)g(E.)h(Sc)m(hmidt.)49
+b(`LEX)33 b(|)h(A)f(Lexical)g(Analyser)g(Generator'.)52
+b(In)32 b Fi(UNIX)j(Pr)-5 b(o-)337 4876 y(gr)g(ammer's)34
+b(Manual)f(2)p Fs(.)e(A)-8 b(T&T)30 b(Bell)g(Lab)s(oratories,)g(Murra)m
+(y)g(Hill,)f(NJ,)h(1975.)150 5064 y([11])47 b(S.)32 b(C.)g(Johnson.)46
+b Fi(Y)-7 b(A)n(CC)34 b(|)g(Y)-7 b(et)34 b(A)n(nother)h(Compiler)h
+(Compiler)p Fs(.)49 b(C)32 b(S)g(T)-8 b(ec)m(hnical)32
+b(Rep)s(ort)g(32,)337 5177 y(Bell)d(T)-8 b(elephone)30
+b(Lab)s(oratories,)h(Murra)m(y)f(Hill,)e(NJ,)j(1975.)1882
+5531 y(123)p eop
+%%Page: 124 128
+124 127 bop 150 573 a Fs([12])47 b(ISO/TR)c(10303-12:1997.)88
+b Fi(Industrial)48 b(automation)g(systems)e(and)h(inte)-5
+b(gr)g(ation)47 b(|)f(Pr)-5 b(o)g(duct)337 686 y(data)38
+b(r)-5 b(epr)g(esentation)39 b(and)e(exchange)f(|)g(Part)h(12:)50
+b(Description)37 b(metho)-5 b(d:)51 b(The)36 b(EXPRESS-I)337
+799 y(language)d(r)-5 b(efer)g(enc)g(e)33 b(manual)p
+Fs(,)f(1997.)150 986 y([13])47 b(P)m(eter)g(R.)f(Wilson.)85
+b Fi(`FL)-5 b(aTT)e(eN:)47 b(A)g(Pr)-5 b(o)g(gr)g(am)49
+b(to)e(Flatten)i(L)-5 b(aT)e(eX)47 b(Sour)-5 b(c)g(e)48
+b(Files')p Fs(.)87 b(NIST,)337 1099 y(Gaithersburg,)29
+b(MD)i(20899,)i(Decem)m(b)s(er)e(1994.)43 b(\(In)30 b(draft\).)150
+1287 y([14])47 b(Don)31 b(Lib)s(es.)38 b Fi(Obfusc)-5
+b(ate)g(d)34 b(C)e(and)i(Other)f(Mysteries)p Fs(.)41
+b(John)29 b(Wiley)h(&)g(Sons,)g(Inc.,)g(1993.)150 1474
+y([15])47 b(A.)31 b(I.)f(Holub.)39 b Fi(Compiler)c(Design)d(in)g(C)p
+Fs(.)41 b(Pren)m(tice-Hall,)30 b(Inc.,)g(1990.)150 1662
+y([16])47 b(Andrew)21 b(Oram)g(and)h(Stev)m(e)h(T)-8
+b(alb)s(ott.)27 b Fi(Managing)e(Pr)-5 b(oje)g(cts)26
+b(with)g(make)p Fs(.)h(O'Reilly)20 b(&)i(Asso)s(ciates,)337
+1775 y(Inc.,)30 b(second)h(edition,)e(1991.)150 1963
+y([17])47 b(Ga)m(ylen)27 b(R.)h(Rinaudot.)34 b Fi(The)c(IGES/PDES)f(Or)
+-5 b(ganization)32 b(STEP)d(On-Line)f(Information)k(Ser-)337
+2076 y(vic)-5 b(e)p Fs(.)40 b(NISTIR)29 b(5511,)k(NIST,)c
+(Gaithersburg,)h(MD)h(20899,)i(Octob)s(er)d(1994.)150
+2263 y([18])47 b(N.)21 b(Wirth.)j(`What)d(Can)g(W)-8
+b(e)21 b(Do)h(Ab)s(out)e(the)h(Unnecessary)g(Div)m(ersit)m(y)f(of)h
+(Notation)h(for)e(Syn)m(tactic)337 2376 y(De\014nitions?'.)39
+b Fi(Communic)-5 b(ations)35 b(of)e(the)g(A)n(CM)p Fs(,)c
+(20\(11\):822{823,)37 b(No)m(v)m(em)m(b)s(er)31 b(1977.)150
+2564 y([19])47 b(Ronald)28 b(Mak.)40 b Fi(Writing)31
+b(Compilers)j(&)d(Interpr)-5 b(eters)33 b(|)f(A)n(n)f(Applie)-5
+b(d)33 b(Appr)-5 b(o)g(ach)p Fs(.)41 b(John)29 b(Wiley)337
+2677 y(&)h(Sons,)g(Inc.,)g(1991.)1882 5531 y(124)p eop
+%%Trailer
+end
+userdict /end-hook known{end-hook}if
+%%EOF
diff --git a/support/ltx2x/ltx2x.tex b/support/ltx2x/ltx2x.tex
new file mode 100644
index 0000000000..beb6807367
--- /dev/null
+++ b/support/ltx2x/ltx2x.tex
@@ -0,0 +1,7453 @@
+% ltx2x.tex Description of ltx2x program
+\documentclass[11pt]{article}
+\usepackage{url}
+\usepackage{ltx2html}
+\setlength{\textheight}{8.0in}
+\setlength{\textwidth}{6.0in}
+\setlength{\oddsidemargin}{0.25in}
+\setlength{\evensidemargin}{0.25in}
+\setlength{\marginparwidth}{0.6in}
+\setcounter{secnumdepth}{4}
+\setcounter{tocdepth}{4}
+% define these to save some typing
+\newcommand{\lx}{{\small\sl LTX2X}}
+\newcommand{\ctab}{command table}
+\newcommand{\Express}{{\sc Express}}
+\newcommand{\ExpressA}{{\sc Express-A}}
+\newcommand{\ExpressG}{{\sc Express-G}}
+\newcommand{\ExpressI}{{\sc Express-I}}
+\newenvironment{code}{\begin{small}}{\end{small}}
+\newcommand{\keyword}[1]{\begin{small}\texttt{#1}\end{small}}
+\newcommand{\keytext}[1]{\begin{small}\texttt{#1}\end{small}}
+\newcommand{\file}[1]{\texttt{#1}}
+\mltitle{LaTeX to X translator}
+\begin{document}
+\title{ \textsl{LTX2X:} A \protect\LaTeX\ to X Auto-tagger}
+\author{Peter R. Wilson \\
+ Catholic University of America\thanks{This work was performed
+while a Guest Researcher at the National Institute of Standards and
+Technology} \\
+ Email: \texttt{pwilson@cme.nist.gov} }
+\date{January 1997}
+
+\bibliographystyle{unsrt}
+\pagenumbering{roman}
+\maketitle
+
+\begin{abstract}
+ \lx{} is a table-driven program that will replace \LaTeX\ commands
+by user defined text. This report describes the beta version of the system.
+\lx{} supports both a declaritive command style and an interpreted
+procedural language tentatively called \ExpressA.
+Details are given of the program functionality including examples.
+System installation instructions are provided.
+\end{abstract}
+
+\tableofcontents
+\listoftables
+
+\clearpage
+\pagenumbering{arabic}
+
+\section{Introduction} \label{sec:introduction}
+
+ \LaTeX~\cite{LAMPORT94}, which is built on top of \TeX~\cite{KNUTH84a},
+is a document tagging system
+that is very popular in the academic and scientific publishing communities
+because of the high quality typeset material that the system outputs
+for normal text and especially for mathematics.
+
+ In particular, many of the documents forming the
+International Standard ISO~ 10303, commonly referred to as STEP~\cite{STEPIS},
+have been written using \LaTeX\ as
+the document tagging language. Lately there have been moves towards converting
+the STEP documents to embody SGML~\cite{GOLDFARB90}
+rather than \LaTeX\ markup. This has led
+to an interest in the automatic conversion from \LaTeX\ to SGML
+documents.
+The \lx\ system is an initial attempt to provide a generic capability for
+converting \LaTeX\ tags into other kinds of tags.
+
+ The \lx\ system described below is in a beta release state. That is, there
+is probably some more work to be done on it but experience from use is
+needed to determine desirable additional functionality. However, the code
+has been stable for some time.
+Bug reports or suggested
+enhancements (especially if the suggestions are accompanied by working code)
+are encouraged, as are constructive comments about this document.
+
+ Essentially, \lx{} reads a file containing \LaTeX{} markup,
+replaces the \LaTeX{} commands by user-defined text, and writes the result
+out to another file. The program operates from a command table that specifies
+the replacement text. In general, no programming knowledge or skills are
+required to write a command table, which \lx{} will then interpret.
+Some knowledge of \LaTeX{} is required, but no more than is necessary
+for authoring a \LaTeX{} document.
+
+ \lx{} has proved capable of performing such functions as:
+\begin{itemize}
+\item Conversion of documents marked up according to a specific \LaTeX{}
+ documentclass to documents tagged according to a specific SGML DTD.
+\item Removal of \LaTeX{} commands to produce deTeXed source.
+\item Conversion of simple \LaTeX{} documents to
+ HTML~\cite{MUSCIANO96} tagged documents for publication on the
+ World Wide Web.
+\end{itemize}
+
+ The remainder of this introduction gives an overview of the \lx{} program.
+The command table is described in more detail in section~\ref{sec:command-table}
+and information on running the \lx{} program is provided in
+section~\ref{sec:program}. Section~\ref{sec:expressa} gives an
+overview
+of the \ExpressA{} language.\footnote{The overview is necessarily
+rather brief as I am shortly moving to a new place of employment and
+\ExpressA{} is the latest addition to the system.}
+Although the functionality available through the command table facility is
+suitable for many tasks, especially since an interpreter for the \ExpressA{}
+general programming language is included within \lx,
+section~\ref{sec:special} gives details on how the system can
+be extended for cases where this proves to be inadequate.
+
+ The report ends with several appendices. An example command table for
+deTeXing a document is reproduced in~\ref{sec:detexing} and some of
+the issues in converting from \LaTeX{} to HTML are discussed
+in~\ref{sec:htmling}. The known limitations
+of \lx{} are listed in~\ref{sec:limitations} and a summary of the command
+table facilities are given in~\ref{sec:summary}. Appendix~\ref{sec:install}
+provides instructions on installing the \lx{} program, together with copyright
+and warranty information. Finally, \ref{sec:ctabgrammar} and \ref{sec:expgrammar}provide grammars for the \ctab and \ExpressA, respectively.
+
+\subsection{Overview}
+
+ The intent of Leslie Lamport, the author of \LaTeX, was to provide a document
+tagging system that enabled the capture of the logical structure of a document.
+This system uses Donald Knuth's \TeX\ system as its typesetting engine~\cite{KNUTH84a},
+and thus has an inherent capability for high quality typesetting.
+
+ All \LaTeX\ commands are distinguished by starting with a backslash (\verb|\|).
+Generally speaking, the name of a command is a string of alphabetic characters
+(e.g. \verb|\acommand|). Commands may take arguments. Required arguments are
+enclosed in curly braces (i.e. \verb|{| and \verb|}|). Optional arguments
+are enclosed in square brackets (i.e. \verb|[| and \verb|]|). The general syntax
+for a command is the command name (preceded by a backslash) followed by the
+argument list with a maximum\footnote{Under very unusual
+circumstances this limit may be exceeded.} of nine arguments.
+
+ The \lx\ program reads a \LaTeX\ document file and outputs a
+transformation of this file. By default it outputs the normal text
+while for each \LaTeX{} command and argument performs some
+user-specified actions; typically these actions involve the output
+of specific text corresponding to the particular command.
+The actions are specified in a \emph{\ctab} file, written by the user,
+which is read into the \lx\ system before document processing is
+begun. A \ctab\ consists of a listing of the \LaTeX\ commands of interest
+together with the desired actiond for each of these commands and their
+arguments.
+Different effects may be easily obtained by changing the \ctab\
+file. For example, a simple \ctab{} file may be written that will delete
+all the \LaTeX\ commands from a document, resulting in a plain ASCII file
+with no embedded markup.\footnote{To afficionados,
+this process is known as de-\TeX ing.}
+A more complex command table may be written that will replace \LaTeX\ tags
+with appropriate SGML tags.
+
+ In some circles it is traditional to introduce a programming
+language by providing an example program that prints `Hello world'.
+In contrast, the following \ctab{} file called \file{bye.ct},
+when used in conjunction
+with a typical vanilla \LaTeX{} file, will transform the \LaTeX{} file
+to a file that consists only of the words `Goodbye document'.
+
+\begin{code}
+\begin{verbatim}
+C= bye.ct "Goodbye document" for ltx2x
+
+TYPE= COMMAND
+NAME= \documentclass
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case a LaTeX v2.09 document
+TYPE= COMMAND
+NAME= \documentstyle
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case there is no \documentclass/style command
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+END_CTFILE= end of bye.ct
+\end{verbatim}
+\end{code}
+
+ Essentially the \ctab{} instructs \lx{} what to print for each \LaTeX{}
+command. A \ctab{} file consists of a series of commands, one per line
+and introduced by a keyword such as \keyword{TYPE=}. Keywords are case
+insensitive but by convention are written in upper case. Comments in
+a \ctab{} are introduced by the keyword \keyword{C=}.
+
+ The main body of a \ctab{} consists of the specification of
+\LaTeX{} commands of interest and the actions to be taken for these.
+Each specification commences with the keyword \keyword{TYPE=} and is
+completed by the keyword \keyword{END\_TYPE}, the relevant actions
+being listed between these two keywords.
+
+ \lx{} treats some \LaTeX{} commands specially; among these are
+\verb|\begin{document}| and \verb|\end{document}|. In a \ctab{}
+these are specified by the types \keyword{TYPE= BEGIN\_DOCUMENT} and
+\keyword{TYPE= END\_DOCUMENT}. The actions at
+\verb|\begin{document}| are firstly to print the string `Goodbye document'
+(specified in the line \keyword{START\_TAG= "Goodbye document"}) and
+secondly to stop printing any output (specified in the line
+\keyword{PC\_AT\_END= NO\_PRINT}).
+
+ By not specifying the \keyword{END\_DOCUMENT} entry, the default
+action is used for the \verb|\end{document}| command.
+
+ The \ctab{} entries for the commands \verb|\documentclass| and
+\verb|\documentstyle| specify that, if either of these is in the
+source document, then it is to be replaced by the text string
+\keytext{"Goodbye document"}, and then all further printing is to
+be switched off.
+
+ The other three entries in the \ctab{} specify the actions for any
+other kind of \LaTeX{} command. The keyword \keyword{OTHER\_BEGIN}
+signifies a \LaTeX{} command of the form \verb|\begin{name}| and
+\keyword{OTHER\_END} signifies a command of the form \verb|\end{name}|.
+The keyword \keyword{OTHER\_COMMAND} signifies any other kind of
+\LaTeX{} command (e.g., \verb|\acommand ... |). The actions declared
+for these are all \keyword{PRINT\_CONTROL= NO\_PRINT} which shuts off
+any printing of the command or its arguments. In the \ctab{} \file{bye.ct}
+these are only included to prevent printing before the
+\verb|\begin{document}|.
+
+ To run \lx{} with the above \ctab, type the following (where \verb|>|
+is assumed to be the system prompt):
+\begin{verbatim}
+> ltx2x -f bye.ct input.tex output.tex
+\end{verbatim}
+where \file{bye.ct} is the name of the \ctab, and
+\file{input.tex} and \file{output.tex} are the names of the input \LaTeX{}
+file and the resulting processed file respectively.
+
+
+ As an example of a more useful \ctab\ file, the following one called
+\file{decomm.ct} will remove all \LaTeX\ comments from a typical
+\LaTeX{} source file.
+
+\begin{code}
+\begin{verbatim}
+C= decomm.ct Command table file for ltx2x to de-comment LaTeX source
+
+C= ------------------------------------ set newline characters
+ESCAPE_CHAR= ?
+NEWLINE_CHAR= N
+
+C= ----------------------------------- built in commands
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "\begin{document}"
+END_TYPE
+
+TYPE= END_DOCUMENT
+ START_TAG= "\end{document}"
+END_TYPE
+
+TYPE= BEGIN_VERB
+ START_TAG= "\verb|"
+END_TYPE
+
+TYPE= END_VERB
+ START_TAG= "|"
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "\begin{verbatim}"
+END_TYPE
+\end{verbatim}
+\verb|TYPE= END_VERBATIM| \\
+\verb| START_TAG= "\end{verbatim}"| \\
+\verb|END_TYPE|
+\begin{verbatim}
+TYPE= LBRACE
+ START_TAG= "{"
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= "}"
+END_TYPE
+
+TYPE= PARAGRAPH
+ START_TAG= "?N?N "
+END_TYPE
+
+C= ------------------- define '\item' tags within lists
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "\begin{itemize}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "\begin{enumerate}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "\begin{description}"
+ START_ITEM= "\item"
+ START_ITEM_PARAM= "["
+ END_ITEM_PARAM= "] "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= itemize
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= enumerate
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+END_TYPE
+
+C= --------------------- pass through all other LaTeX commands
+
+TYPE= OTHER_COMMAND
+END_TYPE
+
+TYPE= OTHER_BEGIN
+END_TYPE
+
+TYPE= OTHER_END
+END_TYPE
+
+END_CTFILE= end of file decomm.ct
+\end{verbatim}
+\end{code} % end small
+
+ In the above \ctab\ file, the first pair of commands (\keyword{ESCAPE\_CHAR=}
+and \keyword{NEWLINE\_CHAR=}) define the character pair that are to be used to
+signify a `newline' within a tag. An example of their use is later in the
+file in the \keyword{PARAGRAPH} command type.
+
+ As indicated above, \lx\ treats some \LaTeX\ commands specially.
+These are listed next in the
+\ctab. The special \LaTeX{} commands are the begin and end of the
+\verb|document| and \verb|verbatim|
+environments, together with the \verb|\verb| command, left and right braces,
+the \verb*|\ | command, and the \lx{} \keyword{PARAGRAPH} specification.
+There are default actions for these, but apart from the \verb*|\ | command
+the defaults are not appropriate in this case.
+Above, the actions are to replace the
+\LaTeX{} command by the string forming the \LaTeX{} command. The exception
+is that paragraphs (the \keyword{PARAGRAPH} specification) should start
+with at least one blank line and be indented some spaces.
+
+ The \LaTeX\ \verb|\item| command is used within lists. \lx\ has to be
+told how to treat the \verb|\item| command within each kind of list. This
+has been done above for the \verb|itemize|, \verb|enumerate| and
+\verb|description| environments.
+
+ The final instructions in the \ctab\ file tell \lx\ to pass through the
+text of all other commands and their arguments. The end of the \ctab\ file
+is either the physical end of the file or the command \keyword{END\_CTFILE=},
+whichever comes first. The \keyword{END\_CTFILE=} command acts like the
+\keyword{C=} command in that arbitrary text can be put after the command.
+
+ To use the \file{decomm.ct} \ctab{} to de-comment a \LaTeX\ file, type
+the following (where \verb|>| is assumed to be the system prompt):
+\begin{verbatim}
+> ltx2x -f decomm.ct input.tex output.tex
+\end{verbatim}
+where \file{input.tex} and \file{output.tex} are the names of the input \LaTeX\
+file for de-commenting and the resulting de-commented version respectively.
+
+\section{The \ctab\ file} \label{sec:command-table}
+
+ By default, \lx\ does not output any \LaTeX\ comments.
+Otherwise, whenever it comes
+across a \LaTeX\ command it looks at the data in the \ctab\ file to determine
+what actions it should take. The two most typical actions are either
+to print out the command as read in, or to replace the command by some (possibly
+empty) text.
+
+ Each line in a \ctab\ file is either blank or starts with a keyword followed
+by one or more blanks. For
+example, a comment in the file is a line that starts with \keyword{C= };
+the remainder of the line is any comment text. Comments may be placed anywhere
+in the file.
+
+
+\subsection{Special print characters in tags}
+
+ \lx\ is written in C~\cite{KERNIGHAN88}.
+The C language enables certain non-printing characters
+to be defined. These are typically written in the form \verb|\c| where \verb|\|
+is the C escape character and \verb|c|
+is a particular character. \lx\ understands some of these special printing
+characters and the \ctab\ enables these to be given non-default values.
+
+ The default escape character (\verb|\|) may be redefined via the
+\keyword{ESCAPE\_CHAR=} command. For example,
+\begin{code}
+\begin{verbatim}
+ESCAPE_CHAR= ?
+\end{verbatim}
+\end{code}
+will make the question mark character the escape character. Typically, the escape
+character is changed in most \ctab s to avoid clashing with the \LaTeX{} \verb|\|
+character.
+The following commands
+can be used to redefine the C special characters. Each of these commands takes
+a single character as its value. If a relevant command is not given, then the
+default value is used.
+\begin{description}
+\item[\keyword{NEWLINE\_CHAR=}] a new line (default is \verb|n|) \\
+\item[\keyword{HORIZONTAL\_TAB\_CHAR=}] horizontal tab (default is \verb|t|) \\
+\item[\keyword{VERTICAL\_TAB\_CHAR=}] vertical tab (default is \verb|v|) \\
+\item[\keyword{BACKSPACE\_CHAR=}] backspace (default is \verb|b|) \\
+\item[\keyword{CARRIAGE\_RETURN\_CHAR=}] carriage return (default is \verb|r|) \\
+\item[\keyword{FORMFEED\_CHAR=}] formfeed (default is \verb|f|) \\
+\item[\keyword{AUDIBLE\_ALLERT\_CHAR=}] beep the terminal (default is \verb|a|) \\
+\item[\keyword{HEX\_CHAR=}] following characters form the hexadecimal number of
+ the character
+ to be printed (default is \verb|x|) (e.g. \verb|?xA3|) \\
+\end{description}
+ These command lines are all optional within a \ctab\ and their ordering is
+immaterial. However, if any are present then they must be at the beginning of
+the \ctab.
+
+ The above special characters are useful when specifying the replacement text
+for \LaTeX\ commands.
+
+
+\subsection{\protect\LaTeX\ command types}
+
+ The commands for controlling the actions performed on \LaTeX\ commands
+are enclosed between the command lines \keyword{TYPE= } and \keyword{END\_TYPE},
+as below.
+\begin{code}
+\begin{verbatim}
+TYPE= CommandType
+ C= a possibly empty set of commands
+END_TYPE
+\end{verbatim}
+\end{code}
+where \keyword{CommandType} is an \lx\ keyword signifying the kind of \LaTeX\
+command being specified.
+
+\subsubsection{Built in command types}
+
+ Some \LaTeX\ commands are pre-defined within \lx. Default actions
+are provided for these but it is recommended that type specifications
+for each of these commands be put in the \ctab{} anyway. The keywords for
+these commands are:
+\begin{description}
+\item[\keyword{BEGIN\_DOCUMENT}] Corresponds to the \LaTeX\ command
+ \verb|\begin{document}|.
+\item[\keyword{END\_DOCUMENT}] Corresponds to the \LaTeX\ command
+ \verb|\end{document}|.
+\item[\keyword{BEGIN\_VERBATIM}] Corresponds to the \LaTeX\ commands
+ \verb|\begin{verbatim}| and \\
+ \verb|\begin{verbatim*}|.
+\item[\keyword{END\_VERBATIM}] Corresponds to the \LaTeX\ commands
+ \verb|\end{verbatim}| and \verb|\end{verbatim*}|.
+\item[\keyword{BEGIN\_VERB}] Corresponds to the \LaTeX\ commands
+ \verb|\verb| and \verb|\verb*|, together with the succeeding character.
+\item[\keyword{END\_VERB}] Corresponds to the appearance of the character
+ that completes the \LaTeX\ commands
+ \verb|\verb| and \verb|\verb*|.
+\item[\keyword{LBRACE}] Corresponds to the \LaTeX\ left brace character
+ \verb|{|.
+\item[\keyword{RBRACE}] Corresponds to the \LaTeX\ right brace character
+ \verb|}|.
+\item[\keyword{BEGIN\_DOLLAR}] Corresponds to the \LaTeX\ \verb|$| symbol signalling the
+ start of an in-text math formula.
+\item[\keyword{END\_DOLLAR}] Corresponds to the \LaTeX\ \verb|$| symbol signalling the
+ end of an in-text math formula.
+\item[\keyword{PARAGRAPH}] Corresponds to the \LaTeX\ protocol of a blank
+ line signalling the start/end of a paragraph.
+\item[\keyword{SLASH\_SPACE}] Corresponds to the \LaTeX\ \verb*|\ | command.
+\item[\keyword{OTHER\_COMMAND}] Corresponds to any \LaTeX\ command of the form
+ \verb|\command| not specified elsewhere within the \ctab.
+\item[\keyword{OTHER\_BEGIN}] Corresponds to any \LaTeX\ command of the form
+ \verb|\begin{environment}| not specified elsewhere within the \ctab.
+\item[\keyword{OTHER\_END}] Corresponds to any \LaTeX\ command of the form
+ \verb|\end{environment}| not specified elsewhere within the \ctab.
+\end{description}
+
+
+ The ordering of these built in type specifications is immaterial. If
+any of the above are not specified within the \ctab{} then \lx{} will use
+their default action.
+ With the exception of the \keyword{SLASH\_SPACE} command type, the
+default action is to do nothing (i.e., produce no output).
+The default action for the \keyword{SLASH\_SPACE}
+command type is to output a space.
+
+\subsubsection{Optional command types}
+
+ For the purposes of \lx, \LaTeX\ commands are divided into various classes.
+The keywords for these clases, and the class descriptions, are listed below.
+
+\begin{description}
+\item[\keyword{TEX\_CHAR}] Corresponding to \LaTeX's special characters (with the exception
+ of the \$, \{\ and \}\ characters).
+\item[\keyword{CHAR\_COMMAND}] Corresponding to \LaTeX\ commands of the type
+ \verb|\c| where \verb|c| is a single non-alphabetic character.
+\item[\keyword{COMMAND}] Corresponding to \LaTeX\ commands of the type
+ \verb|\command|, where \verb|command| is the name of the command (except for
+ \verb|\begin|, \verb|\end| and \verb|\item|).
+\item[\keyword{BEGIN\_ENV}] Corresponding to \LaTeX\ commands of the type
+ \verb|\begin{environment}| where \verb|environment| is the name of the
+ environment, except for those list environments whose bodies
+ consist of \verb|\item| commands.
+\item[\keyword{END\_ENV}] Corresponding to \LaTeX\ commands of the type
+ \verb|\end{environment}|, with the same restrictions as for \verb|BEGIN_ENV|.
+\item[\keyword{BEGIN\_LIST\_ENV}] Corresponding to \LaTeX\ commands of the type
+ \verb|\begin{environment}| where \verb|environment| is the name of an
+ environment whose body consists of \verb|\item| commands.
+\item[\keyword{END\_LIST\_ENV}] Corresponding to \LaTeX\ commands of the type
+ \verb|\end{environment}| to match \verb|BEGIN_LIST_ENV|.
+\item[\keyword{VCOMMAND}] Corresponding to a \LaTeX{} \verb|\verb|-like command.
+\item[\keyword{BEGIN\_VENV}] Corresponding to the start of a verbatim-like
+ environment.
+\item[\keyword{END\_VENV}] Corresponding to the end of a verbatim-like
+ environment.
+\item[\keyword{SECTIONING}] Corresponding to \LaTeX\ commands of the type
+ \verb|\command|, where \verb|command| is a document sectioning command
+ such as \verb|chapter| or \verb|subsection|.
+\item[\keyword{SPECIAL}] Reserved for possible future use.
+\item[\keyword{SPECIAL\_COMMAND}] Corresponding to the \verb|COMMAND| keyword,
+ except that some special output processing is to be defined.
+\item[\keyword{SPECIAL\_BEGIN\_ENV}] Corresponding to the \verb|BEGIN_ENV| keyword,
+ except that some special output processing is to be defined.
+\item[\keyword{SPECIAL\_END\_ENV}] Corresponding to the \verb|END_ENV| keyword,
+ except that some special output processing is to be defined.
+\item[\keyword{SPECIAL\_BEGIN\_LIST}] Corresponding to the \verb|BEGIN_LIST_ENV|
+ keyword,
+ except that some special output processing is to be defined.
+\item[\keyword{SPECIAL\_END\_LIST}] Corresponding to the \verb|END_LIST_ENV| keyword,
+ except that some special output processing is to be defined.
+\item[\keyword{SPECIAL\_SECTIONING}] Corresponding to the \verb|SECTIONING| keyword,
+ except that some special output processing is to be defined.
+\item[\keyword{\_PICTURE\_}] Corresponding to some of the \LaTeX\ picture
+ drawing commands.
+\item[\keyword{COMMAND\_...}] Corresponding to some of the \LaTeX{} commands
+ whose arrangements of required and optional arguments are untypical.
+\end{description}
+
+ The ordering of these types within a \ctab\ is immaterial.
+
+ Each of the above type specifications requires a \keyword{NAME=} command,
+whose value is the
+name of the relevant command or environment being specified. For example, the
+following is a (partial) specification of the figure environment and the caption
+command.
+
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_ENV
+NAME= figure
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+END_TYPE
+
+TYPE= COMMAND
+NAME= \caption
+END_TYPE
+\end{verbatim}
+\end{code}
+
+\subsection{Command action tags}
+
+ When \lx\ reads a \LaTeX\ command it performs the following actions:
+\begin{enumerate}
+\item Looks up the name of the command or environment in the \ctab. If
+ it is not found, then the appropriate default type is used.
+\item Sets the printing mode according to the \keyword{PC\_AT\_START=}
+ command.
+\item Performs the actions specified in the \ctab\ by the
+ \keyword{START\_TAG=} command.
+\item Processes any specified arguments to the command.
+\item Performs the actions specified in the \ctab\ by the \keyword{END\_TAG=}
+ command.
+\item Sets the printing mode according to the \keyword{PC\_AT\_END=} command.
+\end{enumerate}
+
+\begin{description}
+\item[NOTES]:
+\begin{enumerate}
+\item Except for the default processing of \keyword{OTHER\_} types, it does not
+ output the command itself.
+\item If a tag action is not specified, then the default action is null (e.g.,
+ nothing will appear in the output).
+\end{enumerate}
+\end{description}
+
+ Within a \ctab\ all text strings for output are enclosed within double
+quotes. For example:
+\begin{code}
+\begin{verbatim}
+START_TAG= "Some "text" string\n another line of text."
+\end{verbatim}
+\end{code}
+
+ Assuming that \verb|\n| means a newline, when this string action is performed
+by \lx\ it will appear in the output file as:
+\begin{code}
+\begin{verbatim}
+Some "text" string
+another line of text.
+\end{verbatim}
+\end{code}
+
+ A text string starts with the first double quote and ends with the last double
+quote on the command line. A text string has to be written on a single line
+within the \ctab. C language special print characters can be embedded within the
+text string (e.g. the \verb|\n| for a newline in the above example). Remember
+that the first section of the \ctab\ is used for specifying the
+particular \ctab\ version of these.
+
+ If a text string is too long to fit comfortably on a single line in the
+\ctab, it may be continued via the \keyword{STRING:} command. As many of these
+can be used in succession as required (subject to internal limitations within \lx).
+
+ For instance,
+\begin{code}
+\begin{verbatim}
+START_TAG= "Some "text" string\n"
+ STRING: "another line of text."
+\end{verbatim}
+\end{code}
+has the same effect as the previous example.
+
+ The following specification is designed to write out the contents of the
+\verb|\caption| command\footnote{Strictly speaking, the specification does not
+do this exactly, but this simplified illustration will be corrected in
+the next sections.},
+preceded by the word `CAPTION' and followed by at least one
+blank line (assuming that the escape character has been set to \verb|?|).
+
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+END_TYPE
+\end{verbatim}
+\end{code}
+Assuming that somewhere in a \LaTeX\ file there is the command
+\begin{code}
+\begin{verbatim}
+stuff
+\caption{This is a caption.}
+more stuff
+\end{verbatim}
+\end{code}
+then the expected effect (see footnote) is
+\begin{code}
+\begin{verbatim}
+stuff
+
+ CAPTION This is a caption.
+
+more stuff
+\end{verbatim}
+\end{code}
+
+\subsection{Argument actions}
+
+ \LaTeX\ commands can take arguments. The text for a required argument is
+enclosed in curly braces, while the text for an optional argument is enclosed
+in square brackets. \lx\ can be directed to perform actions at the start and end
+of each argument.
+
+ The number of required arguments is specified by the command line
+\keyword{REQPARAMS=}
+where the value of the command is a digit between 1 and 9 inclusive.
+
+ \lx\ assumes that a command can have only one optional argument, and that this
+is either first or last in the argument list. The potential presence of an
+optional argument is indicated by the command line \keyword{OPT\_PARAM=},
+where the
+value is either the keyword \keyword{FIRST} (for first in the list) or
+\keyword{LAST} (for last in the list).
+
+ The actions to be performed at the start and end of each required argument
+are specified via the commands \keyword{START\_TAG\_1=} and \keyword{END\_TAG\_1=}
+for the first required argument, through \keyword{START\_TAG\_9=} and
+\keyword{END\_TAG\_9=} for the ninth argument.
+The actions to be performed at the start and end of the optional argument
+are specified by the command lines \keyword{START\_OPT=} and \keyword{END\_OPT=}.
+
+ The argument delimiters (the braces or brackets) are not printed.
+
+ In the simplest case, the action is to print a specified text string
+(enclosed in double quotes, and continued with \keyword{STRING:} commands
+if necessary). Other kinds of actions are also possible.
+An unspecified tag defaults to doing no action.
+
+\subsubsection{Print options}
+
+\paragraph{Argument processing}
+
+ By default, \lx\ processes (i.e. outputs as appropriate)
+the text of a argument.
+Printing of the argument text may be disabled, if required. The command line
+that controls argument printing is of the form \keyword{PRINT\_P1=} through
+\keyword{PRINT\_P9=} for required arguments and
+\keyword{PRINT\_OPT=} for the optional
+argument. The value of these commands is one from several keywords,
+the most common being \keyword{NO\_PRINT}; this
+switches off printing of the text of the indicated argument.
+Default printing is resumed after the indicated argument.
+
+ Continuing the caption example from earlier, we can now complete it. The full
+syntax of the \LaTeX\ command is:
+\begin{code}
+\begin{verbatim}
+\caption[optional table of contents entry]{Caption in the text}
+\end{verbatim}
+\end{code}
+That is, it has one required argument, which prints the caption text both in
+the body of the document and in the table of contents, unless the first optional
+argument is present, in which case its value gets printed in the table of
+contents instead.
+
+ Assume that an instance of the caption command in a document is:
+\begin{code}
+\begin{verbatim}
+Some stuff
+\caption[Short caption]{Long caption for the body of the text.}
+More stuff
+\end{verbatim}
+\end{code}
+Recall the previous \ctab\ caption specification. The actual output from
+processing this would be
+\begin{code}
+\begin{verbatim}
+Some stuff
+
+ CAPTION [Short caption]{Long caption for the body of the text.}
+
+More stuff
+\end{verbatim}
+\end{code}
+because, unless \lx\ is told that there are command arguments and how they should
+be treated, it will just print them out together with their surrounding
+delimiters.
+
+ The following \ctab\ entry will give more acceptable results.
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+\end{verbatim}
+\end{code}
+
+ For the above captioning instance, the output will now be:
+\begin{code}
+\begin{verbatim}
+Some stuff
+
+ CAPTION Long caption for the body of the text.
+
+More stuff
+\end{verbatim}
+\end{code}
+
+ The default print mode is to print text to the output file.
+
+ The keywords that can be used to control argument printing are:
+\begin{description}
+\item[\keyword{NO\_PRINT}] Do not print anything.
+\item[\keyword{TO\_SYSBUF}] Print to the \lx{} system buffer.
+\item[\keyword{TO\_BUFFER num}] Print to the \lx{} buffer
+ number \keyword{num}.
+\item[\keyword{TO\_FILE name}] Print to the file called \keyword{name}.
+\item[\keyword{NO\_OP}] Skip all processing of the argument.
+\end{description}
+Note that even if the print mode is set to \keyword{NO\_PRINT}, the
+argument text will still be processed. Only the \keyword{NO\_OP}
+specification temporarly turns off the processing.
+
+
+\paragraph{General printing}
+
+ Just as the printing mode can be set for each argument, it can also be
+set at the start and end of processing a \LaTeX{} command or environment.
+
+ The specifications \keyword{PC\_AT\_START=} and \keyword{PC\_AT\_END=}
+can be used to set the printing mode at the start of processing a command
+and at the end, respectively. The keywords that can be used in these
+specifications are:
+\begin{description}
+\item[\keyword{NO\_PRINT}] Do not print anything.
+\item[\keyword{TO\_SYSBUF}] Print to the \lx{} system buffer.
+\item[\keyword{TO\_BUFFER num}] Print to the \lx{} buffer
+ number \keyword{num}.
+\item[\keyword{TO\_FILE name}] Print to the file called \keyword{name}.
+\item[\keyword{RESET}] Reset the print mode back to what it was.
+\end{description}
+
+ Unlike the argument printing controls, the print mode is not
+automatically reset. This has to be explicitly specified.
+
+ As an example, assume that it is required to remove all \keytext{figure}
+environments from a \LaTeX{} source and put them into a file on their own.
+The following \ctab{} code could be used to accomplish this.
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_ENV
+NAME= figure
+ PC_AT_START= TO_FILE allfigs.tex
+ START_TAG= "?n\begin{figure}"
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+ START_TAG= "\end{figure}"
+ PC_AT_END= RESET
+END_TYPE
+\end{verbatim}
+\end{code}
+When a \LaTeX{} \keytext{figure} environment is started, printing is switched
+to go to the file called \file{allfigs.tex}. At the end of the \keytext{figure}
+environment, the print mode is reset back to what it was before the environment
+began. If at the first \keytext{figure} environment the \file{allfigs.tex}
+file did not exist, then \lx{} would create it automatically.
+
+\paragraph{Read actions}
+
+ As noted above, one of the actions that can be specified for a
+\LaTeX{} comand's argument is to set the print mode for printing to a buffer
+or a file. Similarly there are actions which will read from a buffer or
+a file and print the contents. Within an argument tag these kinds of actions are
+specified via the keyword \keyword{SOURCE:}. This can take one of several
+values:
+\begin{description}
+\item[\keyword{SYSBUF}] Print the contents of the \lx{} system buffer.
+\item[\keyword{BUFFER num}] Print the contents of the \lx{} buffer
+ number \keyword{num}.
+\item[\keyword{FILE name}] Print the contents of the file called
+ \keyword{name}.
+\end{description}
+
+ In a previous example, the \LaTeX{} \keytext{figure} environments
+were all written to the file \file{allfig.tex}. This file could be read
+in again just before the end of the document so that all figures will be
+typeset after everything else.
+\begin{code}
+\begin{verbatim}
+TYPE= END_DOCUMENT
+ END_TAG= "?n % figures collected here by LTX2X ?n"
+ SOURCE: FILE allfigs.tex
+ STRING: "?n\end{document}?n"
+END_TYPE
+\end{verbatim}
+\end{code}
+
+ As another example of the use of the print actions consider the \LaTeX{}
+\verb|\maketitle| command. This typesets the arguments of the \verb|\title|,
+\verb|\author| and \verb|\date| commands, which must have been previously
+specified but not necessarily in this ordering. Here is one way this can
+be simulated using \lx.
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND
+NAME= \title
+ START_TAG=
+ RESET_BUFFER: 1
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \author
+ START_TAG=
+ RESET_BUFFER: 2
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 2
+END_TYPE
+
+TYPE= COMMAND
+NAME= \date
+ START_TAG=
+ RESET_BUFFER: 3
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \maketitle
+ START_TAG= "?n"
+ SOURCE: BUFFER 1
+ STRING: "?n?n"
+ SOURCE: BUFFER 2
+ STRING: "?n?n"
+ SOURCE: BUFFER 3
+ STRING: "?n?n"
+ END_TAG=
+ RESET_BUFFER: 1
+ RESET_BUFFER: 2
+ RESET_BUFFER: 3
+END_TYPE
+\end{verbatim}
+\end{code}
+For the \verb|\title| command, the print mode for its argument is set
+for printing to the buffer number~1. The single action at the start of
+the command is to make sure that buffer~1 is empty (the line
+\keyword{RESET\_BUFFER: 1}). The actions for the \verb|\author| and
+\verb|\date| commands are similar, except that they print their argument
+texts to buffers~2 and~3 respectively.
+
+ The \verb|\maketitle| command takes no arguments, so all actions
+must be placed under \keyword{START\_TAG=} and/or \keyword{END\_TAG=}.
+There are a set of actions specified for \keyword{START\_TAG=}. Firstly
+a newline is printed and this is followed by the contents of buffer~1
+(i.e., the text of the argument of the \verb|\title| command).
+Then two new lines are printed, followed by the contents of buffer~2
+(the author). Finally another two newlines are printed, the contents
+of buffer~3 (the date), and another two newlines. The actions
+for \keyword{END\_TAG=} are to clear the contents of the three buffers.
+
+ Just to extend the example, here is a specification for the
+\LaTeX{} \verb|\thanks| command. \lx{} is not designed to do footnoting
+(as it does not do page breaking)
+so instead the thanks text will be placed inside parentheses on a new line.
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND
+NAME= \thanks
+ START_TAG= "?n ("
+ REQPARAMS= 1
+ END_TAG= ") "
+END_TYPE
+\end{verbatim}
+\end{code}
+
+
+ Given these \ctab{} specification and the following portion of a
+\LaTeX{} document
+\begin{code}
+\begin{verbatim}
+\date{29 February 2000}
+\title{The Calculation of Leap Days\thanks{Originally published in JIR}}
+\author{A. N. Other}
+...
+\maketitle
+\end{verbatim}
+\end{code}
+then output from \lx{} will be:
+\begin{code}
+\begin{verbatim}
+The Calculation of Leap Days
+ (Originally published in JIR)
+
+A. N. Other
+
+29 February 2000
+\end{verbatim}
+\end{code}
+Note that as the \verb|\thanks| command appears within the argument of the
+\verb|\title| command, it is written to the same place as the text of
+the argument of \verb|\title|. Thus, it also gets written to the output file
+when \verb|\maketitle| is processed.
+
+\subsubsection{Print switching}
+
+ There are individual actions that enable the printing destination
+to be changed at will within the action set for any particular tag.
+\begin{description}
+\item[\keyword{SWITCH\_TO\_BUFFER: num}] Direct any following printing
+ to the \lx{} buffer number \keyword{num}.
+\item[\keyword{SWITCH\_TO\_FILE: name}] Direct any following printing
+ to the file called \keyword{name}.
+\item[\keyword{SWITCH\_TO\_SYSBUF}] Direct any following printing
+ to the \lx{} system buffer.
+\item[\keyword{SWITCH\_BACK:}] Undo the effect of the last
+ \keytext{SWITCH\_TO...} action.
+\end{description}
+
+ As an example of the utility of this type of action, consider
+again the \LaTeX{} \verb|\maketitle| command. When \LaTeX{} processes
+this command, it typesets the date as specified by the \verb|\date|
+command, or if this has not been specified then it prints the current
+date instead. We can arrange for \lx{} to do something similar by
+adding the following to the \ctab{} shown earlier for the \verb|\date|
+and \verb|\maketitle| commands.
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND
+NAME= \documentclass
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+ START_TAG=
+ c= Initialise buffer 3 to `Today'
+ RESET_BUFFER: 3
+ SWITCH_TO_BUFFER: 3
+ STRING: "Today"
+ SWITCH_BACK:
+END_TYPE
+\end{verbatim}
+\end{code}
+ At the start of the document, the above actions put the string
+\keytext{Today} into \keytext{BUFFER 3}, having first ensured that it is
+empty. If the \LaTeX{} source includes a \verb|\date| command, then
+the contents of the buffer will be overwritten, otherwise it will be
+as initialised. In any event, when the \verb|\maketitle| command is
+processed, the value output for the date will be either \keytext{Today}
+or whatever the argument was of the \verb|\date| command.
+
+\subsubsection{Notes on the use of buffers and files}
+
+ Resetting a buffer or a file always has the effect of emptying it
+of an prior contents.
+
+ When printing from a buffer or a file, the entire contents are
+printed. There is no limit to the number of times that a buffer
+or a file can be used as a printing source.
+
+ When printing to a buffer, the new strings are appended at
+the end of the current contents of the buffer, at least until it
+overflows. Unlike the behaviour of files,
+this is independant of any intervening prints from the buffer.
+
+ When printing to a file, the new strings are appended at the
+end of the current contents of the file. However, if a file is printed
+to after it has been printed from, the prior contents of the file
+are lost, and the new string is added at the start of the file.
+In general, it is safest to treat files as either read-only or write-only.
+
+
+
+\subsubsection{User specified modes}
+
+ Consider the \LaTeX{} command \verb|\\|. In normal text this signifies
+that a line break must occur. In a \verb|tabular| environment, though,
+it signifies the end of a row in a table. Suppose that in the \lx{}
+procesing of a tabular environment it is required to start and end each
+row with a vertical bar and to seperate each column also with a vertical
+bar. However, in normal text a \verb|\\| command should just translate
+into a newline. Just to complicate matters further, assume that in
+an \verb|eqnarray| environment, the \verb|&| column seperator is to
+be translated to some spaces, and that the string `(X)' is to be
+put at the end of every row.
+
+ In other words, we need to process some commands differently
+according to where they appear in the LaTeX{} source. An \lx{} \ctab{}
+provides this capability through mode setting and mode-dependent actions.
+Here is an example of using this facility to solve the requirements
+outlined above.
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_ENV
+NAME= tabular
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: tabular
+END_TYPE
+
+TYPE= END_ENV
+NAME= tabular
+ START_TAG=
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarry
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: eqn
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray
+ START_TAG= " (X)?n"
+ RESET_MODE:
+END_TYPE
+
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " | "
+IN_MODE= eqn
+ START_TAG= " "
+END_MODE
+END_TYPE
+
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+IN_MODE= tabular
+ START_TAG= " |?n"
+ STRING: " | "
+END_MODE
+IN_MODE= eqn
+ START_TAG= " (X)?n"
+END_MODE
+END_TYPE
+\end{verbatim}
+\end{code}
+
+ Let us look at the specification for the \verb|\tabular| environment first.
+The \keyword{END\_TAG=} action is specified by the single command line
+\keyword{SET\_MODE:}~\keytext{tabular}, where \keytext{tabular} is any convenient
+name for identifying a mode. Thus, this will set the mode to be \keytext{tabular}.
+The action at the end of the environment is to reset the mode
+(\keyword{RESET\_MODE:})
+to whatever its previous value was. It is assumed that the last row in any
+\verb|tabular| environment is finished by \verb|\\|. Similar actions are
+performed for the \verb|eqnarray| environment, except that the mode is called
+\keytext{eqn} instead of \keytext{tabular}. The other difference is that it
+is assumed that the last row is not ended by \verb|\\|, so the end of
+the \verb|eqnarray| environment has to also act like the \verb|\\|.
+
+ Turning now to the specification for the \verb|&| command, the first part
+of the specification identifies the type and name of the \LaTeX{} command.
+This is then followed by the mode-independent set of actions,
+which in this case
+consists of printing a vertical bar with some spaces on either side of it.
+Following these are any mode-dependent actions, bracketed between
+\keyword{IN\_MODE=} and \keyword{END\_MODE}. The value for \keyword{IN\_MODE=}
+is the name of the relevent mode. In this case the only mode-dependent
+action occurs when \keytext{MODE eqn} is in effect and it is to print
+some spaces instead of the default spaces and vertical bar.
+
+ The specification for the \verb|\\| command has its set of
+mode-independent default actions,
+namely just to print a newline, and two sets of mode-dependent actions.
+When the \keytext{tabular} mode is in effect, it prints some spaces, a vertical
+bar, a newline, more spaces, a vertical bar, and finally some more spaces.
+On the other hand, when the \keytext{eqn} mode is in effect, it prints some
+spaces, the string `(X)' and a newline. If a mode is in effect
+that is not defined within the specification (e.g., mode \keytext{anon})
+it performs the default mode-independent actions.
+
+ As a perhaps more practical example, the following \ctab{} code will
+convert simple \LaTeX{} \verb|tabular|
+ environments to appropriate mark-up for HTML tables. It is assumed that
+the \verb|tabular| environment is always within a \verb|table| environment.
+
+ To set the perspective a little, here is the code for a simple table
+in \LaTeX:
+\begin{code}
+\begin{verbatim}
+\begin{table}[tbp]
+\centering
+\caption{A simple table typeset by \LaTeX.} \label{tab:lxtab}
+\begin{tabular}{|l||r|r||r|r|} \hline
+Stock & \multicolumn{2}{c||}{1994} & \multicolumn{2}{c|}{1995} \\ \cline{2-5}
+ & low & high & low & high \\ \hline
+ABC & 27 & 36 & 23 & 45 \\
+DEF & 53 & 72 & 19 & 54 \\
+GHI & 28 & 49 & 17 & 79 \\ \hline
+\end{tabular}
+\end{table}
+\end{verbatim}
+\end{code}
+This will be typeset as shown in table~\ref{tab:lxtab}.
+\begin{table}[tbp]
+\centering
+\caption{A simple table typeset by \LaTeX.} \label{tab:lxtab}
+\begin{tabular}{|l||r|r||r|r|} \hline
+Stock & \multicolumn{2}{c||}{1994} & \multicolumn{2}{c|}{1995} \\ \cline{2-5}
+ & low & high & low & high \\ \hline
+ABC & 27 & 36 & 23 & 45 \\
+DEF & 53 & 72 & 19 & 54 \\
+GHI & 28 & 49 & 17 & 79 \\ \hline
+\end{tabular}
+\end{table}
+
+ The corresponding HTML code for the table after translation is:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+<p><center><table border>
+<caption>A simple table typeset by LaTeX.</caption> <a name="tab:lxtab"></a>
+
+<tr><td> Stock </td><td colspan=2> 1994 </td><td colspan=2> 1995 </tr>
+<tr><td >
+ </td><td > low </td><td > high </td><td > low </td><td > high </tr>
+<tr><td > ABC </td><td > 27 </td><td > 36 </td><td > 23 </td><td > 45 </tr>
+<tr><td >
+DEF </td><td > 53 </td><td > 72 </td><td > 19 </td><td > 54 </tr>
+<tr><td >
+GHI </td><td > 28 </td><td > 49 </td><td > 17 </td><td > 79 </tr>
+<tr><td >
+</table></center>
+\end{verbatim}
+\end{code}
+\end{latexonly}
+
+\begin{code}
+\begin{htmlverbatim}
+\ST{p}\ST{center}\ST{table border}
+\ST{caption}A simple table typeset by LaTeX.\ET{caption} \ST{a name="tab:lxtab"}\ET{a}
+
+\ST{tr}\ST{td} Stock \ET{td}\ST{td colspan=2} 1994 \ET{td}\ST{td colspan=2} 1995 \ET{tr}
+\ST{tr}\ST{td}
+ \ET{td}\ST{td} low \ET{td}\ST{td} high \ET{td}\ST{td} low \ET{td}\ST{td} high \ET{tr}
+\ST{tr}\ST{td} ABC \ET{td}\ST{td} 27 \ET{td}\ST{td} 36 \ET{td}\ST{td} 23 \ET{td}\ST{td} 45 \ET{tr}
+\ST{tr}\ST{td}
+DEF \ET{td}\ST{td} 53 \ET{td}\ST{td} 72 \ET{td}\ST{td} 19 \ET{td}\ST{td} 54 \ET{tr}
+\ST{tr}\ST{td}
+GHI \ET{td}\ST{td} 28 \ET{td}\ST{td} 49 \ET{td}\ST{td} 17 \ET{td}\ST{td} 79 \ET{tr}
+\ST{tr}\ST{td}
+\ET{table}\ET{center}
+\end{htmlverbatim}
+\end{code}
+
+ In the HTML browser that I use this is displayed
+approximately as shown for table~\ref{tab:httab}.
+
+\begin{table}[tbp]
+\centering
+\caption{A simple table typeset after translation to HTML.} \label{tab:httab}
+\begin{tabular}{||l|l|l|l|l||} \hline\hline
+Stock & \multicolumn{2}{l||}{1994} & \multicolumn{2}{l|}{1995} \\ \hline
+ & low & high & low & high \\ \hline
+ABC & 27 & 36 & 23 & 45 \\
+DEF & 53 & 72 & 19 & 54 \\
+GHI & 28 & 49 & 17 & 79 \\ \hline \hline
+\end{tabular}
+\end{table}
+
+ In HTML a table is enclosed between
+\keytext{\ST{table}} and \keytext{\ET{table}} tags.
+Each row of the table is enclosed between
+\keytext{\ST{tr}} and \keytext{\ET{tr}} tags,
+and each element in a row is enclosed between
+\keytext{\ST{td}} and \keytext{\ET{td}} tags.
+Under certain circumstances the closing tags (i.e.,
+those like \keytext{\ET{...}})
+can be inferred by the HTML procesors and need
+not be explicitly put into the source text. The equivalent HTML tags to a
+\LaTeX{} \verb|\multicolumn{num}{col}{text}| command are\\
+\keytext{\ST{td colspan=num} text \ET{td}}.
+
+ The general actions that \lx{} has to perform in doing the \LaTeX{} to
+HTML translation are:
+\begin{itemize}
+\item The start and end of a \verb|table| environment has to translate to
+ the HTML start and end table tags \keytext{\ST{table}} and
+ \keytext{\ET{table}}.
+ (Actually this also needs to handle the
+ centering of the HTML table and drawing a border round it as well.)
+
+\item The start and end of the \verb|tabular| environment has to translate
+ into a row start
+ \keytext{\ST{tr}\ST{td}} and end \keytext{\ET{tr}}
+ in the HTML table (and set the mode for the
+ \LaTeX{} \verb|\\| command).
+
+\item The \verb|\\| command must end one row of the HTML table and start the
+ next row
+ (\keytext{\ET{tr}?n\ST{tr}\ST{td}}).
+ It need not end a data element as
+ this is automatically closed by the end of the row.
+
+\item The \verb|&| column delimeter must end one HTML data element and start
+ another one (i.e., \keytext{\ET{td}\ST{td}}).
+
+\item The difficulty is in handling the \verb|\multicolumn| command. In the easy
+ case the \LaTeX{} to HTML translation is: \\
+ \keytext{... \Amp{} text \Amp{} ...} maps to \\
+ \keytext{... \ET{td}\ST{td} text \ET{td}\ST{td} ...}. \\
+ However, when a multicolumn is involved the translation is \\
+\verb|... & \multicolumn{N}{P}{text} & ...| maps to \\
+\keytext{... \ET{td}\ST{td colspan=N} text \ET{td}\ST{td} ...}. \\
+As there is no look-ahead in \lx{} we have to be careful about starting a
+data element after a \verb|&| because at that point \lx{} cannot know
+whether or not a \verb|\multicolumn| command comes next, or just an ordinary
+data element.
+
+\end{itemize}
+
+ We solve this last problem partly by using buffers
+(numbers \keytext{8} and \keytext{9} in the specification below)
+as temporary storage, and partly by a subtle specification for the
+\verb|\multicolumn| command.
+
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+C= start of a table
+TYPE= BEGIN_ENV
+NAME= table
+ START_TAG= "<center><table border>"
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+END_TYPE
+
+C= end a table
+TYPE= END_ENV
+NAME= table
+ START_TAG= "</table></center>"
+END_TYPE
+
+C= start a tabular
+TYPE= BEGIN_ENV
+NAME= tabular
+ START_TAG= "?n<tr><td"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ C= ignore the column specification
+ PRINT_P1= NO_OP
+ END_TAG=
+ SET_MODE: tabular
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+
+C= end a tabular
+TYPE= END_ENV
+NAME= tabular
+ PC_AT_START= RESET
+ START_TAG= ">"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ RESET_MODE:
+END_TYPE
+
+C= we can do some processing of the \mutlicolumn command
+TYPE= COMMAND
+NAME= \multicolumn
+ PC_AT_START= TO_BUFFER 8
+ REQPARAMS= 2
+ START_TAG_1= " colspan="
+ PRINT_P2= NO_PRINT
+ PC_AT_END= RESET
+END_TYPE
+
+C= now for the end/start of a row
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "<br>"
+IN_MODE= tabular
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "> "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= "</tr>?n<tr><td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_MODE
+END_TYPE
+
+C= and the column seperator
+TYPE= TEX_CHAR
+NAME= &
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "> "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= " </td><td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+
+\begin{htmlverbatim}
+C= start of a table
+TYPE= BEGIN\_ENV
+NAME= table
+ START\_TAG= "\ST{center}\ST{table border}"
+ OPT\_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT\_OPT= NO\_PRINT
+END\_TYPE
+
+C= end a table
+TYPE= END\_ENV
+NAME= table
+ START\_TAG= "\ET{table}\ET{center}"
+END\_TYPE
+
+C= start a tabular
+TYPE= BEGIN\_ENV
+NAME= tabular
+ START\_TAG= "?n\ST{tr}\LT{}td"
+ RESET\_BUFFER: 8
+ RESET\_BUFFER: 9
+ OPT\_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT\_OPT= NO\_PRINT
+ REQPARAMS= 1
+ C= ignore the column specification
+ PRINT\_P1= NO\_OP
+ END\_TAG=
+ SET\_MODE: tabular
+ PC\_AT\_END= TO\_BUFFER 9
+END\_TYPE
+
+C= end a tabular
+TYPE= END\_ENV
+NAME= tabular
+ PC\_AT\_START= RESET
+ START\_TAG= "\GT"
+ RESET\_BUFFER: 8
+ RESET\_BUFFER: 9
+ RESET\_MODE:
+END\_TYPE
+
+C= we can do some processing of the \verb|\multicolumn| command
+TYPE= COMMAND
+NAME= \verb|\multicolumn|
+ PC\_AT\_START= TO\_BUFFER 8
+ REQPARAMS= 2
+ START\_TAG\_1= " colspan="
+ PRINT\_P2= NO\_PRINT
+ PC\_AT\_END= RESET
+END\_TYPE
+
+C= now for the end/start of a row
+TYPE= CHAR\_COMMAND
+NAME= \verb|\\|
+ START\_TAG= "\ST{br}"
+IN\_MODE= tabular
+ PC\_AT\_START= RESET
+ START\_TAG=
+ SOURCE: BUFFER 8
+ STRING: "\GT{} "
+ RESET\_BUFFER: 8
+ SOURCE: BUFFER 9
+ END\_TAG= "\ET{tr}?n\ST{tr}\LT{}td "
+ RESET\_BUFFER: 9
+ PC\_AT\_END= TO\_BUFFER 9
+END\_MODE
+END\_TYPE
+
+C= and the column seperator
+TYPE= TEX\_CHAR
+NAME= \Amp
+ PC\_AT\_START= RESET
+ START\_TAG=
+ SOURCE: BUFFER 8
+ STRING: "\GT "
+ RESET\_BUFFER: 8
+ SOURCE: BUFFER 9
+ END\_TAG= " \ET{td}\LT{}td "
+ RESET\_BUFFER: 9
+ PC\_AT\_END= TO\_BUFFER 9
+END\_TYPE
+\end{htmlverbatim}
+
+ Regarding the \verb|\multicolumn| specification, we state that as far as
+\lx{} is concerned, it only has two required parameters, and that the action
+for the second one is \keyword{NO\_PRINT}. The first argument is written to
+buffer \keytext{8} after `colspan=' has first been put into it. \lx{} will treat
+the actual third argument to the \verb|\multicolumn| as ordinary text, just
+as if there was no \verb|\multicolumn| in the \LaTeX{} source. We use buffer
+\keytext{9} for storing the text of a data element. When \lx{} processes
+a \keytext{\Amp} column delimeter it first outputs the contents of
+buffer \keytext{8} (the number of columns specification) and then appropriate
+HTML characters. It then outputs the contents of buffer \keytext{9} (the
+element text), finishes off the element and partially starts the next element.
+Similar actions are performed at the start of the \keytext{tabular} environment
+and at the end of each row in the table.
+
+\subsection{Sectioning command types}
+
+ \lx\ does some particular processing for sectioning command types. Although
+\LaTeX\ can determine where any section of a document ends, other tagging systems
+cannot always do this. They require both a `begin section' and an `end section'
+tag. \lx\ can take account of the nesting depth of document sections and,
+given appropriate specifications, can supply both `begin section' and `end section'
+tags appropriately. This requires a little bit more in the way of specifications
+than we have met so far.
+
+ For a \keyword{SECTIONING} command type, the command line
+\keyword{SECTIONING\_LEVEL=}
+must be included within the specification. The value of this command is a keyword
+from the following list.
+\begin{description}
+\item[\keyword{PART}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\part| command.
+\item[\keyword{CHAPTER}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\chapter| command.
+\item[\keyword{SECT}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\section| command.
+\item[\keyword{SUBSECT}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\subsection| command.
+\item[\keyword{SUBSUBSECT}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\subsubsection| command.
+\item[\keyword{PARA}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\paragraph| command.
+\item[\keyword{SUBPARA}] For a sectioning command equivalent to the
+ \LaTeX\ \verb|\subparagraph| command.
+\end{description}
+
+ When a sectioning command is read from the \LaTeX\ source, \lx\ firstly
+performs the \keyword{END\_TAG=} actions for any `lower level' sections
+that this one is closing off. It then performs the \keyword{START\_TAG=}
+actions for the current command, and stores its own \keyword{END\_TAG=} actions for
+later use. It then goes on and process any arguments as usual.
+ The \keyword{END\_DOCUMENT} command automatically closes off any opened
+sections.
+
+ As an example, assume that some kind soul has supplied a \LaTeX\ style
+file that makes the commands \verb|\clause| synonymous with \verb|\subsection|,
+and \verb|\sclause| synonymous with \verb|\subsubsection|, etc. Also assume
+that it is required to output start and end tags of the form
+\keytext{\ST{div.1}} and \keytext{\ET{div.1}}
+for sections, \keytext{\ST{div.2}} for clauses, etc., and surround the
+headings with tags \keytext{\ST{heading}} and \keytext{\ET{heading}}.
+Further, the first
+optional argument is of no interest as the output is going to be
+used by a processing system unable to automatically handle tables of contents.
+Part of an appropriate \ctab\ for doing this is:
+
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ END_TAG= "?n</div.1>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "<heading>"
+ END_TAG_1= "</heading>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \clause
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "?n?n<div.2>?n"
+ END_TAG= "?n</div.2>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "<heading>"
+ END_TAG_1= "</heading>?n"
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= SECTIONING
+NAME= \verb|\section|
+ SECTIONING\_LEVEL= SECT
+ START\_TAG= "?n?n\ST{div.1}?n"
+ END\_TAG= "?n\ET{div.1}"
+ OPT\_PARAM= FIRST
+ PRINT\_OPT= NO\_PRINT
+ REQPARAMS= 1
+ START\_TAG\_1= "\ST{heading}"
+ END\_TAG\_1= "\ET{heading}?n"
+END\_TYPE
+
+TYPE= SECTIONING
+NAME= \verb|\clause|
+ SECTIONING\_LEVEL= SUBSECT
+ START\_TAG= "?n?n\ST{div.2}?n"
+ END\_TAG= "?n\ET{div.2}"
+ OPT\_PARAM= FIRST
+ PRINT\_OPT= NO\_PRINT
+ REQPARAMS= 1
+ START\_TAG\_1= "\ST{heading}"
+ END\_TAG\_1= "\ET{heading}?n"
+END\_TYPE
+\end{htmlverbatim}
+
+ An example output resulting from this \ctab\ (if it had been applied to this
+document) is:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+...
+</div.2>
+</div.1>
+
+<div.1>
+<heading>The command table file</heading>
+
+ By default, ...
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+...
+\ET{div.2}
+\ET{div.1}
+
+\ST{div.1}
+\ST{heading}The command table file\ET{heading}
+
+ By default, ...
+\end{htmlverbatim}
+
+\subsection{List environment types}
+
+ In \LaTeX\ the use of the \verb|\item| command is restricted to within a
+list environment. The typeset appearance of an \verb|\item| typically depends
+on the particular environment in which it is used. \lx\ has a limited capability
+of modifying its \verb|\item| tagging output. It can also provide an `end item'
+tag for those tagging systems that require such a thing.
+
+ For such list environments, identified by the command type keyword
+\keyword{BEGIN\_LIST\_ENV},
+the following command lines should be included within the type specification.
+\begin{description}
+\item[\keyword{START\_ITEM=}] Actions to be performed at the start
+ of each \verb|\item| command in the list.
+\item[\keyword{END\_ITEM=}] Actions to be performed after processing all
+ the \verb|\item|'s text.
+\item[\keyword{START\_ITEM\_PARAM=}] Actions to be performed at the start of an
+ \verb|\item|'s optional argument text.
+\item[\keyword{END\_ITEM\_PARAM=}] Actions to be performed at the end of an
+ \verb|\item|'s optional argument text.
+\end{description}
+As usual, an unspecified tag defaults to no actions.
+
+ For example, assume that we are not interested in tagging the end of an item,
+but we do want to mark each item in an \verb|itemize| environment with the lowercase
+letter `o', each \verb|enumerate| item with `(N)' and put a colon after the
+optional argument in a description environment. Also, each item should have some
+indentation from the left hand margin.
+
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_ITEM= "?n (N) "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+END_TYPE
+\end{verbatim}
+\end{code}
+
+ With the above commands, this \LaTeX{} text:
+\begin{verbatim}
+\begin{description}
+\item[An example]
+ \begin{itemize}
+ \item the first item;
+ \item the second item.
+ \end{itemize}
+\end{description}
+\end{verbatim}
+will be transformed into:
+\begin{verbatim}
+ An example :
+ o the first item;
+ o the second item.
+\end{verbatim}
+
+\subsection{Character types}
+
+ \LaTeX\ treats some characters specially. These special characters are:
+\verb|#|,
+\verb|$|,
+\verb|%|,
+\verb|&|,
+\verb|~|,
+\verb|_|,
+\verb|^|,
+\verb|\|,
+\verb|{|,
+\verb|}|,
+and, under some circumstances, also the
+character \verb|@|.
+ \lx\ recognizes these special characters and, if directed, will
+perform specified actions; otherwise it treats them as it treats any alphanumeric
+character, which is just to print it.
+
+ It has already been stated that commands for the left and right braces
+(i.e. \verb|{| and \verb|}|) must be given
+within the \ctab\ as command types
+\keyword{LBRACE}, \keyword{RBRACE} respectively.
+The dollar symbol (\$) must also be specified via the two command types
+\keyword{BEGIN\_DOLLAR} and \keyword{END\_DOLLAR}. Here is an
+example of replacing the dollar signs by tags intended to indicate
+the start and end of a mathematical phrase.
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_DOLLAR
+ START_TAG= "<math>"
+END_TYPE
+
+TYPE= END_DOLLAR
+ START_TAG= "</math>"
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= BEGIN\_DOLLAR
+ START\_TAG= "\ST{math}"
+END\_TYPE
+
+TYPE= END\_DOLLAR
+ START\_TAG= "\ET{math}"
+END\_TYPE
+\end{htmlverbatim}
+
+ Commands for the other special \LaTeX\ characters are specified with the
+\keyword{TEX\_CHAR} command type keyword.
+
+The characters \verb|_| (underscore) and \verb|^| (caret) are used in
+\LaTeX{} math mode to indicate subscripting and superscripting respectively. The
+following will replace \verb|^| by \keytext{\ST{sup}}, print the superscript
+text (which must be enclosed in braces\footnote{It is good practice to
+always enclose superscript and subscript text in braces, even though
+\TeX\ does not always require this.}) and at the end close with
+\keytext{\ET{sup}}.
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "<sup>"
+ REQPARAMS= 1
+ END_TAG= "</sup>"
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+
+\begin{htmlverbatim}
+TYPE= TEX\_CHAR
+NAME= \verb|^|
+ START\_TAG= "\ST{sup}"
+ REQPARAMS= 1
+ END\_TAG= "\ET{sup}"
+END\_TYPE
+\end{htmlverbatim}
+
+Given the above specifications, then \verb|$(2^{15} - 1)$| will be transformed
+into \\
+\keytext{\ST{math}(2\ST{sup}15\ET{sup} - 1)\ET{math}}.
+
+\subsection{Verbatim like types}
+
+ The command type \keyword{VCOMMAND} is for the procesing of \LaTeX{}
+\verb|\verb|-like commands where the argument of the command is to be
+typeset as-is. For example, there might be a command called \verb|\url|
+which takes one argument which is meant to be an Internet URL. If the
+application was the conversion of a \LaTeX{} document to HTML, then the
+following specification could be useful.
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= VCOMMAND
+NAME= \url
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 7
+ START_TAG=
+ RESET_BUFFER: 7
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 7
+ STRING: "">"
+ SOURCE: BUFFER 7
+ STRING: "</a>"
+ RESET_BUFFER: 7
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= VCOMMAND
+NAME= \verb|\url|
+ REQPARAMS= 1
+ PRINT\_P1= TO\_BUFFER 7
+ START\_TAG=
+ RESET\_BUFFER: 7
+ END\_TAG= "\LT{}a href=""
+ SOURCE: BUFFER 7
+ STRING: ""\GT"
+ SOURCE: BUFFER 7
+ STRING: "\ET{a}"
+ RESET\_BUFFER: 7
+END\_TYPE
+\end{htmlverbatim}
+
+If the \LaTeX{} source included:
+\begin{code}
+\begin{verbatim}
+... obtainable from
+\url{http://www.cdrom.com/pub/tex}
+\end{verbatim}
+\end{code}
+then the resulting \lx{} output would be:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+... obtainable from
+<a href="http://www.cdrom.com/pub/tex">http://www.cdrom.com/pub/tex</a>
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+... obtainable from
+\ST{a href="http://www.cdrom.com/pub/tex"}http://www.cdrom.com/pub/tex\ET{a}
+\end{htmlverbatim}
+which, if this was then read via an appropriate browser, a link to the URL
+\begin{htmlonly}
+<a href="http://www.cdrom.com/pub/tex">http://www.cdrom.com/pub/tex</a>
+\end{htmlonly}
+would be automatically established.
+
+ Similarly \verb|verbatim|-like environments can also be specified with
+the types \keyword{BEGIN\_VENV} and \keyword{END\_VENV}.
+For example, the \file{html.sty} package defines three \LaTeX{}
+environments for documents that might be converted from \LaTeX{} tagging
+to HTML tagging. One of these, \verb|latexonly| is for \LaTeX{} code
+that is not to occur in the HTMLed document and another is \verb|htmlonly|
+which contains HTML code that is required for an HTML version
+of the document but which is not to appear in the \LaTeX ed document.
+The third one is \verb|rawhtml| which is for HTML code to be output
+verbatim to the HTML document source.
+These could be simulated by:
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_VENV
+NAME= latexonly
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= latexonly
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= END_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= rawhtml
+END_TYPE
+
+TYPE= END_VENV
+NAME= rawhtml
+END_TYPE
+\end{verbatim}
+\end{code}
+
+
+\subsection{Odd command types}
+
+ The majority of commands in \LaTeX{} that take optional arguments
+have only a single optional argument that is either immediately after
+the command or after all the required arguments. There are, however, some
+commands that do not fit this pattern. This set of command types enables
+at least some of these `odd' commands to be handled.
+
+ The command type keyword is of the form \keytext{COMMAND\_code}, where
+\keytext{code} indicates the type and ordering of the arguments. The
+\keytext{code} is composed from combinations of the letters \keytext{O}
+(for an optional argument) and \keytext{P} (for a required parameter (i.e.,
+argument)). The ordering of these letters in the \keytext{code} specifies
+the type and ordering of the command's arguments.
+
+ The `odd' command types are:
+\begin{description}
+\item[\keyword{COMMAND\_OOP}] Corresponding to a \LaTeX{} command of the form \\
+\verb|\com[OptParam][OptParam]{ReqParam}|.
+For example, the \verb|\makebox|
+command falls into this category.
+
+\item[\keyword{COMMAND\_OOOPP}] Corresponding to a \LaTeX{} command of the form \\
+\verb|\com[OptParam][OptParam][OptParam]{ReqParam}{ReqParam}|.
+For example, the \verb|\parbox|
+command falls into this category.
+
+\item[\keyword{COMMAND\_OPO}] Corresponding to a \LaTeX{} command of the form \\
+\verb|\com[OptParam]{ReqParam}[OptParam]|.
+For example, the \verb|\RequirePackage| and \verb|\LoadClass|
+commands fall into this category.
+
+\item[\keyword{COMMAND\_POOOP}] Corresponding to a \LaTeX{} command of the form \\
+\verb|\com{ReqParam}[OptParam][OptParam][OptParam]{ReqParam}|.
+
+\item[\keyword{COMMAND\_POOP}] Corresponding to a \LaTeX{} command of the form \\
+\verb|\com{ReqParam}[OptParam][OptParam]{ReqParam}|.
+For example, the \verb|\newcommand| and its companion commands
+fall into this category.
+
+\item[\keyword{COMMAND\_POOPP}] Corresponding to a \LaTeX{} command of the form \\
+\verb|\com{ReqParam}[OptParam][OptParam]{ReqParam}{ReqParam}|.
+For example, the \verb|\newenvironment| and its companion command
+fall into this category.
+\end{description}
+
+ As usual, the command name is required, as are any actions. However,
+it is not necessary to specify the number of required arguments (i.e.
+\keyword{REQPARAMS=}) nor the position of the optional argument (i.e.
+\keyword{OPT\_PARAM=}), as \lx\ already has this information. The tag actions
+are according to the argument ordering given in the \keytext{code} and are
+specified by the required argument tags (e.g. \keytext{START\_TAG\_n=} and
+\keytext{END\_TAG\_n=}).
+Do not use any of the command lines for optional arguments. Argument
+actions are controlled in the usual manner.
+
+ A typical example of the use of these commands is to supress any processing
+of the \LaTeX{} \verb|\newcommand| and its ilk. For example:
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND_POOP
+NAME= \providecommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \renewenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+\end{verbatim}
+\end{code}
+
+
+\subsection{Other command types}
+
+ The \keytext{OTHER\_} command types (\keyword{OTHER\_COMMAND},
+\keyword{OTHER\_BEGIN}
+and \keyword{OTHER\_END})
+are very limited in what can be affected. Basically, these provide for
+default printing actions if the corresponding \LaTeX\ command has not been
+identified elsewhere in the \ctab.
+
+ If there are no commands within the specification, the name of the command and
+all its arguments will be printed verbatim.
+
+ The command lines \keyword{START\_TAG=} and \keyword{END\_TAG=}
+cause the corresponding
+actions to be performed before and after the name of the command is printed. Any
+arguments are printed verbatim.
+
+ The command line \keyword{PRINT\_CONTROL=} with a value of \keyword{NO\_PRINT}
+causes the command name not to be printed, nor any arguments that \lx\ may
+find associated with the command.
+
+\subsection{Picture types}
+
+ The \keytext{\_PICTURE\_} command types differ from all the other types in
+\lx, just as they do in \LaTeX. In \LaTeX\ some of the picture drawing commands
+take arguments of the form \verb|(number, number)|, representing a coordinate
+pair, as well as the usual
+required arguments enclosed in curly braces and possibly an optional
+argument enclosed in square brackets. Within \lx, commands that take coordinate
+arguments are treated specially in the \ctab.
+
+ Generally speaking, the \lx\ command types are of the form
+\keytext{PICTURE\_code},
+where \keytext{code} indicates the type and ordering of the arguments. The
+\keytext{code} is composed from combinations of the letters \keytext{C} (for a
+coordinate argument), \keytext{O} (for an optional argument) and \keytext{P} (for
+a required argument). For example, \keyword{PICTURE\_PCOP} indicates a picture
+command that has a required argument, followed by a coordinate argument,
+followed by an optional argument and finally another required argument.
+
+ The provided picture types are:
+\begin{description}
+\item[\keyword{BEGIN\_PICTURE\_CC}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\begin{PictureEnv}(coords)(coords)|, where the final coordinate argument
+ is optional.
+\item[\keyword{PICTURE\_CCPP}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com(coords)(coords){ReqParam}{ReqParam}|.
+ For example, the \verb|\multiput| command falls into this category.
+\item[\keyword{PICTURE\_CO}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com(coords)[OptParam]|.
+ For example, the standard \LaTeX\ \verb|\oval| command falls into
+ this category.
+\item[\keyword{PICTURE\_COP}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com(coords)[OptParam]{ReqParam}|.
+ For example, the \verb|\makebox| and \verb|\framebox| commands fall
+ into this category.
+\item[\keyword{PICTURE\_CP}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com(coords){ReqParam}|.
+ For example, the \verb|\put|, \verb|\line| and \verb|\vector| commands
+ fall into this category.
+\item[\keyword{PICTURE\_OCC}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com[OptParam](coords)(coords)|.
+ For example, the \verb|\graphpaper| command from the \verb|graphpap|
+ package falls into this category.
+\item[\keyword{PICTURE\_OCCC}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com[OptParam](coords)(coords)(coords)|.
+ For example, the \verb|\qbezier| command falls into this category.
+\item[\keyword{PICTURE\_OCO}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com[OptParam](coords)[OptParam]|.
+ For example, the \verb|\oval| command from the \verb|pict2e| package
+ falls into this category.
+\item[\keyword{PICTURE\_PCOP}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\com{ReqParam}(coords)[OptParam]{ReqParam}|.
+ For example, the \verb|\dashbox| and \verb|\savebox| commands fall
+ into this category.
+\item[\keyword{END\_PICTURE}] Corresponding to a \LaTeX\ command of the form \\
+ \verb|\end{PictureEnv}|.
+\end{description}
+
+ As usual, the command name is required, as are any actions. However,
+it is not necessary to specify the number of required arguments (i.e.
+\keyword{REQPARAMS=}) nor the position of the optional argument (i.e.
+\keyword{OPT\_PARAM=}), as \lx\ already has this information. The tag actions
+are according to the argument ordering given in the \keytext{code} and are
+specified by the required argument tags (e.g. \keytext{START\_TAG\_n=} and
+\keytext{END\_TAG\_n=}).
+Do not use any of the command lines for optional arguments. Argument
+actions controlled in the usual manner.
+
+ As an example, the following specifications within a \ctab\ should be
+sufficient to ensure that any picture commands in a source file are
+not passed through to the output file.
+
+\begin{code}
+\begin{verbatim}
+TYPE= BEGIN_PICTURE_CC
+NAME= picture
+PRINT_P1= NO_PRINT
+PRINT_P2 = NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CP
+NAME= \put
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_OP
+END_TYPE
+
+TYPE= PICTURE_CCPP
+NAME= \multiput
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_PCOP
+NAME= \savebox
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_OCC
+NAME= \graphpaper
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCCC
+NAME= \qbezier
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= END_PICTURE
+NAME= picture
+END_TYPE
+\end{verbatim}
+\end{code}
+
+\begin{description}
+\item[NOTE 1:] The action \keyword{NO\_OP} cannot be applied to an
+ argument that is a coordinate pair.
+
+\item[NOTE 2:] As \lx\ is essentially limited to printing actions,
+and cannot actually process any
+\LaTeX\ picture drawing commands, the suppression of picture printing is
+probably the most usual use of the picture commands.
+\end{description}
+
+\subsection{Special command types}
+
+ The \keytext{SPECIAL\_} commands, namely \keyword{SPECIAL\-\_COMMAND},
+\keyword{SPECIAL\-\_BEGIN\-\_ENV},
+ \keyword{SPECIAL\-\_BEGIN\-\_LIST},
+\keyword{SPECIAL\-\_END\-\_ENV},
+\keyword{SPECIAL\-\_END\-\_LIST} and
+\keyword{SPECIAL\-\_SECTIONING}, are provided for cases where some special kind of
+output processing is required that is not built into \lx. In order to implement
+any commands of these types, it is necessary to modify the internals of \lx\
+and recompile the source code. This is not recommended.
+
+\subsection{File inclusion}
+
+ A \ctab\ file can include other \ctab\ files. In turn an included
+file can recursively include other \ctab\ files. The file inclusion command
+line is
+\begin{code}
+\begin{verbatim}
+INCLUDE= FileName
+\end{verbatim}
+\end{code}
+where \keyword{FileName} is the name of the \ctab\ file to be included. The effect
+is that the above line is replaced by the contents of \keyword{FileName}.
+
+ For example, assume that there are three \ctab\ files called respectively
+\file{detex.ct}, \file{detex.l2x} and \file{detex.fl}. The contents of these
+files are:
+\begin{code}
+\begin{verbatim}
+C= ----------file detex.ct
+...
+INCLUDE= detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+\end{verbatim}
+\end{code}
+and for \file{detex.l2x} as:
+\begin{code}
+\begin{verbatim}
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+INCLUDE= detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+END_CTFILE= end of file detex.l2x
+\end{verbatim}
+\end{code}
+and lastly \file{detex.fl} is:
+\begin{code}
+\begin{verbatim}
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+END_CTFILE= end file detex.fl
+\end{verbatim}
+\end{code}
+ Then, as far as \lx\ is concerned, the original \file{detex.ct} file is
+treated as though it had been written as:
+\begin{code}
+\begin{verbatim}
+C= ----------file detex.ct
+...
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+\end{verbatim}
+\end{code}
+
+ Note that nasty things will happen if you have a cycle of inclusions. That is,
+you must not have anything similar to file \file{A} including file \file{B} which
+includes file \file{C} which in turn includes either file \file{A} or \file{B}.
+
+\subsection{Interpreter commands} \label{sec:intcom}
+
+ \lx\ includes an interpreter for a procedural programming language
+that is based on the ISO international standard \Express{} information
+modeling language~\cite{EBOOK, EXPRESSIS}. At the moment the
+programming language within \lx{} is anonymous, but for ease
+of reference I will call it \ExpressA
+(\Express{} -Almost? -Approximate? -Anonymous?).
+The \ExpressA{} language is described later in section~\ref{sec:expressa},
+but for now it is sufficient to know the commands that signify
+the start and end of this code.
+
+ The command \keyword{CODE\_SETUP=} indicates the commencement of
+code to be run before any document processing occurs. The
+\keyword{END\_CODE} command signifies the end of this code block.
+This block should be placed in the \ctab{} before any other commands
+except for the \keytext{ESCAPE...} commands, if any. This block
+can contain variable declarations, function and procedure declarations,
+and statements.
+
+ Code consisting purely of statements can be placed anywhere that
+a tagging action may be specified. These statements are enclosed
+between a \keyword{CODE:} and \keyword{END\_CODE} pair of commands.
+
+ The \ExpressA{} language is described in detail in \ref{sec:expressa},
+but to give a flavour of it here
+is a simple possible application. It has been noted that \lx{} will find
+difficulty in processing the contents of the \LaTeX{} \keytext{picture}
+environment. The following portions of a \ctab{} write the contents
+of a \keytext{figure} environment to an external file and uses the programming
+language to keep a count of the number of figures so processed.
+
+\begin{code}
+\begin{verbatim}
+c= declare and initialise a variable
+CODE_SETUP=
+ LOCAL
+ fignum : INTEGER;
+ END_LOCAL;
+ fignum := 0;
+END_CODE
+
+c= write figure contents to an external file
+TYPE= BEGIN_ENV
+NAME= figure
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ PC_AT_START= TO_FILE figs.tmp
+ START_TAG=
+ CODE:
+ fignum := fignum + 1; -- increment figure counter
+ println; -- print a blank line
+ println('%%% FIGURE ', fignum); -- write counter as a LaTeX comment
+ END_CODE
+ STRING: "\begin{figure}"
+END_TYPE
+
+c= close figure environment, back to normal output, and output
+c= text indicating that a figure should be here
+TYPE= END_ENV
+NAME= figure
+ PC_AT_START= RESET
+ START_TAG=
+ SWITCH_TO_FILE: figs.tmp
+ STRING: "\end{figure}?n?n"
+ SWITCH_BACK:
+ CODE:
+ println;
+ println('PLACE FOR FIGURE ', fignum);
+ println;
+ END_CODE
+END_TYPE
+\end{verbatim}
+\end{code}
+
+\section{The LTX2X program} \label{sec:program}
+
+ \lx\ is written using flex and bison. The resulting C code should
+compile on any system. More details are given later, but for the end-user
+the next section describes how to run the program, assuming that is available
+on your system.
+
+\subsection{Running LTX2X}
+
+ The syntax for running the compiled version of \lx\ is:
+\begin{verbatim}
+ltx2x [-c] [-f table-file] [-p number] [-w] [-D dir_cat_char]
+ [-P path_seperators] [-S]
+ [-i number] [-l number] [-t] [-y number] [-C] [-E]
+ input-file output-file
+\end{verbatim}
+where elements in square brackets are options. The options fall into
+two groups, one for the casual user and the other for those who may be
+interested in the internals of \lx. The first group of options includes:
+\begin{description}
+\item[{\tt -c}] By default, \lx\ ignores all \LaTeX\ comments in the input
+ file. This option causes \lx\ to write the comments to the output file.
+
+\item[{\tt -f}] By default, \lx\ reads the \ctab\ from a file called
+ \verb|ltx2x.ct|. If the required \ctab\ is in a file with another name this
+ option is used to change from the default file. For example,
+\begin{verbatim}
+> ltx2x in.tex out.l2x
+\end{verbatim}
+reads a \ctab\ from \verb|ltx2x.ct|, while
+\begin{verbatim}
+> ltx2x -f detex.ct in.tex out.l2x
+\end{verbatim}
+reads a \ctab\ from file \verb|detex.ct|.
+
+\item[{\tt -p}] This option causes \lx\ to `pretty print' the output file
+ (as far as it is able to). The \verb|number| is required and it indicates
+ the desired maximum number
+ of characters per output line. If this is considered to be too small,
+ then \lx\ chooses a value. Note that pretty printing is only applied
+ to the source file --- not to any replacement tags. That is, it
+ only tries to format the running text from the source file.
+
+\item[{\tt -w}] By default, \lx\ outputs source white space just at it reads it.
+ This option causes \lx\ to collapse any amount of contiguous white space
+ to a single space. The \verb|-p| option includes the \verb|-w| option.
+
+\item[{\tt -D}] The value of this option is the character that the operating system
+ uses to catenate directory names to form a path (see~\ref{sec:search}).
+ The default value is a
+ slash (i.e. \verb|/|). The default could be changed to a backslash, for example,
+ by \verb|-D \|.
+
+\item[{\tt -P}] The environment variable (see~\ref{sec:search})
+ contains a list of directories (also known
+ as path names). In the operating system that I use, these are separated by
+ the colon (\verb|:|) character which, together with the semi-colon
+ and space characters, form
+ the \lx\ default separators. The path separator characters can be changed
+ with this option.
+ For example, \verb|-P :| will make the separators be a colon
+ or a space (space is automatically included in the separator list).
+
+\item[{\tt -S}] This option enables the source level debugger
+ (see~\ref{sec:sld}) for any embedded \ExpressA{} code.
+\end{description}
+
+The second group of options are principally for those who might be
+extending the \lx{} system.
+
+\begin{description}
+\item[{\tt -i}] This produces information that may be useful for debugging
+ the \ExpressA{} interpreter. \verb|number| is an integer
+ between 1 and 9 inclusive.
+ The greater the number, the more diagnostics are generated.
+
+\item[{\tt -l}] This produces information that may be useful for debugging
+ the \lx{} program. \verb|number| is an integer between 1 and 9 inclusive.
+ The greater the number, the more diagnostics are generated.
+
+\item[{\tt -t}] This generates diagnostics related to the processing of
+ the \ctab\ file.
+
+\item[{\tt -y}] Like the \verb|l| option, but produces diagnostic information
+ from the parser (this is actually a null option, but may be useful
+ in the future).
+
+\item[{\tt -C}] Disable any interpreter debugging information during
+ the code generation pass. This is not necessary unless the {\tt -i}
+ option is used.
+
+\item[{\tt -E}] Disable any interpreter debugging information during
+ the code execution processing.This is not necessary unless the {\tt -i}
+ option is used.
+
+\end{description}
+
+
+
+
+ \lx\ first reads the specified \ctab\ file, together with any included files,
+looking first in the current directory, then in the directories specified by
+the environment variable (if it exists).
+ It then reads the \verb|input-file| from the current directory,
+performs the actions specified in the \ctab\ and outputs the results to
+the \verb|output-file|.
+
+ Three other files are also generated.
+\begin{itemize}
+\item \verb|ltx2xct.lis| --- This contains a human-readable form of the internal
+ representation of the \ctab. It may be useful if there are any errors
+ in the original \ctab.
+\item \verb|ltx2x.err| --- This contains any error or warning messages generated
+ by \lx. It also contains any diagnostic information that may have been
+ requested via a command line option.
+\item \verb|interp.csg| --- This contains a human readable listing of the
+ internal byte code generated by the \ExpressA{} interpreter.
+\end{itemize}
+
+ When \lx\ is running normally it prints out a counter to the terminal
+indicating how many hundreds of input source file lines it has processed.
+Lack of such output is an indication that the program may be in a loop and
+chewing up CPU cycles to no avail. In this case, stop the program and examine
+the output for indications of where the trouble is occurring.
+
+ A limited number of errors are allowed when processing the \ctab\
+and the input \LaTeX\ file before \lx\ gives up and quits. In
+particular, if it is reading a \ctab\ file that includes another file, say one
+called \file{zilch},
+that it cannot read, it prints the following message to the user's terminal.
+\begin{verbatim}
+Can't open file zilch
+Enter new file name, or I to ignore, or Q to quit
+:
+\end{verbatim}
+A {\tt Q} (or {\tt q}) response stops \lx\ from any further processing. An
+{\tt I} (or {\tt i}) response causes \lx\ to stop looking for the included file
+and continue processing the current file. Any other response is taken to be
+the name of an included file, which \lx\ then tries to read. If it fails, then
+the above message is repeated. The user is given a limited number of opportunities
+to identify a readable file before \lx\ quits altogether with this message:
+\begin{verbatim}
+Last attempt. Can't open file zilch. I'm giving up.
+\end{verbatim}
+
+
+ Regarding performance, the time taken by \lx\ to process a document does
+not appear to be significantly different from the time to \LaTeX\ the
+same document.
+
+\subsubsection{Directory searching} \label{sec:search}
+
+ The program employs a search algorithm to find files that are not
+in the current directory. It first looks in the current directory and
+if a file of the given name is found, then that is used. If the file
+is not found, then it searches for it among directories that are
+specified in a system environment variable. This variable specifies
+a list of pathnames, where the directories forming the path are
+combined using a catenation character. For example, \verb|dir1/dir2/dir3|
+could be a pathname, where the slash (\verb|/|) is the catenation character.
+If it is looking for file \verb|afile.txt| it will catenate the file name
+to the path name (e.g. \verb|dir1/dir2/dir3/afile.txt|) and look for
+that. The pathnames in the list are separated by another character
+(in fact it can be one from a list of characters). For example here
+is a list of two pathnames; \verb|dir1/dir2;dir1/dir4|, where the semi-colon
+(\verb|;|) is the pathname separator.
+
+ By default, the program uses a slash (\verb|/|) as the directory
+catenation character and the pathname separators can be a space, or
+a colon or a semi-colon (i.e., any of \verb*| :;|). All these characters
+can be altered via the program command line options, and should be set to
+match the conventions of your operating system.
+
+ The environment variable used by the program is LTX2XTABLES.
+On the operating system that I use, I set this in my login file like:
+\begin{verbatim}
+setenv LTX2XTABLES .:/dir1/dir2:/dir3/dir4
+\end{verbatim}
+Your system may have different conventions. Note that if the environment
+variable is not set, only files in the current directory are considered.
+
+
+\subsection{System components}
+
+ The system consists of five main components --- a lexer, a parser, a
+library of support functions and \ctab\ parsing code, a
+user-defined library of functions, and an interpreter for the \ExpressA{}
+language.
+
+\subsubsection{The lexer}
+
+ The lexer is generated by flex~\cite{LEVINE92}
+(a more functional version of lex~\cite{LESK75}).
+The source for the lexer is in file \file{l2x.l}.
+Its principal function is to read a \LaTeX\
+source file and recognize \LaTeX\ commands. In general, it passes off the
+relevant command tokens to the parser for performing appropriate actions.
+
+ However, the lexer does do some processing of the source itself.
+\begin{itemize}
+\item It recognizes \LaTeX\ comments (i.e. any text starting with a percent
+ sign and ending with a newline). It silently ignores these comments, unless
+ run with the \verb|-c| option.
+\item It recognizes the `standard' \LaTeX\ verbatims. It will write out the
+ appropriate tags at the start and end of the verbatim text, while writing
+ the verbatim text directly to the output file, bypassing the parser.
+ It does not distinguish between the unstarred and starred
+ versions of the verbatims.
+\item Newlines and whitespace are directly written to the output file, again
+ bypassing the parser. The \verb|-p| and \verb|-w| options control the
+ final appearance of whitespace, newlines and paragraphing.
+\item It recognizes the command \verb*|\ | i.e. a backslash followed by a
+ space, and writes the tags defined in the \verb|SLASH_SPACE| specification
+ directly to the output file.
+\end{itemize}
+
+ The lexer is designed to recognize four kinds of \LaTeX\ commands.
+\begin{itemize}
+\item Commands of the form \verb|\begin{environment}|
+\item Commands of the form \verb|\end{environment}|
+\item Any other command of the form \verb|\command|
+\item As special cases, commands that are 'verbatim-like' or `verb-like'.
+\end{itemize}
+When it finds a command, it looks up the command or environment name in the
+\ctab\ and sends the appropriate token and its \ctab\ location to the
+parser. As a special case the contents of verbatim-like environments and
+the argument of verb-like coommands are processesd within
+the lexer and not sent to the parser.
+
+
+\subsubsection{The parser}
+
+ The parser is generated by bison~\cite{LEVINE92}
+(a more powerful version of YACC~\cite{JOHNSON75}).
+The source for the parser is in file \file{l2x.y}.
+Essentially it defines a very simple
+grammar for a \LaTeX\ document. That is, the grammar is limited to
+generic kinds of commands and command arguments. It does not understand
+the `meaning' of any of the commands or arguments.
+
+ When the parser receives a token from the lexer it tries to match it with
+one of the grammar rules, performing the actions specified by the \ctab.
+Here is an extract from the parser grammar file, \file{l2x.y},
+for a \LaTeX\ command that has
+two required arguments followed by an optional argument.
+
+\begin{code}
+\begin{verbatim}
+l2xComm2Opt: COMMAND_2_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_opt($1,2);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+\end{verbatim}
+\end{code}
+
+ The actions are enclosed in braces, and are interspersed with the elements
+of the grammar.
+
+ The token \verb|COMMAND_2_OPT| indicates that the lexer has found a command
+that takes two required arguments followed by an optional argument.
+The parser then performs some
+actions. The \verb|start_with_req| function is the standard \lx\ function
+for the first action in a command production where the final argument
+is optional. The \verb|$1| refers to the
+location of the particular command in the \ctab, and its value is passed to the
+parser by the lexer.
+
+ The parser then expects a required argument (i.e. \verb|{|, token \verb|LBRACE|)
+as the start of the required argument, followed by the text of the argument and
+finished off by a right brace (i.e. \verb|}|, token \verb|RBRACE|); the grammar
+for all of this is specified in the production called \verb|ReqParam|). If it
+finds these it performs some further actions, otherwise it reports an
+error.
+In this case the action is defined by the function \verb|action_p_p1|,
+which is the standard action performed between two required arguments
+(the second argument in the function call specifies the Pth argument that
+has been recognized). Another required argument is then expected.
+In this case the action is defined by the function \verb|action_p_opt|,
+which is the standard action performed between the end of the Pth required argument
+and the start of an optional argument. It then looks for an optional
+argument, the grammar for which is specified in the production called
+\verb|OptParam|. The final action is specified by the standard function
+\verb|action_last_opt| for finishing off a command that ends with an
+optional argument.
+
+ The grammar for a command that that has two required arguments,
+and possibly an
+initial optional argument is similar:
+
+\begin{code}
+\begin{verbatim}
+l2xComm2: COMMAND_2
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_last_p($1,2);
+ }
+ ;
+\end{verbatim}
+\end{code}
+
+\subsubsection{The support libraries}
+
+ Source code for the C main program and support functions is in file
+\file{l2xlib.c}.
+ The main program is responsible for reading in the \ctab\ and calling the
+lexer and parser to do the appropriate processing.
+ The file also contains a variety of support functions that are, or could
+be, used in the lexer, parser, action library, or user-defined library.
+
+ The standard actions for the grammar are contained in file \file{l2xacts.c}.
+
+\subsubsection{The user-defined library}
+
+ The intent of this library is that masochistic users can define their
+own functions for use within \lx\ when processing their \verb|SPECIAL_|
+commands, without having to modify the \lx\ support or action libraries.
+
+ Source code for the user-defined library should be maintained in a file
+called \file{l2xusrlb.c} and a corresponding header file called \file{l2xusrlb.h}.
+
+\subsubsection{The \ExpressA{} interpreter}
+
+ The \ExpressA{} interpreter is based on algorithms originally developed
+by Ronald Mak~\cite{MAKR91} for interpreting Pascal. His original
+algorithms have been modified and extended to cater for \ExpressA.
+The interpreter module has a minimal interface with the rest of the
+\lx{} system, and could easily be modified to be a stand-alone program
+(in fact it started that way in the first place). The interface
+between \lx{} and the interpreter is confined to the small
+\file{l2xistup.c} file.
+
+
+\section{The \ExpressA{} programming language} \label{sec:expressa}
+
+ \Express{} is a language for information modeling and includes both
+declarative and procedural aspects~\cite{EBOOK}. There are also two other
+companion languages called respectively \ExpressG{} and \ExpressI. The former
+of these is a graphical form of the declaritive aspects of \Express, and the
+later is an instiation and test case specification language. These languages
+are either ISO international standards~\cite{EXPRESSIS} or on the way
+to becoming so~\cite{EXPRESSITR}.
+
+ Certain of the procedural aspects of \Express{} and \ExpressI{} are relevent
+to the \lx{} concepts and so, together with some other reasons,
+it seemed appropriate to provide an interpreter for a similar language for
+use within \lx. \ExpressA{} provides a major subset of the \Express{} procedural
+language, together with some Pascal-like additions for input and output.
+Of particular note, strings are a built-in type in \ExpressA. The language
+also supports three-valued logic and the concept of an `indeterminate'
+value of any type.
+
+ Earlier I gave an example \ctab{} to replace the text of a
+\LaTeX{} document with the words `Goodbye document'. Here is
+an \ExpressA{} program that outputs `Goodbye document'.
+\begin{code}
+\begin{verbatim}
+println('Goodbye document');
+END_CODE
+\end{verbatim}
+\end{code}
+
+ The following gives a brief overview of \ExpressA. For more details
+consult Schenck \& Wilson~\cite{EBOOK}.
+
+\subsection{Basic elements}
+
+ \ExpressA{} is a case-insensitive language and uses the ASCII character
+set. Two kinds of comments are supported --- an end of line comment,
+which starts with a \verb|--| pair and continues until the end of the current
+line --- and an extended comment. An extended comment starts with a
+\verb|(*| pair and is ended by a matching \verb|*)| pair; extended comments
+may be nested.
+
+ The language contains many reserved words, some of which are only
+applicable to the \Express{} and \ExpressI{} languages.
+
+ Identifiers are composed of an initial letter, possibly followed by
+any number of letters, digits, and the underscore character.
+
+ Literals are self defining constant values. An integer literal consists
+of one or more digits, the first of which shall not be zero. Real numbers
+start with one or more digits, followed by a decimal point. Further
+digits may occur after the point, and finaly there may be an exponent
+in the `e' notation format (e.g., \verb|123.456e-78|).
+
+ A string literal is any sequence of characters enclosed by single
+quote marks. If a single quote mark is meant to form part of the string,
+two quote marks must be used at that point.
+
+ Logical literals consists of one of these keywords: \keyword{FALSE},
+\keyword{UNKNOWN} or \keyword{TRUE}.
+
+ \ExpressA{} also includes some other constants. \keyword{PI} stands
+for the value of the mathematical constant $\pi$ (3.1415\ldots),
+and \keyword{CONST\_E}
+stands for the value of the mathematical constant $e$ (2.7182\ldots),
+the base of natural logarithms. The special token \verb|?| stands for
+an indeterminate value of any type. The three constants
+\keyword{THE\_DAY}, \keyword{THE\_MONTH} and \keyword{THE\_YEAR} are integer
+values for the current date holding the day of the month (1--31), the
+month of the year (1--12) and the year (four digits), respectively.
+
+
+\subsection{Data types}
+
+ \ExpressA{} is a typed language. The simple data types are: \keyword{INTEGER},
+\keyword{REAL}, \keyword{STRING} and \keyword{LOGICAL}.
+
+ The aggregation data types are \keyword{ARRAY}, \keyword{BAG}, \keyword{LIST},
+and \keyword{SET}. The array data type is of a fixed size and must have
+declared lower and upper bounds (index range), such as \verb|ARRAY [-7:10] OF|.
+The other aggregate data types are dynamic in size, but may have lower and
+upper bounds specified for the number of elements, such as \verb|SET [2:5] OF|,
+meaning a set that should have between two and five members. For the
+dynamic aggregates the upper bound may be given as \verb|?|, which means
+an unlimited upper bound, such as \verb|LIST [2:?] OF|. If a bound
+specification is absent, then the dynamic aggregate can hold from zero
+to any number of elements.\footnote{The dynamic aggregates may not
+be fully implemented due to lack of time.}
+
+ Aggregates are one dimensional, but can be chained together for
+multi-dimensional aggregates, like
+\begin{code}
+\begin{verbatim}
+ARRAY [1:4] OF LIST OF INTEGER;
+\end{verbatim}
+\end{code}
+
+ The enumeration data type is a parenthesised comma seperated list of
+identifiers. These identifiers represent the values of the enumerated type;
+for instance
+\begin{code}
+\begin{verbatim}
+ENUMERATION OF (red, green, blue)
+\end{verbatim}
+\end{code}
+
+ A defined data type is one declared and named by the user using the
+\keyword{TYPE} and \keyword{END\_TYPE} construct. For example
+\begin{code}
+\begin{verbatim}
+TYPE length = REAL; END_TYPE;
+TYPE crowd_size = INTEGER; END_TYPE;
+TYPE signal_colour = ENUMERATION OF (red, amber, green); END_TYPE;
+\end{verbatim}
+\end{code}
+
+ An entity data type consists of a list of attributes and their types, enclosed
+in a \keyword{ENTITY} and \keyword{END\_ENTITY} pair. An entity type
+is named.
+\begin{code}
+\begin{verbatim}
+ENTITY an_ent;
+ auditorium_width : length;
+ audience : crowd_size;
+ title : STRING;
+ profit : REAL;
+END_ENTITY;
+\end{verbatim}
+\end{code}
+
+ \ExpressA{} provides for algorithms in the form of functions and procedures.
+
+A \keyword{FUNCTION} is an algorithm that operates on parameters and returns
+a single resultant value of a specified data type. An invocation of a function
+in an expression evaluates to the resultant value at the point of invocation.
+For example:
+\begin{code}
+\begin{verbatim}
+FUNCTION func (par1 : INTEGER; par2 : STRING) : STRING;
+ LOCAL
+ str : STRING;
+ -- other variable declarations
+ END_LOCAL;
+ -- the algorithm statements are here
+ RETURN(str);
+END_FUNCTION;
+\end{verbatim}
+\end{code}
+Note that the parameters are typed.
+
+ A \keyword{PROCEDURE} is an algorithm that receives parameters from the
+point of invocation and operates on them in some manner. Changes to the parameters
+within the procedure are only reflected to the point of invocation
+when the formal parameter is preceded by the keyword \keyword{VAR}.
+For example:
+\begin{code}
+\begin{verbatim}
+PROCEDURE proc (par1 : INTEGER; VAR par2 : STRING);
+ -- local declarations and the algorithm statements
+END_PROCEDURE;
+\end{verbatim}
+\end{code}
+Note that the parameters are typed. In this case the value of \keytext{par2}
+may be changed.
+
+ Variables are declared in a local block, enclosed by the keywords
+\keyword{LOCAL} and \keyword{END\_LOCAL}. A variable declaration consists
+of an identifer and its type, such as:
+\begin{code}
+\begin{verbatim}
+LOCAL
+ str : STRING;
+ e1, e2 : an_ent; -- e1 and e2 are both of type an_ent
+ e3 : an_ent; -- so is e3
+ num : INTEGER;
+ col : signal_colour;
+ matrix : ARRAY [1:15] OF ARRAY [1:15] OF REAL;
+END_LOCAL;
+\end{verbatim}
+\end{code}
+
+ The above declarations must be in the following order:
+\begin{enumerate}
+\item \keyword{ENTITY} and/or \keyword{TYPE} declarations
+\item \keyword{FUNCTION} and/or \keyword{PROCEDURE} declarations
+\item a \keyword{LOCAL} declaration block
+\end{enumerate}
+
+ After the above can come any number of statements.
+
+\subsection{Statements}
+
+ \ExpressA{} supports the following statements:
+\begin{itemize}
+\item Null statement
+\item Assignment statement
+\item Call statement
+\item \keyword{BEGIN} \ldots \keyword{END} compound statement
+\item \keyword{CASE} \ldots \keyword{END\_CASE} statement
+\item \keyword{IF} \ldots \keyword{THEN} \ldots \keyword{ELSE}
+ \ldots \keyword{END\_IF} statement
+\item \keyword{REPEAT} \ldots \keyword{WHILE} \ldots \keyword{UNTIL} \ldots
+ \keyword{END\_REPEAT} statement. This also includes the
+ \keyword{ESCAPE} and \keyword{SKIP} statements
+\item \keyword{RETURN} statement
+\end{itemize}
+
+ All the above statements are completed by a \keytext{;} (semicolon).
+The \emph{null} statement just consists of a semicolon.
+
+ The \emph{assignment} statement is used to assign an instance to a local
+variable or parameter. The data types must be compatible.
+\begin{code}
+\begin{verbatim}
+LOCAL
+ a, b, c : REAL;
+END_LOCAL;
+...
+ a := 2.3E-6;
+ b := a;
+ a := -27.0;
+ c := 33.3*b;
+\end{verbatim}
+\end{code}
+
+ The \emph{call} statement invokes a procedure or a function. The actual
+parameters provided with the call must agree in number, order and type
+with the formal parameters specified in the procedure or function
+declaration. The supplied parameter values must be assignment compatible
+with the formal parameters. This is an example of calling the \ExpressA{}
+defined \keyword{INSERT} procedure which takes three parameters:
+\begin{code}
+\begin{verbatim}
+INSERT(my_list, list_element, 0);
+\end{verbatim}
+\end{code}
+
+ The \emph{compound} statement consists of one or more statements enclosed
+between a \keyword{BEGIN} and \keyword{END} pair. The enclosed statements
+are treated as a single statement.
+\begin{code}
+\begin{verbatim}
+...
+ BEGIN
+ a := 2.3e-7;
+ b := a;
+ c := b*33.3;
+ END;
+\end{verbatim}
+\end{code}
+
+ The \emph{case} statement is a means of selectively executing statements
+based on the value of an expresion.
+\begin{code}
+\begin{verbatim}
+LOCAL
+ a : INTEGER;
+ x, y : REAL;
+END_LOCAL;
+...
+ a := 2;
+ x := 21.9;
+ CASE 2*a OF
+ 1 : x := SIN{x};
+ 2 : x := SQRT(x);
+ 3 : x := LOG(x);
+ 4 : x := COS(x); -- this is executed
+ 5, 6 : y := y**x;
+ OTHERWISE : x := 0.0;
+ END_CASE;
+\end{verbatim}
+\end{code}
+The integer expression following the \keyword{CASE} keyword is evaluated.
+The result is compared to the values of the case labels and the
+statement following the first matching label is executed. Execution then
+continues at the statement following the \keytext{END\_CASE;}. If no
+label matches, then no statements within the case block are executed,
+except if an \keyword{OTHERWISE} label is included, which will match
+anything. All other labels are examined before looking for the
+\keyword{OTHERWISE}.
+
+ The \emph{if \ldots then \ldots else} statement allows the conditional
+execution of statements depending on the value of a \keyword{LOGICAL}
+expression. When the expression evaluates to \keyword{TRUE} the statement(s)
+following the \keyword{THEN} are executed, after which control passes
+to the statement following the closing \keyword{END\_IF}. When the logical
+expression evaluates to \keyword{FALSE} or \keyword{UNKNOWN} the \keyword{THEN}
+statements are jumped over and execution starts at the statement(s) following
+the \keyword{ELSE} keyword if present, or at the statement following
+the \keyword{END\_IF} keyword.
+\begin{code}
+\begin{verbatim}
+IF a > 20 THEN
+ b := a + 2;
+ c := c - 1;
+ELSE
+ IF a > 10 THEN
+ b := a + 1;
+ ELSE
+ c := c + 1;
+ END_IF;
+END_IF;
+\end{verbatim}
+\end{code}
+
+ The \emph{repeat} statement is used to control the conditional repetition
+of a series of statements. The control conditions are:
+\begin{itemize}
+\item finite iteration until an integer expression reaches a specified
+ value;
+\item \keyword{WHILE} a logical condition is \keyword{TRUE};
+\item \keyword{UNTIL} a logical condition is \keyword{TRUE}.
+\end{itemize}
+\begin{code}
+\begin{verbatim}
+REPEAT i := 100 TO 0 BY -7 WHILE r >= 0.0 UNTIL err < 1.0e-8;
+ ...
+ r := ...;
+ err := ...;
+END_REPEAT;
+\end{verbatim}
+\end{code}
+At entry to the \keyword{REPEAT} statement the iteration variable is
+initialized to the first bound. If the variable less than or equal to the
+\keyword{TO} bound and the increment is positive, or the variable is less
+than the \keyword{TO} bound and the increment is negative, processing
+jumps to after the \keyword{END\_REPEAT}, otherwise processing continues.
+The \keyword{WHILE} condition is checked and if
+\keyword{TRUE} then the statements in the body are executed. After
+these have been executed the \keyword{UNTIL} condition is checked. If this
+is not \keyword{TRUE} then processing continues by incrementing the iteration
+variable by either unity or by the \keyword{BY} value if present. The whole
+process then starts again with the checking of the iteration variable
+against the \keyword{TO} bound.
+
+ All three types of controls are optional. If none are given then the
+\keyword{REPEAT} statement will loop for ever. The \emph{escape} statement
+causes an immediate transfer out of the \keyword{REPEAT} statement
+in which it occurs. The \emph{skip} statement causes a jump to the
+end of the \keyword{REPEAT} statement in which it occurs (i.e., to the point
+where the \keyword{UNTIL} expression is tested).
+\begin{code}
+\begin{verbatim}
+REPEAT UNTIL (a = 1);
+ ...
+ IF a = 0 THEN
+ ESCAPE;
+ END_IF;
+ ...
+ IF a > 10 THEN
+ SKIP;
+ END_IF;
+ ...
+ ...
+-- SKIP transfers control to here
+END_REPEAT;
+ -- ESCAPE transfers control to here
+\end{verbatim}
+\end{code}
+
+ The \emph{return} statement terminates the execution of a \keyword{FUNCTION}
+or \keyword{PROCEDURE}. The \keyword{RETURN} statement within a function
+must specify an expression, the value of which is the value returned
+by the function. A \keyword{RETURN} in a procedure must not specify an
+expression.
+\begin{code}
+\begin{verbatim}
+RETURN(a <> b); -- example for within a function
+RETURN; -- example for within a procedure
+\end{verbatim}
+\end{code}
+
+\subsection{Expressions}
+
+ Expressions are combinations of operators, operands and function calls
+which are evaluated to produce a value. The simplest expression is
+either a literal value or the name of a variable.
+
+\subsubsection{Arithmetic operators}
+
+ The arithmetic operators act on number values and produce a number
+result. If any operand
+is indeterminate (i.e., \verb|?|) then the result is also
+indeterminate. The operators are:
+\begin{description}
+\item[Unary] The operators \verb|+| and \verb|-|, the latter of which
+negates its following operand.
+\item[Binary] Addition (\verb|+|),
+ subtraction (\verb|-|),
+ multiplication (\verb|*|),
+ real division (\verb|/|),
+ exponentiation (\verb|**|),
+ integer division (\keyword{DIV}),
+ and modulo (\keyword{MOD}).
+\end{description}
+
+\subsubsection{Relational operators}
+
+ The result of a relational expression is a \keyword{LOGICAL} value.
+If either operand is indeterminate, the expression evaluates to
+\keyword{UNKNOWN}.
+
+\begin{description}
+\item[Value comparison] Equal (\verb|=|),
+ not equal (\verb|<>|),
+ greater than (\verb|>|),
+ less than (\verb|<|),
+ greater than or equal (\verb|>=|), and
+ less than or equal (\verb|<=|).
+
+\item[Membership] The \keyword{IN} operator tests an item for membership
+in a dynamic aggregate (e.g., \keytext{IF fred IN mylist THEN ...}).
+
+\item[Matching] The \keyword{LIKE} operator compares a string against a pattern,
+evaluating to \keyword{TRUE} if they match. The pattern characters are:
+ \begin{itemize}
+ \item \verb|@| Matches any letter.
+ \item \verb|^| Matches any upper-case letter.
+ \item \verb|?| Matches any character.
+ \item \verb|&| Matches remainder of string.
+ \item \verb|#| Matches any digit.
+ \item \verb|$| Matches a substring terminated by a space character
+ or end-of-string.
+ \item \verb|*| Matches any number of characters.
+ \item \verb|\| Begins a pattern escape sequence.
+ \item \verb|!| Negation character (used with the other characters).
+ \item Any other character matches itself.
+ \end{itemize}
+
+ Some examples:
+ \begin{itemize}
+ \item \verb|'The quick red fox' LIKE '$$$$'| is \keyword{TRUE}.
+ \item \verb|'Page 231' LIKE '$ ###'| is \keyword{TRUE}.
+ \item \verb|'Page 27' LIKE 'Page ###'| is \keyword{FALSE}.
+ \item \verb|'\aaaa' LIKE '\\aaaa'| is \keyword{TRUE}.
+ \item \verb|'\aaaa' LIKE '\aaaa'| is \keyword{FALSE}.
+ \item \verb|'aaaa' LIKE 'a@@a'| is \keyword{TRUE}.
+ \end{itemize}
+
+\end{description}
+
+\subsubsection{Logical operators}
+
+ The logical operators produce a logical result. Except for the
+\keyword{NOT} operator which takes one logical operand (e.g., \keytext{NOT op}),
+they take two logical operands (e.g., \keytext{op1 XOR op2}).
+
+ The evaluation of the \keyword{NOT} operator is given in table~\ref{tab:not}.
+
+\begin{table}
+\centering
+\caption{The NOT logical operator} \label{tab:not}
+\begin{tabular}{|c|c|} \hline
+Operand value & Result value \\ \hline
+\keyword{TRUE} & \keyword{FALSE} \\
+\keyword{UNKNOWN} & \keyword{UNKNOWN} \\
+\keyword{FALSE} & \keyword{TRUE} \\ \hline
+\end{tabular}
+\end{table}
+
+ The evaluation of the \keyword{AND}, \keyword{OR} and \keyword{XOR} operators
+is given in table~\ref{tab:andorxor}.
+
+\begin{table}
+\centering
+\caption{The AND, OR and XOR logical operators}
+\label{tab:andorxor}
+\begin{tabular}{|c|c||c|c|c|} \hline
+Op1 & Op2 & Op1 \keyword{AND} Op2 & Op1 \keyword{OR} Op2 & Op1 \keyword{XOR} Op2 \\ \hline
+\keyword{TRUE} & \keyword{TRUE} & \keyword{TRUE} & \keyword{TRUE} & \keyword{FALSE} \\
+\keyword{TRUE} & \keyword{UNKNOWN} & \keyword{UNKNOWN} & \keyword{TRUE} & \keyword{UNKNOWN} \\
+\keyword{TRUE} & \keyword{FALSE} & \keyword{FALSE} & \keyword{TRUE} & \keyword{TRUE} \\
+\keyword{UNKNOWN} & \keyword{TRUE} & \keyword{UNKNOWN} & \keyword{TRUE} & \keyword{UNKNOWN} \\
+\keyword{UNKNOWN} & \keyword{UNKNOWN} & \keyword{UNKNOWN} & \keyword{UNKNOWN} & \keyword{UNKNOWN} \\
+\keyword{UNKNOWN} & \keyword{FALSE} & \keyword{FALSE} & \keyword{UNKNOWN} & \keyword{UNKNOWN} \\
+\keyword{FALSE} & \keyword{TRUE} & \keyword{FALSE} & \keyword{TRUE} & \keyword{TRUE} \\
+\keyword{FALSE} & \keyword{UNKNOWN} & \keyword{FALSE} & \keyword{UNKNOWN} & \keyword{UNKNOWN} \\
+\keyword{FALSE} & \keyword{FALSE} & \keyword{FALSE} & \keyword{FALSE} & \keyword{FALSE} \\ \hline
+\end{tabular}
+\end{table}
+
+\subsubsection{Miscellaneous}
+
+\begin{description}
+
+\item[Function call] A function may be called without the result necessarily
+being assigned to a variable. If \keytext{fun} is a function with two
+arguments (for simplicitly integer arguments) and returning a logical
+value, then
+\begin{code}
+\begin{verbatim}
+log := fun(i1, i2);
+fun(i3, 24*i4);
+\end{verbatim}
+\end{code}
+are both legitimate calls.
+
+
+\item[Dot operator] The dot operator is used to access an attribute from an
+entity. If \keytext{ent} is an \keyword{ENTITY} type with an attribute
+\keytext{att}, then \keytext{ent.attr} evaluates to the value of the
+\keytext{attr} attribute within the \keytext{ent}.
+
+\item[String operators] \mbox{} \\
+ The \verb|+| operator takes two strings as
+its operands and evaluates to the string that is the concatenation of its
+operands. For example:
+\begin{code}
+\begin{verbatim}
+str1 := 'string1';
+str2 := 'string2';
+str1 := str1 + str2;
+-- str1 = 'string1string2' is TRUE
+\end{verbatim}
+\end{code}
+
+ The substring operator \verb|[i1:i2]| is a postfix operator that when
+applied to a string, evalutes to the string whose characters are composed
+of the \verb|i1|'th through the \verb|i2|'th characters, inclusively,
+of its operand. Note that \verb|i2| must be greater than or equal to
+\verb|i1|, and both must be within the limits of the number of characters
+in the string. For example:
+\begin{code}
+\begin{verbatim}
+str1 := 'string';
+str2 := str1[2:4];
+str1 := str1 + str2;
+-- str1 = 'tristring' is TRUE
+\end{verbatim}
+\end{code}
+
+\item[Aggregate operators] \mbox{} \\
+ The index operator \verb|[i]| is a postfix operator that can be applied
+to an aggregate operand; the expression evaluates to the value of the
+aggregate at the index position. For example, if \keytext{lagg} is a
+list of integers:
+\begin{code}
+\begin{verbatim}
+insert(lagg, 20, 0);
+insert(lagg, 40, 0);
+insert(lagg, 60, 0);
+insert(lagg, 80, 0);
+-- lagg[2] = 60 is TRUE
+\end{verbatim}
+\end{code}
+
+\item[Interval expression] \mbox{} \\
+ An \emph{interval expression} is a \keyword{LOGICAL} expression
+consisting of three operands and two operators. It has the form:
+\begin{code}
+\begin{verbatim}
+{ low op1 test op2 high }
+\end{verbatim}
+\end{code}
+where \keytext{op1} and \keytext{op2} are either of the two relational
+operators \verb|<| or \verb|<=|, and \keytext{low}, \keytext{test} and
+\keytext{high} are expressions of the same type. The interval expression
+is equivalent to:
+\begin{code}
+\begin{verbatim}
+((low op1 test) AND (test op2 high))
+\end{verbatim}
+\end{code}
+The value of the interval expression is given by
+\begin{enumerate}
+\item If any operand is indeterminate, then it evauates to \keyword{UNKNOWN}.
+\item If either of the logical relationships evaluates to \keyword{FALSE},
+ then it evauates to \keyword{FALSE}.
+\item If both logical relationships evalute to \keyword{TRUE},
+ then it evauates to \keyword{TRUE}.
+\item Otherwise it evaluates to \keyword{UNKNOWN}.
+\end{enumerate}
+For example:
+\begin{code}
+\begin{verbatim}
+i := 10;
+{1 <= i < 20} -- is TRUE
+{1 <= i < 10} -- is FALSE
+i := ?;
+{1 <= i < 10} -- is UNKNOWN
+\end{verbatim}
+\end{code}
+
+
+\end{description}
+
+
+\subsection{Built in procedures and functions}
+
+\subsubsection{Procedures}
+
+ The following procedures are an integral part of \ExpressA. They are
+shown as signatures to inidicate the data types of the formal parameters.
+For convenience, \keytext{GENERIC} is used to indicate any type.
+
+\begin{itemize}
+\item \keytext{INSERT (VAR L:LIST OF GENERIC; E:GENERIC; P:INTEGER)} \\
+ \keyword{INSERT} inserts the element \keytext{E} into a list
+\keytext{L} at position \keytext{P}. The insertion follows the existing
+element at \keytext{P}, so that if \keytext{P=0}, \keytext{E} will
+become the first element.
+
+\item \keytext{REMOVE (VAR L:LIST OF GENERIC; P:INTEGER)} \\
+ \keyword{REMOVE} modifies the list \keytext{L} by deleting the
+element at position \keytext{P}.
+
+\item \keytext{SYSTEM (V:STRING)} \\
+ \keyword{SYSTEM} passes the string \keytext{V} to the operating system.
+This is typically used to get the operating system to perform some action.
+
+\item \keytext{ READ(VAR V1, V2,...:GENERIC)}, \keytext{READLN(VAR V1, V2,...:GENERIC)} \\
+ These two procedures are similar to the Pascal procedures of the same
+ name and put data from standard input into the variable(s)
+ \keytext{V1}, etc.
+
+ The argument is a comma-seperated list of variables. The variables may be
+ of different types, but the types are limited to
+ \keyword{INTEGER},
+ \keyword{REAL},
+ \keyword{LOGICAL}, and
+ \keyword{STRING}.
+ The procedure gets the next value of the variable's type from standard input
+ and assigns it to the variable. An integer is recognised as a set of digits,
+ optinally preceeded by a sign. A real is in either decimal or scientific
+ notation (e.g., \verb|12.34| or \verb|1.234e1|). A logical is \verb|TRUE|,
+ \verb|FALSE| or \verb|UNKNOWN| (case independent, so \verb|TRUE| could also
+ be \verb|tRuE|). A string is
+ any non-empty set of characters ended by white space (e.g., \verb*|string |
+ is one string but \verb*|ball of str8 string | is four strings). The difference
+ between \keyword{READ} and \keyword{READLN} is that the former performs the
+ actions described above, while the latter will discard any remaining characters
+ in the input line after processing its arguments.
+
+
+\item \keytext{ WRITE(format)}, \keytext{WRITELN(format)} \\
+ These two procedures are similar to the Pascal procedures of the same name.
+ They write data to standard output.
+
+ The \keytext{format} consists of a comma-seperated list of variables with
+ optional spacing specifications. The variable types may be
+ \keyword{INTEGER},
+ \keyword{REAL},
+ \keyword{LOGICAL}, or
+ \keyword{STRING}.
+ The \keyword{LOGICAL} and \keyword{STRING} types take no spacing declarations.
+ An \keyword{INTEGER} variable can take one optional space specification which
+ is an integer number specifying the minimum field width for printing the value
+ (e.g., \keytext{int:6} to specify a minimum field width of 6 characters).
+ A \keyword{REAL} variable can take two optional space specifications. The
+ first is the field width and the second is the number of digits to be printed
+ (e.g., \keytext{r:10:5} for printing with a field width of 10 characters
+ and to a pecision of 5 digits). For example:
+\begin{code}
+\begin{verbatim}
+BEGIN_LOCAL
+ int : INTEGER;
+ r : REAL;
+ log : LOGICAL;
+ str : STRING;
+END_LOCAL;
+ int := 23;
+ r := 23.0;
+ log := true;
+ str := 'This is a string.';
+WRITE('Example', int, r:10:5, ' ', log, ' ', str);
+\end{verbatim}
+\end{code}
+will produce:
+\begin{code}
+\begin{verbatim}
+Example 23 23.000 TRUE This is a string.
+\end{verbatim}
+\end{code}
+
+ The difference between \keyword{WRITE} and \keyword{WRITELN} is that the latter
+ will end the output line after it has output the values of its arguments.
+ (\keyword{WRITELN} need take no arguments, in which case it justs ends the current
+ output line).
+
+\item \keytext{ PRINT(format)}, \keytext{PRINTLN(format)} \\
+ These \keyword{PRINT} procedures are the same as the
+ \keyword{WRITE} procedures, except that they send the data
+ to the current \lx{} output destination.
+
+\end{itemize}
+
+\subsubsection{Functions}
+
+ The following functions are supplied as part of \ExpressA. They are
+exhibited as signatures to show the formal parameters. For convenience,
+\keytext{NUMBER} is being used to denote either an \keyword{INTEGER} or a
+\keyword{REAL} number.
+
+\begin{itemize}
+\item \keytext{ABS (V:NUMBER) : NUMBER;} \\
+ \keyword{ABS} returns the absolute value of its argument.
+\item \keytext{COS (V:NUMBER) : REAL;} \\
+ Returns the cosine of an an angle specified in radians.
+\item \keytext{EOF () : LOGICAL;} \\
+ Returns \keyword{TRUE} if the next character from standard input
+ is `end-of-file', otherwise it returns \keyword{FALSE}.
+\item \keytext{EOLN () : LOGICAL;} \\
+ Returns \keyword{TRUE} if the next character from standard input
+ is `end-of-line', otherwise it returns \keyword{FALSE}.
+\item \keytext{EXISTS (V:GENERIC) : LOGICAL;} \\
+ The function \keyword{EXISTS} returns \keyword{FALSE} if its
+ argument is indeterminate or does not exist, otherwise it returns
+ \keyword{TRUE}.
+\item \keytext{EXP (V:NUMBER) : REAL;} \\
+ Returns $e$ (the base of natural logarithms (\keyword{CONST\_E}))
+ raised to the power of \keytext{V}.
+\item \keytext{HIBOUND (V:AGGREGATE OF GENERIC) : INTEGER;} \\
+ \keyword{HIBOUND} returns the declared upper index of an \keyword{ARRAY}
+ or the declared upper bound of a
+ \keyword{BAG}, \keyword{LIST} or \keyword{SET}.
+\item \keytext{HIINDEX (V:AGGREGATE OF GENERIC) : INTEGER;} \\
+ \keyword{HIINDEX} returns the declared upper index of an \keyword{ARRAY}
+ or the number of elements in a
+ \keyword{BAG}, \keyword{LIST} or \keyword{SET}.
+\item \keytext{LENGTH (V:STRING) : INTEGER;} \\
+ Returns the number of characters in its argument.
+\item \keytext{LOBOUND (V:AGGREGATE OF GENERIC) : INTEGER;} \\
+ \keyword{LOBOUND} returns the declared lower index of an \keyword{ARRAY}
+ or the declared lower bound of a
+ \keyword{BAG}, \keyword{LIST} or \keyword{SET}.
+\item \keytext{LOG (V:NUMBER) : REAL;} \\
+ Returns the natural logarithm of its argument.
+\item \keytext{LOG2 (V:NUMBER) : REAL;} \\
+ Returns the base 2 logarithm of its argument.
+\item \keytext{LOG10 (V:NUMBER) : REAL;} \\
+ Returns the base 10 logarithm of its argument.
+\item \keytext{LOINDEX (V:AGGREGATE OF GENERIC) : INTEGER;} \\
+ \keyword{LOINDEX} returns the declared lower index of an \keyword{ARRAY}
+ or the value 1 for a
+ \keyword{BAG}, \keyword{LIST} or \keyword{SET}.
+
+ The \keytext{..INDEX} functions are useful for iterating over
+ aggregates. For example, if \keytext{lagg} is a list of integer,
+ then all the elements can be printed out as a comma-seperated
+ list enclosed in parentheses by:
+\begin{code}
+\begin{verbatim}
+writeln;
+write('lagg = (');
+REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ IF (i = HIINDEX(lagg)) THEN write(lagg[i]:1);
+ ELSE write(lagg[i]:1, ', ');
+ END_IF;
+END_REPEAT;
+writeln(')');
+\end{verbatim}
+\end{code}
+\item \keytext{NVL (V:GENERIC; SUBS:GENERIC) : GENERIC;} \\
+ If the argument \keytext{V} exists then it is returned, otherwise
+ the argument \keytext{SUBS} is returned. Both arguments must be
+ of the same type.
+\item \keytext{ODD (V:INTEGER) : LOGICAL;} \\
+ Returns \keyword{TRUE} or \keyword{FALSE} depending on whether or not
+ its argument is odd or even.
+\item \keytext{REXPR (V:STRING; E:STRING) : LOGICAL;} \\
+ This function tests whether the \keytext{V} string parameter
+ matches a regular expression \keytext{E}. \keyword{REXPR}
+ returns \keyword{TRUE} if there is a match, \keyword{FALSE}
+ if there is not a match, or \keyword{UNKNOWN} if the regular
+ expression is ill-formed.
+
+ In the regular expression, most characters stand for themselves,
+ but \verb|\| can be used to escape any of the meta-characters.
+ \begin{itemize}
+ \item The meta-characters \keytext{(} and \keytext{)} are used for
+ grouping sub-expressions.
+ \item \verb?|? between expressions means one or the other.
+ \item \keytext{+} following an expression means match one or more times.
+ \item \keytext{*} following an expression means match zero or more times.
+ \item \keytext{?} following an expression means match zero or one times.
+ \item \verb|[...]| is an expression indicating that any of the enclosed
+ characters are acceptable.
+ \item \verb|[^...]| is an expression indicating that any characters
+ except those enclosed are acceptable.
+ \item Within a bracket expression a range of characters can be
+ specified by providing the first and last with a seperating hyphen.
+ For instance, \keytext{[a-zA-Z]} will match any alphabetic character.
+ \end{itemize}
+
+ Some examples:
+ \begin{itemize}
+ \item \verb|[a-zA-Z]+| match one or more letters.
+ \item \verb|[0-9]+.[0-9]+([eE][\-\+]?[0-9]+)?| match a floating
+ point number \\
+ (e.g., \verb|1.23e-27| or \verb|0.987|)
+ \item \verb|[a-zA-Z][0-9a-zA-Z_]*| match an \ExpressA{} variable.
+ \item \verb|[^0-9a-zA-Z]| match anything except letters or digits.
+ \item \verb?(I|i)(F|f)? case insensitive match for the word \verb|IF|.
+ \end{itemize}
+
+\item \keytext{ROUND (V:NUMBER) : INTEGER;} \\
+ Returns the nearest integer to its argument value.
+\item \keytext{SIN (V:NUMBER) : REAL;} \\
+ Returns the sine of an an angle specified in radians.
+\item \keytext{SIZEOF (V:AGGREGATE OF GENERIC) : INTEGER;} \\
+ \keyword{SIZEOF} returns the number of elements in its argument.
+ When \keytext{V} is an \keyword{ARRAY} this is the declared number
+ of elements. When \keytext{V} is a
+ \keyword{BAG}, \keyword{LIST} or \keyword{SET} this is the actual
+ number of elements.
+\item \keytext{SQRT (V:NUMBER) : REAL;} \\
+ Returns the square root of its argument.
+\item \keytext{TAN (V:NUMBER) : REAL;} \\
+ Returns the tangent of an an angle specified in radians.
+\item \keytext{TRUNC (V:NUMBER) : INTEGER;} \\
+ Chops off any decimal part of its argument, returning the corresponding
+ integer value.
+
+\end{itemize}
+
+
+\subsection{Source level debugger} \label{sec:sld}
+
+ The \ExpressA{} interpreter includes a source level debugger for
+use when your code appears to be misbehaving. When in operation the
+debugger will prompt for a command to be entered. It understands
+the following commands.
+
+\begin{itemize}
+\item \keytext{<return>} Continue processing.
+\item \keyword{break} \keytext{<number>} Place a breakpoint at the statement
+ on line \keytext{<number>}.
+\item \keyword{break} Print the line numbers of all the breakpoints.
+\item \keyword{unbreak} \keytext{<number>} Remove the breakpoint from line
+ \keytext{<number>}.
+\item \keyword{unbreak} Remove all breakpoints.
+\item \keyword{trace} Turn on statement tracing.
+\item \keyword{untrace} Turn off statement tracing.
+\item \keyword{entry} Turn on tracing of entry to procedures and functions.
+\item \keyword{unentry} Turn off entry tracing.
+\item \keyword{exit} Turn on tracing of exits from procedures and functions.
+\item \keyword{unexit} Turn off exit tracing.
+\item \keyword{traceall} Turn on all tracing.
+\item \keyword{untraceall} Turn off all tracing.
+\item \keyword{stack} Turn on display of the runtime stack accesses.
+\item \keyword{unstack} Turn off stack display.
+\item \keyword{step} Turn on single-stepping.
+\item \keyword{unstep} Turn off single stepping.
+\item \keyword{fetch} \keytext{<variable>} Print data fetches for
+ \keytext{<variable>}.
+\item \keyword{store} \keytext{<variable>} Print data stores for
+ \keytext{<variable>}.
+\item \keyword{watch} \keytext{<variable>} Print both data fetches and
+ stores for \keytext{<variable>}.
+\item \keyword{watch} Print the names of all variables being watched.
+\item \keyword{unwatch} \keytext{<variable>} Remove the watch from
+ \keytext{<variable>}.
+\item \keyword{unwatch} Remove all watches.
+\item \keyword{show} \keytext{<expression>} Print the value of
+ the \ExpressA{} expresion \keytext{<expression>}. The variables
+ in the expression must have been declared in the \ExpressA{} code.
+ For example:
+\begin{code}
+\begin{verbatim}
+show (23.0 + LOG(num))/(PI*r**2)
+\end{verbatim}
+\end{code}
+\item \keyword{assign} \keytext{<variable := expression>} Assign the value
+ of \keytext{<expression>} to the \ExpressA{} variable \keytext{<variable>}.
+ For example:
+\begin{code}
+\begin{verbatim}
+assign num := SIN(theta/300.0)
+\end{verbatim}
+\end{code}
+\item \keyword{where} Print the current line number and the text of the
+ next statement to be executed.
+\item \keyword{kill} Terminate the execution of the \lx{} program.
+\end{itemize}
+
+\subsection{Example \ExpressA{} code}
+
+ The following demonstrates most of the functionality of \ExpressA.
+Most of this is not particularly interesting, except possibly for the
+algorithms for calculating the date of Easter and for generating
+magic squares.
+
+\begin{code}
+\begin{verbatim}
+ c= fun.ct Test of CODE ltx2x
+
+CODE_SETUP=
+ ENTITY ent;
+ attr1, attr3 : INTEGER;
+ attr2 : STRING;
+ END_ENTITY;
+
+ TYPE joe = INTEGER;
+ END_TYPE;
+
+ TYPE colour = ENUMERATION OF (red, blue, green);
+ END_TYPE;
+
+
+PROCEDURE easter;
+(* calculates the date of Easter for the present year
+ The algorithm can be applied to any year between
+ 1900 and 2099 inclusive, but if so, then the year
+ should be checked to ensure that it is within this range. *)
+ LOCAL
+ n, a, b, m, q, w : INTEGER;
+ day : INTEGER;
+ month : STRING;
+ END_LOCAL;
+
+ n := THE_YEAR - 1900;
+ a := n MOD 19;
+ b := (7*a + 1) DIV 19;
+ m := (11*a + 4 - b) MOD 29;
+ q := n DIV 4;
+ w := (n + q + 31 - m) MOD 7;
+ day := 25 - m - w;
+ month := 'April';
+ IF (day < 1) THEN
+ month := 'March';
+ day := day + 31;
+ END_IF;
+ writeln('In ', THE_YEAR:1, ' Easter is on ', month, day:3);
+END_PROCEDURE;
+
+
+FUNCTION magic_square(order:INTEGER): LOGICAL;
+(* calculates magic squares from order 1 through 15.
+ The order must be an odd number. *)
+ LOCAL
+ row, col, num : INTEGER;
+ sqr_order : INTEGER;
+ magic : ARRAY[1:15] OF ARRAY[1:15] OF INTEGER;
+ END_LOCAL;
+
+ IF (order > 15) THEN -- only squares up to order 15
+ RETURN(FALSE);
+ ELSE
+ IF (order < 1) THEN -- squares have at least one entry
+ RETURN(FALSE);
+ ELSE
+ IF (NOT ODD(order)) THEN -- squares are odd
+ RETURN(FALSE);
+ END_IF;
+ END_IF;
+ END_IF;
+
+ sqr_order := order**2;
+ row := 1;
+ col := (order + 1) DIV 2;
+ REPEAT num := 1 TO sqr_order;
+ magic[row][col] := num;
+ IF ((num MOD order) <> 0) THEN
+ IF (row = 1) THEN row := order; ELSE row := row - 1; END_IF;
+ IF (col = order) THEN col := 1; ELSE col := col + 1; END_IF;
+ ELSE
+ IF (num <> sqr_order) THEN row := row + 1; END_IF;
+ END_IF;
+ END_REPEAT;
+
+ writeln(Magic square of order ',order:2);
+ REPEAT row := 1 TO order;
+ REPEAT col := 1 TO order;
+ write(magic[row][col]:4);
+ END_REPEAT;
+ writeln;
+ END_REPEAT;
+ writeln;
+
+ RETURN(TRUE);
+END_FUNCTION;
+
+FUNCTION month(mnum:INTEGER) : STRING;
+(* Given an integer representing the month in a year,
+ returns the name of the month. *)
+LOCAL
+ str : STRING;
+END_LOCAL;
+
+ CASE mnum OF
+ 1 : str := 'January';
+ 2 : str := 'February';
+ 3 : str := 'March';
+ 4 : str := 'April';
+ 5 : str := 'May';
+ 6 : str := 'June';
+ 7 : str := 'July';
+ 8 : str := 'August';
+ 9 : str := 'September';
+ 10 : str := 'October';
+ 11 : str := 'November';
+ 12 : str := 'December';
+ OTHERWISE : str := '';
+ END_CASE;
+RETURN(str);
+END_FUNCTION;
+
+ LOCAL
+ a : array[1:3] of integer;
+ lagg : list [0:5] of integer;
+ a23 : array[1:2] of array[1:3] of integer;
+ i, n : integer;
+ s1, s2 : string;
+ b : logical;
+ r1, r2 : real;
+ nega : array[-3:-1] of integer;
+ posa : array[3:5] of integer;
+ j : joe;
+ ex : ent;
+ END_LOCAL;
+
+ -- start with a massive compound statement
+ BEGIN
+
+ writeln;
+ println;
+
+ (* write today's date *)
+ writeln('Today is ', THE_DAY:1, ' ', month(THE_MONTH), ' ', THE_YEAR:1);
+ writeln;
+
+ (* The user might be interested in Easter *)
+ easter;
+ writeln;
+
+ (* Call some math functions *)
+ r1 := PI/4;
+ writeln('r1 = PI/4 (0.78539...)', r1);
+ writeln('cos(r1) (0.70710...)', cos(r1));
+ writeln('sin(r1) (0.70710...)', sin(r1));
+ writeln('tan(r1) (1.0)', tan(r1));
+
+ r1 := CONST_E;
+ writeln('r1 = CONST_E (2.7182...)', r1);
+ writeln('log(4.5) (1.50407...)', log(4.5));
+ writeln('log2(8) (3.0)', log2(8));
+ writeln('log10(10) (1.0)', log10(10));
+
+ r2 := exp(10);
+ writeln('exp(10) (2.203...e4)', r2);
+
+ r2 := sqrt(121);
+ writeln('sqrt(121) (11.0)', r2);
+
+ (* populate and print some arrays *)
+ writeln;
+ posa[3] := 10;
+ posa[4] := 20;
+ posa[5] := 30;
+ REPEAT i := LOINDEX(posa) TO HIINDEX(posa);
+ writeln('posa[', i:1, '] = ', posa[i]);
+ END_REPEAT;
+
+ writeln;
+ nega[-3] := 1;
+ nega[-2] := 2;
+ nega[-1] := 3;
+ REPEAT i := LOINDEX(nega) TO HIINDEX(nega);
+ writeln('nega[', i:1, '] = ', nega[i]);
+ END_REPEAT;
+
+ (* Do some things with a list *)
+
+ -- check the initial size (should be empty)
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+
+ -- insert elements at the front
+ INSERT(lagg, 10, 0);
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+ INSERT(lagg, 20, 0);
+ writeln('no. of els in lagg = ', SIZEOF(lagg));
+
+ -- print some of the elements
+ i := lagg[1];
+ writeln('first in lagg = ', i);
+ writeln('lagg[2] = ', lagg[2]);
+
+ -- check if a value in in the list
+ b := 10 IN lagg;
+ writeln(b); -- should be TRUE
+ b := 30 IN lagg;
+ writeln(b); -- should be FALSE
+
+ -- write all the elements
+ REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ writeln('lagg[', i:1, '] = ', lagg[i]);
+ println('lagg[', i:1, '] = ', lagg[i]);
+ END_REPEAT;
+
+ (* see what happens with an indeterminate value *)
+ b := FALSE;
+ b := ?;
+ writeln(b);
+ println(b);
+ (* Some more attempts with indeterminate *)
+ i := 2;
+ n := 3*i;
+ writeln(i, n); -- should be 2 6
+ n := 3*?;
+ writeln(i, n); -- should be 2 ?
+ i := ?;
+ n := 3*i;
+ writeln(i, n); -- should be ? ?
+
+END; -- end of compound statement
+ -- but we can have individual statements
+
+
+ (* Try to provide some excitement by making a magic square *)
+ writeln;
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ IF NOT magic_square(n) THEN
+ writeln('I did not like your number which was ', n:1);
+ writeln('If you get it right next time, something magic will happen.');
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ magic_square(n);
+ END_IF;
+
+
+ (* Try a couple of REPEAT statements *)
+ writeln('Test REPEAT (should print -2)');
+ i := -2;
+ REPEAT UNTIL i = 0;
+ writeln(i);
+ println(i);
+ ESCAPE;
+ i := i + 1;
+ END_REPEAT;
+
+ writeln('Test REPEAT (should print 3, 2, 1)');
+ REPEAT i := 3 TO 1 BY -1;
+ writeln(i);
+ END_REPEAT;
+
+
+ (* Try the LIKE operator *)
+ writeln('Test LIKE');
+ writeln(('A' LIKE 'A')); -- should be TRUE
+ writeln(('A' LIKE 'b')); -- should be FALSE
+ writeln(('Page 407' LIKE '$###')); -- should be TRUE
+ writeln(('Page 23' LIKE '$###')); -- should be FALSE
+
+
+ (* Try the REXPR function *)
+ writeln('Test rexpr');
+ writeln(rexpr('A', 'A')); -- should be TRUE
+ writeln(rexpr('A', 'b')); -- should be FALSE
+ writeln(rexpr('Page 407', '[a-zA-Z]+\ [0-9]+')); -- should be TRUE
+ writeln(rexpr('Page 23', '[a-zA-Z]+\ [0-9]')); -- should be FALSE
+
+
+ (* Try an ARRAY OF ARRAY *)
+ a23[1][1] := 11;
+ a23[1][2] := 12;
+ a23[1][3] := 13;
+ a23[2][1] := 21;
+ a23[2][2] := 22;
+ a23[2][3] := 23;
+
+ writeln('Test REPEAT (should be 1 1 11, 1 2 12, 1 3 13, 2 1 21, 2 2 22 etc)');
+ REPEAT n := 1 TO 2;
+ REPEAT i := 1 TO 3;
+ writeln(n, i, a23[n][i]);
+ END_REPEAT;
+ END_REPEAT;
+
+
+ (* do some simple string operations *)
+ s1 := 'string';
+ writeln(s1); -- should be string
+ s2 := s1[2:4];
+ writeln(s2); -- should be tri
+ b := s1 <> s2;
+ writeln(b); -- should be TRUE
+ writeln(s2 + s1); -- should be tristring
+
+
+ (* Assign and print to a user-defined type *)
+ j := 33;
+ writeln(j*3); -- should be 99
+
+ (* Do something with a variable of type ENTITY */
+ ex.attr1 := 33;
+ ex.attr2 := 'The attribute named attr2';
+ ex.attr3 := ex.attr1/3;
+ writeln('ex.attr1 should be 33 and is: ', ex.attr1);
+ writeln('ex.attr2 is: ', ex.attr2);
+ writeln('ex.attr3 should be 11 and is: ', ex.attr3);
+
+END_CODE
+\end{verbatim}
+\end{code}
+
+\section{Specifying a {\tt SPECIAL\_} command} \label{sec:special}
+
+ This section gives some hints on how to specify a \LaTeX\ command that
+requires some special processing. The faint-hearted should skip this. It is
+assumed that the implementor will have knowledge of \LaTeX, C programming,
+and lex and
+YACC style lexer and parser generator systems.
+
+ There are two ways of defining \verb|SPECIAL_| kinds of commands though
+neither is particularly simple. The easiest is by what is termed the
+{\em coding} method. This involves modifying the standard actions. The
+more complicated means is by the {\em grammar} method, which involves extending
+the production grammar and, typically, also coding new kinds of actions.
+
+ The process of specifying one of the \verb|SPECIAL_| kinds of command
+actions is:
+\begin{itemize}
+\item Seriously question the need for the special command. One is only required if
+ the standard actions cannot be coerced into serving the needs of the command
+ processing and/or the command grammar is not supported by the \lx\ system.
+\item Design the required entry for the \ctab.
+\item Decide whether the coding or the grammar method is to be used for
+ extending \lx.
+ \begin{description}
+ \item[Coding method] Modify the actions in \file{l2xusrlb.c},
+ and possibly
+ add new functions in \file{l2xusrlb.c} and \file{l2xusrlb.h}.
+
+ \item[Grammar method] Extend the grammar in \file{l2x.y}. Typically it
+ be necessary to add new functions to the user-defined
+ library \file{l2xusrlb} as well.
+ \end{description}
+\item Compile the modified \lx\ system. A \verb|make| file for this is given
+ in Appendix~\ref{sec:install}.
+\item Test the extensions and debug the program.
+\end{itemize}
+
+ The \verb|l2xlib| has many functions that may be of use in this process.
+ Some of these are indicated below.
+
+\begin{itemize}
+\item \verb|char *strsave(char s[])| saves a string somewhere
+\item \verb|void myprint(char s[])| writes a string to the output medium. Its
+ particular action is controlled by the \verb|set_print| and
+ \verb|reset_print| functions, as well as the \verb|-p| option.
+\item \verb|void verbatim_print(char s[])| like \verb|myprint|,
+ writes a string to the output medium. Its actions are controlled
+ by the current print mode, and newlines are obeyed (i.e., it ignores
+ any pretty-printing option).
+\item \verb|void yyerror(char s[])| used by the lexer and parser to print
+ an error message string.
+\item \verb|void warning(char s[])| writes a warning message string.
+\item \verb|void do_newline()| used within the lexer to set internal variables
+ whenever a newline is encountered in the input.
+\item \verb|void initialise_sysbuf()| initialises the system supplied string
+ buffer.
+\item \verb|void print_sysbuf()| writes the content of the system string buffer
+ to the output file.
+\item \verb|void copy_sysbuf(char s[])| copies the contents of the system
+ string buffer to the user-supplied string. It is the user's responsibility
+ to ensure that the string is big enough.
+\item \verb|void set_print(PSTRWC pswitch)| controls the action of \verb|myprint|,
+ \verb|print_newline| and \verb|verbatim_print|. If the input argument is
+ \verb|p_default_print|
+ then the print functions should write to the output file; this is the
+ default behavior. If the
+ argument is \verb|p_no_print|, then no writing occurs. If the argument
+ is \verb|p_print_to_sysbuf|, then the print functions write to the system
+ string buffer.
+\item \verb|void reset_print()| resets the behavior of the print functions. This
+ function should always be used after a call to \verb|set_print|.
+\item \verb|int lookup_entry(char s[], int kind)| returns the location
+ within the \ctab\ of the
+ command name given in \verb|s| of the command type given in \verb|kind|.
+ If \verb|kind| is \verb|DONT_CARE| then the position of the first occurrence
+ of \verb|s| is returned.
+\item \verb|void get_env_name(char s[])| extracts the name of a \LaTeX\
+ environment from \verb|s|, which is assumed to have the form
+ \verb|\something { environment }|. The name of the environment is put
+ into the global string \verb|env_name|.
+\item \verb|PSENTRY get_mode_sym(int loc)| returns a pointer to the
+ symbol table entry at position \verb|loc| in the \ctab{}
+ for the current mode.
+\item \verb|int command_type(int loc)| returns the system defined
+ kind of command at location
+ \verb|loc| in the \ctab.
+\item \verb|int get_user_type(int loc)| returns the user input (\verb|TYPE=|)
+ kind of command at location
+ \verb|loc| in the \ctab.
+\item \verb|PSTRWC get_t(PSENTRY loc)| returns a pointer to the
+ \verb|START_TAG=| specification for symbol entry \verb|loc|.
+ There are similar functions for other tagging specifications.
+\item \verb|PSTRWC get_tag_t(PSENTRY loc, int n)| returns a pointer
+ to the \verb|START_TAG_n| specification for the \verb|n|'th
+ argument for symbol entry \verb|loc|. There are similar
+ functions for other argument tagging specifications.
+\item \verb|PSTRWC get_param_print(PSENTRY loc, int n)| returns a
+ pointer to the print control specification for the
+ \verb|n|'th required argument for symbol entry \verb|loc|.
+ There are similar functions for other print controls.
+\item \verb|int get_level(PSENTRY loc)| returns the \verb|SECTIONING_LEVEL=|
+ value for symbol entry \verb|loc|.
+\end{itemize}
+
+ The process of specifying a \verb|SPECIAL_| is best described via
+an example.
+
+\subsection{Example}
+
+ Assume that there is a `non-standard' \LaTeX\ command
+which has one required argument. When this command is processed by \LaTeX\ its
+effect is to start a new section in a document entitled
+{\em Normative References}. Some boilerplate text is then typeset (specified
+within the definition of the command). This boilerplate includes two
+instances of the text from the argument of the command. Finally, a
+{\tt description}
+list environment is started.
+
+ In \LaTeX\ terms, this command could have been defined as:
+\begin{code}
+\begin{verbatim}
+\newcommand{\XXspecial}[1]{\section{Normative References}
+ Some boilerplate text with #1
+ in the middle. Now there is
+ some more boilerplate with #1
+ in the middle of it.
+ \begin{description} }
+\end{verbatim}
+\end{code}
+
+ For the purposes of the example, it is desired to replace the occurrence
+of the \verb|\XXspecial| command by the `normal' section heading for the
+output tagged style, and also print out the boilerplate text including
+the argument text in the right places. The start of the list environment has
+also to be taken into account. The \verb|\item| optional argument text is
+to be enclosed in parentheses, with a dash before the main text.
+These requirements are not something that can
+be currently accomplished with the standard \lx\ system.
+
+ To make the requirements more concrete, if the input \LaTeX\ source
+includes:
+\begin{code}
+\begin{verbatim}
+....
+\XXspecial{REQ PARAM TEXT}
+
+\item[Ref 1] Text 1.
+\item[Ref 2] Text 2.
+\end{description}
+....
+\end{verbatim}
+\end{code}
+then the desired output is to look like:
+\begin{code}
+\begin{verbatim}
+....
+
+</div.1>
+
+<div.1>
+<heading>Normative References</heading>
+
+Some boilerplate text with REQ PARAM TEXT
+in the middle. Now there is
+some more boilerplate with REQ PARAM TEXT
+in the middle of it.
+
+ (Ref 1) -- Text 1.
+ (Ref 2) -- Text 2.
+....
+\end{verbatim}
+\end{code}
+
+
+ Now, let's write a specification for the \ctab, which we will do in pieces,
+starting with the sectioning tags. In this tagging style, end tags for sections
+take the form \keytext{\ET{div.1}}, and start tags the form \keytext{\ST{div.1}}.
+The titles of sections are enclosed between \keytext{\ST{heading}} and
+\keytext{\ET{heading}} tags. We also
+want some newlines in the output to set things off. If \verb|?| is used as the
+escape character, then we can specify for the sectioning tagging:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+SECTIONING_LEVEL= SECT
+START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+END_TAG= "?n</div.1>"
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+SECTIONING\_LEVEL= SECT
+START\_TAG= "?n?n\ST{div.1}?n"
+ STRING: "\ST{heading}Normative References\ET{heading}?n"
+END\_TAG= "?n\ET{div.1}"
+\end{htmlverbatim}
+
+ There is one required argument and no optional arguments, so we need:
+\begin{code}
+\begin{verbatim}
+REQPARAMS= 1
+\end{verbatim}
+\end{code}
+
+ The \LaTeX\ command also starts off a \verb|description| environment, so we have
+to set the tags for the \verb|\item| commands that will follow. This is done by:
+\begin{code}
+\begin{verbatim}
+START_ITEM= "?n"
+START_ITEM_PARAM= " ("
+END_ITEM_PARAM= ") -- "
+\end{verbatim}
+\end{code}
+
+ Most of the work is now completed though we still have to give the command name,
+decide what sort of \verb|SPECIAL_| it will be and set the \verb|SPECIAL_TOKEN|
+value. None of the provided \verb|SPECIAL_| types exactly fit this entry as it is
+a mixture of sectioning and list environment, so we will just call it a
+\verb|SPECIAL_COMMAND| type.
+To summarize, the effective state of the \ctab\ entry is:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= SPECIAL_COMMAND
+C= NAME= to be specified
+C= SPECIAL_TOKEN= to be specified
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= SPECIAL\_COMMAND
+C= NAME= to be specified
+C= SPECIAL\_TOKEN= to be specified
+ SECTIONING\_LEVEL= SECT
+ START\_TAG= "?n?n\ST{div.1}?n"
+ STRING: "\ST{heading}Normative References\ET{heading}?n"
+ END\_TAG= "?n\ET{div.1}"
+ REQPARAMS= 1
+ START\_ITEM= "?n"
+ START\_ITEM\_PARAM= " ("
+ END\_ITEM\_PARAM= ") -- "
+END\_TYPE
+\end{htmlverbatim}
+
+ For pedagogical purposes, this special will be implemented using both the
+grammar and code methods, and the command names used will be \verb|\GRAMMspecial|
+and \verb|\CODEspecial| respectively.
+
+\subsubsection{Grammar method implementation}
+
+ The command name for this implementation will be \verb|\GRAMMspecial|.
+
+ The grammar method requires changes to the grammar specified in \file{l2x.y}.
+
+\begin{enumerate}
+\item A new token has to be defined, call it \verb|GRAMMSPECIAL|, in the first
+part of the file. There is a slot for this under the comment \verb|/* specials */|.
+An integer number, greater than or equal to 10,000 (ten thousand) and less than
+32,768 ($2^{15}$), has to be
+associated with this token.\footnote{The upper limit of $(2^{15}-1)$ is
+set by the bison processor.}
+ Further, this number must not be the same as any other
+number associated with any other token. Let us use
+the maximum number 32,767. The relevant portion of \file{l2x.y} will look like
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+ /* specials */
+%token <pos> /* other specials here */
+%token <pos> GRAMMSPECIAL 32767
+ /* precedences */
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+ /* specials */
+\%token \ST{pos} /* other specials here */
+\%token \ST{pos} GRAMMSPECIAL 32767
+ /* precedences */
+\end{htmlverbatim}
+This number is used for communication within the \lx\ system, and is the number
+set as the value of the \verb|SPECIAL_TOKEN| in the \ctab. We can now finalize
+the \ctab\ entry as:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= SPECIAL_COMMAND
+NAME= \GRAMMspecial
+SPECIAL_TOKEN= 32767
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= SPECIAL\_COMMAND
+NAME= \verb|\GRAMMspecial|
+SPECIAL\_TOKEN= 32767
+ SECTIONING\_LEVEL= SECT
+ START\_TAG= "?n?n\ST{div.1}?n"
+ STRING: "\ST{heading}Normative References\ET{heading}?n"
+ END\_TAG= "?n\ET{div.1}"
+ REQPARAMS= 1
+ START\_ITEM= "?n"
+ START\_ITEM\_PARAM= " ("
+ END\_ITEM\_PARAM= ") -- "
+END\_TYPE
+\end{htmlverbatim}
+
+\item A new production, or productions, has to be added to the grammar. There is
+a place for this at the end of the rules section in the file, under the predefined
+production \verb|l2xSpecials|. Let us call our new production \verb|GrammSpecial|,
+and add it as:
+\begin{code}
+\begin{verbatim}
+l2xSpecials: ASpecial
+ | AnotherSpecial
+ | GrammSpecial
+ ;
+\end{verbatim}
+\end{code}
+where the \verb|ASpecial| and \verb|AnotherSpecial| are pre-existing specials.
+
+\item The production now has to be defined, specifying the expected syntax
+and required actions. This looks like:
+\begin{code}
+\begin{verbatim}
+GrammSpecial: GRAMMSPECIAL
+ {
+ start_section($1);
+ myprint(get_t($1));
+ myprint(get_tag_t($1,1));
+ initialise_sysbuf();
+ set_print(p_print_to_sysbuf);
+ }
+ ReqParam
+ {
+ initialise_string(grammbuf);
+ copy_sysbuf(grammbuf);
+ reset_print();
+ prwboiler1();
+ print_sysbuf();
+ prwboiler2();
+ myprint(grammbuf);
+ prwboiler3();
+ start_list($1);
+ }
+ ;
+\end{verbatim}
+\end{code}
+ The actions are enclosed in braces and are defined in terms of
+C code.
+
+ Once the parser has been given the \verb|GRAMMSPECIAL| token from the lexer,
+it will attempt to
+perform the actions within the first set of braces. The first of these,
+\verb|start_section($1)|, is the \lx\ action for starting a sectioning command.
+Basically, this deals with any closing of prior sections of the document and
+remembering the closing tag for this section.
+The next two actions
+print the start tags for the command and its required argument,
+taking the strings from the \ctab.
+\verb|initialise_sysbuf()| initializes the
+system string buffer ready for new input. Then the print control is set so
+that any output will be directed into the system string buffer rather
+than the output
+file. This finishes the first set of actions.
+
+ The production grammar for the required argument comes next. If this
+is incorrect, the parser automatically gives an (uninformative) error message.
+Otherwise, the last set of actions are done. At this point, the text
+of the required argument will be contained in the system string buffer.
+This is then copied to a temporary buffer \verb|grammbuf|, that we have yet
+to define, by calling
+\verb|copy_sysbuf(grammbuf)| having first made sure that this buffer has
+been cleared of any previous contents (the \verb|initialise_string(grammbuf)|
+action). The printing control must now be reset (\verb|reset_print()|), or
+things might get corrupted later. A function \verb|prwboiler1()| is called to
+print the first part of the boilerplate text, followed by printing the contents
+of the system buffer by the action \verb|print_sysbuf()| (remember that this should
+contain the text of the required argument). The second part of the boilerplate
+is written by the function \verb|prwboiler2()|. Just for pedagogical purposes,
+the required argument text is written out using the text stored in the temporary
+buffer (\verb|myprint(grammbuf)|) rather than from the system buffer. The penultimate
+action is the printing of the last piece of boilerplate.
+
+ The final action --- \verb|start_list($1)| --- is the standard \lx\ action
+at the start of a list environment. This remembers the various tags for the list
+items to follow.
+
+ A character buffer, \verb|grammbuf|, is now defined in the initial
+section of the \file{l2x.y} file, as:
+\begin{code}
+\begin{verbatim}
+char grammbuf[80];
+\end{verbatim}
+\end{code}
+which is intended to be large enough to hold the text of the required
+argument of the command.
+
+ This completes the changes to the grammar file.
+
+\item The three functions called out in the above actions for printing
+the boilerplate are coded and placed in the user library file
+\file{l2xusrlb.c} and are also added to \file{l2xusrlb.h}. Here is
+the relevant code as it would appear in \file{l2xusrlb.c}.
+\begin{code}
+\begin{verbatim}
+ /* demonstration string definition */
+
+STRING boiler_string_3 = "\nin the middle of it.\n\n";
+
+ /* demonstration functions */
+
+/* PRWBOILER1 print some demonstration boilerplate */
+void prwboiler1()
+{
+ myprint("\nSome boilerplate text with ");
+} /* end PRWBOILER1 */
+
+/* PRWBOILER2 print some demonstration boilerplate */
+void prwboiler2()
+{
+ myprint("\nin the middle. Now there is\n");
+ myprint("some more boilerplate with ");
+} /* end PRWBOILER2 */
+
+/* PRWBOILER3 yet more demonstration boilerplate */
+void prwboiler3()
+{
+ myprint(boiler_string_3);
+} /* end PRWBOILER1 */
+\end{verbatim}
+\end{code}
+
+\item The system is recompiled, using \verb|make|, and tested on some example
+\LaTeX\ files.
+
+\end{enumerate}
+
+
+
+\subsubsection{Code method implementation}
+
+ This method `merely' requires extending the standard actions to
+account for the new requirements. First, however, we must complete
+the definition of the \ctab\ entry. We will call the new
+command \verb|\CODEspecial|. Also a unique value has to be assigned
+to the \verb|SPECIAL_TOKEN|. This must have a value greater than or
+equal to 50,000 (fifty thousand). We will use a value 59,999. Later this
+value is used within the action code to identify the special.
+The \ctab\ entry is thus:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= SPECIAL_COMMAND
+NAME= \CODEspecial
+SPECIAL_TOKEN= 59999
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= SPECIAL\_COMMAND
+NAME= \verb|\CODEspecial|
+SPECIAL\_TOKEN= 59999
+ SECTIONING\_LEVEL= SECT
+ START\_TAG= "?n?n\ST{div.1}?n"
+ STRING: "\ST{heading}Normative References\ET{heading}?n"
+ END\_TAG= "?n\ET{div.1}"
+ REQPARAMS= 1
+ START\_ITEM= "?n"
+ START\_ITEM\_PARAM= " ("
+ END\_ITEM\_PARAM= ") -- "
+END\_TYPE
+\end{htmlverbatim}
+which only differs from that for the grammar implemented special in the
+\verb|SPECIAL_TOKEN=| and the \verb|NAME=| values.
+
+ Before proceeding further, some explanation of the internals of
+the \lx\ system is in order.
+
+\begin{description}
+\item[Command table entry] Internally, an array of C {\tt struct}s
+is used for storing the data corresponding to the \ctab. The {\tt struct}
+is fully
+defined in file \file{l2xcom.h}, and type {\tt PSENTRY} is a
+pointer to an instance of the {\tt struct}. There is an entry in
+the internal \ctab{} for each command. Where a command specification
+is mode-dependent, then the entries for this are stored as a list (the
+\ctab{} array is actually an array of lists of command specifications,
+one list per command).
+
+For the purposes at hand, only a few
+of the elements are of concern; these are \verb|kind|, \verb|parse_kind|
+and \verb|special_token|. The element \verb|kind| contains an identifier
+of the \verb|TYPE=| value; that is, the type of the command as specified
+by the user. The element \verb|special_token| contains the
+\verb|SPECIAL_TOKEN=| value. The \verb|parse_kind| element contains
+an identifier of the type of command as assigned internally by \lx.
+This last identifier is generated by the table processing code
+in \verb|l2xlib.c| and corresponds to one of the token values
+acceptable to the parser.
+
+\item[The lexer] The lexer reads the source \LaTeX\ file, looking for
+\LaTeX\ commands (essentially anything starting with a backslash). Each
+time it finds a command it looks it up in the command table array, and
+sends its parser token value (the \verb|parse_kind| value) and the command
+table array position to the parser.
+
+\item[The parser] Given a token from the lexer, the parser finds the
+appropriate grammar production and performs the specified actions. It
+is able to access command information through having the command table
+position.
+
+\item[The grammar] The grammar used for the \LaTeX\ general commands (and
+environments) is actually very simple --- the complexity is reserved for the
+lexer and the actions. At the grammar level, no distinction is made
+between a command and an environment. There are a total of 19 different
+command types (tokens), which fall into a smaller number of groups.
+\begin{enumerate}
+\item A command with no arguments.
+\item A command with just a single optional argument.
+\item Commands with a final optional argument and between 1 and 8 required
+ arguments.
+\item Commands with between 1 and 8 required arguments. In this case
+ it is always assumed that there might be an initial optional
+ argument.
+\item A command with 9 required arguments.
+\end{enumerate}
+Note that this partitioning is based solely on the number of required
+arguments and the position (if any is declared) of an optional
+argument.
+
+ For example, if a command/environment is specified in the \ctab\ as
+having one required argument and no optional arguments, then this will
+be treated as a command with possibly an initial optional argument and
+one required argument. The grammar for this is:
+\begin{code}
+\begin{verbatim}
+l2xComm1: COMMAND_1
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_last_p($1,1);
+ }
+ ;
+\end{verbatim}
+\end{code}
+where the words in all upper case are grammar tokens, and words in mixed
+case are other grammar productions. The actions are enclosed between braces.
+The \verb|$1| is the position of the command in the command table array.
+
+\item[Actions] The standard actions are contained in file \file{l2xacts.c}.
+Within the code for each standard action, provision is made for
+calling
+action code for specials. All the functions have the same
+general structure. Here, for instance, is the code for the standard
+action that is called between the start of a command and a first optional
+argument.
+\begin{code}
+\begin{verbatim}
+/* START_WITH_OPT start action for command with optional param */
+void start_with_opt(pos)
+int pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ start_it(pos); /* command start action */
+ default_start_with_opt(pos); /* start optional param */
+ break;
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING:
+ special_start_with_opt(pos);
+ break;
+ default: /* should not be here! */
+ warning("(start_with_opt) Unrecognized command type");
+ break;
+ } /* end switch on user_kind */
+} /* end START_WITH_OPT */
+\end{verbatim}
+\end{code}
+
+ The special actions code is in file \verb|l2xusrlib.c|. The code
+for these all follow the same general pattern. For example, here is
+the code implementing the special action between the start of a
+command and a first optional argument.
+\begin{code}
+\begin{verbatim}
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+\end{verbatim}
+\end{code}
+Note that the code as provided just issues a warning message.
+
+
+\end{description}
+
+
+ With this background, we will now go on with the example.
+
+\begin{enumerate}
+\item Decide on how the \lx\ system will translate your command/environment
+description into its internal grammar command type. In this case it
+will translate into a command with possibly an initial optional argument
+and one required argument.
+
+\item Examine the grammar for the command and hence determine which standard
+actions will be called. In this case there are three of these, namely
+\verb|start_with_opt|, \verb|action_opt_first| and \verb|action_last_p|.
+These are the actions that might require modification.
+
+\item Determine what actions are required for your special. Conceptually
+replace the standard actions in the grammar by your actions. Then determine
+how these should be incorporated into the special action code in
+\verb|l2xusrlb|. In plain
+language, the grammar and conceptual actions for the example are:
+\begin{code}
+\begin{verbatim}
+l2xComm1: COMMAND_1
+ {
+ start of as a sectioning command
+ ignore the optional argument as there isn't one
+ }
+ OptParam
+ {
+ finish processing the non-existent optional
+ get ready to store the argument text in a buffer
+ }
+ ReqParam
+ {
+ print the boilerplate and argument text
+ start the description list
+ }
+ ;
+\end{verbatim}
+\end{code}
+Note that this is essentially the same as we did for the grammar
+implementation for \verb|\GRAMMspecial|, except that there is the additional
+optional argument to be dealt with.
+
+\item Modify the requisite special action code.
+
+ In the example, three standard actions have to be modified. Here is
+the modification to \verb|special_start_with_opt|:
+\begin{code}
+\begin{verbatim}
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ codespecial_start(pos);
+ default_start_with_opt(pos);
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+\end{verbatim}
+\end{code}
+The addition is done by adding a new \verb|case 59999:| together with
+appropriate code. The number 59999 is that corresponding to the
+value for \verb|SPECIAL_TOKEN=| in the command table specification
+of \verb|\CODEspecial|. The function \verb|codespecial_start| is to
+be written, while \verb|default_start_with_opt| is an \lx\ defined
+function which initiates processing of an initial optional argument.
+
+ Similarly, here is the modification to \verb|special_action_opt_first|:
+\begin{code}
+\begin{verbatim}
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ default_end_start_opt(pos);
+ codespecial_p1(pos);
+ break;
+
+ /* end of cases for specials */
+\end{verbatim}
+\end{code}
+where \verb|codespecial_p1| is to be written and \verb|default_end_start_opt|
+is the standard \lx\ action at the end of an initial optional argument.
+
+Finally, here is the modification to \verb|special_action_last_p|:
+\begin{code}
+\begin{verbatim}
+/* SPECIAL_ACTION_LAST_P action after last req argument */
+void special_action_last_p(pos,p)
+int pos; /* position of command in table */
+int p; /* number of last argument */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ if (p == 1) { /* has only one req param */
+ codespecial_end(pos);
+ }
+ break;
+
+ /* end of cases for specials */
+ /* stuff deleted to save space */
+\end{verbatim}
+\end{code}
+
+\item Code the functions for the new actions.
+
+ Code for these functions should be put into file \verb|l2xusrlb.c|
+and file \verb|l2xusrlb.h| modified accordingly.
+
+ Here is the code for the three \verb|codespecial_| functions.
+\begin{code}
+\begin{verbatim}
+char codebuf[80]; /* a string buffer */
+
+/* CODESPECIAL_START actions for start of CODEspecial command */
+void codespecial_start(pos)
+int pos; /* command table position */
+{
+ start_section(pos); /* do start of sectioning */
+ myprint(get_t(pos)); /* print start tag */
+} /* end CODESPECIAL_START */
+
+/* CODESPECIAL_P1 actions at start of CODEspecial param 1 */
+void codespecial_p1(pos)
+int pos; /* command table position */
+{
+ myprint(get_tag_t(pos,1)); /* print 1st param start tag */
+ initialise_sysbuf(); /* clear system string buffer */
+ set_print(p_print_to_sysbuf); /* put arg text into sys buffer */
+} /* end CODESPECIAL_P1 */
+
+/* CODESPECIAL_END actions at end of CODEspecial command */
+void codespecial_end(pos)
+int pos; /* command table position */
+{
+ initialise_string(codebuf); /* clear this string buffer */
+ copy_sysbuf(codebuf); /* copy sys buffer into codebuf */
+ reset_print(); /* normal printing */
+ prwboiler1(); /* print some boilerplate */
+ print_sysbuf(); /* print system buffer */
+ prwboiler2(); /* print more boilerplate */
+ myprint(codebuf); /* print codebuff */
+ prwboiler3(); /* print yet more boilerplate */
+ start_list(pos); /* start a list environment */
+} /* end CODESPECIAL_END */
+\end{verbatim}
+\end{code}
+Note that these actions are almost identical to those that were used
+within the grammar when implementing the \verb|\GRAMMspecial| command.
+
+\item Compile the modified system and test it on example \LaTeX\ files.
+
+\end{enumerate}
+
+\subsection{Notes}
+
+\begin{enumerate}
+\item Installation of a \keyword{SPECIAL\_} can be limited to making changes
+ to the parser (file \verb|l2x.y|) and/or the user library
+ (files \verb|l2xusrlb.c| and \verb|l2xusrlb.h|).
+ It should not be necessary to touch any other part of the system.
+
+\item Changes to \file{l2x.y} will necessitate executing the parser generator
+ on this file and
+ system compilation. Changes to the other files will only necessitate
+ compilation.
+
+\item Always use the \keytext{myprint}, \keytext{verbatim\_print}
+ or \keytext{print\_sysbuf} functions for
+ printing because they incorporate the print control
+ capability.
+
+\item The printing in the above example is trivial. However, it is good practice
+ to define printed output separately from the parser. It makes for easier
+ maintenance. If, for example the boilerplate above was several thousand
+ characters, it might have been an idea to store the text in a file, or
+ files, and then have the boilerplate printing functions read from
+ the file(s).
+ If the text is in a state of flux this could be a good design decision
+ in any case, as changing the text would only involve modifying the
+ text file(s) and avoid recompilation of \lx.
+\end{enumerate}
+
+\subsubsection{An updated method}
+
+ The above descriptions of installing a \verb|SPECIAL_| command were
+written for the original release of the \lx{} system, which did not
+have the input and output specification facilities currently available
+within a \ctab. Below is given a possible \ctab{} entry using these
+facilities.
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= SPECIAL_COMMAND
+NAME= \THIRDspecial
+ C= SPECIAL_TOKEN= set the appropriate number
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ RESET_SYSBUF:
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ PRINT_P1= TO_SYSBUF
+ END_TAG_1=
+ STRING: "?nSome boilerplate text with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle. Now there is?n"
+ STRING: "some more boilerplate with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle of it.?n"
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= SPECIAL\_COMMAND
+NAME= \THIRDspecial
+ C= SPECIAL\_TOKEN= set the appropriate number
+ SECTIONING\_LEVEL= SECT
+ START\_TAG= "?n?n\ST{div.1}?n"
+ STRING: "\ST{heading}Normative References\ET{heading}?n"
+ RESET\_SYSBUF:
+ END\_TAG= "?n\ET{div.1}"
+ REQPARAMS= 1
+ PRINT\_P1= TO\_SYSBUF
+ END\_TAG\_1=
+ STRING: "?nSome boilerplate text with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle. Now there is?n"
+ STRING: "some more boilerplate with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle of it.?n"
+ START\_ITEM= "?n"
+ START\_ITEM\_PARAM= " ("
+ END\_ITEM\_PARAM= ") -- "
+END\_TYPE
+\end{htmlverbatim}
+The actual implementation of this as either a grammar special or a code
+special is left as an exercise for the reader. Basically it involves
+the deletion of the specific print action and buffer code because this is now
+handled automatically via the \ctab{} specification.
+
+
+\clearpage
+\appendix
+\section{Example \protect\ctab\ file for de-\TeX ing} \label{sec:detexing}
+
+ This appendix provides the skeleton of a \ctab\ file that could be used for
+de-\TeX ing a \LaTeX\ document.
+
+\begin{code}
+\begin{verbatim}
+C= detex.ct command table file for ltx2x to deTeX source
+
+C= -----------------------------------escape sequences
+
+C= don't use default here as it may clash with command name output
+ESCAPE_CHAR= ?
+C= keep tye default vaues for the rest
+
+C= ----------------------------------- the built in commands
+TYPE= BEGIN_DOCUMENT
+END_TYPE
+
+TYPE= END_DOCUMENT
+END_TYPE
+
+TYPE= BEGIN_VERB
+END_TYPE
+
+TYPE= END_VERB
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+END_TYPE
+
+TYPE= END_DOLLAR
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= " "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+C= throw away naked braces
+TYPE= LBRACE
+END_TYPE
+
+TYPE= RBRACE
+END_TYPE
+
+C= Pretty printing will probably be applied. Indent start of paragraphs
+TYPE= PARAGRAPH
+ START_TAG= "?n?n "
+END_TYPE
+
+C= -------------------------------------(La)TeX special characters
+
+C= hash (for use in \def s )
+TYPE= TEX_CHAR
+NAME= #
+END_TYPE
+
+C= ampersand (tabular column delimiter, replace by some spaces)
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " "
+END_TYPE
+
+C= twiddle (unbreakable space)
+TYPE= TEX_CHAR
+NAME= ~
+ START_TAG= " "
+END_TYPE
+
+C= underscore (math subscript)
+TYPE= TEX_CHAR
+NAME= _
+ START_TAG= "_"
+END_TYPE
+
+C= caret (math superscript)
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "^"
+END_TYPE
+
+C= at
+TYPE= TEX_CHAR
+NAME= @
+ START_TAG= "@"
+END_TYPE
+
+C= ------------------------- default single character commands
+C= (replace by appropriate character)
+
+C= LaTeX start a new line
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+END_TYPE
+
+C= small space
+TYPE= CHAR_COMMAND
+ NAME= \,
+START_TAG= " "
+END_TYPE
+
+C= end of sentence space
+TYPE= CHAR_COMMAND
+NAME= \@
+ START_TAG= " "
+END_TYPE
+
+C= hash
+TYPE= CHAR_COMMAND
+NAME= \#
+ START_TAG= "#"
+END_TYPE
+
+C= dollar
+TYPE= CHAR_COMMAND
+NAME= \$
+ START_TAG= "$"
+END_TYPE
+
+C= ampersand
+TYPE= CHAR_COMMAND
+NAME= \&
+ START_TAG= "&"
+END_TYPE
+
+C= underscore
+TYPE= CHAR_COMMAND
+NAME= \_
+ START_TAG= "_"
+END_TYPE
+
+C= percent
+TYPE= CHAR_COMMAND
+NAME= \%
+ START_TAG= "%"
+END_TYPE
+
+C= left brace
+TYPE= CHAR_COMMAND
+NAME= \{
+ START_TAG= "{"
+END_TYPE
+
+C= right brace
+TYPE= CHAR_COMMAND
+NAME= \}
+ START_TAG= "}"
+END_TYPE
+
+C= optional hyphenation
+TYPE= CHAR_COMMAND
+NAME= \-
+ START_TAG= ""
+END_TYPE
+
+C= ----------------------------- General LaTeX
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+ START_ITEM= "?n -- "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "?n"
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+START_TAG= "?n"
+END_TYPE
+
+C= replace \footnote with parenthesized text
+TYPE= COMMAND
+NAME= \footnote
+ START_TAG= " ("
+ END_TAG= ") "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+C= ----------------------- sectioning (keep headers only)
+
+C= repeat for all the other sectioning commands
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= repeat for all the other starred sectioning commands
+TYPE= SECTIONING
+NAME= \section*
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= and whatever else is interesting
+END_CTFILE=
+\end{verbatim}
+\end{code}
+
+\section{LaTeX to HTML translation} \label{sec:htmling}
+
+ The \ctab{} file \file{l2h.ct} contains a set of commands that
+enable simple \LaTeX{} documents to be translated into HTML tagged
+documents for display using a World Wide Web browser. At a minumum
+this \ctab{} can be used for conversion of the \LaTeX{} source of
+this manual. It can also handle some very simple mathematics but not
+pictures.\footnote{HTML itself cannot handle pictures directly (i.e.,
+there is no equivalent to the \LaTeX{} \keytext{picture} environment),
+and can only handle simple mathematics.} The specification
+for the HTML tags was taken from Musciano and Kennedy~\cite{MUSCIANO96}.
+
+ Generally speaking and subject to the above limitations,
+a \LaTeX{} document can be translated
+to HTML without the document having been planned for this purpose,
+with one exception.
+The exception is that a new \LaTeX{} command should be used in the
+document preamble.
+I have called this \verb|\mltitle| and its purpose to to define
+the contents of the header for the HTML text. The definition of this command
+is:
+\begin{verbatim}
+\newcommand{\mltitle}[1]{}
+\end{verbatim}
+That is, as far as \LaTeX{} is concerned, the argument to the command is
+thrown away and is a non-event. As far as the \file{l2h.ct} \ctab{} is concerned
+the argument is the header title. As an example, this manual starts with:
+\begin{verbatim}
+...
+\mltitle{LaTeX to X translator}
+\begin{document}
+\title{\lx: A \LaTeX{} to X Auto-tagger}
+...
+\end{verbatim}
+which gets converted into:
+\begin{latexonly}
+\begin{verbatim}
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+</h1>
+...
+\end{verbatim}
+\end{latexonly}
+\begin{htmlverbatim}
+<html>
+<head>
+<title>LaTeX to X translator\ET{title}
+\ET{head}
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+\ET{h1}
+...
+\end{htmlverbatim}
+If the \verb|\mltitle| command is not used, then the effect is to have
+an empty \ST{title} in the \ST{head} of the HTML document.
+
+
+ Several aspects of the design of \file{l2h.ct} in the context of
+the conversion of typical \LaTeX{} documents have been discussed
+as examples in the body of the manual. However, there are some aspects
+specific to the translation of this document should be mentioned.
+These stem from the fact that HTML has no tags corresponding to
+to the \LaTeX{} \verb|\verb| command or \verb|verbatim| environment which
+switch off the meanings of special characters.
+
+ HTML treats the characters \LT, \GT, \Amp{} and \HASH{} specially.
+Within a \ST{pre}...\ET{pre} the browser honours the line breaks
+but does not switch off the meanings of the special characters. In \LaTeX{},
+the \verb|\verb| command switches off all special characters but prohibits
+any line breaking. The \verb|verbatim| environment both honours line breaks
+and switches off all special characters. The difficulty with this particular
+document is that I want to show author-formatted HTML source, and that is not
+easly possible, unlike using the \LaTeX{} \verb|verbatim| environment for
+showing user-formatted \LaTeX{} source.
+
+ The problem was solved through the use of two \LaTeX{} environments.
+The first of these is \keytext{latexonly} which is used for input that is
+to be processed normally by \LaTeX{} but which is to be totally ignored
+by \lx. The other environment is \keytext{htmlverbatim} which is used
+for input that is to be totally ignored by \LaTeX{} but which is to be
+processed by \lx{} into an HTML \ST{pre} environment.
+
+ A package file has been written which provides some addtional
+commands and environments.
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+% ltx2html.sty --- Some useful commands and environments when using
+% ltx2x to convert from LaTeX to HTML tagging.
+%
+% Author: Peter Wilson August 1996
+%
+\ProvidesPackage{ltx2html}[1996/08/29 ltx2x HTMLing]
+\RequirePackage{html} % the package file for the Perl program
+ % latex2html
+
+% The document title for the WWW browser.
+% If used, must be placed in the preamble.
+\newcommand{\mltitle}[1]{}
+
+% argument is for processing by LaTeX only
+\providecommand{\latex}[1]{#1}
+
+% argument is for HTML processing only
+\providecommand{\html}[1]{}
+
+% print argument as an SGML/HTML start tag
+\newcommand{\ST}[1]{\texttt{<#1>}}
+
+% print argument as an SGML/HTML end tag
+\newcommand{\ET}[1]{\texttt{</#1>}}
+
+% print HTML special characters
+\newcommand{\Amp}{\&}
+\newcommand{\GT}{\texttt{>}}
+\newcommand{\LT}{\texttt{<}}
+\newcommand{\HASH}{\#}
+
+% treat contents as a LaTeX comment but
+% translate contents into an HTML "verbatim" environment
+% Use as: \begin{htmlverbatim} ... \end{htmlverbatim}
+\excludecomment{htmlverbatim}
+
+\endinput
+\end{verbatim}
+\end{code}
+\end{latexonly}
+
+\begin{htmlverbatim}
+% ltx2html.sty --- Some useful commands and environments when using
+% ltx2x to convert from LaTeX to HTML tagging.
+%
+% Author: Peter Wilson August 1996
+%
+\verb|\ProvidesPackage{ltx2html}[1996/08/29 ltx2x HTMLing]|
+\verb|\RequirePackage{html} % the package file for the Perl program|
+ \% latex2html
+
+\% The document title for the WWW browser.
+\% If used, must be placed in the preamble.
+\verb|\newcommand{\mltitle}[1]{}|
+
+\% argument is for processing by LaTeX only
+\verb|\providecommand{\latex}[1]|\{\HASH{}1\}
+
+\% argument is for HTML processing only
+\verb|\providecommand{\html}[1]{}|
+
+\% print argument as an SGML/HTML start tag
+\verb|\newcommand{\ST}|[1]\{\ST{\HASH{}1}\}
+
+\% print argument as an SGML/HTML end tag
+\verb|\newcommand{\ET}|[1]\{\ET{\HASH{}1}\}
+
+\% print HTML special characters
+\verb|\newcommand{\Amp}|\{\Amp\}
+\verb|\newcommand{\GT}|\{\GT\}
+\verb|\newcommand{\LT}|\{\LT\}
+\verb|\newcommand{\HASH}|\{\HASH\}
+
+\% treat contents as a LaTeX comment but
+\% translate contents into an HTML "verbatim" environment
+\verb|% Use as: \begin{htmlverbatim} ... \end{htmlverbatim}|
+\verb|\excludecomment{htmlverbatim}|
+
+\verb|\endinput|
+\end{htmlverbatim}
+
+ The \ctab{} entries for some of these are:
+\begin{latexonly}
+\begin{code}
+\begin{verbatim}
+TYPE= COMMAND
+NAME= \Amp
+ START_TAG= "&amp;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \GT
+ START_TAG= "&gt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \LT
+ START_TAG= "&lt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \HASH
+ START_TAG= "&#035;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ST
+ START_TAG= "&lt;"
+ END_TAG= "&gt;"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ET
+ START_TAG= "&lt;/"
+ END_TAG= "&gt;"
+ REQPARAMS= 1
+END_TYPE
+\end{verbatim}
+\end{code}
+\end{latexonly}
+\begin{htmlverbatim}
+TYPE= COMMAND
+NAME= \Amp
+ START\_TAG= "\Amp{}amp;"
+END\_TYPE
+
+TYPE= COMMAND
+NAME= \GT
+ START\_TAG= "\Amp{}gt;"
+END\_TYPE
+
+TYPE= COMMAND
+NAME= \LT
+ START\_TAG= "\Amp{}lt;"
+END\_TYPE
+
+TYPE= COMMAND
+NAME= \HASH
+ START\_TAG= "\Amp\HASH035;"
+END\_TYPE
+
+TYPE= COMMAND
+NAME= \verb|\ST|
+ START\_TAG= "\Amp{}lt;"
+ END\_TAG= "\Amp{}gt;"
+ REQPARAMS= 1
+END\_TYPE
+
+TYPE= COMMAND
+NAME= \verb|\ET|
+ START\_TAG= "\Amp{}lt;/"
+ END\_TAG= "\Amp{}gt;"
+ REQPARAMS= 1
+END\_TYPE
+\end{htmlverbatim}
+
+ Finally, as an example, this is how some of the prior example text
+could be
+written in the source of this document.
+\begin{latexonly}
+\begin{verbatim}
+\begin{latexonly}
+\begin{verbatim}
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+</h1>
+...
+\end{verbatim}
+\verb|\end{verbatim}| \\
+\verb.\end{latexonly}.
+\end{latexonly}
+\begin{latexonly}
+\begin{verbatim}
+
+\begin{htmlverbatim}
+<html>
+<head>
+<title>LaTeX to X translator\ET{title}
+\ET{head}
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+\ET{h1}
+...
+\end{htmlverbatim}
+\end{verbatim}
+\end{latexonly}
+
+\begin{htmlverbatim}
+\verb|\begin{latexonly}|
+\verb|\begin{verbatim}|
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+</h1>
+...
+\verb|\end{verbatim}|
+\verb|\end{latexonly}|
+
+\verb|\begin{htmlverbatim}|
+<html>
+<head>
+<title>LaTeX to X translator\verb|\ET{title}|
+\verb|\ET{head}|
+<body>
+
+<h1 align=center>
+<title>LaTeX to X translator\verb|\ET{title}|
+\verb|\ET{head}|
+\verb|...|
+\verb|\end{htmlverbatim}|
+\end{htmlverbatim}
+
+ Reading the \LaTeX{} source of this document will reveal some
+other details. Admittedly the problem was compounded by the fact
+that this document contains demonstrations of both \LaTeX{} and
+HTML commands which will be processed through both \LaTeX{} and HTML
+browsers, thus a modicum of care is required to appropriately
+process both sets of special characters.
+
+
+\section{Known limitations} \label{sec:limitations}
+
+ \lx\ does not do everything that it might (and probably never will).
+The following are some of the things that it does not do.
+
+\begin{itemize}
+\item It does not understand the \LaTeX\ \verb|\input| or \verb|\include|
+ commands ---
+ it just reads the source file as given. It may be useful to pre-process the
+ source file through a program that will automatically incorporate included
+ files into a \LaTeX\ root file~\cite{PRW94b}.
+
+\item The \verb|\newcommand| and friends do not readily
+ fit into the command patterns that
+ \lx\ can deal with. In particular, if it comes across a \verb|\newcommand|
+ specification for a command that is specified in the \ctab, interesting
+ results might occur (for example, all the following output could be thrown
+ away if the command takes any arguments).
+
+ For instance, if the document and the \ctab\ contain:
+\begin{code}
+\begin{verbatim}
+\newcommand{\lx}{LTX2X}
+....
+The \lx\ program ...
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+\end{verbatim}
+\end{code}
+ then there is usually no problem. On the other hand, if the document and
+ the \ctab\ contain:
+\begin{code}
+\begin{verbatim}
+\newcommand{\fd}[1]{\texttt{#1}}
+....
+where \fd{InputFile} is the name ...
+
+TYPE= COMMAND
+NAME= \fd
+ REQPARAMS= 1
+END_TYPE
+\end{verbatim}
+\end{code}
+ then there may be a problem, which might be as `minor' as \lx\ reporting
+ a parse error when it has reached \verb|\newcommand{\fd}| in the input
+ file and then carrying on, or it may be more serious.
+
+\item There is a slight problem with optional arguments. \lx\ always takes the
+ first close bracket (\verb|]|) after the opening bracket as signalling
+ the end of the argument text. This occurs even if the close bracket
+ is enclosed in braces (i.e. \verb|{]}|). Opening brackets within optional
+ argument text are handled correctly.
+
+\item It cannot sensibly handle \LaTeX{}
+ constructs of the form \verb|{\em emph text}|.
+ That is, except for command arguments, it does not recognize
+ \verb|{...}| as a grouping construct, so cannot successfully
+ tag the end of the \verb|emph text| in the example. On the other
+ hand, if constructs like \verb|\emph{emph text}| or
+ \verb|\begin{em}emph text\end{em}| are used instead, start and end
+ tags can be generated, given appropriate specifications in the
+ \ctab.
+
+\item It assumes that all commands that take arguments are written so
+ that each argument is enclosed in braces. For example, the
+ superscripting command should be written as \verb|^{2}| and not
+ as \verb|^2|. Similarly, accent commands should be written as
+ \verb|\={o}| rather than \verb|\=o|, and so on.
+
+\item There has not been time to test all aspects of the \ExpressA{}
+ interpreter. It is possible that this may not perform quite
+ as advertised. In particular dynamic aggregates have not been fully
+ implemented. For example:
+\begin{code}
+\begin{verbatim}
+LIST OF INTEGER;
+\end{verbatim}
+\end{code}
+ appears to be handled correctly. More complicated constructs involving
+ dynamic aggregates, such as
+\begin{code}
+\begin{verbatim}
+ARRAY [1:7] OF LIST OF ARRAY [-21:21] OF INTEGER;
+\end{verbatim}
+\end{code}
+ have not been tested. It is improbable that \keyword{BAG} will
+ work; the status of \keyword{SET} is similar and additionally
+ the uniqueness test for set membership has not been implemented.
+\item No doubt other limitations will come to light as \lx\ gets more use.
+ On the other
+ hand, \lx{} has been able to handle a broader range of cases than
+ it was designed to address.
+
+
+\end{itemize}
+
+
+\section{Command table summary} \label{sec:summary}
+
+ This section summarizes the commands and specifications available
+for defining a \ctab.
+
+\subsection{Special print characters}
+
+ The combination of an escape character and another character can be used to
+specify certain non-visible characters within a tag string. The commands are
+given in Table~\ref{tab:spc}.
+
+\begin{table}[htbp]
+\centering
+\caption{Special print character commands.} \label{tab:spc}
+\begin{tabular}{|l|c|} \hline
+Command & Default \\ \hline
+\keyword{AUDIBLE\_ALERT\_CHAR=} & \verb|a| \\
+\keyword{BACKSPACE\_CHAR=} & \verb|b| \\
+\keyword{CARRIAGE\_RETURN\_CHAR=} & \verb|r| \\
+\keyword{ESCAPE\_CHAR=} & \verb|\| \\
+\keyword{FORMFEED\_CHAR=} & \verb|f| \\
+\keyword{HEX\_CHAR=} & \verb|x| \\
+\keyword{HORIZONTAL\_TAB\_CHAR=} & \verb|t| \\
+\keyword{NEWLINE\_CHAR=} & \verb|n| \\
+\keyword{VERTICAL\_TAB\_CHAR=} & \verb|v| \\ \hline
+\end{tabular}
+\end{table}
+
+ These commands take one character as their value. If any commands are not
+specified, then the default value is used. These commands, if used, must be
+at the beginning of the \ctab\ before any \keyword{TYPE=} commands,
+although their ordering is not significant among themselves.
+
+\subsection{\ExpressA{} code initialization}
+
+ The keyword \keyword{CODE\_SETUP=} indicates that the following part
+of the \ctab, up until the \keyword{END\_CODE} keyword, contains
+\ExpressA{} code declarations and/or statements. If used, this block
+must come before any of the \keyword{TYPE=} commands.
+
+\subsection{Comments and file inclusion}
+
+ A comment within a \ctab\ file is any line starting with \keyword{C= }.
+
+ A file can be included within another \ctab\ file with the command line
+\begin{verbatim}
+INCLUDE= FileName
+\end{verbatim}
+where \keytext{FileName} is the name of the file to be included. The
+\keyword{INCLUDE=}
+command cannot appear between the command pair \keyword{TYPE=} and its following
+\keyword{END\_TYPE}.
+
+ The end of a \ctab\ file is either the physical end of the file or
+the command \keyword{END\_CTFILE=}, whichever occurs first.
+
+\subsection{Command types}
+
+ All command type specifications have the general form:
+\begin{verbatim}
+TYPE= CommandType
+NAME= CommandName
+ C= a possibly empty list of mode-independent commands
+ C= possibly sets of mode-dependent commands
+END_TYPE
+\end{verbatim}
+where \keytext{CommandType} is a keyword identifying the kind of command being
+specified and \keytext{CommandName} is the identifier of a \LaTeX{} command
+or environment. The potential set of commands that can be used between the
+\keyword{TYPE=}
+and \keyword{END\_TYPE} commands depends on the kind of command being specified,
+but the special print character commands, Table~\ref{tab:spc},
+and the \keyword{INCLUDE=} command cannot
+appear within a type specification. All command specifications, except
+for the built in command types (see Table~\ref{tab:rct}),
+must include at least a \keyword{NAME=} command.
+The ordering of commands within a type
+specification is not significant. The ordering of type specifications within
+a \ctab\ file is not significant.
+
+ The \keyword{NAME=} command takes as its value the name of a \LaTeX\ command or
+environment. The name must be written exactly as it would appear in a \LaTeX\
+source file. That is, \verb|\command| for any command except \verb|\begin{}|
+or \verb|\end{}|, and as \verb|env| for an
+environment begun as \verb|\begin{env}| or ended by \verb|\end{env}|.
+
+\subsubsection{Built in command types}
+
+ Table~\ref{tab:rct} lists the keywords for the built in command types.
+
+\begin{table}[htbp]
+\centering
+\caption{Built in command type keywords.} \label{tab:rct}
+\begin{tabular}{|l|c|} \hline
+Keyword & \LaTeX\ command \\ \hline
+\keyword{BEGIN\_DOCUMENT} & \verb|\begin{document}| \\
+\keyword{BEGIN\_DOLLAR} & \verb|$| at start of in-text math \\
+\keyword{BEGIN\_VERB} & \verb|\verb| or \verb|\verb*| and its following character \\
+\keyword{BEGIN\_VERBATIM} & \verb|\begin{verbatim}| or \verb|\begin{verbatim*}| \\
+\keyword{END\_DOCUMENT} & \verb|\end{document}| \\
+\keyword{END\_DOLLAR} & \verb|$| at end of in-text math \\
+\keyword{END\_VERB} & the ending character for \verb|\verb| or \verb|\verb*| \\
+\keyword{END\_VERBATIM} & \verb|\end{verbatim}| or \verb|\end{verbatim*}| \\
+\keyword{LBRACE} & \verb|{| \\
+\keyword{OTHER\_BEGIN} & of the form \verb|\begin{env}| not specified elsewhere \\
+\keyword{OTHER\_COMMAND} & of the form \verb|\comm| not specified elsewhere \\
+\keyword{OTHER\_END} & of the form \verb|\end{env}| not specified elsewhere \\
+\keyword{PARAGRAPH} & blank source line \\
+\keyword{RBRACE} & \verb|}| \\
+\keyword{SLASH\_SPACE} & \verb*|\ | \\ \hline
+\end{tabular}
+\end{table}
+
+ The built in command type specifications can only sensibly use two kinds
+of actions ---
+those specified at the start of the command (e.g., \keyword{PC\_AT\_START=}
+and \keyword{START\_TAG=}) and/or actions at the end of the command
+(e.g., \keyword{PC\_AT\_END} and \keyword{END\_TAG=}).
+The \keyword{NAME=} command must not be used.
+
+ The \keyword{OTHER\_} types are an exception to the above, in that they can include
+the command line \keyword{PRINT\_CONTROL= NO\_PRINT}.
+
+ \lx\ checks the command table for the presence of these required types. If one
+or more have not been specified, then they are automatically added to the command table
+with default values (e.g. empty strings) for the tags, and a warning message is
+printed giving the default value(s).
+
+\subsubsection{Optional command types}
+
+ For discussion purposes, the optional command types have been tabulated
+in different categories. The basic distinction between these categories is
+the sets of commands that are permissible within the command specification.
+
+ At a minimum, all the specifications must include a \keyword{NAME=} command
+and must not contain any \keyword{PRINT\_CONTROL=} or \keyword{INCLUDE=} commands
+or the special
+print character commands listed in Table~\ref{tab:spc}.
+
+
+ The keywords for the general command types are given Table~\ref{tab:gct}.
+
+\begin{table}[htbp]
+\centering
+\caption{General command type keywords.} \label{tab:gct}
+\begin{tabular}{|l|c|} \hline
+Keyword & \LaTeX\ command form \\ \hline
+\keyword{TEX\_CHAR} & \LaTeX\ special characters (except \verb|{ } $|) \\
+\keyword{CHAR\_COMMAND} & \verb|\c|, where \verb|c| is non-alphabetic \\
+\keyword{COMMAND} & \verb|\command| except for sectioning or picture commands \\
+\keyword{BEGIN\_ENV} & \verb|\begin{env}| except for \verb|\item| lists \\
+\keyword{END\_ENV} & \verb|\end{env}| except for \verb|\item| lists \\
+\keyword{VCOMMAND} & a \verb|\verb|-like command \\
+\keyword{BEGIN\_VENV} & start of a \verb|verbatim|-like environment \\
+\keyword{END\_VENV} & end of a \verb|verbatim|-like environment \\ \hline
+\end{tabular}
+\end{table}
+
+ A general command type specification can include any of the tagging and print
+option commands. They cannot contain a \keyword{SECTION\_LEVEL=} command, nor can
+they contain any of the \keyword{\_ITEM\_} commands.
+
+ The keywords for the specific command types are given in Table~\ref{tab:sct}.
+
+\begin{table}[htbp]
+\centering
+\caption{Specific command type keywords.} \label{tab:sct}
+\begin{tabular}{|l|c|} \hline
+Keyword & \LaTeX\ command form \\ \hline
+\keyword{BEGIN\_LIST\_ENV} & \verb|\begin{env}| for \verb|\item| lists \\
+\keyword{BEGIN\_PICTURE\_CC} & \verb|\begin{pic}()()| \\
+\keyword{END\_LIST\_ENV} & \verb|\end{env}| for \verb|\item| lists \\
+\keyword{END\_PICTURE} & \verb|\end{pic}| \\
+\keyword{PICTURE\_CCPP} & \verb|\pic()(){}{}| \\
+\keyword{PICTURE\_CO} & \verb|\pic()[]| \\
+\keyword{PICTURE\_COP} & \verb|\pic()[]{}| \\
+\keyword{PICTURE\_CP} & \verb|\pic(){}| \\
+\keyword{PICTURE\_OCC} & \verb|\pic[]()()| \\
+\keyword{PICTURE\_OCCC} & \verb|\pic[]()()()| \\
+\keyword{PICTURE\_OCO} & \verb|\pic[]()[]| \\
+\keyword{PICTURE\_PCOP} & \verb|\pic{}()[]{}| \\
+\keyword{SECTIONING} & \verb|\command| for a document section \\
+\keyword{COMMAND\_OOP} & \verb|\com[][]{}| \\
+\keyword{COMMAND\_OOOPP} & \verb|\com[][][]{}{}| \\
+\keyword{COMMAND\_OPO} & \verb|\com[]{}[]| \\
+\keyword{COMMAND\_POOOP} & \verb|\com{}[][][]{}| \\
+\keyword{COMMAND\_POOP} & \verb|\com{}[][]{}| \\
+\keyword{COMMAND\_POOPP} & \verb|\com{}[][]{}{}| \\ \hline
+\end{tabular}
+\end{table}
+
+ A \keyword{BEGIN\_LIST\_ENV} specification should include at least a
+\keyword{START\_ITEM=} command. The other \keyword{\_ITEM\_} commands
+are optional.
+Other commands follow the rules for the general command types.
+
+ The potential commands for the \keyword{\_PICTURE\_} commands are the same as
+for the general commands, with the exception that commands related to optional
+argument processing are not available for use.
+
+ A \keyword{SECTIONING} command specification must include a
+\keyword{SECTIONING\_LEVEL=}
+command. Other commands follow the rules for the general command types.
+
+ The keywords for the special command types are given in
+Table~\ref{tab:specct}.
+
+\begin{table}[htbp]
+\centering
+\caption{Special command type keywords.} \label{tab:specct}
+\begin{tabular}{|l|c|} \hline
+Keyword & \LaTeX\ command form \\ \hline
+\keyword{SPECIAL} & reserved for possible future use \\
+\keyword{SPECIAL\_BEGIN\_ENV} & \verb|\begin{env}| except for \verb|\item| lists \\
+\keyword{SPECIAL\_BEGIN\_LIST} & \verb|\begin{env}| for \verb|\item| lists \\
+\keyword{SPECIAL\_COMMAND} & \verb|\command| \\
+\keyword{SPECIAL\_END\_ENV} & \verb|\end{env}| except for \verb|\item| lists \\
+\keyword{SPECIAL\_END\_LIST} & \verb|\end{env}| for \verb|\item| lists \\
+\keyword{SPECIAL\_SECTIONING} & \verb|\command| for a document section \\ \hline
+\end{tabular}
+\end{table}
+
+ Apart from the general restrictions on the allowed commands within
+a specification, there are no restrictions on the commands that can be
+included within the specification of a \keyword{SPECIAL\_} command. It is up
+to the creator of the special to decide what is appropriate. However,
+each \keyword{SPECIAL\_} specification must include the command
+\begin{verbatim}
+SPECIAL_TOKEN= N
+\end{verbatim}
+where \keytext{N} is an integer number (with $10000 \leq N \leq 32767$ for a
+grammar special, or $N > 50000$ for a code special) that has been specified
+within \lx\ as being identified with the grammar and actions corresponding to the
+value of the \keyword{NAME=} command for the \keyword{SPECIAL\_}.
+
+\subsection{Tag specification commands}
+
+\subsubsection{Arguments}
+
+ The commands relating to the specification of \LaTeX\ command arguments
+are given in Table~\ref{tab:param}.
+
+\begin{table}[htbp]
+\centering
+\caption{Argument commands.} \label{tab:param}
+\begin{tabular}{|l|c|} \hline
+Command & Value \\ \hline
+\keyword{OPT\_PARAM=} & \keyword{FIRST} or \keyword{LAST} \\
+\keyword{REQPARAMS=} & Integer. The number of required arguments \\ \hline
+\end{tabular}
+\end{table}
+
+ The \keyword{OPT\_PARAM=} command specifies that the \LaTeX\ command takes one
+optional argument and it is the \keyword{FIRST} or \keyword{LAST} in the argument
+list.
+
+ The \keyword{REQPARAMS=} command specifies that the \LaTeX\ command has
+\verb|Integer| number of required arguments. \verb|Integer| must be between
+one and nine\footnote{Or eight if \keyword{OPT\_PARAM=} is specified.} inclusive.
+
+ Absence of these commands implies that the relevant \LaTeX\ command has
+no arguments of the unspecified kind.
+
+\subsubsection{Tag actions}
+
+ The commands for specifying the tag actions are summarized in
+Table~\ref{tab:tag}.
+The \keyword{\_ITEM\_} commands can only be used within a
+\keyword{BEGIN\_LIST\_ENV} or a \keyword{SPECIAL\_} command specification.
+
+\begin{table}[htbp]
+\centering
+\caption{Tag commands.} \label{tab:tag}
+\begin{tabular}{|l|c|} \hline
+Command & Application \\ \hline
+\keyword{END\_ITEM=} & actions after \verb|\item| text \\
+\keyword{END\_ITEM\_PARAM=} & actions after \verb|\item| optional argument \\
+\keyword{END\_OPT=} & actions after optional argument \\
+\keyword{END\_TAG=} & actions after all arguments processed \\
+\keyword{END\_TAG\_n=} & actions after n'th required argument \\
+\keyword{START\_ITEM=} & actions before \verb|\item| \\
+\keyword{START\_ITEM\_PARAM=} & actions before \verb|\item| optional argument \\
+\keyword{START\_OPT=} & actions before optional argument \\
+\keyword{START\_TAG=} & actions at start of command \\
+\keyword{START\_TAG\_n=} & actions before n'th required argument \\ \hline
+\end{tabular}
+\end{table}
+
+
+
+ Each of these commands can specify a list of actions to be performed;
+typically this is just to print a text string. A string is any set of
+characters enclosed in double
+quote marks. The string can include any special printing characters. The
+text string starts immediately after the first double quote and ends immediately
+before the last double quote. The string cannot include a physical linebreak
+within the \ctab\ file. If the first action is to print a string then the
+string may be placed on the same line as the keyword.
+
+ The actions are listed one per line and are performed in the order they
+are listed. Table~\ref{tab:tagaction} lists the action commands.
+
+\begin{table}[htbp]
+\centering
+\caption{Tag actions.} \label{tab:tagaction}
+\begin{tabular}{|l|l|l|} \hline
+Keyword & Value & Application \\ \hline
+\keyword{STRING:} & text string & Print the string \\
+\keyword{SOURCE:} & \keyword{BUFFER} \keytext{num} & Print the contents of
+ buffer number \keytext{num} \\
+\keyword{SOURCE:} & \keyword{FILE} \keytext{name} & Print the contents of file
+\keytext{name} \\
+\keyword{SOURCE:} & \keyword{SYSBUF} & Print the contents of the system buffer \\
+\keyword{RESET\_BUFFER:} & \keytext{num} & Reset the buffer \keytext{num} \\
+\keyword{RESET\_FILE:} & \keytext{name} & Reset the file \keytext{name} \\
+\keyword{RESET\_SYSBUF:} & & Reset the system buffer \\
+\keyword{SWITCH\_TO\_BUFFER:} & \keytext{num} & Print to buffer number \keytext{num} \\
+\keyword{SWITCH\_TO\_FILE:} & \keytext{name} & Print to file called \keytext{name} \\
+\keyword{SWITCH\_TO\_SYSBUF:} & & Print to the system buffer \\
+\keyword{SWITCH\_BACK:} & & Reset the print mode \\
+\keyword{SET\_MODE:} & \keytext{name} & Set the mode to \keytext{name} \\
+\keyword{RESET\_MODE:} & & Reset the mode to its prior value \\
+\keyword{CODE:} & & Start of a set of \ExpressA{} statements \\ \hline
+\end{tabular}
+\end{table}
+
+\subsubsection{Print control}
+
+ The print control commands are summarized in Table~\ref{tab:print}.
+These are used to set the print mode at the start and end of a command, and for
+each argument. The exception is the \keyword{PRINT\_CONTROL=} command
+which can only be used within an \keyword{OTHER\_} command type
+specification, and which is the only print control that can be
+specified for the \keyword{OTHER\_} commands.
+
+\begin{table}[htbp]
+\centering
+\caption{Print control commands.} \label{tab:print}
+\begin{tabular}{|l|l|} \hline
+Command & Application \\ \hline
+\keyword{PRINT\_CONTROL=} & printing of \keyword{OTHER\_} commands \\
+\keyword{PC\_AT\_START=} & set printing at start of command \\
+\keyword{PC\_AT\_END=} & set printing at end of command \\
+\keyword{PRINT\_OPT=} & printing of optional argument \\
+\keyword{PRINT\_Pn=} & printing of n'th required argument \\ \hline
+\end{tabular}
+\end{table}
+
+The values that these commands may take are given in Table~\ref{tab:pcvalues}.
+These direct where any print output is to be directed. The default is to
+send all output the the file named as the output on the command line when
+starting \lx.
+
+\begin{table}[htbp]
+\centering
+\caption{Print control values.} \label{tab:pcvalues}
+\begin{tabular}{|l|l|} \hline
+Value & Application \\ \hline
+\keyword{NO\_PRINT} & Do not print at all \\
+\keyword{TO\_SYSBUF} & Print to the system buffer \\
+\keyword{TO\_BUFFER} \keytext{num} & Print to buffer number \keytext{num} \\
+\keyword{TO\_FILE} \keytext{name} & Print to file called \keytext{name} \\
+\keyword{NO\_OP} & Do not do any processing \\
+\keyword{RESET} & Reset the print mode \\ \hline
+\end{tabular}
+\end{table}
+
+ \keyword{NO\_PRINT} and \keyword{NO\_OP} both produce no printed output.
+However, in the \keyword{NO\_OP} case the lexer handles all the processing,
+and effectively just ignores the source document text. In the \keyword{NO\_PRINT}
+case, the source text is processed as normal, but the printing is directed
+to a black hole.
+
+
+
+\subsubsection{Sectioning}
+
+
+ \keyword{SECTIONING} command specifications require a
+\keyword{SECTIONING\_LEVEL=}
+command. The values that this can take are listed in Table~\ref{tab:level}.
+
+\begin{table}[htbp]
+\centering
+\caption{Sectioning level values.} \label{tab:level}
+\begin{tabular}{|l|l|} \hline
+Value & Application \\ \hline
+\keyword{PART} & sectioning equivalent to \verb|\part| \\
+\keyword{CHAPTER} & sectioning equivalent to \verb|\chapter| \\
+\keyword{SECT} & sectioning equivalent to \verb|\section| \\
+\keyword{SUBSECT} & sectioning equivalent to \verb|\subsection| \\
+\keyword{SUBSUBSECT} & sectioning equivalent to \verb|\subsubsection| \\
+\keyword{PARA} & sectioning equivalent to \verb|\paragraph| \\
+\keyword{SUBPARA} & sectioning equivalent to \verb|\subprargraph| \\ \hline
+\end{tabular}
+\end{table}
+
+ A sectioning command specification uses the \keyword{END\_TAG=} text tag differently
+from its use by any other specification. In this case, the tag is printed at
+the closure of the text forming the body of the section of the document. A
+document section is considered to be closed when it is followed by a higher
+level sectioning command. The values in Table~\ref{tab:level} are listed
+in decreasing level. That is, a section at level \keyword{CHAPTER} is at a higher
+level than a section at level \keyword{PARA}.
+
+\begin{description}
+\item[NOTE] For the use of writers of \keyword{SPECIAL\_} command specifications,
+\keyword{SECTIONING\_LEVEL=} can be given some additional values. These are
+\keyword{PARTm2} and \keyword{PARTm1} for levels respectively two and one higher
+than \keyword{PART}, and \keyword{SUBPARAp1} and \keyword{SUBPARAp2} for levels respectively
+one and two lower than \keyword{SUBPARA}.
+\end{description}
+
+\section{System installation} \label{sec:install}
+
+ This section describes how to install the \lx\ program and some of the
+internal size limits within \lx.
+
+
+ The basic \lx\ system requires the following source files:
+\begin{description}
+\item[\file{l2x.l}] the lexer source.
+\item[\file{l2x.y}] the parser source.
+\item[\file{l2xlib.c}, \file{l2xlib.h}] main program and support functions.
+\item[\file{l2xlibtc.h}] header file containing keywords and their
+ representations as strings.
+\item[\file{l2xcom.h}] header file for all system components
+ (except for getopt, srchenv and the interpreter).
+\item[\file{l2xacts.c}, \file{l2xacts.h}] standard action functions.
+\item[\file{l2xusrlb.c}, \file{l2xusrlb.h}] special actions and user-defined functions.
+\item[\file{strtypes.h}] header file with some type definitions.
+\item[\file{getopt.c}, \file{getopt.h}] functions for handling command line
+ options~\cite[Chapter 6]{LIBES93}.
+\item[\file{srchenv.c}, \file{srchenv.h}] functions for searching directories
+ for files~\cite[page 747]{HOLUB90}.
+\end{description}
+
+ The \ExpressA{} interpreter also requires the following files:
+\begin{description}
+\item[\file{l2xistup.c}] the interface between the main part of \lx{}
+ and the interpreter.
+\item[\file{l2xicmon.h}] header file for the interface.
+\item[\file{l2xirtne.c}, \file{l2xistd.c}, \file{l2xidecl.c},
+ \file{l2xistmt.c}, \file{l2xiexpr.c}] the files that contain the code for
+ parsing \ExpressA. Respectively they deal with functions and procedures,
+ the built-in functions, declarations, statements, and expressions.
+\item[\file{l2xiprse.h}] header file for parsing.
+\item[\file{l2xixutl.c}, \file{l2xiexec.h}] utility routines
+ supporting the execution module and
+ for managing the interpreter's stack.
+\item[\file{l2xixstd.c}, \file{l2xixstm.c}, \file{l2xixxpr.c}] functions for
+ executing the \ExpressA{} built in functions, statements and expressions.
+\item[\file{l2xirexp.c}, \file{l2xirexpr.h}] general functions for processing
+ and executing regular expressions.
+\item[\file{listsetc.c}, \file{listsetc.h}] general functions for processing
+ lists.
+\item[\file{l2xiscan.c}, \file{l2xiscan.h}] lexing routines for the interpreter.
+\item[\file{l2xisymt.c}, \file{l2xisymt.h}] routines for managing the
+ interpreter's symbol tables.
+\item[\file{l2xidbug.c}] the source level debugger.
+\item[\file{l2xierr.c}, \file{l2xierr.h}] \ExpressA{} language error handling
+ and diagnostic output for the user.
+\item[\file{l2xiidbg.c}, \file{l2xiidbg.h}, \file{l2xisdcl.c}] diagnostics
+ for a developer of the interpreter.
+\item[\file{licomsym.h}] general header file for the interpreter modules.
+\item[\file{l2xidftc.h}, \file{l2xiertc.h}, \file{l2xisctc.h}, \file{l2xisftc.h}]
+header files containing keywords and their representations as strings.
+\end{description}
+
+The following files may be useful:
+\begin{description}
+\item[\file{man}] the manpage
+\item[\file{printct.c}] a program to print and update \ctab{} files;
+\item[\file{ltx2html.sty}] a \LaTeX{} package file to assist in retagging
+a \LaTeX{} document to an HTML document.
+\end{description}
+
+ Essentially, installing \lx\ consists of processing the file \file{l2x.l}
+through a lexer generator, processing the file \file{l2x.y} through a
+parser generator, and then compiling the results together with the other
+supplied source files.
+
+ The lexer source file \file{l2x.l} and the parser source file
+\file{l2x.y} have to be processed by flex (or equivalent) and bison
+(or equivalent) respectively to generate C code. This code, together
+with the code in the other source files must then be compiled
+and linked to form the executable.
+
+ The executable must then, after suitable testing, be moved to
+its final place in your system and the manpage (file \file{man})
+also copied to its final position in your directory structure.
+
+ Included in the \lx{} distribution are several \ctab{} files. One is
+\file{detex.ct} which provides an example of commands for de-\TeX ing
+a document.\footnote{You may wish to try using \file{detex.ct} on the
+\LaTeX\ source of this document to see what the effect is. This can
+also serve as a check on the system installation.}
+Another is \file{remcom.ct}
+which provides an example of commands to remove comments from a
+\LaTeX\ document. The \ctab{} file \file{bye.ct} replaces a \LaTeX{}
+document by "Goodbye document".
+Another is \file{ltx2x.ct} which does nothing except try and include
+another file named \file{ZiLcH}, which presumably is not on anyone's
+system. Running \lx\ with this file will prompt for another name of a
+file if it cannot find \file{ZiLcH}; enter an existing file (like \file{detex.ct})
+at the prompt.\footnote{This is one way of setting up \lx\ for interactive
+specification of the desired \ctab\ file(s).}
+
+ The \ctab{} file \file{l2h.ct} has proven to be adequate for converting
+the \LaTeX{} source of this manual, and other \LaTeX{} documents without
+pictures and only limited mathematics, into an ASCII file with HTML
+tags instead.
+
+ The file \file{fun.ct} contains some test code for the \ExpressA{}
+interpreter. The contents are similar to the example shown at the end of
+section~\ref{sec:expressa}.
+
+The \file{l2xusrlb} files are skeletons. The system does include
+the functions and parser constructs for the \verb|\GRAMMspecial| and
+\verb|\CODEspecial| commands used as examples previously. The last two
+entries in \file{remcom.ct} are the specification of these, and the
+implementation is as described previously.
+
+\subsection{Command table printing}
+
+ The grammar of the \ctab{} has been changed slightly since the
+initial release of \lx. The utility C program in \file{printct.c} may be used to:
+\begin{itemize}
+\item Pretty-print a \ctab;
+\item Convert an original \ctab{} to one that conforms to the new grammar.
+\end{itemize}
+
+ The syntax for running \file{printct} is:
+\begin{verbatim}
+printct [-D dir_cat_char] [-P path_seperators] [-f table_file] [-t]
+\end{verbatim}
+where elements in square brackets are options. These options are identical
+to the corresponding ones for \lx{} and are as follows:
+\begin{description}
+\item[{\tt -f}] By default, \file{printct} reads the \ctab\ from a file called
+ \file{ltx2x.ct}. If the required \ctab\ is in a file with another name this
+ option is used to change from the default file. For example,
+\begin{verbatim}
+> printct
+\end{verbatim}
+reads a \ctab\ from \verb|ltx2x.ct|, while
+\begin{verbatim}
+> printct -f detex.ct
+\end{verbatim}
+reads a \ctab\ from file \verb|detex.ct|.
+
+\item[{\tt -t}] This generates some diagnostics related to the processing of
+ the \ctab\ file.
+
+\item[{\tt -D}] The value of this option is the character that the operating system
+ uses to catenate directory names to form a path (see~\ref{sec:search}).
+ The default value is a
+ slash (i.e. \verb|/|). The default could be changed to a backslash, for example,
+ by \verb|-D \|.
+
+\item[{\tt -P}] The environment variable (see~\ref{sec:search})
+ contains a list of directories (also known
+ as path names). In the operating system that I use, these are separated by
+ the colon (\verb|:|) character which, together with the semi-colon
+ and space characters, form
+ the \lx\ default separators. The path separator characters can be changed
+ with this option.
+ For example, \verb|-P :| will make the separators be a colon
+ or a space (space is automatically included in the separator list).
+\end{description}
+
+ \file{printct} only reads a single \ctab{} file and outputs the
+pretty-printed and updated version to file \file{printct.lis}. It performs
+a very limited amount of error checking and writes error messages and
+statistics to the file \file{printct.err}.
+
+
+\subsection{A {\tt make} file}
+
+
+ Here is a UNIX \file{make} file~\cite{ORAM91} for the \lx\ system.
+
+\begin{code}
+\begin{verbatim}
+# makefile for program ltx2x --- LaTeX to X autotagger
+#
+##################### Change the following for your setup
+# The compiler
+CC = cc
+
+# We use flex (or equivalent, but not lex) to generate the lexer
+LEX = flex
+# and the options
+LEXFLAGS = -v
+
+# We use bison (or equivalent) to generate the parser
+YACC = bison
+# and the options
+YACCFLAGS = -y -d -v
+
+# Libraries to be used
+LIBS = -ly -ll -lm
+
+# The root directory for the installation (e.g., /usr/local )
+ROOTDIR = /proj/ltx/teTeX033
+
+# Where to place the running code (e.g. /usr/local/bin )
+BINDIR = ${ROOTDIR}/bin
+
+# Where to place the manpage (e.g., /usr/local/man/man1 )
+MANEXT = 1
+MANDIR = ${ROOTDIR}/man/man${MANEXT}
+
+# Just in case you want to change the name of the binary
+# (and then you should also change the man page and documentation).
+# So, do not change this.
+PROG = ltx2x
+
+# Where to place the user documentation (e.g., /usr/local/doc/ltx2x )
+DOCDIR = ${ROOTDIR}/doc/${PROG}
+
+# Where to place the example command tables (e.g., /usr/local/lib/config/ltx2x )
+CTDIR = ${ROOTDIR}/lib/config/${PROG}
+
+# The file copy command (copy but do not delete original)
+COPY = cp
+
+# The file move command (move and delete original)
+MOVE = mv
+
+# The file delete command
+DELETE = rm
+
+# The make directory (hierarchy) command
+MAKEDIR = mkdirhier
+
+# The stream editor command
+SED = sed
+
+# Command to write to the terminal (stdout)
+ECHO = echo
+
+################### You should not have to change anything after this
+
+# The source modules
+L2XSRCS = l2xytab.c l2xlexyy.c l2xlib.c l2xacts.c l2xusrlb.c
+getopt.c srchenv.c
+
+INTSRCS = l2xirtne.c l2xistd.c l2xidecl.c l2xistmt.c l2xiexpr.c
+l2xiscan.c l2xisymt.c l2xierr.c l2xiidbg.c l2xistup.c l2xistm.c
+l2xixxpr.c l2xixstd.c l2xidbug.c l2xisdcl.c l2xirexp.c listsetc.c
+
+# The object modules
+L2XOBJS = l2xytab.o l2xlexyy.o l2xlib.o l2xacts.o l2xusrlb.o
+ getopt.o srchenv.o
+
+INTSRCS = l2xirtne.o l2xistd.o l2xidecl.o l2xistmt.o l2xiexpr.o
+l2xiscan.o l2xisymt.o l2xierr.o l2xiidbg.o l2xistup.o l2xistm.o
+l2xixxpr.o l2xixstd.o l2xidbug.o l2xisdcl.o l2xirexp.o listsetc.o
+
+OBJS = ${L2XOBJS} ${INTOBJS}
+
+# Link object code together into PROG
+ltx2x : ${OBJS}
+ ${CC} -o ${PROG} ${OBJS} ${LIBS}
+
+# Compile C source code into object code
+getopt.o : getopt.c getopt.h
+ ${CC} -c getopt.c
+l2xytab.o : l2xytab.c l2xlib.h l2xusrlb.h l2xacts.h strtypes.h l2xcom.h
+ ${CC} -c l2xytab.c
+l2xlexyy.o : l2xlexyy.c l2xytab.h l2xlib.h l2xusrlb.h l2xcom.h
+ ${CC} -c l2xlexyy.c
+l2xlib.o : l2xlib.c getopt.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xlib.c
+l2xusrlb.o : l2xusrlb.c l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xusrlb.c
+l2xacts.o : l2xacts.c l2xusrlb.h l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xacts.c
+srchenv.o : srchenv.c srchenv.h
+ ${CC} -c srchenv.c
+
+# Generate C code for parsing
+l2xytab.c l2xytab.h: l2x.y
+ @ ${ECHO} "Expect 10 shift/reduce conflicts to be reported"
+ ${YACC} ${YACCFLAGS} l2x.y
+ ${MOVE} y.tab.c l2xytab.c
+ ${MOVE} y.tab.h l2xytab.h
+
+# Generate C code for lexing
+l2xlexyy.c : l2x.l
+ ${LEX} ${LEXFLAGS} l2x.l
+ ${MOVE} lex.yy.c l2xlexyy.c
+
+# the interpreter modules
+
+# compiler flags for analyze and execute modules
+ANLFLAG = -Danalyze
+RUNFLAG = -Dtrace
+
+# interpreter header files
+SOMEH = l2xicmon.h l2xierr.h l2xiscan.h l2xisymt.h licomsym.h l2xiidbg.h
+MOSTH = ${SOMEH} l2xiprse.h
+ALLH = ${MOSTH} l2xicpr.h l2xiexec.h
+
+# interpreter interface
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+# the parser module
+
+l2xirtne.o : l2xirtne.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xirtne.c
+
+l2xistd.o : l2xistd.c ${MOSTH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c l2xistd.c
+
+l2xidecl.o : l2xidecl.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xisdecl.c
+
+l2xistmt.o : l2xistmt.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xistmt.c
+
+l2xiexpr.o : l2xiexpr.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiexpr.c
+
+# the scanner module
+
+l2xiscan.o : l2xiscan.c ${SOMEH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiscan.c
+
+# symbol table module
+
+l2xisymt.o : l2xisymt.c l2xicmon.h l2xierr.h l2xisymt.h licomsym.h l2xiidbg.h
+ ${CC} -c l2xisymt.c
+
+# executor module
+
+l2xixutl.o : l2xixutl.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixutl.c
+
+l2xixstm.o : l2xixstm.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstm.c
+
+l2xixxpr.o : l2xixxpr.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixxpr.c
+
+l2xixstd.o : l2xixstd.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstd.c
+
+l2xidbug.o : l2xidbug.c ${SOMEH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xidbug.c
+
+# error and miscellaneous
+
+l2xisdcl.o : l2xisdcl.c ${SOMEH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xisdcl.c
+
+l2xiidbg.o : l2xiidbg.c ${SOMEH} l2xiexec.h
+ ${CC} -c l2xiidbg.c
+
+l2xirexp.o : l2xirexp.c l2xirexp.h
+ ${CC} -c l2xirexp.c
+
+listsetc.o : listsetc.c listsetc.h
+ ${CC} -c listsetc.c
+
+# only call make install if BINDIR has been set
+install : ltx2x
+ ${MAKEDIR} ${BINDIR}
+ ${MOVE} ${PROG} ${BINDIR}
+
+# Edit the file man to replace DOCUMENTDIR by the actual directory
+# where the user manual is to be placed, and CTDIR by the location
+# of the example command table files.
+# Then copy the manpage to the proper place
+manpage :
+ ${SED} 's!DOCUMENTDIR!${DOCDIR}!; s!CTDIR!${CTDIR}!' man > tman
+ ${MAKEDIR} ${MANDIR}
+ ${COPY} tman ${MANDIR}/${PROG}.${MANEXT}
+
+# Copy the user manuals to the proper place
+doc :
+ ${MAKEDIR} ${DOCDIR}
+ ${COPY} ltx2x.tex ${DOCDIR}/${PROG}.tex
+ ${COPY} ltx2x.ps ${DOCDIR}/${PROG}.ps
+ ${COPY} ltx2x.txt ${DOCDIR}/${PROG}.txt
+ ${COPY} ltx2x.html ${DOCDIR}/${PROG}.html
+
+# Copy the example command tables to their final location
+ctables :
+ ${MAKEDIR} ${CTDIR}
+ ${COPY} ltx2x.ct ${CTDIR}/ltx2x.ct
+ ${COPY} detex.ct ${CTDIR}/detex.ct
+ ${COPY} remcom.ct ${CTDIR}/remcom.ct
+ ${COPY} l2h.ct ${CTDIR}/l2h.ct
+ ${COPY} bye.ct ${CTDIR}/bye.ct
+ ${COPY} fun.ct ${CTDIR}/fun.ct
+
+# Do almost everything except clean up
+all : ltx2x install manpage doc ctables
+
+# call make clean to remove the object files, info from YACC,
+# and the edited version of the manpage
+clean :
+ ${DELETE} *.o
+ ${DELETE} y.output
+ ${DELETE} tman
+
+# Compile the command table printer
+printct : printct.o getopt.o srchenv.o
+ ${CC} -o printct printct.o getopt.o srchenv.o
+
+printct.o : printct.c getopt.h strtypes.h l2xcom.h
+ ${CC} -c printct.c
+\end{verbatim}
+\end{code}
+
+ If you use the above makefile then the first part should be edited
+to reflect your system's configuration. You could do \verb|make all|
+which should do everything for you, except the cleaning up.
+A more conservative approach is recommended. First
+just do \verb|make| which will generate the executable. This can then be
+tested. When all is well do \verb|make install| and \verb|make manpage|
+which will put the executable and the manpage into their final positions.
+Finally, \verb|make clean| will remove the intermediate files generated
+during the build process.
+
+ The above \file{make} file uses flex as the lexer generator. You can use your
+favorite one instead but it must, unlike lex, support exclusive start states.
+Also, bison is used above as the parser generator. Again, you can use your
+favorite one. As far as I am aware, there is nothing remarkable about the
+grammar, except that during early development I exceeded the size limits
+of yacc. The grammar has been simplified since then, so this may no longer
+be a problem. \\
+NOTE: If bison is used it reports that there are 10 shift/reduce
+conflicts. It appears that these can be safely ignored.
+
+ One compilation problem has been noted by Uwe
+Sassenberg\footnote{\texttt{<sassen@hal1.physik.uni-dortmund.de>}}
+on AIX~3.2 and
+IRIX~5.3 systems, but I could not reproduce it on a SunOS 4.1.3 system. This
+is when the main procedure of \lx{} is processing the optional command
+line arguments. For some reason it had difficulties with the C
+\verb|EOF|. The symptom was that the program compiled but when it was
+run
+it sat there absorbing CPU cycles and doing nothing as it had got into
+an infinite \verb|while| loop. The cure was to insert
+the following line of code in file \file{l2xlib.c}:
+\begin{verbatim}
+main(argc,argv)
+...
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv, "l:ty:f:cp:wE:P:D:"))) {
+/* insert this line of code: if (optchar == 255) break; end insert */
+ switch(optchar) {
+...
+\end{verbatim}
+This code line which you may need to insert is supplied as a comment in
+the distributed source.
+
+\subsection{Limits and errors}
+
+ The \lx\ system has some built-in limits which are defined in \file{l2xlib.c}.
+The following is a listing of the relevant sizes.
+
+\begin{description}
+\item[\keyword{CLAUSE\_STACK\_SIZE}] The maximum nesting depth of
+document sectioning. This is set somewhat larger than the number of
+standard \LaTeX\ sectioning command types.
+(Default~10)
+
+\item[\keyword{EVERY\_N\_LINES}] Controls the frequency of printing
+processed line numbers to the terminal.
+(Default~100)
+
+\item[\keyword{LIST\_STACK\_SIZE}] The maximum nesting depth of list
+environments. This is set somewhat larger than the standard \LaTeX\ nesting depth.
+(Default~10)
+
+\item[\keyword{MAX\_BUFFER}] The maximum number of characters that can be held
+in the system buffer, and also the maximum number of characters in a
+pretty-printed output line.
+(Default~2000)
+
+\item[\keyword{MAX\_CT\_STACK}] The maximum nesting depth for included
+\ctab\ files.
+(Default~20)
+
+\item[\keyword{MAX\_ERRORS}] The maximum number of non-fatal errors
+discovered in \ctab\ processing or in source file processing before
+\lx\ quits.
+(Default~10)
+
+\item[\keyword{MAX\_LINE}] The maximum number of characters in a line of
+a \LaTeX\ source file.
+(Default~2000)
+
+\item[\keyword{MAX\_PRINT\_STACK}] The maximum nesting depth for print
+control commands.
+(Default~100)
+
+\item[\keyword{MAX\_TABLE\_ENTRIES}] The maximum number of
+\keyword{TYPE} specifications in a \ctab\ (including the built in
+type specifications).
+(Default~1000)
+
+\item[\keyword{MAX\_TABLE\_LINE}] The maximum number of characters in a line in
+a \ctab\ file.
+(Default~254)
+
+\item[\keyword{MAX\_USER\_BUFFS}] The maximum number of user buffers.
+(Default 20)
+
+\item[\keyword{MAX\_UBUFF\_LEN}] The maximum number of characters that can be
+stored in a user buffer.
+(Default 510)
+
+\item[\keyword{MAX\_USER\_FILES}] The maximum number of user files.
+(Default 16)
+\end{description}
+
+ \lx{} prints out a summary of the program statistices at the end of
+the \file{ltx2x.err} file.
+ If the limits are not suitable for your purposes, then they may be changed and
+the system rebuilt.
+
+ \lx\ can produce a variety of error and warning messages, for example
+when any of the above limits are exceeded. Some of the messages are related
+to command table processing, while others are related to \LaTeX\ document
+processing. Both these kinds of messages are targeted to the normal
+end user. There is another set of messages that are aimed at the implementor
+of new \keyword{SPECIAL\_} commands. An implementor may also find some of the
+debugging options useful if things really fall apart.
+
+
+\subsection{Availability}
+
+ Source code and documentation for \lx\ is available from the
+NIST SOLIS (SC4 On-Line Information Service) system~\cite{RINAUDOT94}
+in directory \\
+\file{/subject/sc4/editing/latex/programs/ltx2x}. \\
+ SOLIS can be accessed by:
+\begin{itemize}
+\item Anonymous ftp to \file{ftp.cme.nist.gov} (\texttt{cd} to \file{/pub/subject/sc4...})
+\item URL \url{http://www.nist.gov/sc4}
+\end{itemize}
+
+ Any comments should be directed to \texttt{apde@cme.nist.gov}.
+
+\subsubsection{Copyright}
+
+ Development of this software was funded by the United States Government
+and is not subject to copyright. It was developed by the
+Manufacturing Systems Integration Division (MSID) of the
+Manufacturing Engineering Laboratory (MEL) of the
+National Institute of Standards and Technology (NIST).
+
+\subsubsection{Disclaimer}
+
+ There is no warranty for the \lx\ software. If the \lx\ software
+is modified by someone else and passed on, NIST requests that the software's
+recipients be notified that what they have is not what NIST distributed.
+
+\begin{description}
+\item[Policies] \mbox{}
+\begin{enumerate}
+\item Anyone may copy and distribute verbatim copies of the
+ source code as received in any medium.
+\item Anyone may modify your copy or copies of the \lx\ source
+ code or any portion of it, and copy and distribute such
+ modifications provided that all modifications are clearly
+ associated with the entity that performs the modifications.
+\end{enumerate}
+
+\item[NO WARRANTY] \mbox{}
+
+ NIST PROVIDES ABSOLUTELY NO WARRANTY. THE \lx\ SOFTWARE IS
+PROVIDED `AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+SHOULD ANY PORTION OF THE \lx\ SOFTWARE PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, INCLUDING ANY
+LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF
+THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY NIST)
+THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+\end{description}
+
+
+\section{A grammar for the \ctab} \label{sec:ctabgrammar}
+
+\subsection{Notation}
+
+ The syntactical constructs used correspond to a derivative of
+the Wirth Syntax Notation (WSN)~\cite{WIRTH77}. The semantics of the
+enclosing braces are:
+\begin{itemize}
+\item curly braces `\texttt{\{ \}}' indicate xero or more repetitions;
+\item square brackets `\texttt{[ ]}' indicate an optional element;
+\item parenthesis `\texttt{( )}' indicates a group;
+\item vertical bar `\texttt{|}' indicates that exactly one of the
+ terms in the expression shall be chosen.
+\end{itemize}
+
+ Here is the grammar for WSN defined in itself.
+\begin{code}
+\begin{verbatim}
+syntax = { production } .
+production = identifier '=' expression '.' .
+expression = term { '|' term } .
+term = factor { factor } .
+factor = identifier | literal | group | option | repetition .
+identifier = character { character } .
+literal = '''' character { character } '''' .
+group = '(' expression ')' .
+option = '[' expression ']' .
+repetition = '{' expression '}' .
+\end{verbatim}
+\end{code}
+
+ We also use the following shorthand notation for particular characters:
+\begin{itemize}
+\item \verb|\c| --- any printable character
+\item \verb|\n| --- the end of line character(s)
+\item \verb|eof| --- the end of file character(s)
+\end{itemize}
+
+\subsection{Grammar}
+
+ First, the keywords. Note that these are case insensitive.
+\begin{code}
+\begin{verbatim}
+AudibleAlertChar = 'AUDIBLE_ALERT_CHAR=' .
+BackspaceChar = 'BACKSPACE_CHAR=' .
+BeginDocument = 'BEGIN_DOCUMENT' .
+BeginDollar = 'BEGIN_DOLAR' .
+BeginEnv = 'BEGIN_ENV' .
+BeginListEnv = 'BEGIN_LIST_ENV' .
+BeginPictureCc = 'BEGIN_PICTURE_CC' .
+BeginVenv = 'BEGIN_VENV' .
+BeginVerb = 'BEGIN_VERB' .
+BeginVerbatim = 'BEGIN_VERBATIM' .
+Buffer = 'BUFFER' .
+CarriageReturnChar = 'CARRIAGE_RETURN_CHAR=' .
+Chapter = 'CHAPTER' .
+CharCommand = 'CHAR_COMMAND' .
+Command = 'COMMAND' .
+CommandOop = 'COMMAND_OOP' .
+CommandOoopp = 'COMMAND_OOOPP' .
+CommandOpo = 'COMMAND_OPO' .
+CommandPooop = 'COMMAND_POOOP' .
+CommandPoop = 'COMMAND_POOP' .
+CommandPoopp = 'COMMAND_POOPP' .
+Comment = 'C=' .
+EndCtfile = 'END_CTFILE=' .
+EndDocument = 'END_DOCUMENT' .
+EndDollar = 'END_DOLAR' .
+EndEnv = 'END_ENV' .
+EndItem = 'END_ITEM=' .
+EndItemParam = 'END_ITEM_PARAM=' .
+EndListEnv = 'END_LIST_ENV' .
+EndMode = 'END_MODE' .
+EndOpt = 'END_OPT=' .
+EndPicture = 'END_PICTURE' .
+EndTag = 'END_TAG=' .
+EndTag1 = 'END_TAG_1=' .
+EndTag2 = 'END_TAG_2=' .
+EndTag3 = 'END_TAG_3=' .
+EndTag4 = 'END_TAG_4=' .
+EndTag5 = 'END_TAG_5=' .
+EndTag6 = 'END_TAG_6=' .
+EndTag7 = 'END_TAG_7=' .
+EndTag8 = 'END_TAG_8=' .
+EndTag9 = 'END_TAG_9=' .
+EndType = 'END_TYPE' .
+EndVenv = 'END_VENV' .
+EndVerb = 'END_VERB' .
+EndVerbatim = 'END_VERBATIM' .
+EscapeChar = 'ESCAPE_CHAR=' .
+File = 'FILE' .
+First = 'FIRST' .
+FormfeedChar = 'FORMFEED_CHAR=' .
+HexChar = 'HEX_CHAR=' .
+HorizontalTabChar = 'HORIZONTAL_TAB_CHAR=' .
+Include = 'INCLUDE=' .
+InMode = 'IN_MODE=' .
+Last = 'LAST' .
+Lbrace = 'LBRACE' .
+Name = 'NAME=' .
+NewlineChar = 'NEWLINE_CHAR=' .
+NoOp = 'NO_OP' .
+NoPrint = 'NO_PRINT' .
+OptParam = 'OPT_PARAM=' .
+OtherBegin = 'OTHER_BEGIN' .
+OtherCommand = 'OTHER_COMMAND' .
+OtherEnd = 'OTHER_END' .
+Para = 'PARA' .
+Paragraph = 'PARAGRAPH' .
+Part = 'PART' .
+Partm1 = 'PARTm1' .
+Partm2 = 'PARTm2' .
+PcAtEnd = 'PC_AT_END=' .
+PcAtStart = 'PC_AT_START=' .
+PictureCcpp = 'PICTURE_CCPP' .
+PictureCo = 'PICTURE_CO' .
+PictureCop = 'PICTURE_COP' .
+PictureCp = 'PICTURE_CP' .
+PictureOcc = 'PICTURE_OCC' .
+PictureOccc = 'PICTURE_OCCC' .
+PictureOco = 'PICTURE_OCO' .
+PicturePcop = 'PICTURE_PCOP' .
+PrintControl = 'PRINT_CONTROL=' .
+PrintP1 = 'PRINT_P1=' .
+PrintP2 = 'PRINT_P2=' .
+PrintP3 = 'PRINT_P3=' .
+PrintP4 = 'PRINT_P4=' .
+PrintP5 = 'PRINT_P5=' .
+PrintP6 = 'PRINT_P6=' .
+PrintP7 = 'PRINT_P7=' .
+PrintP8 = 'PRINT_P8=' .
+PrintP9 = 'PRINT_P9=' .
+PrintOpt = 'PRINT_OPT=' .
+Rbrace = 'RBRACE' .
+Reqparams = 'REQPARAMS=' .
+Reset = 'RESET' .
+ResetBuffer = 'RESET_BUFFER:' .
+ResetMode = 'RESET_MODE:' .
+Sect = 'SECT' .
+Sectioning = 'SECTIONING' .
+SectioningLevel = 'SECTIONING_LEVEL=' .
+SetMode = 'SET_MODE:' .
+SlashSpace = 'SLASH_SPACE' .
+Source = 'SOURCE:' .
+Special = 'SPECIAL' .
+SpecialBeginEnv = 'SPECIAL_BEGIN_ENV' .
+SpecialBeginList = 'SPECIAL_BEGIN_LIST' .
+SpecialCommand = 'SPECIAL_COMMAND' .
+SpecialEndEnv = 'SPECIAL_END_ENV' .
+SpecialEndList = 'SPECIAL_END_LIST' .
+SpecialSectioning = 'SPECIAL_SECTIONING' .
+StartItem = 'START_ITEM=' .
+StartItemParam = 'START_ITEM_PARAM=' .
+StartOpt = 'START_OPT=' .
+StartTag = 'START_TAG=' .
+StartTag1 = 'START_TAG_1=' .
+StartTag2 = 'START_TAG_2=' .
+StartTag3 = 'START_TAG_3=' .
+StartTag4 = 'START_TAG_4=' .
+StartTag5 = 'START_TAG_5=' .
+StartTag6 = 'START_TAG_6=' .
+StartTag7 = 'START_TAG_7=' .
+StartTag8 = 'START_TAG_8=' .
+StartTag9 = 'START_TAG_9=' .
+String = 'STRING:' .
+SubPara = 'SUBPARA' .
+SubParap1 = 'SUBPARAp1' .
+SubParap2 = 'SUBPARAp2' .
+SubSect = 'SUBSECT' .
+SubSubSect = 'SUBSUBSECT' .
+SwitchBack = 'SWITCH_BACL: ' .
+SwitchToBuffer = 'SWITCH_TO_BUFFER: ' .
+SwitchToFile = 'SWITCH_TO_FILE: ' .
+SwitchToSysbuf = 'SWITCH_TO_SYSBUF: ' .
+Sysbuf = 'SYSBUF' .
+TexChar = 'TEX_CHAR' .
+ToBuffer = 'TO_BUFFER' .
+ToFile = 'TO_FILE' .
+ToSysbuf = 'TO_SYSBUF' .
+Type = 'TYPE=' .
+Vcommand = 'VCOMMAND' .
+VerticalTabChar = 'VERTICAL_TAB_CHAR=' .
+\end{verbatim}
+\end{code}
+
+Some utility productions.
+\begin{code}
+\begin{verbatim}
+latex_id = \c { \c } .
+name = \c { \c } .
+text = '"' { \c } '"' .
+Eol = \n .
+digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+integer = digit { digit } .
+ct_file_name = name .
+file_id = name .
+buffer_id = integer .
+mode_id = name .
+\end{verbatim}
+\end{code}
+
+The starting production.
+\begin{code}
+\begin{verbatim}
+table = [ special_chars ] { specification | inclusion | comment } eof .
+\end{verbatim}
+\end{code}
+
+Productions for \keytext{inclusion} and \keytext{comment} and \keytext{eof}.
+\begin{code}
+\begin{verbatim}
+inclusion = Include ct_file_name Eol .
+comment = Comment { \c } Eol .
+eof = EndCtfile { \c } Eol .
+\end{verbatim}
+\end{code}
+
+Productions for \keytext{special\_chars}.
+\begin{code}
+\begin{verbatim}
+special_chars = [ escape ] [ alert ] [ backspace ] [ return ] [ feed ]
+ [ hex ] [ htab ] [ newline ] [ vtab ] { comment } .
+escape = EscapeChar \c Eol Eol .
+alert = AudibleAlertChar \c Eol .
+backspace = BackspaceChar \c Eol .
+return = CarriageReturnChar \c Eol .
+feed = FormfeedChar \c Eol .
+hex = HexChar \c Eol .
+htab = HorizontalTabChar \c Eol .
+newline = NewlineChar \c Eol .
+vtab = VerticalTabChar \c Eol .
+\end{verbatim}
+\end{code}
+
+
+
+Productions for \keytext{specification}.
+\begin{code}
+\begin{verbatim}
+specification = built_in | normal | list | section | special | picture | odd .
+built_in = (Type built_in_type Eol) [ built_in_body ] end_type .
+end_type = EndType Eol .
+built_in_type = BeginDocument | BeginDollar | BeginVerb | BeginVerbatim |
+ EndDocument | EndDollar | EndVerb | EndVerbatim |
+ Lbrace | OtherBegin | OtherCommand | OtherEnd |
+ Paragraph | Rbrace | SlashSpace .
+normal = (Type normal_type Eol) type_name [ normal_body ] end_type .
+type_name = Name latex_id Eol .
+normal_type = BeginEnv | BeginVenv | CharCommand | Command |
+ EndEnv | EndVenv | TexChar | Vcommand .
+list = (Type list_type Eol) type_name [ list_body ] end_type .
+list_type = BeginListEnv | EndListEnv .
+section = (Type Sectioning Eol) type_name [ section_body ] end_type .
+special = (Type special_type Eol) type_name [ special_body ] end_type .
+special_type = Special | SpecialBeginEnv | SpecialBeginList |
+ SpecialCommand | SpecialEndEnv | SpecialEndList |
+ SpecialSectioning .
+picture = (Type picture_type Eol) type_name [ picture_body ] end_type .
+picture_type = BeginPictureCc | EndPicture | PictureCcpp | PictureCo |
+ PictureCop | PictureCp | PictureOcc |
+ PictureOccc | PictureOco | PicturePcop .
+odd = (Type odd_type Eol) type_name [ odd_body ] end_type .
+odd_type = CommandOop | CommandOoopp | CommandOpo |
+ CommandPooop | CommandPoop | CommandPoopp .
+\end{verbatim}
+\end{code}
+
+The \keytext{X\_body} productions.
+\begin{code}
+\begin{verbatim}
+built_in_body = [ basic_body ]
+ { start_mode [ basic_body ] end_mode } .
+start_mode = InMode mode_id Eol .
+end_mode = EndMode Eol .
+normal_body = [ basic_norm_body ]
+ { start_mode [ basic_norm_body ] end_mode } .
+sect_body = [ basic_sect_body ]
+ { start_mode [ basic_sect_body ] end_mode } .
+list_body = [ basic_list_body ]
+ { start_mode [ basic_list_body ] end_mode } .
+picture_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+odd_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+special_body = [ basic_special_body ]
+ { start_mode [ basic_special_body ] end_mode } .
+\end{verbatim}
+\end{code}
+
+
+Note: the ordering of the components of the following
+\keytext{basic\_X\_body} productions is immaterial.
+\begin{code}
+\begin{verbatim}
+basic_body = [ start_it ] [ end_it ] .
+basic_norm_body = [ basic_body ] [ no_req_arg ] [ opt_arg_pos ]
+ { arg_print } { arg_action } .
+basic_sect_body = sect_level [ basic_norm_body ] .
+sect_level = SectioningLevel div_level Eol .
+div_level = Chapter | Para | Part | Partm1 | Partm2 | Sect | Subpara |
+ Subparap1 | Subparap2 | Subsect | Subsubsect .
+basic_defarg_body = [ basic_body ] { arg_print } { arg_action } .
+basic_list_body = [ basic_norm_body ] { item_action } .
+basic_special_body = [ sect_level ] [ basic_list_body ] .
+no_req_arg = Reqparams integer Eol .
+opt_arg_pos = OptParam ( First | Last ) Eol .
+\end{verbatim}
+\end{code}
+
+The \keytext{start\_it} and \keytext{end\_it} productions.
+\begin{code}
+\begin{verbatim}
+start_it = [ start_print ] [start_action ] .
+start_print = PcAtStart ( basic_pc_kind | Reset ) Eol .
+basic_pc_kind = NoPrint | ToSysbuf | print_to_buffer | print_to_file .
+print_to_buffer = ToBuffer buffer_id .
+print_to_file = ToFile file_id .
+start_action = StartTag [ text ] Eol { tag_action } .
+tag_action = ( String text |
+ Source ( Sysbuf | user_buffer | user_file ) |
+ ResetBuffer buffer_id |
+ ResetFile file_id |
+ ResetSysbuf |
+ SwitchToBuffer buffer_id |
+ SwitchToFile file_id |
+ SwitchToSysbuf |
+ SwitchBack |
+ SetMode mode_id |
+ ResetMode )
+ Eol .
+user_buffer = Buffer buffer_id .
+user_file = File file_id .
+end_it = [ end_print ] [ end_action ] .
+end_print = PcAtEnd (basic_pc_kind | Reset) Eol .
+end_action = EndTag [ text ] Eol { tag_action } .
+\end{verbatim}
+\end{code}
+
+The \keytext{arg\_print} productions.
+\begin{code}
+\begin{verbatim}
+arg_print = print_arg_kind (basic_pc_kind | NoOp ) Eol .
+print_arg_kind = PrintOpt | PrintP1 | PrintP2 | PrintP3 | PrintP4 |
+ PrintP5 | PrintP6 | PrintP7 | PrintP8 | PrintP9 .
+\end{verbatim}
+\end{code}
+
+The \keytext{arg\_action} productions.
+\begin{code}
+\begin{verbatim}
+arg_action = arg_tag_kind [ text ] Eol { tag_action } .
+arg_tag_kind = EndOpt | EndTag1 | EndTag2 | EndTag3 | EndTag4 |
+ EndTag5 | EndTag6 | EndTag7 | EndTag8 | EndTag9 |
+ StartOpt | StartTag1 | StartTag2 | StartTag3 | StartTag4 |
+ StartTag5 | StartTag6 | StartTag7 | StartTag8 | StartTag9 .
+\end{verbatim}
+\end{code}
+
+The \keytext{item\_action} productions.
+\begin{code}
+\begin{verbatim}
+item_action = item_tag_kind [ text ] Eol { tag_action } .
+item_tag_kind = EndItem | EndItemParam | StartItem | StartItemParam .
+\end{verbatim}
+\end{code}
+
+ The parser in \lx{} for the \ctab{} is very simple. For each \keyword{TYPE=}
+in the \ctab{} it creates a \keytext{struct} to hold the specification
+data. If any type is multiply defined, then which one will be finally used
+is somewhat random because of the sorting and searching algorithms employed
+internally. No checks are made for multiply defined entries.
+
+ Each command in the \ctab{} starts on a seperate line.
+ The parser reads only as much of a table line as is necessary to parse that
+line according to the first token that it finds on the line. The data in
+each line after parsing is added to the current \keytext{struct} for the
+\LaTeX{} command.
+If any of the command lines within an entry are multiply defined,
+then the latest one will overwrite any earlier ones.
+
+ This line-based parsing means that effectively anything between the
+end of the required data on the line is ignored by the parser, and so could
+be treated as a comment. There is no guarantee that this behaviour will
+be maintained in future releases of \lx.
+
+\section{A grammar for \ExpressA} \label{sec:expgrammar}
+
+ The same WSN notation is used for the grammar for \ExpressA{} as
+for the \ctab{} grammar.
+
+ First the keywords. Note that these are case insensitive. Also
+not all of the keywords have been used in this implementation
+of \ExpressA; those that have not been used are reserved for the
+future.
+
+\begin{code}
+\begin{verbatim}
+ ABS = 'abs' .
+ ABSTRACT = 'abstract' .
+ ACOS = 'acos' .
+ AGGREGATE = 'aggregate' .
+ ALIAS = 'alias' .
+ AND = 'and' .
+ ANDOR = 'andor' .
+ ARRAY = 'array' .
+ AS = 'as' .
+ ASIN = 'asin' .
+\end{verbatim}
+
+\begin{verbatim}
+ ATAN = 'atan' .
+ BAG = 'bag' .
+ BEGIN = 'begin' .
+ BINARY = 'binary' .
+ BLENGTH = 'blength' .
+ BOOLEAN = 'boolean' .
+ BY = 'by' .
+ CALL = 'call' .
+ CASE = 'case' .
+ CONSTANT = 'constant' .
+\end{verbatim}
+
+\begin{verbatim}
+ CONST_E = 'const_e' .
+ CONTEXT = 'context' .
+ COS = 'cos' .
+ CRITERIA = 'criteria' .
+ DERIVE = 'derive' .
+ DIV = 'div' .
+ ELSE = 'else' .
+ END = 'end' .
+ END_ALIAS = 'end_alias' .
+ END_CALL = 'end_call' .
+\end{verbatim}
+
+\begin{verbatim}
+ END_CASE = 'end_case' .
+ END_CODE = 'end_code' .
+ END_CONSTANT = 'end_constant' .
+ END_CONTEXT = 'end_context' .
+ END_CRITERIA = 'end_criteria' .
+ END_ENTITY = 'end_entity' .
+ END_FUNCTION = 'end_function' .
+ END_IF = 'end_if' .
+ END_LOCAL = 'end_local' .
+ END_MODEL = 'end_model' .
+\end{verbatim}
+
+\begin{verbatim}
+ END_NOTES = 'end_notes' .
+ END_OBJECTIVE = 'end_objective' .
+ END_PARAMETER = 'end_parameter' .
+ END_PROCEDURE = 'end_procedure' .
+ END_PURPOSE = 'end_purpose' .
+ END_REALIZATION = 'end_realization' .
+ END_REFERENCES = 'end_references' .
+ END_REPEAT = 'end_repeat' .
+ END_RULE = 'end_rule' .
+ END_SCHEMA = 'end_schema' .
+\end{verbatim}
+
+\begin{verbatim}
+ END_SCHEMA_DATA = 'end_schema_data' .
+ END_TEST_CASE = 'end_test_case' .
+ END_TYPE = 'end_type' .
+ ENTITY = 'entity' .
+ ENUMERATION = 'enumeration' .
+ EOF = 'eof' .
+ EOLN = 'eoln' .
+ ESCAPE = 'escape' .
+ EXISTS = 'exists' .
+ EXP = 'exp' .
+ FALSE = 'false' .
+\end{verbatim}
+
+\begin{verbatim}
+ FIXED = 'fixed' .
+ FOR = 'for' .
+ FORMAT = 'format' .
+ FROM = 'from' .
+ FUNCTION = 'function' .
+ GENERIC = 'generic' .
+ HIBOUND = 'hibound' .
+ HIINDEX = 'hiindex' .
+ IF = 'if' .
+ IMPORT = 'import' .
+\end{verbatim}
+
+\begin{verbatim}
+ IN = 'in' .
+ INSERT = 'insert' .
+ INTEGER = 'integer' .
+ INVERSE = 'inverse' .
+ LENGTH = 'length' .
+ LIKE = 'like' .
+ LIST = 'list' .
+ LOBOUND = 'lobound' .
+ LOINDEX = 'loindex' .
+ LOCAL = 'local' .
+\end{verbatim}
+
+\begin{verbatim}
+ LOG = 'log' .
+ LOG10 = 'log10' .
+ LOG2 = 'log2' .
+ LOGICAL = 'logical' .
+ MOD = 'mod' .
+ MODEL = 'model' .
+ NOT = 'not' .
+ NOTES = 'notes' .
+ NUMBER = 'number' .
+ NVL = 'nvl' .
+\end{verbatim}
+
+\begin{verbatim}
+ OBJECTIVE = 'objective' .
+ ODD = 'odd' .
+ OF = 'of' .
+ ONEOF = 'oneof' .
+ OPTIONAL = 'optional' .
+ OR = 'or' .
+ ORD = 'ord' .
+ OTHERWISE = 'otherwise' .
+ PARAMETERi = 'parameter' .
+ PI = 'pi' .
+\end{verbatim}
+
+\begin{verbatim}
+ PRED = 'pred' .
+ PROCEDURE = 'procedure' .
+ PURPOSE = 'purpose' .
+ QUERY = 'query' .
+ READ = 'read' .
+ READLN = 'readln' .
+ REAL = 'real' .
+ REALIZATION = 'realization' .
+ REFERENCE = 'reference' .
+ REFERENCES = 'references' .
+\end{verbatim}
+
+\begin{verbatim}
+ REMOVE = 'remove' .
+ REPEAT = 'repeat' .
+ RETURN = 'return' .
+ REXPR = 'rexpr' .
+ ROLESOF = 'rolesof' .
+ ROUND = 'round' .
+ RULE = 'rule .
+ SCHEMA = 'schema' .
+ SCHEMA_DATA = 'schema_data' .
+ SELECT = 'select' .
+\end{verbatim}
+
+\begin{verbatim}
+ SELF = 'self' .
+ SET = 'set' .
+ SIN = 'sin' .
+ SIZEOF = 'sizeof' .
+ SKIP = 'skip' .
+ SQRT = 'sqrt' .
+ STRING = 'string' .
+ SUBOF = 'subof' .
+ SUBTYPE = 'subtype' .
+ SUCC = 'succ' .
+\end{verbatim}
+
+\begin{verbatim}
+ SUPERTYPE = 'supertype' .
+ SUPOF = 'supof' .
+ SYSTEM = 'system' .
+ TAN = 'tan' .
+ TEST_CASE = 'test_case' .
+ THE_DAY = 'the_day' .
+ THE_MONTH = 'the_month' .
+ THE_YEAR = 'the_year' .
+ THEN = 'then' .
+ TO = 'to' .
+\end{verbatim}
+
+\begin{verbatim}
+ TRUE = 'true' .
+ TRUNC = 'trunc' .
+ TYPE = 'type' .
+ TYPEOF = 'typeof' .
+ UNIQUE = 'unique' .
+ UNKNOWN = 'unknown' .
+ UNTIL = 'until' .
+ USE = 'use' .
+ USEDIN = 'usedin' .
+ USING = 'using' .
+\end{verbatim}
+
+\begin{verbatim}
+ VALUE = 'value' .
+ VALUE_IN = 'value_in' .
+ VALUE_UNIQUE = 'value_unique' .
+ VAR = 'var' .
+ WHERE = 'where' .
+ WHILE = 'while' .
+ WITH = 'with' .
+ WRITE = 'write' .
+ WRITELN = 'writeln' .
+ XOR = 'xor' .
+\end{verbatim}
+\end{code}
+
+The following rules define various classes of characters which are used in
+constructing the tokens.
+
+\begin{code}
+\begin{verbatim}
+ digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+ digits = digit { digit } .
+ letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' |
+ 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' |
+ 'w' | 'x' | 'y' | 'z' .
+ lparen_not_star = '(' not_star .
+ not_lparen_star = not_paren_star | ')' .
+ not_paren_star = letter | digit | not_paren_star_special .
+ not_paren_star_quote_special = '!' | '"' | '#' | '$' | '%' | '&' | '+' |
+ ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' |
+ '@' | '[' | '\' | ']' | '^' | '_' | '`' | '{' | '|' | '}' |
+ '~' .
+ not_paren_star_special = not_paren_star_quote_special | '''' .
+ not_quote = not_paren_star_quote_special | letter | digit | '(' | ')' | '*' .
+ not_rparen = not_paren_star | '*' | '(' .
+\end{verbatim}
+
+\begin{verbatim}
+ not_star = not_paren_star | '(' | ')' .
+ octet = hex_digit hex_digit .
+ special = not_paren_star_quote_special | '(' | ')' | '*' | '''' .
+ star_not_rparen = '*' not_rparen .
+\end{verbatim}
+\end{code}
+
+
+ The following rules specify how certain combinations of characters are
+interpreted as lexical elements within the language.
+
+\begin{code}
+\begin{verbatim}
+ integer_literal = digits .
+ real_literal = digits '.' [ digits ] [ 'e' [ sign ] digits ] .
+ simple_id = letter { letter | digit | '_' } .
+ simple_string_literal = \q { ( \q \q ) | not_quote | \s | \o } \q .
+\end{verbatim}
+\end{code}
+
+The following rules specify the syntax of comments in \ExpressA.
+
+
+\begin{code}
+\begin{verbatim}
+ embedded_remark = '(*' { not_lparen_star | lparen_not_star |
+ star_not_rparen | embedded_remark } '*)' .
+ remark = embedded_remark | tail_remark .
+ tail_remark = '--' { \a | \s | \o } \n .
+\end{verbatim}
+\end{code}
+
+
+The following rules represent identifiers which are known to have a particular
+meaning (i.e., to be declared elsewhere as types or functions, etc.).
+
+
+
+\begin{code}
+\begin{verbatim}
+ attribute_ref = attribute_id .
+ constant_ref = constant_id .
+ entity_ref = entity_id .
+ enumeration_ref = enumeration_id .
+ function_ref = function_id .
+ parameter_ref = parameter_id .
+ procedure_ref = procedure_id .
+ type_ref = type_id .
+ variable_ref = variable_id .
+\end{verbatim}
+\end{code}
+
+
+
+ The following rules specify how the previous lexical elements may be
+combined into constructs of \ExpressA. White space and/or remark(s) may appear
+between any two tokens in these rules. The primary syntax rule for \ExpressA{}
+is \verb|express_a|.
+
+
+
+\begin{code}
+\begin{verbatim}
+ actual_parameter_list = '(' parameter { ',' parameter } ')' .
+ add_like_op = '+' | '-' | OR | XOR .
+ aggregation_types = array_type | bag_type | list_type | set_type .
+ algorithm_head = { declaration } [ local_decl ] .
+ array_type = ARRAY bound_spec OF base_type .
+ assignment_stmt = general_ref { qualifier } ':=' expression ';' .
+ attribute_decl = attribute_id .
+ attribute_id = simple_id .
+ attribute_qualifier = '.' attribute_ref .
+ bag_type = BAG [ bound_spec ] OF base_type .
+\end{verbatim}
+
+\begin{verbatim}
+ base_type = aggregation_types | simple_types | named_types .
+ boolean_type = BOOLEAN .
+ bound_1 = numeric_expression .
+ bound_2 = numeric_expression .
+ bound_spec = '[' bound_1 ':' bound_2 ']' .
+ built_in_constant = CONST_E | PI | THE_DAY | THE_MONTH | THE_YEAR | '?' .
+ built_in_function = ABS | COS | EOF | EOLN | EXISTS | EXP |
+ HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX |
+ LOG | LOG2 | LOG10 | NVL | ODD | ORD | PRED |
+ REXPR | ROUND | SIN | SIZEOF |
+ SQRT | SUCC | TAN | TRUNC .
+ built_in_procedure = INSERT | PRINT | PRINTLN | READ | READLN | REMOVE |
+ SYSTEM | WRITE | WRITELN .
+ case_action = case_label { ',' case_label } ':' stmt .
+ case_label = expression .
+\end{verbatim}
+
+\begin{verbatim}
+ case_stmt = CASE selector OF { case_action } [ OTHERWISE ':' stmt ]
+ END_CASE ';' .
+ compound_stmt = BEGIN stmt { stmt } END ';' .
+ constant_factor = built_in_constant .
+ constructed_types = enumeration_type .
+ declaration = entity_decl | function_decl | procedure_decl | type_decl .
+ entity_body = { explicit_attr } .
+ entity_decl = entity_head entity_body END_ENTITY ';' .
+ entity_head = ENTITY entity_id ';' .
+ entity_id = simple_id .
+ enum_id = simple_id .
+\end{verbatim}
+
+\begin{verbatim}
+ enumeration_reference = enum_id .
+ enumeration_type = ENUMERATION OF '(' enum_id { ',' enum_id } ')' .
+ escape_stmt = ESCAPE ';' .
+ explicit_attr = attribute_decl { ',' attribute_decl } ':' base_type ';' .
+ express_a = { declaration } [ local_decl ] { stmt } END_CODE .
+ expression = simple_expression [ rel_op_extended simple_expression ] .
+ factor = simple_factor [ '**' simple_factor ] .
+ formal_parameter = parameter_id { ',' parameter_id } ':' parameter_type .
+ function_call = ( built_in_function | function_ref )
+ [ actual_parameter_list ] .
+ function_decl = function_head [ algorithm_head ] stmt { stmt }
+ END_FUNCTION ';' .
+\end{verbatim}
+
+\begin{verbatim}
+ function_head = FUNCTION function_id [ '(' formal_parameter
+ { ';' formal_parameter } ')' ] ':' parameter_type ';' .
+ function_id = simple_id .
+ generalized_types = general_aggregation_types .
+ general_aggregation_types = general_array_type | general_bag_type |
+ general_list_type | general_set_type .
+ general_array_type = ARRAY [ bound_spec ] OF parameter_type .
+ general_bag_type = BAG [ bound_spec ] OF parameter_type .
+ general_list_type = LIST [ bound_spec ] OF parameter_type .
+ general_ref = parameter_ref | variable_ref .
+ general_set_type = SET [ bound_spec ] OF parameter_type .
+ if_stmt = IF logical_expression THEN stmt { stmt } [ ELSE stmt { stmt } ]
+ END_IF ';' .
+\end{verbatim}
+
+\begin{verbatim}
+ increment = numeric_expression .
+ increment_control = variable_id ':=' bound_1 TO bound_2 [ BY increment ] .
+ index = numeric_expression .
+ index_1 = index .
+ index_2 = index .
+ index_qualifier = '[' index_1 [ ':' index_2 ] ']' .
+ integer_type = INTEGER .
+ interval = '{' interval_low interval_op interval_item interval_op
+ interval_high '}' .
+ interval_high = simple_expression .
+ interval_item = simple_expression .
+\end{verbatim}
+
+\begin{verbatim}
+ interval_low = simple_expression .
+ interval_op = '<' | '<=' .
+ list_type = LIST [ bound_spec ] OF base_type .
+ literal = integer_literal | logical_literal | real_literal |
+ string_literal .
+ local_decl = LOCAL local_variable { local_variable } END_LOCAL ';' .
+ local_variable = variable_id { ',' variable_id } ':' parameter_type ';' .
+ logical_expression = expression .
+ logical_literal = FALSE | TRUE | UNKNOWN .
+ logical_type = LOGICAL .
+ multiplication_like_op = '*' | '/' | DIV | MOD | AND | '||' .
+\end{verbatim}
+
+\begin{verbatim}
+ named_types = entity_ref | type_ref .
+ null_stmt = ';' .
+ numeric_expression = simple_expression .
+ parameter = expression .
+ parameter_id = simple_id .
+ parameter_type = generalized_types | named_types | simple_types .
+ population = entity_ref .
+ primary = literal | ( qualifiable_factor { qualifier } ) .
+ procedure_call_stmt = ( built_in_procedure | procedure_ref )
+ [ actual_parameter_list ] ';' .
+ procedure_decl = procedure_head [ algorithm_head ] { stmt } END_PROCEDURE ';' .
+\end{verbatim}
+
+\begin{verbatim}
+ procedure_head = PROCEDURE procedure_id [ '(' [ VAR ] formal_parameter
+ { ';' [ VAR ] formal_parameter } ')' ] ';' .
+ procedure_id = simple_id .
+ qualifiable_factor = attribute_ref | constant_factor | function_call |
+ general_ref | population .
+ qualifier = attribute_qualifier | index_qualifier .
+ real_type = REAL .
+ referenced_attribute = attribute_ref | qualified_attribute .
+ rel_op = '<' | '>' | '<=' | '>=' | '<>' | '=' | ':<>:' | ':=:' .
+ rel_op_extended = rel_op | IN | LIKE .
+ repeat_control = [ increment_control ] [ while_control ] [ until_control ] .
+ repeat_stmt = REPEAT repeat_control ';' stmt { stmt } END_REPEAT ';' .
+\end{verbatim}
+
+\begin{verbatim}
+ return_stmt = RETURN [ '(' expression ')' ] ';' .
+ selector = expression .
+ set_type = SET [ bound_spec ] OF base_type .
+ sign = '+' | '-' .
+ simple_expression = term { add_like_op term } .
+ simple_factor = enumeration_reference | interval |
+ ( [ unary_op ] ( '(' expression ')' | primary ) ) .
+ simple_types = integer_type | logical_type | real_type | string_type .
+ skip_stmt = SKIP ';' .
+ stmt = assignment_stmt | case_stmt | compound_stmt | escape_stmt |
+ if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt |
+ skip_stmt .
+ string_literal = simple_string_literal .
+\end{verbatim}
+
+\begin{verbatim}
+ string_type = STRING .
+ term = factor { multiplication_like_op factor } .
+ type_decl = TYPE type_id '=' underlying_type ';' END_TYPE ';' .
+ type_id = simple_id .
+ unary_op = '+' | '-' | NOT .
+ underlying_type = constructed_types | aggregation_types | simple_types |
+ type_ref .
+ until_control = UNTIL logical_expression .
+ variable_id = simple_id .
+ while_control = WHILE logical_expression .
+\end{verbatim}
+\end{code}
+
+
+
+
+\addcontentsline{toc}{section}{References}
+%\bibliography{refs,prw}
+
+\begin{thebibliography}{10}
+
+\bibitem{LAMPORT94}
+Leslie Lamport.
+\newblock {\em LaTeX: A Document Preparation System}.
+\newblock Addison-Wesley Publishing Company, second edition, 1994.
+
+\bibitem{KNUTH84a}
+Donald~E. Knuth.
+\newblock {\em The TeXbook}.
+\newblock Addison-Wesley Publishing Company, 1984.
+
+\bibitem{STEPIS}
+ISO 10303.
+\newblock {\em Industrial automation systems and integration --- Product data
+ representation and exchange}, 1994.
+
+\bibitem{GOLDFARB90}
+C.~A. Goldfarb.
+\newblock {\em The SGML Handbook}.
+\newblock Oxford University Press, 1990.
+\newblock (Edited and with a foreword by Yuri Rubinsky).
+
+\bibitem{MUSCIANO96}
+Chuck Musciano and Bill Kennedy.
+\newblock {\em {HTML --- The Definitive Guide}}.
+\newblock O'Reilly \& Associates, Inc., 1996.
+
+\bibitem{KERNIGHAN88}
+Brian~W. Kernighan and Dennis~M. Ritchie.
+\newblock {\em The C Programming Language}.
+\newblock Prentice Hall, second edition, 1988.
+
+\bibitem{EBOOK}
+Douglas~A. Schenck and Peter~R. Wilson.
+\newblock {\em Information Modeling the EXPRESS Way}.
+\newblock Oxford University Press (ISBN 0-19-308714-3), 1994.
+
+\bibitem{EXPRESSIS}
+ISO 10303-11:1994.
+\newblock {\em Industrial automation systems and integration --- Product data
+ representation and exchange --- Part 11: Description methods: The EXPRESS
+ language reference manual}, 1994.
+
+\bibitem{LEVINE92}
+John~R. Levine, Tony Mason, and Doug Brown.
+\newblock {\em lex \& yacc}.
+\newblock O'Reilly \& Associates, Inc., second edition, 1992.
+
+\bibitem{LESK75}
+M.~E. Lesk and E.~Schmidt.
+\newblock `{LEX --- A Lexical Analyser Generator}'.
+\newblock In {\em UNIX Programmer's Manual 2}. AT\&T Bell Laboratories, Murray
+ Hill, NJ, 1975.
+
+\bibitem{JOHNSON75}
+S.~C. Johnson.
+\newblock {\em YACC --- Yet Another Compiler Compiler}.
+\newblock C S Technical Report 32, Bell Telephone Laboratories, Murray Hill,
+ NJ, 1975.
+
+\bibitem{EXPRESSITR}
+ISO/TR 10303-12:1997.
+\newblock {\em Industrial automation systems and integration --- Product data
+ representation and exchange --- Part 12: Description method: The EXPRESS-I
+ language reference manual}, 1997.
+
+\bibitem{PRW94b}
+Peter~R. Wilson.
+\newblock {\em `{FLaTTeN: A Program to Flatten LaTeX Source Files}'}.
+\newblock NIST, Gaithersburg, MD 20899, December 1994.
+\newblock (In draft).
+
+\bibitem{LIBES93}
+Don Libes.
+\newblock {\em Obfuscated C and Other Mysteries}.
+\newblock John Wiley \& Sons, Inc., 1993.
+
+\bibitem{HOLUB90}
+A.~I. Holub.
+\newblock {\em Compiler Design in C}.
+\newblock Prentice-Hall, Inc., 1990.
+
+\bibitem{ORAM91}
+Andrew Oram and Steve Talbott.
+\newblock {\em Managing Projects with make}.
+\newblock O'Reilly \& Associates, Inc., second edition, 1991.
+
+\bibitem{RINAUDOT94}
+Gaylen~R. Rinaudot.
+\newblock {\em {The IGES/PDES Organization STEP On-Line Information Service}}.
+\newblock NISTIR 5511, NIST, Gaithersburg, MD 20899, October 1994.
+
+\bibitem{WIRTH77}
+N.~Wirth.
+\newblock `{What Can We Do About the Unnecessary Diversity of Notation for
+ Syntactic Definitions?}'.
+\newblock {\em Communications of the ACM}, 20(11):822--823, November 1977.
+
+\bibitem{MAKR91}
+Ronald Mak.
+\newblock {\em Writing Compilers \& Interpreters --- An Applied Approach}.
+\newblock John Wiley \& Sons, Inc., 1991.
+
+\end{thebibliography}
+
+
+
+\end{document}
diff --git a/support/ltx2x/ltx2x.txt b/support/ltx2x/ltx2x.txt
new file mode 100644
index 0000000000..6d35c48d93
--- /dev/null
+++ b/support/ltx2x/ltx2x.txt
@@ -0,0 +1,7012 @@
+
+
+
+TITLE: LTX2X: A LaTeX to X Auto-tagger
+
+ AUTHOR(S): Peter R. Wilson
+ Catholic University of America
+(This work was performed while a Guest Researcher at the National Institute of
+Standards and Technology)
+
+ Email: pwilson@cme.nist.gov
+
+ DATE: January 1997
+
+
+
+
+ABSTRACT:
+ L2X is a table-driven program that will replace LaTeX commands by user
+defined text. This report describes the beta version of the system. L2X
+supports both a declaritive command style and an interpreted procedural
+language tentatively called EXPRESS-A. Details are given of the program
+functionality including examples. System installation instructions are
+provided.
+
+
+
+
+
+
+
+
+
+SECTION: Introduction
+
+ (sec:introduction)
+
+ LaTeX [ LAMPORT94], which is built on top of TeX [ KNUTH84a], is a
+document tagging system that is very popular in the academic and scientific
+publishing communities because of the high quality typeset material that the
+system outputs for normal text and especially for mathematics.
+
+ In particular, many of the documents forming the International Standard
+ISO 10303, commonly referred to as STEP [ STEPIS], have been written using
+LaTeX as the document tagging language. Lately there have been moves towards
+converting the STEP documents to embody SGML [ GOLDFARB90] rather than LaTeX
+markup. This has led to an interest in the automatic conversion from LaTeX to
+SGML documents. The L2X system is an initial attempt to provide a generic
+capability for converting LaTeX tags into other kinds of tags.
+
+ The L2X system described below is in a beta release state. That is, there
+is probably some more work to be done on it but experience from use is needed
+to determine desirable additional functionality. However, the code has been
+stable for some time. Bug reports or suggested enhancements (especially if the
+suggestions are accompanied by working code) are encouraged, as are
+constructive comments about this document.
+
+ Essentially, L2X reads a file containing LaTeX markup, replaces the LaTeX
+commands by user-defined text, and writes the result out to another file. The
+program operates from a command table that specifies the replacement text. In
+general, no programming knowledge or skills are required to write a command
+table, which L2X will then interpret. Some knowledge of LaTeX is required, but
+no more than is necessary for authoring a LaTeX document.
+
+ L2X has proved capable of performing such functions as:
+
+ o Conversion of documents marked up according to a specific LaTeX
+documentclass to documents tagged according to a specific SGML DTD.
+ o Removal of LaTeX commands to produce deTeXed source.
+ o Conversion of simple LaTeX documents to HTML [ MUSCIANO96] tagged
+documents for publication on the World Wide Web.
+
+
+ The remainder of this introduction gives an overview of the L2X program.
+The command table is described in more detail in section (sec:command-table)
+and information on running the L2X program is provided in section
+(sec:program). Section (sec:expressa) gives an overview of the EXPRESS-A
+language. (Footnote: The overview is necessarily rather brief as I am shortly
+moving to a new place of employment and EXPRESS-A is the latest addition to
+the system.) Although the functionality available through the command table
+facility is suitable for many tasks, especially since an interpreter for the
+EXPRESS-A general programming language is included within L2X, section
+(sec:special) gives details on how the system can be extended for cases where
+this proves to be inadequate.
+
+ The report ends with several appendices. An example command table for
+deTeXing a document is reproduced in (sec:detexing) and some of the issues in
+converting from LaTeX to HTML are discussed in (sec:htmling). The known
+limitations of L2X are listed in (sec:limitations) and a summary of the
+command table facilities are given in (sec:summary). Appendix (sec:install)
+provides instructions on installing the L2X program, together with copyright
+and warranty information. Finally, (sec:ctabgrammar) and
+(sec:expgrammar)provide grammars for the command table and EXPRESS-A,
+respectively.
+
+
+
+
+SUB-SECTION: Overview
+
+
+
+ The intent of Leslie Lamport, the author of LaTeX, was to provide a
+document tagging system that enabled the capture of the logical structure of a
+document. This system uses Donald Knuth's TeX system as its typesetting engine
+[ KNUTH84a], and thus has an inherent capability for high quality typesetting.
+
+
+ All LaTeX commands are distinguished by starting with a backslash (\).
+Generally speaking, the name of a command is a string of alphabetic characters
+(e.g. \acommand). Commands may take arguments. Required arguments are enclosed
+in curly braces (i.e. { and }). Optional arguments are enclosed in square
+brackets (i.e. [ and ]). The general syntax for a command is the command name
+(preceded by a backslash) followed by the argument list with a maximum
+(Footnote: Under very unusual circumstances this limit may be exceeded.) of
+nine arguments.
+
+ The L2X program reads a LaTeX document file and outputs a transformation
+of this file. By default it outputs the normal text while for each LaTeX
+command and argument performs some user-specified actions; typically these
+actions involve the output of specific text corresponding to the particular
+command. The actions are specified in a command table file, written by the
+user, which is read into the L2X system before document processing is begun. A
+command table consists of a listing of the LaTeX commands of interest together
+with the desired actiond for each of these commands and their arguments.
+Different effects may be easily obtained by changing the command table file.
+For example, a simple command table file may be written that will delete all
+the LaTeX commands from a document, resulting in a plain ASCII file with no
+embedded markup. (Footnote: To afficionados, this process is known as de-TeX
+ing.) A more complex command table may be written that will replace LaTeX
+tags with appropriate SGML tags.
+
+ In some circles it is traditional to introduce a programming language by
+providing an example program that prints `Hello world'. In contrast, the
+following command table file called bye.ct, when used in conjunction with a
+typical vanilla LaTeX file, will transform the LaTeX file to a file that
+consists only of the words `Goodbye document'.
+
+
+
+C= bye.ct "Goodbye document" for ltx2x
+
+TYPE= COMMAND
+NAME= \documentclass
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case a LaTeX v2.09 document
+TYPE= COMMAND
+NAME= \documentstyle
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+C= just in case there is no \documentclass/style command
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "Goodbye document"
+ PC_AT_END= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+END_CTFILE= end of bye.ct
+
+
+
+ Essentially the command table instructs L2X what to print for each LaTeX
+command. A command table file consists of a series of commands, one per line
+and introduced by a keyword such as TYPE=. Keywords are case insensitive but
+by convention are written in upper case. Comments in a command table are
+introduced by the keyword C=.
+
+ The main body of a command table consists of the specification of LaTeX
+commands of interest and the actions to be taken for these. Each specification
+commences with the keyword TYPE= and is completed by the keyword END_TYPE, the
+relevant actions being listed between these two keywords.
+
+ L2X treats some LaTeX commands specially; among these are \begin{document}
+and \end{document}. In a command table these are specified by the types TYPE=
+BEGIN_DOCUMENT and TYPE= END_DOCUMENT. The actions at \begin{document} are
+firstly to print the string `Goodbye document' (specified in the line
+START_TAG= "Goodbye document") and secondly to stop printing any output
+(specified in the line PC_AT_END= NO_PRINT).
+
+ By not specifying the END_DOCUMENT entry, the default action is used for
+the \end{document} command.
+
+ The command table entries for the commands \documentclass and
+\documentstyle specify that, if either of these is in the source document,
+then it is to be replaced by the text string "Goodbye document", and then all
+further printing is to be switched off.
+
+ The other three entries in the command table specify the actions for any
+other kind of LaTeX command. The keyword OTHER_BEGIN signifies a LaTeX command
+of the form \begin{name} and OTHER_END signifies a command of the form
+\end{name}. The keyword OTHER_COMMAND signifies any other kind of LaTeX
+command (e.g., \acommand ... ). The actions declared for these are all
+PRINT_CONTROL= NO_PRINT which shuts off any printing of the command or its
+arguments. In the command table bye.ct these are only included to prevent
+printing before the \begin{document}.
+
+ To run L2X with the above command table, type the following (where > is
+assumed to be the system prompt):
+
+> ltx2x -f bye.ct input.tex output.tex
+
+ where bye.ct is the name of the command table, and input.tex and output.tex
+are the names of the input LaTeX file and the resulting processed file
+respectively.
+
+ As an example of a more useful command table file, the following one
+called decomm.ct will remove all LaTeX comments from a typical LaTeX source
+file.
+
+
+
+C= decomm.ct Command table file for ltx2x to de-comment LaTeX source
+
+C= ------------------------------------ set newline characters
+ESCAPE_CHAR= ?
+NEWLINE_CHAR= N
+
+C= ----------------------------------- built in commands
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "\begin{document}"
+END_TYPE
+
+TYPE= END_DOCUMENT
+ START_TAG= "\end{document}"
+END_TYPE
+
+TYPE= BEGIN_VERB
+ START_TAG= "\verb|"
+END_TYPE
+
+TYPE= END_VERB
+ START_TAG= "|"
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "\begin{verbatim}"
+END_TYPE
+
+ TYPE= END_VERBATIM
+ START_TAG= "\end{verbatim}"
+ END_TYPE
+
+TYPE= LBRACE
+ START_TAG= "{"
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= "}"
+END_TYPE
+
+TYPE= PARAGRAPH
+ START_TAG= "?N?N "
+END_TYPE
+
+C= ------------------- define '\item' tags within lists
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "\begin{itemize}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "\begin{enumerate}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "\begin{description}"
+ START_ITEM= "\item"
+ START_ITEM_PARAM= "["
+ END_ITEM_PARAM= "] "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= itemize
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= enumerate
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+END_TYPE
+
+C= --------------------- pass through all other LaTeX commands
+
+TYPE= OTHER_COMMAND
+END_TYPE
+
+TYPE= OTHER_BEGIN
+END_TYPE
+
+TYPE= OTHER_END
+END_TYPE
+
+END_CTFILE= end of file decomm.ct
+
+ In the above command table file, the first pair of commands (ESCAPE_CHAR= and
+NEWLINE_CHAR=) define the character pair that are to be used to signify a
+`newline' within a tag. An example of their use is later in the file in the
+PARAGRAPH command type.
+
+ As indicated above, L2X treats some LaTeX commands specially. These are
+listed next in the command table. The special LaTeX commands are the begin and
+end of the document and verbatim environments, together with the \verb
+command, left and right braces, the \ command, and the L2X PARAGRAPH
+specification. There are default actions for these, but apart from the \
+command the defaults are not appropriate in this case. Above, the actions are
+to replace the LaTeX command by the string forming the LaTeX command. The
+exception is that paragraphs (the PARAGRAPH specification) should start with
+at least one blank line and be indented some spaces.
+
+ The LaTeX \item command is used within lists. L2X has to be told how to
+treat the \item command within each kind of list. This has been done above for
+the itemize, enumerate and description environments.
+
+ The final instructions in the command table file tell L2X to pass through
+the text of all other commands and their arguments. The end of the command
+table file is either the physical end of the file or the command END_CTFILE=,
+whichever comes first. The END_CTFILE= command acts like the C= command in
+that arbitrary text can be put after the command.
+
+ To use the decomm.ct command table to de-comment a LaTeX file, type the
+following (where > is assumed to be the system prompt):
+
+> ltx2x -f decomm.ct input.tex output.tex
+
+ where input.tex and output.tex are the names of the input LaTeX file for
+de-commenting and the resulting de-commented version respectively.
+
+
+
+
+SECTION: The command table file
+
+ (sec:command-table)
+
+ By default, L2X does not output any LaTeX comments. Otherwise, whenever it
+comes across a LaTeX command it looks at the data in the command table file to
+determine what actions it should take. The two most typical actions are either
+to print out the command as read in, or to replace the command by some
+(possibly empty) text.
+
+ Each line in a command table file is either blank or starts with a keyword
+followed by one or more blanks. For example, a comment in the file is a line
+that starts with C= ; the remainder of the line is any comment text. Comments
+may be placed anywhere in the file.
+
+
+
+
+SUB-SECTION: Special print characters in tags
+
+
+
+ L2X is written in C [ KERNIGHAN88]. The C language enables certain
+non-printing characters to be defined. These are typically written in the form
+\c where \ is the C escape character and c is a particular character. L2X
+understands some of these special printing characters and the command table
+enables these to be given non-default values.
+
+ The default escape character (\) may be redefined via the ESCAPE_CHAR=
+command. For example,
+
+ESCAPE_CHAR= ?
+
+ will make the question mark character the escape character. Typically, the
+escape character is changed in most command table s to avoid clashing with the
+LaTeX \ character. The following commands can be used to redefine the C
+special characters. Each of these commands takes a single character as its
+value. If a relevant command is not given, then the default value is used.
+
+ NEWLINE_CHAR= : a new line (default is n)
+
+ HORIZONTAL_TAB_CHAR= : horizontal tab (default is t)
+
+ VERTICAL_TAB_CHAR= : vertical tab (default is v)
+
+ BACKSPACE_CHAR= : backspace (default is b)
+
+ CARRIAGE_RETURN_CHAR= : carriage return (default is r)
+
+ FORMFEED_CHAR= : formfeed (default is f)
+
+ AUDIBLE_ALLERT_CHAR= : beep the terminal (default is a)
+
+ HEX_CHAR= : following characters form the hexadecimal number of the
+character to be printed (default is x) (e.g. ?xA3)
+
+ These command lines are all optional within a command table and their
+ordering is immaterial. However, if any are present then they must be at the
+beginning of the command table.
+
+ The above special characters are useful when specifying the replacement
+text for LaTeX commands.
+
+
+
+
+SUB-SECTION: LaTeX command types
+
+
+
+ The commands for controlling the actions performed on LaTeX commands are
+enclosed between the command lines TYPE= and END_TYPE, as below.
+
+TYPE= CommandType
+ C= a possibly empty set of commands
+END_TYPE
+
+ where CommandType is an L2X keyword signifying the kind of LaTeX command
+being specified.
+
+
+
+
+SUB-SUB-SECTION: Built in command types
+
+
+
+ Some LaTeX commands are pre-defined within L2X. Default actions are
+provided for these but it is recommended that type specifications for each of
+these commands be put in the command table anyway. The keywords for these
+commands are:
+
+ BEGIN_DOCUMENT : Corresponds to the LaTeX command \begin{document}.
+ END_DOCUMENT : Corresponds to the LaTeX command \end{document}.
+ BEGIN_VERBATIM : Corresponds to the LaTeX commands \begin{verbatim} and
+ \begin{verbatim*}.
+ END_VERBATIM : Corresponds to the LaTeX commands \end{verbatim} and
+\end{verbatim*}.
+ BEGIN_VERB : Corresponds to the LaTeX commands \verb and \verb*, together
+with the succeeding character.
+ END_VERB : Corresponds to the appearance of the character that completes
+the LaTeX commands \verb and \verb*.
+ LBRACE : Corresponds to the LaTeX left brace character {.
+ RBRACE : Corresponds to the LaTeX right brace character }.
+ BEGIN_DOLLAR : Corresponds to the LaTeX $ symbol signalling the start of
+an in-text math formula.
+ END_DOLLAR : Corresponds to the LaTeX $ symbol signalling the end of an
+in-text math formula.
+ PARAGRAPH : Corresponds to the LaTeX protocol of a blank line signalling
+the start/end of a paragraph.
+ SLASH_SPACE : Corresponds to the LaTeX \ command.
+ OTHER_COMMAND : Corresponds to any LaTeX command of the form \command not
+specified elsewhere within the command table.
+ OTHER_BEGIN : Corresponds to any LaTeX command of the form
+\begin{environment} not specified elsewhere within the command table.
+ OTHER_END : Corresponds to any LaTeX command of the form
+\end{environment} not specified elsewhere within the command table.
+
+
+ The ordering of these built in type specifications is immaterial. If any
+of the above are not specified within the command table then L2X will use
+their default action. With the exception of the SLASH_SPACE command type, the
+default action is to do nothing (i.e., produce no output). The default action
+for the SLASH_SPACE command type is to output a space.
+
+
+
+
+SUB-SUB-SECTION: Optional command types
+
+
+
+ For the purposes of L2X, LaTeX commands are divided into various classes.
+The keywords for these clases, and the class descriptions, are listed below.
+
+
+
+ TEX_CHAR : Corresponding to LaTeX's special characters (with the
+exception of the $, { and } characters).
+ CHAR_COMMAND : Corresponding to LaTeX commands of the type \c where c is
+a single non-alphabetic character.
+ COMMAND : Corresponding to LaTeX commands of the type \command, where
+command is the name of the command (except for \begin, \end and \item).
+ BEGIN_ENV : Corresponding to LaTeX commands of the type
+\begin{environment} where environment is the name of the environment, except
+for those list environments whose bodies consist of \item commands.
+ END_ENV : Corresponding to LaTeX commands of the type \end{environment},
+with the same restrictions as for BEGIN_ENV.
+ BEGIN_LIST_ENV : Corresponding to LaTeX commands of the type
+\begin{environment} where environment is the name of an environment whose body
+consists of \item commands.
+ END_LIST_ENV : Corresponding to LaTeX commands of the type
+\end{environment} to match BEGIN_LIST_ENV.
+ VCOMMAND : Corresponding to a LaTeX \verb-like command.
+ BEGIN_VENV : Corresponding to the start of a verbatim-like environment.
+ END_VENV : Corresponding to the end of a verbatim-like environment.
+ SECTIONING : Corresponding to LaTeX commands of the type \command, where
+command is a document sectioning command such as chapter or subsection.
+ SPECIAL : Reserved for possible future use.
+ SPECIAL_COMMAND : Corresponding to the COMMAND keyword, except that some
+special output processing is to be defined.
+ SPECIAL_BEGIN_ENV : Corresponding to the BEGIN_ENV keyword, except that
+some special output processing is to be defined.
+ SPECIAL_END_ENV : Corresponding to the END_ENV keyword, except that some
+special output processing is to be defined.
+ SPECIAL_BEGIN_LIST : Corresponding to the BEGIN_LIST_ENV keyword, except
+that some special output processing is to be defined.
+ SPECIAL_END_LIST : Corresponding to the END_LIST_ENV keyword, except that
+some special output processing is to be defined.
+ SPECIAL_SECTIONING : Corresponding to the SECTIONING keyword, except that
+some special output processing is to be defined.
+ _PICTURE_ : Corresponding to some of the LaTeX picture drawing commands.
+ COMMAND_... : Corresponding to some of the LaTeX commands whose
+arrangements of required and optional arguments are untypical.
+
+
+ The ordering of these types within a command table is immaterial.
+
+ Each of the above type specifications requires a NAME= command, whose
+value is the name of the relevant command or environment being specified. For
+example, the following is a (partial) specification of the figure environment
+and the caption command.
+
+
+
+TYPE= BEGIN_ENV
+NAME= figure
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+END_TYPE
+
+TYPE= COMMAND
+NAME= \caption
+END_TYPE
+
+
+
+
+
+
+SUB-SECTION: Command action tags
+
+
+
+ When L2X reads a LaTeX command it performs the following actions:
+
+ (#) Looks up the name of the command or environment in the command table.
+If it is not found, then the appropriate default type is used.
+ (#) Sets the printing mode according to the PC_AT_START= command.
+ (#) Performs the actions specified in the command table by the START_TAG=
+command.
+ (#) Processes any specified arguments to the command.
+ (#) Performs the actions specified in the command table by the END_TAG=
+command.
+ (#) Sets the printing mode according to the PC_AT_END= command.
+
+
+
+
+ NOTES : :
+
+ (#) Except for the default processing of OTHER_ types, it does not output
+the command itself.
+ (#) If a tag action is not specified, then the default action is null
+(e.g., nothing will appear in the output).
+
+
+
+ Within a command table all text strings for output are enclosed within
+double quotes. For example:
+
+START_TAG= "Some "text" string\n another line of text."
+
+
+
+ Assuming that \n means a newline, when this string action is performed by
+L2X it will appear in the output file as:
+
+Some "text" string
+another line of text.
+
+
+
+ A text string starts with the first double quote and ends with the last
+double quote on the command line. A text string has to be written on a single
+line within the command table. C language special print characters can be
+embedded within the text string (e.g. the \n for a newline in the above
+example). Remember that the first section of the command table is used for
+specifying the particular command table version of these.
+
+ If a text string is too long to fit comfortably on a single line in the
+command table, it may be continued via the STRING: command. As many of these
+can be used in succession as required (subject to internal limitations within
+L2X).
+
+ For instance,
+
+START_TAG= "Some "text" string\n"
+ STRING: "another line of text."
+
+ has the same effect as the previous example.
+
+ The following specification is designed to write out the contents of the
+\caption command (Footnote: Strictly speaking, the specification does not do
+this exactly, but this simplified illustration will be corrected in the next
+sections.) , preceded by the word `CAPTION' and followed by at least one blank
+line (assuming that the escape character has been set to ?).
+
+
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+END_TYPE
+
+ Assuming that somewhere in a LaTeX file there is the command
+
+stuff
+\caption{This is a caption.}
+more stuff
+
+ then the expected effect (see footnote) is
+
+stuff
+
+ CAPTION This is a caption.
+
+more stuff
+
+
+
+
+
+
+SUB-SECTION: Argument actions
+
+
+
+ LaTeX commands can take arguments. The text for a required argument is
+enclosed in curly braces, while the text for an optional argument is enclosed
+in square brackets. L2X can be directed to perform actions at the start and
+end of each argument.
+
+ The number of required arguments is specified by the command line
+REQPARAMS= where the value of the command is a digit between 1 and 9
+inclusive.
+
+ L2X assumes that a command can have only one optional argument, and that
+this is either first or last in the argument list. The potential presence of
+an optional argument is indicated by the command line OPT_PARAM=, where the
+value is either the keyword FIRST (for first in the list) or LAST (for last in
+the list).
+
+ The actions to be performed at the start and end of each required argument
+are specified via the commands START_TAG_1= and END_TAG_1= for the first
+required argument, through START_TAG_9= and END_TAG_9= for the ninth argument.
+The actions to be performed at the start and end of the optional argument are
+specified by the command lines START_OPT= and END_OPT=.
+
+ The argument delimiters (the braces or brackets) are not printed.
+
+ In the simplest case, the action is to print a specified text string
+(enclosed in double quotes, and continued with STRING: commands if necessary).
+Other kinds of actions are also possible. An unspecified tag defaults to doing
+no action.
+
+
+
+
+SUB-SUB-SECTION: Print options
+
+
+
+
+
+
+SUB-SUB-SUB-SECTION: Argument processing
+
+
+
+ By default, L2X processes (i.e. outputs as appropriate) the text of a
+argument. Printing of the argument text may be disabled, if required. The
+command line that controls argument printing is of the form PRINT_P1= through
+PRINT_P9= for required arguments and PRINT_OPT= for the optional argument. The
+value of these commands is one from several keywords, the most common being
+NO_PRINT; this switches off printing of the text of the indicated argument.
+Default printing is resumed after the indicated argument.
+
+ Continuing the caption example from earlier, we can now complete it. The
+full syntax of the LaTeX command is:
+
+\caption[optional table of contents entry]{Caption in the text}
+
+ That is, it has one required argument, which prints the caption text both in
+the body of the document and in the table of contents, unless the first
+optional argument is present, in which case its value gets printed in the
+table of contents instead.
+
+ Assume that an instance of the caption command in a document is:
+
+Some stuff
+\caption[Short caption]{Long caption for the body of the text.}
+More stuff
+
+ Recall the previous command table caption specification. The actual output
+from processing this would be
+
+Some stuff
+
+ CAPTION [Short caption]{Long caption for the body of the text.}
+
+More stuff
+
+ because, unless L2X is told that there are command arguments and how they
+should be treated, it will just print them out together with their surrounding
+delimiters.
+
+ The following command table entry will give more acceptable results.
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION "
+ END_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+
+
+ For the above captioning instance, the output will now be:
+
+Some stuff
+
+ CAPTION Long caption for the body of the text.
+
+More stuff
+
+
+
+ The default print mode is to print text to the output file.
+
+ The keywords that can be used to control argument printing are:
+
+ NO_PRINT : Do not print anything.
+ TO_SYSBUF : Print to the L2X system buffer.
+ TO_BUFFER num : Print to the L2X buffer number num.
+ TO_FILE name : Print to the file called name.
+ NO_OP : Skip all processing of the argument.
+ Note that even if the print mode is set to NO_PRINT, the argument text will
+still be processed. Only the NO_OP specification temporarly turns off the
+processing.
+
+
+
+
+SUB-SUB-SUB-SECTION: General printing
+
+
+
+ Just as the printing mode can be set for each argument, it can also be set
+at the start and end of processing a LaTeX command or environment.
+
+ The specifications PC_AT_START= and PC_AT_END= can be used to set the
+printing mode at the start of processing a command and at the end,
+respectively. The keywords that can be used in these specifications are:
+
+ NO_PRINT : Do not print anything.
+ TO_SYSBUF : Print to the L2X system buffer.
+ TO_BUFFER num : Print to the L2X buffer number num.
+ TO_FILE name : Print to the file called name.
+ RESET : Reset the print mode back to what it was.
+
+
+ Unlike the argument printing controls, the print mode is not automatically
+reset. This has to be explicitly specified.
+
+ As an example, assume that it is required to remove all figure
+environments from a LaTeX source and put them into a file on their own. The
+following command table code could be used to accomplish this.
+
+TYPE= BEGIN_ENV
+NAME= figure
+ PC_AT_START= TO_FILE allfigs.tex
+ START_TAG= "?n\begin{figure}"
+END_TYPE
+
+TYPE= END_ENV
+NAME= figure
+ START_TAG= "\end{figure}"
+ PC_AT_END= RESET
+END_TYPE
+
+ When a LaTeX figure environment is started, printing is switched to go to the
+file called allfigs.tex. At the end of the figure environment, the print mode
+is reset back to what it was before the environment began. If at the first
+figure environment the allfigs.tex file did not exist, then L2X would create
+it automatically.
+
+
+
+
+SUB-SUB-SUB-SECTION: Read actions
+
+
+
+ As noted above, one of the actions that can be specified for a LaTeX
+comand's argument is to set the print mode for printing to a buffer or a file.
+Similarly there are actions which will read from a buffer or a file and print
+the contents. Within an argument tag these kinds of actions are specified via
+the keyword SOURCE:. This can take one of several values:
+
+ SYSBUF : Print the contents of the L2X system buffer.
+ BUFFER num : Print the contents of the L2X buffer number num.
+ FILE name : Print the contents of the file called name.
+
+
+ In a previous example, the LaTeX figure environments were all written to
+the file allfig.tex. This file could be read in again just before the end of
+the document so that all figures will be typeset after everything else.
+
+TYPE= END_DOCUMENT
+ END_TAG= "?n % figures collected here by LTX2X ?n"
+ SOURCE: FILE allfigs.tex
+ STRING: "?n\end{document}?n"
+END_TYPE
+
+
+
+ As another example of the use of the print actions consider the LaTeX
+\maketitle command. This typesets the arguments of the \title, \author and
+\date commands, which must have been previously specified but not necessarily
+in this ordering. Here is one way this can be simulated using L2X.
+
+TYPE= COMMAND
+NAME= \title
+ START_TAG=
+ RESET_BUFFER: 1
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \author
+ START_TAG=
+ RESET_BUFFER: 2
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 2
+END_TYPE
+
+TYPE= COMMAND
+NAME= \date
+ START_TAG=
+ RESET_BUFFER: 3
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 3
+END_TYPE
+
+TYPE= COMMAND
+NAME= \maketitle
+ START_TAG= "?n"
+ SOURCE: BUFFER 1
+ STRING: "?n?n"
+ SOURCE: BUFFER 2
+ STRING: "?n?n"
+ SOURCE: BUFFER 3
+ STRING: "?n?n"
+ END_TAG=
+ RESET_BUFFER: 1
+ RESET_BUFFER: 2
+ RESET_BUFFER: 3
+END_TYPE
+
+ For the \title command, the print mode for its argument is set for printing
+to the buffer number 1. The single action at the start of the command is to
+make sure that buffer 1 is empty (the line RESET_BUFFER: 1). The actions for
+the \author and \date commands are similar, except that they print their
+argument texts to buffers 2 and 3 respectively.
+
+ The \maketitle command takes no arguments, so all actions must be placed
+under START_TAG= and/or END_TAG=. There are a set of actions specified for
+START_TAG=. Firstly a newline is printed and this is followed by the contents
+of buffer 1 (i.e., the text of the argument of the \title command). Then two
+new lines are printed, followed by the contents of buffer 2 (the author).
+Finally another two newlines are printed, the contents of buffer 3 (the date),
+and another two newlines. The actions for END_TAG= are to clear the contents
+of the three buffers.
+
+ Just to extend the example, here is a specification for the LaTeX \thanks
+command. L2X is not designed to do footnoting (as it does not do page
+breaking) so instead the thanks text will be placed inside parentheses on a
+new line.
+
+TYPE= COMMAND
+NAME= \thanks
+ START_TAG= "?n ("
+ REQPARAMS= 1
+ END_TAG= ") "
+END_TYPE
+
+
+
+ Given these command table specification and the following portion of a
+LaTeX document
+
+\date{29 February 2000}
+\title{The Calculation of Leap Days\thanks{Originally published in JIR}}
+\author{A. N. Other}
+...
+\maketitle
+
+ then output from L2X will be:
+
+The Calculation of Leap Days
+ (Originally published in JIR)
+
+A. N. Other
+
+29 February 2000
+
+ Note that as the \thanks command appears within the argument of the \title
+command, it is written to the same place as the text of the argument of
+\title. Thus, it also gets written to the output file when \maketitle is
+processed.
+
+
+
+
+SUB-SUB-SECTION: Print switching
+
+
+
+ There are individual actions that enable the printing destination to be
+changed at will within the action set for any particular tag.
+
+ SWITCH_TO_BUFFER: num : Direct any following printing to the L2X buffer
+number num.
+ SWITCH_TO_FILE: name : Direct any following printing to the file called
+name.
+ SWITCH_TO_SYSBUF : Direct any following printing to the L2X system
+buffer.
+ SWITCH_BACK: : Undo the effect of the last SWITCH_TO... action.
+
+
+ As an example of the utility of this type of action, consider again the
+LaTeX \maketitle command. When LaTeX processes this command, it typesets the
+date as specified by the \date command, or if this has not been specified then
+it prints the current date instead. We can arrange for L2X to do something
+similar by adding the following to the command table shown earlier for the
+\date and \maketitle commands.
+
+TYPE= COMMAND
+NAME= \documentclass
+ OPT_PARAM= FIRST
+ REQPARAMS= 1
+ PRINT_OPT= NO_PRINT
+ PRINT_P1= NO_PRINT
+ START_TAG=
+ c= Initialise buffer 3 to `Today'
+ RESET_BUFFER: 3
+ SWITCH_TO_BUFFER: 3
+ STRING: "Today"
+ SWITCH_BACK:
+END_TYPE
+
+ At the start of the document, the above actions put the string Today into
+BUFFER 3, having first ensured that it is empty. If the LaTeX source includes
+a \date command, then the contents of the buffer will be overwritten,
+otherwise it will be as initialised. In any event, when the \maketitle command
+is processed, the value output for the date will be either Today or whatever
+the argument was of the \date command.
+
+
+
+
+SUB-SUB-SECTION: Notes on the use of buffers and files
+
+
+
+ Resetting a buffer or a file always has the effect of emptying it of an
+prior contents.
+
+ When printing from a buffer or a file, the entire contents are printed.
+There is no limit to the number of times that a buffer or a file can be used
+as a printing source.
+
+ When printing to a buffer, the new strings are appended at the end of the
+current contents of the buffer, at least until it overflows. Unlike the
+behaviour of files, this is independant of any intervening prints from the
+buffer.
+
+ When printing to a file, the new strings are appended at the end of the
+current contents of the file. However, if a file is printed to after it has
+been printed from, the prior contents of the file are lost, and the new string
+is added at the start of the file. In general, it is safest to treat files as
+either read-only or write-only.
+
+
+
+
+SUB-SUB-SECTION: User specified modes
+
+
+
+ Consider the LaTeX command \\. In normal text this signifies that a line
+break must occur. In a tabular environment, though, it signifies the end of a
+row in a table. Suppose that in the L2X procesing of a tabular environment it
+is required to start and end each row with a vertical bar and to seperate each
+column also with a vertical bar. However, in normal text a \\ command should
+just translate into a newline. Just to complicate matters further, assume that
+in an eqnarray environment, the & column seperator is to be translated to some
+spaces, and that the string `(X)' is to be put at the end of every row.
+
+ In other words, we need to process some commands differently according to
+where they appear in the LaTeX source. An L2X command table provides this
+capability through mode setting and mode-dependent actions. Here is an example
+of using this facility to solve the requirements outlined above.
+
+TYPE= BEGIN_ENV
+NAME= tabular
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: tabular
+END_TYPE
+
+TYPE= END_ENV
+NAME= tabular
+ START_TAG=
+ RESET_MODE:
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= eqnarry
+ C= starting actions, etc., here
+ END_TAG=
+ SET_MODE: eqn
+END_TYPE
+
+TYPE= END_ENV
+NAME= eqnarray
+ START_TAG= " (X)?n"
+ RESET_MODE:
+END_TYPE
+
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " | "
+IN_MODE= eqn
+ START_TAG= " "
+END_MODE
+END_TYPE
+
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+IN_MODE= tabular
+ START_TAG= " |?n"
+ STRING: " | "
+END_MODE
+IN_MODE= eqn
+ START_TAG= " (X)?n"
+END_MODE
+END_TYPE
+
+
+
+ Let us look at the specification for the \tabular environment first. The
+END_TAG= action is specified by the single command line SET_MODE: tabular,
+where tabular is any convenient name for identifying a mode. Thus, this will
+set the mode to be tabular. The action at the end of the environment is to
+reset the mode (RESET_MODE:) to whatever its previous value was. It is assumed
+that the last row in any tabular environment is finished by \\. Similar
+actions are performed for the eqnarray environment, except that the mode is
+called eqn instead of tabular. The other difference is that it is assumed that
+the last row is not ended by \\, so the end of the eqnarray environment has to
+also act like the \\.
+
+ Turning now to the specification for the & command, the first part of the
+specification identifies the type and name of the LaTeX command. This is then
+followed by the mode-independent set of actions, which in this case consists
+of printing a vertical bar with some spaces on either side of it. Following
+these are any mode-dependent actions, bracketed between IN_MODE= and END_MODE.
+The value for IN_MODE= is the name of the relevent mode. In this case the only
+mode-dependent action occurs when MODE eqn is in effect and it is to print
+some spaces instead of the default spaces and vertical bar.
+
+ The specification for the \\ command has its set of mode-independent
+default actions, namely just to print a newline, and two sets of
+mode-dependent actions. When the tabular mode is in effect, it prints some
+spaces, a vertical bar, a newline, more spaces, a vertical bar, and finally
+some more spaces. On the other hand, when the eqn mode is in effect, it prints
+some spaces, the string `(X)' and a newline. If a mode is in effect that is
+not defined within the specification (e.g., mode anon) it performs the default
+mode-independent actions.
+
+ As a perhaps more practical example, the following command table code will
+convert simple LaTeX tabular environments to appropriate mark-up for HTML
+tables. It is assumed that the tabular environment is always within a table
+environment.
+
+ To set the perspective a little, here is the code for a simple table in
+LaTeX:
+
+\begin{table}[tbp]
+\centering
+\caption{A simple table typeset by \LaTeX.} \label{tab:lxtab}
+\begin{tabular}{|l||r|r||r|r|} \hline
+Stock & \multicolumn{2}{c||}{1994} & \multicolumn{2}{c|}{1995} \\ \cline{2-5}
+ & low & high & low & high \\ \hline
+ABC & 27 & 36 & 23 & 45 \\
+DEF & 53 & 72 & 19 & 54 \\
+GHI & 28 & 49 & 17 & 79 \\ \hline
+\end{tabular}
+\end{table}
+
+ This will be typeset as shown in table (tab:lxtab).
+
+ CAPTION: A simple table typeset by LaTeX.
+ (Table: tab:lxtab)
+ Stock | 1994 | 1995
+ | low | high | low | high
+ ABC | 27 | 36 | 23 | 45
+ DEF | 53 | 72 | 19 | 54
+ GHI | 28 | 49 | 17 | 79
+
+
+
+ The corresponding HTML code for the table after translation is:
+
+<p><center><table border>
+<caption>A simple table typeset by LaTeX.</caption> <a name="tab:lxtab"></a>
+
+<tr><td> Stock </td><td colspan=2> 1994 </td><td colspan=2> 1995 </tr>
+<tr><td >
+ </td><td > low </td><td > high </td><td > low </td><td > high </tr>
+<tr><td > ABC </td><td > 27 </td><td > 36 </td><td > 23 </td><td > 45 </tr>
+<tr><td >
+DEF </td><td > 53 </td><td > 72 </td><td > 19 </td><td > 54 </tr>
+<tr><td >
+GHI </td><td > 28 </td><td > 49 </td><td > 17 </td><td > 79 </tr>
+<tr><td >
+</table></center>
+
+
+
+
+
+ In the HTML browser that I use this is displayed approximately as shown
+for table (tab:httab).
+
+
+
+ CAPTION: A simple table typeset after translation to HTML.
+ (Table: tab:httab)
+ Stock | 1994 | 1995
+ | low | high | low | high
+ ABC | 27 | 36 | 23 | 45
+ DEF | 53 | 72 | 19 | 54
+ GHI | 28 | 49 | 17 | 79
+
+
+
+ In HTML a table is enclosed between <table> and </table> tags. Each row of
+the table is enclosed between <tr> and </tr> tags, and each element in a row
+is enclosed between <td> and </td> tags. Under certain circumstances the
+closing tags (i.e., those like </...>) can be inferred by the HTML procesors
+and need not be explicitly put into the source text. The equivalent HTML tags
+to a LaTeX \multicolumn{num}{col}{text} command are
+ <td colspan=num> text </td>.
+
+ The general actions that L2X has to perform in doing the LaTeX to HTML
+translation are:
+
+ o The start and end of a table environment has to translate to the HTML
+start and end table tags <table> and </table>. (Actually this also needs to
+handle the centering of the HTML table and drawing a border round it as well.)
+
+
+
+ o The start and end of the tabular environment has to translate into a row
+start <tr><td> and end </tr> in the HTML table (and set the mode for the LaTeX
+\\ command).
+
+
+ o The \\ command must end one row of the HTML table and start the next row
+(</tr>?n<tr><td>). It need not end a data element as this is automatically
+closed by the end of the row.
+
+
+ o The & column delimeter must end one HTML data element and start another
+one (i.e., </td><td>).
+
+
+ o The difficulty is in handling the \multicolumn command. In the easy case
+the LaTeX to HTML translation is:
+ ... & text & ... maps to
+ ... </td><td> text </td><td> ....
+ However, when a multicolumn is involved the translation is
+ ... & \multicolumn{N}{P}{text} & ... maps to
+ ... </td><td colspan=N> text </td><td> ....
+ As there is no look-ahead in L2X we have to be careful about starting a data
+element after a & because at that point L2X cannot know whether or not a
+\multicolumn command comes next, or just an ordinary data element.
+
+
+
+
+ We solve this last problem partly by using buffers (numbers 8 and 9 in the
+specification below) as temporary storage, and partly by a subtle
+specification for the \multicolumn command.
+
+
+
+C= start of a table
+TYPE= BEGIN_ENV
+NAME= table
+ START_TAG= "<center><table border>"
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+END_TYPE
+
+C= end a table
+TYPE= END_ENV
+NAME= table
+ START_TAG= "</table></center>"
+END_TYPE
+
+C= start a tabular
+TYPE= BEGIN_ENV
+NAME= tabular
+ START_TAG= "?n<tr><td"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ OPT_PARAM= FIRST
+ C= ignore the optional positioning argument
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ C= ignore the column specification
+ PRINT_P1= NO_OP
+ END_TAG=
+ SET_MODE: tabular
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+
+C= end a tabular
+TYPE= END_ENV
+NAME= tabular
+ PC_AT_START= RESET
+ START_TAG= ">"
+ RESET_BUFFER: 8
+ RESET_BUFFER: 9
+ RESET_MODE:
+END_TYPE
+
+C= we can do some processing of the \mutlicolumn command
+TYPE= COMMAND
+NAME= \multicolumn
+ PC_AT_START= TO_BUFFER 8
+ REQPARAMS= 2
+ START_TAG_1= " colspan="
+ PRINT_P2= NO_PRINT
+ PC_AT_END= RESET
+END_TYPE
+
+C= now for the end/start of a row
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "<br>"
+IN_MODE= tabular
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "> "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= "</tr>?n<tr><td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_MODE
+END_TYPE
+
+C= and the column seperator
+TYPE= TEX_CHAR
+NAME= &
+ PC_AT_START= RESET
+ START_TAG=
+ SOURCE: BUFFER 8
+ STRING: "> "
+ RESET_BUFFER: 8
+ SOURCE: BUFFER 9
+ END_TAG= " </td><td "
+ RESET_BUFFER: 9
+ PC_AT_END= TO_BUFFER 9
+END_TYPE
+
+
+
+
+
+ Regarding the \multicolumn specification, we state that as far as L2X is
+concerned, it only has two required parameters, and that the action for the
+second one is NO_PRINT. The first argument is written to buffer 8 after
+`colspan=' has first been put into it. L2X will treat the actual third
+argument to the \multicolumn as ordinary text, just as if there was no
+\multicolumn in the LaTeX source. We use buffer 9 for storing the text of a
+data element. When L2X processes a & column delimeter it first outputs the
+contents of buffer 8 (the number of columns specification) and then
+appropriate HTML characters. It then outputs the contents of buffer 9 (the
+element text), finishes off the element and partially starts the next element.
+Similar actions are performed at the start of the tabular environment and at
+the end of each row in the table.
+
+
+
+
+SUB-SECTION: Sectioning command types
+
+
+
+ L2X does some particular processing for sectioning command types. Although
+LaTeX can determine where any section of a document ends, other tagging
+systems cannot always do this. They require both a `begin section' and an `end
+section' tag. L2X can take account of the nesting depth of document sections
+and, given appropriate specifications, can supply both `begin section' and
+`end section' tags appropriately. This requires a little bit more in the way
+of specifications than we have met so far.
+
+ For a SECTIONING command type, the command line SECTIONING_LEVEL= must be
+included within the specification. The value of this command is a keyword from
+the following list.
+
+ PART : For a sectioning command equivalent to the LaTeX \part command.
+ CHAPTER : For a sectioning command equivalent to the LaTeX \chapter
+command.
+ SECT : For a sectioning command equivalent to the LaTeX \section command.
+
+ SUBSECT : For a sectioning command equivalent to the LaTeX \subsection
+command.
+ SUBSUBSECT : For a sectioning command equivalent to the LaTeX
+\subsubsection command.
+ PARA : For a sectioning command equivalent to the LaTeX \paragraph
+command.
+ SUBPARA : For a sectioning command equivalent to the LaTeX \subparagraph
+command.
+
+
+ When a sectioning command is read from the LaTeX source, L2X firstly
+performs the END_TAG= actions for any `lower level' sections that this one is
+closing off. It then performs the START_TAG= actions for the current command,
+and stores its own END_TAG= actions for later use. It then goes on and process
+any arguments as usual. The END_DOCUMENT command automatically closes off any
+opened sections.
+
+ As an example, assume that some kind soul has supplied a LaTeX style file
+that makes the commands \clause synonymous with \subsection, and \sclause
+synonymous with \subsubsection, etc. Also assume that it is required to output
+start and end tags of the form <div.1> and </div.1> for sections, <div.2> for
+clauses, etc., and surround the headings with tags <heading> and </heading>.
+Further, the first optional argument is of no interest as the output is going
+to be used by a processing system unable to automatically handle tables of
+contents. Part of an appropriate command table for doing this is:
+
+
+
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ END_TAG= "?n</div.1>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "<heading>"
+ END_TAG_1= "</heading>?n"
+END_TYPE
+
+TYPE= SECTIONING
+NAME= \clause
+ SECTIONING_LEVEL= SUBSECT
+ START_TAG= "?n?n<div.2>?n"
+ END_TAG= "?n</div.2>"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ START_TAG_1= "<heading>"
+ END_TAG_1= "</heading>?n"
+END_TYPE
+
+
+
+ An example output resulting from this command table (if it had been
+applied to this document) is:
+
+...
+</div.2>
+</div.1>
+
+<div.1>
+<heading>The command table file</heading>
+
+ By default, ...
+
+
+
+
+
+
+SUB-SECTION: List environment types
+
+
+
+ In LaTeX the use of the \item command is restricted to within a list
+environment. The typeset appearance of an \item typically depends on the
+particular environment in which it is used. L2X has a limited capability of
+modifying its \item tagging output. It can also provide an `end item' tag for
+those tagging systems that require such a thing.
+
+ For such list environments, identified by the command type keyword
+BEGIN_LIST_ENV, the following command lines should be included within the type
+specification.
+
+ START_ITEM= : Actions to be performed at the start of each \item command
+in the list.
+ END_ITEM= : Actions to be performed after processing all the \item's
+text.
+ START_ITEM_PARAM= : Actions to be performed at the start of an \item's
+optional argument text.
+ END_ITEM_PARAM= : Actions to be performed at the end of an \item's
+optional argument text.
+ As usual, an unspecified tag defaults to no actions.
+
+ For example, assume that we are not interested in tagging the end of an
+item, but we do want to mark each item in an itemize environment with the
+lowercase letter `o', each enumerate item with `(N)' and put a colon after the
+optional argument in a description environment. Also, each item should have
+some indentation from the left hand margin.
+
+
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_ITEM= "?n (N) "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+END_TYPE
+
+
+
+ With the above commands, this LaTeX text:
+
+\begin{description}
+\item[An example]
+ \begin{itemize}
+ \item the first item;
+ \item the second item.
+ \end{itemize}
+\end{description}
+
+ will be transformed into:
+
+ An example :
+ o the first item;
+ o the second item.
+
+
+
+
+
+
+SUB-SECTION: Character types
+
+
+
+ LaTeX treats some characters specially. These special characters are: #,
+$, %, &, ~, _, ^, \, {, }, and, under some circumstances, also the character
+@. L2X recognizes these special characters and, if directed, will perform
+specified actions; otherwise it treats them as it treats any alphanumeric
+character, which is just to print it.
+
+ It has already been stated that commands for the left and right braces
+(i.e. { and }) must be given within the command table as command types LBRACE,
+RBRACE respectively. The dollar symbol ($) must also be specified via the two
+command types BEGIN_DOLLAR and END_DOLLAR. Here is an example of replacing the
+dollar signs by tags intended to indicate the start and end of a mathematical
+phrase.
+
+TYPE= BEGIN_DOLLAR
+ START_TAG= "<math>"
+END_TYPE
+
+TYPE= END_DOLLAR
+ START_TAG= "</math>"
+END_TYPE
+
+
+
+ Commands for the other special LaTeX characters are specified with the
+TEX_CHAR command type keyword.
+
+ The characters _ (underscore) and ^ (caret) are used in LaTeX math mode to
+indicate subscripting and superscripting respectively. The following will
+replace ^ by <sup>, print the superscript text (which must be enclosed in
+braces (Footnote: It is good practice to always enclose superscript and
+subscript text in braces, even though TeX does not always require this.) ) and
+at the end close with </sup>.
+
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "<sup>"
+ REQPARAMS= 1
+ END_TAG= "</sup>"
+END_TYPE
+
+
+
+
+
+ Given the above specifications, then $(2^{15} - 1)$ will be transformed
+into
+ <math>(2<sup>15</sup> - 1)</math>.
+
+
+
+
+SUB-SECTION: Verbatim like types
+
+
+
+ The command type VCOMMAND is for the procesing of LaTeX \verb-like
+commands where the argument of the command is to be typeset as-is. For
+example, there might be a command called \url which takes one argument which
+is meant to be an Internet URL. If the application was the conversion of a
+LaTeX document to HTML, then the following specification could be useful.
+
+TYPE= VCOMMAND
+NAME= \url
+ REQPARAMS= 1
+ PRINT_P1= TO_BUFFER 7
+ START_TAG=
+ RESET_BUFFER: 7
+ END_TAG= "<a href=""
+ SOURCE: BUFFER 7
+ STRING: "">"
+ SOURCE: BUFFER 7
+ STRING: "</a>"
+ RESET_BUFFER: 7
+END_TYPE
+
+
+
+ If the LaTeX source included:
+
+... obtainable from
+\url{http://www.cdrom.com/pub/tex}
+
+ then the resulting L2X output would be:
+
+... obtainable from
+<a href="http://www.cdrom.com/pub/tex">http://www.cdrom.com/pub/tex</a>
+
+ which, if this was then read via an appropriate browser, a link to the URL
+would be automatically established.
+
+ Similarly verbatim-like environments can also be specified with the types
+BEGIN_VENV and END_VENV. For example, the html.sty package defines three LaTeX
+environments for documents that might be converted from LaTeX tagging to HTML
+tagging. One of these, latexonly is for LaTeX code that is not to occur in the
+HTMLed document and another is htmlonly which contains HTML code that is
+required for an HTML version of the document but which is not to appear in the
+LaTeX ed document. The third one is rawhtml which is for HTML code to be
+output verbatim to the HTML document source. These could be simulated by:
+
+TYPE= BEGIN_VENV
+NAME= latexonly
+ PC_AT_START= NO_PRINT
+END_TYPE
+
+TYPE= END_VENV
+NAME= latexonly
+ PC_AT_END= RESET
+END_TYPE
+
+TYPE= BEGIN_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= END_ENV
+NAME= htmlonly
+END_TYPE
+
+TYPE= BEGIN_VENV
+NAME= rawhtml
+END_TYPE
+
+TYPE= END_VENV
+NAME= rawhtml
+END_TYPE
+
+
+
+
+
+
+SUB-SECTION: Odd command types
+
+
+
+ The majority of commands in LaTeX that take optional arguments have only a
+single optional argument that is either immediately after the command or after
+all the required arguments. There are, however, some commands that do not fit
+this pattern. This set of command types enables at least some of these `odd'
+commands to be handled.
+
+ The command type keyword is of the form COMMAND_code, where code indicates
+the type and ordering of the arguments. The code is composed from combinations
+of the letters O (for an optional argument) and P (for a required parameter
+(i.e., argument)). The ordering of these letters in the code specifies the
+type and ordering of the command's arguments.
+
+ The `odd' command types are:
+
+ COMMAND_OOP : Corresponding to a LaTeX command of the form
+ \com[OptParam][OptParam]{ReqParam}. For example, the \makebox command falls
+into this category.
+
+
+ COMMAND_OOOPP : Corresponding to a LaTeX command of the form
+ \com[OptParam][OptParam][OptParam]{ReqParam}{ReqParam}. For example, the
+\parbox command falls into this category.
+
+
+ COMMAND_OPO : Corresponding to a LaTeX command of the form
+ \com[OptParam]{ReqParam}[OptParam]. For example, the \RequirePackage and
+\LoadClass commands fall into this category.
+
+
+ COMMAND_POOOP : Corresponding to a LaTeX command of the form
+ \com{ReqParam}[OptParam][OptParam][OptParam]{ReqParam}.
+
+
+ COMMAND_POOP : Corresponding to a LaTeX command of the form
+ \com{ReqParam}[OptParam][OptParam]{ReqParam}. For example, the \newcommand
+and its companion commands fall into this category.
+
+
+ COMMAND_POOPP : Corresponding to a LaTeX command of the form
+ \com{ReqParam}[OptParam][OptParam]{ReqParam}{ReqParam}. For example, the
+\newenvironment and its companion command fall into this category.
+
+
+ As usual, the command name is required, as are any actions. However, it is
+not necessary to specify the number of required arguments (i.e. REQPARAMS=)
+nor the position of the optional argument (i.e. OPT_PARAM=), as L2X already
+has this information. The tag actions are according to the argument ordering
+given in the code and are specified by the required argument tags (e.g.
+START_TAG_n= and END_TAG_n=). Do not use any of the command lines for optional
+arguments. Argument actions are controlled in the usual manner.
+
+ A typical example of the use of these commands is to supress any
+processing of the LaTeX \newcommand and its ilk. For example:
+
+TYPE= COMMAND_POOP
+NAME= \providecommand
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= COMMAND_POOPP
+NAME= \renewenvironment
+ PRINT_P1= NO_OP
+ PRINT_P2= NO_OP
+ PRINT_P3= NO_OP
+ PRINT_P4= NO_OP
+ PRINT_P5= NO_OP
+END_TYPE
+
+
+
+
+
+
+SUB-SECTION: Other command types
+
+
+
+ The OTHER_ command types (OTHER_COMMAND, OTHER_BEGIN and OTHER_END) are
+very limited in what can be affected. Basically, these provide for default
+printing actions if the corresponding LaTeX command has not been identified
+elsewhere in the command table.
+
+ If there are no commands within the specification, the name of the command
+and all its arguments will be printed verbatim.
+
+ The command lines START_TAG= and END_TAG= cause the corresponding actions
+to be performed before and after the name of the command is printed. Any
+arguments are printed verbatim.
+
+ The command line PRINT_CONTROL= with a value of NO_PRINT causes the
+command name not to be printed, nor any arguments that L2X may find associated
+with the command.
+
+
+
+
+SUB-SECTION: Picture types
+
+
+
+ The _PICTURE_ command types differ from all the other types in L2X, just
+as they do in LaTeX. In LaTeX some of the picture drawing commands take
+arguments of the form (number, number), representing a coordinate pair, as
+well as the usual required arguments enclosed in curly braces and possibly an
+optional argument enclosed in square brackets. Within L2X, commands that take
+coordinate arguments are treated specially in the command table.
+
+ Generally speaking, the L2X command types are of the form PICTURE_code,
+where code indicates the type and ordering of the arguments. The code is
+composed from combinations of the letters C (for a coordinate argument), O
+(for an optional argument) and P (for a required argument). For example,
+PICTURE_PCOP indicates a picture command that has a required argument,
+followed by a coordinate argument, followed by an optional argument and
+finally another required argument.
+
+ The provided picture types are:
+
+ BEGIN_PICTURE_CC : Corresponding to a LaTeX command of the form
+ \begin{PictureEnv}(coords)(coords), where the final coordinate argument is
+optional.
+ PICTURE_CCPP : Corresponding to a LaTeX command of the form
+ \com(coords)(coords){ReqParam}{ReqParam}. For example, the \multiput command
+falls into this category.
+ PICTURE_CO : Corresponding to a LaTeX command of the form
+ \com(coords)[OptParam]. For example, the standard LaTeX \oval command falls
+into this category.
+ PICTURE_COP : Corresponding to a LaTeX command of the form
+ \com(coords)[OptParam]{ReqParam}. For example, the \makebox and \framebox
+commands fall into this category.
+ PICTURE_CP : Corresponding to a LaTeX command of the form
+ \com(coords){ReqParam}. For example, the \put, \line and \vector commands
+fall into this category.
+ PICTURE_OCC : Corresponding to a LaTeX command of the form
+ \com[OptParam](coords)(coords). For example, the \graphpaper command from the
+graphpap package falls into this category.
+ PICTURE_OCCC : Corresponding to a LaTeX command of the form
+ \com[OptParam](coords)(coords)(coords). For example, the \qbezier command
+falls into this category.
+ PICTURE_OCO : Corresponding to a LaTeX command of the form
+ \com[OptParam](coords)[OptParam]. For example, the \oval command from the
+pict2e package falls into this category.
+ PICTURE_PCOP : Corresponding to a LaTeX command of the form
+ \com{ReqParam}(coords)[OptParam]{ReqParam}. For example, the \dashbox and
+\savebox commands fall into this category.
+ END_PICTURE : Corresponding to a LaTeX command of the form
+ \end{PictureEnv}.
+
+
+ As usual, the command name is required, as are any actions. However, it is
+not necessary to specify the number of required arguments (i.e. REQPARAMS=)
+nor the position of the optional argument (i.e. OPT_PARAM=), as L2X already
+has this information. The tag actions are according to the argument ordering
+given in the code and are specified by the required argument tags (e.g.
+START_TAG_n= and END_TAG_n=). Do not use any of the command lines for optional
+arguments. Argument actions controlled in the usual manner.
+
+ As an example, the following specifications within a command table should
+be sufficient to ensure that any picture commands in a source file are not
+passed through to the output file.
+
+
+
+TYPE= BEGIN_PICTURE_CC
+NAME= picture
+PRINT_P1= NO_PRINT
+PRINT_P2 = NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_CP
+NAME= \put
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_OP
+END_TYPE
+
+TYPE= PICTURE_CCPP
+NAME= \multiput
+PRINT_P1= NO_PRINT
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_PCOP
+NAME= \savebox
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_OP
+PRINT_P4= NO_OP
+END_TYPE
+
+TYPE= PICTURE_OCC
+NAME= \graphpaper
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+END_TYPE
+
+TYPE= PICTURE_OCCC
+NAME= \qbezier
+PRINT_P1= NO_OP
+PRINT_P2= NO_PRINT
+PRINT_P3= NO_PRINT
+PRINT_P4= NO_PRINT
+END_TYPE
+
+TYPE= END_PICTURE
+NAME= picture
+END_TYPE
+
+
+
+
+
+ NOTE 1: : The action NO_OP cannot be applied to an argument that is a
+coordinate pair.
+
+
+ NOTE 2: : As L2X is essentially limited to printing actions, and cannot
+actually process any LaTeX picture drawing commands, the suppression of
+picture printing is probably the most usual use of the picture commands.
+
+
+
+
+
+SUB-SECTION: Special command types
+
+
+
+ The SPECIAL_ commands, namely SPECIAL_COMMAND, SPECIAL_BEGIN_ENV,
+SPECIAL_BEGIN_LIST, SPECIAL_END_ENV, SPECIAL_END_LIST and SPECIAL_SECTIONING,
+are provided for cases where some special kind of output processing is
+required that is not built into L2X. In order to implement any commands of
+these types, it is necessary to modify the internals of L2X and recompile the
+source code. This is not recommended.
+
+
+
+
+SUB-SECTION: File inclusion
+
+
+
+ A command table file can include other command table files. In turn an
+included file can recursively include other command table files. The file
+inclusion command line is
+
+INCLUDE= FileName
+
+ where FileName is the name of the command table file to be included. The
+effect is that the above line is replaced by the contents of FileName.
+
+ For example, assume that there are three command table files called
+respectively detex.ct, detex.l2x and detex.fl. The contents of these files
+are:
+
+C= ----------file detex.ct
+...
+INCLUDE= detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+
+ and for detex.l2x as:
+
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+INCLUDE= detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+END_CTFILE= end of file detex.l2x
+
+ and lastly detex.fl is:
+
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+END_CTFILE= end file detex.fl
+
+ Then, as far as L2X is concerned, the original detex.ct file is treated as
+though it had been written as:
+
+C= ----------file detex.ct
+...
+C= ---------- file detex.l2x
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+C= ---------- file detex.fl
+
+TYPE= COMMAND
+NAME= \fl
+ START_TAG= "FLaTTeN"
+END_TYPE
+
+C= ---------- end file detex.fl
+
+TYPE= COMMAND
+NAME= \ctab
+ START_TAG= "command table"
+END_TYPE
+
+C= ---------- end of file detex.l2x
+...
+C= ----------end of detex.ct
+END_CTFILE= end of detex.ct
+
+
+
+ Note that nasty things will happen if you have a cycle of inclusions. That
+is, you must not have anything similar to file A including file B which
+includes file C which in turn includes either file A or B.
+
+
+
+
+SUB-SECTION: Interpreter commands
+
+ (sec:intcom)
+
+ L2X includes an interpreter for a procedural programming language that is
+based on the ISO international standard EXPRESS information modeling language
+[ EBOOK, EXPRESSIS]. At the moment the programming language within L2X is
+anonymous, but for ease of reference I will call it EXPRESS-A (EXPRESS
+-Almost? -Approximate? -Anonymous?). The EXPRESS-A language is described later
+in section (sec:expressa), but for now it is sufficient to know the commands
+that signify the start and end of this code.
+
+ The command CODE_SETUP= indicates the commencement of code to be run
+before any document processing occurs. The END_CODE command signifies the end
+of this code block. This block should be placed in the command table before
+any other commands except for the ESCAPE... commands, if any. This block can
+contain variable declarations, function and procedure declarations, and
+statements.
+
+ Code consisting purely of statements can be placed anywhere that a tagging
+action may be specified. These statements are enclosed between a CODE: and
+END_CODE pair of commands.
+
+ The EXPRESS-A language is described in detail in (sec:expressa), but to
+give a flavour of it here is a simple possible application. It has been noted
+that L2X will find difficulty in processing the contents of the LaTeX picture
+environment. The following portions of a command table write the contents of a
+figure environment to an external file and uses the programming language to
+keep a count of the number of figures so processed.
+
+
+
+c= declare and initialise a variable
+CODE_SETUP=
+ LOCAL
+ fignum : INTEGER;
+ END_LOCAL;
+ fignum := 0;
+END_CODE
+
+c= write figure contents to an external file
+TYPE= BEGIN_ENV
+NAME= figure
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ PC_AT_START= TO_FILE figs.tmp
+ START_TAG=
+ CODE:
+ fignum := fignum + 1; -- increment figure counter
+ println; -- print a blank line
+ println('%%% FIGURE ', fignum); -- write counter as a LaTeX comment
+ END_CODE
+ STRING: "\begin{figure}"
+END_TYPE
+
+c= close figure environment, back to normal output, and output
+c= text indicating that a figure should be here
+TYPE= END_ENV
+NAME= figure
+ PC_AT_START= RESET
+ START_TAG=
+ SWITCH_TO_FILE: figs.tmp
+ STRING: "\end{figure}?n?n"
+ SWITCH_BACK:
+ CODE:
+ println;
+ println('PLACE FOR FIGURE ', fignum);
+ println;
+ END_CODE
+END_TYPE
+
+
+
+
+
+
+SECTION: The LTX2X program
+
+ (sec:program)
+
+ L2X is written using flex and bison. The resulting C code should compile
+on any system. More details are given later, but for the end-user the next
+section describes how to run the program, assuming that is available on your
+system.
+
+
+
+
+SUB-SECTION: Running LTX2X
+
+
+
+ The syntax for running the compiled version of L2X is:
+
+ltx2x [-c] [-f table-file] [-p number] [-w] [-D dir_cat_char]
+ [-P path_seperators] [-S]
+ [-i number] [-l number] [-t] [-y number] [-C] [-E]
+ input-file output-file
+
+ where elements in square brackets are options. The options fall into two
+groups, one for the casual user and the other for those who may be interested
+in the internals of L2X. The first group of options includes:
+
+ -c : By default, L2X ignores all LaTeX comments in the input file. This
+option causes L2X to write the comments to the output file.
+
+
+ -f : By default, L2X reads the command table from a file called ltx2x.ct.
+If the required command table is in a file with another name this option is
+used to change from the default file. For example,
+
+> ltx2x in.tex out.l2x
+
+ reads a command table from ltx2x.ct, while
+
+> ltx2x -f detex.ct in.tex out.l2x
+
+ reads a command table from file detex.ct.
+
+
+ -p : This option causes L2X to `pretty print' the output file (as far as
+it is able to). The number is required and it indicates the desired maximum
+number of characters per output line. If this is considered to be too small,
+then L2X chooses a value. Note that pretty printing is only applied to the
+source file --- not to any replacement tags. That is, it only tries to format
+the running text from the source file.
+
+
+ -w : By default, L2X outputs source white space just at it reads it. This
+option causes L2X to collapse any amount of contiguous white space to a single
+space. The -p option includes the -w option.
+
+
+ -D : The value of this option is the character that the operating system
+uses to catenate directory names to form a path (see (sec:search)). The
+default value is a slash (i.e. /). The default could be changed to a
+backslash, for example, by -D \.
+
+
+ -P : The environment variable (see (sec:search)) contains a list of
+directories (also known as path names). In the operating system that I use,
+these are separated by the colon (:) character which, together with the
+semi-colon and space characters, form the L2X default separators. The path
+separator characters can be changed with this option. For example, -P : will
+make the separators be a colon or a space (space is automatically included in
+the separator list).
+
+
+ -S : This option enables the source level debugger (see (sec:sld)) for
+any embedded EXPRESS-A code.
+
+
+ The second group of options are principally for those who might be
+extending the L2X system.
+
+
+
+ -i : This produces information that may be useful for debugging the
+EXPRESS-A interpreter. number is an integer between 1 and 9 inclusive. The
+greater the number, the more diagnostics are generated.
+
+
+ -l : This produces information that may be useful for debugging the L2X
+program. number is an integer between 1 and 9 inclusive. The greater the
+number, the more diagnostics are generated.
+
+
+ -t : This generates diagnostics related to the processing of the command
+table file.
+
+
+ -y : Like the l option, but produces diagnostic information from the
+parser (this is actually a null option, but may be useful in the future).
+
+
+ -C : Disable any interpreter debugging information during the code
+generation pass. This is not necessary unless the -i option is used.
+
+
+ -E : Disable any interpreter debugging information during the code
+execution processing.This is not necessary unless the -i option is used.
+
+
+
+
+ L2X first reads the specified command table file, together with any
+included files, looking first in the current directory, then in the
+directories specified by the environment variable (if it exists). It then
+reads the input-file from the current directory, performs the actions
+specified in the command table and outputs the results to the output-file.
+
+ Three other files are also generated.
+
+ o ltx2xct.lis --- This contains a human-readable form of the internal
+representation of the command table. It may be useful if there are any errors
+in the original command table.
+ o ltx2x.err --- This contains any error or warning messages generated by
+L2X. It also contains any diagnostic information that may have been requested
+via a command line option.
+ o interp.csg --- This contains a human readable listing of the internal
+byte code generated by the EXPRESS-A interpreter.
+
+
+ When L2X is running normally it prints out a counter to the terminal
+indicating how many hundreds of input source file lines it has processed. Lack
+of such output is an indication that the program may be in a loop and chewing
+up CPU cycles to no avail. In this case, stop the program and examine the
+output for indications of where the trouble is occurring.
+
+ A limited number of errors are allowed when processing the command table
+and the input LaTeX file before L2X gives up and quits. In particular, if it
+is reading a command table file that includes another file, say one called
+zilch, that it cannot read, it prints the following message to the user's
+terminal.
+
+Can't open file zilch
+Enter new file name, or I to ignore, or Q to quit
+:
+
+ A Q (or q) response stops L2X from any further processing. An I (or i)
+response causes L2X to stop looking for the included file and continue
+processing the current file. Any other response is taken to be the name of an
+included file, which L2X then tries to read. If it fails, then the above
+message is repeated. The user is given a limited number of opportunities to
+identify a readable file before L2X quits altogether with this message:
+
+Last attempt. Can't open file zilch. I'm giving up.
+
+
+
+ Regarding performance, the time taken by L2X to process a document does
+not appear to be significantly different from the time to LaTeX the same
+document.
+
+
+
+
+SUB-SUB-SECTION: Directory searching
+
+ (sec:search)
+
+ The program employs a search algorithm to find files that are not in the
+current directory. It first looks in the current directory and if a file of
+the given name is found, then that is used. If the file is not found, then it
+searches for it among directories that are specified in a system environment
+variable. This variable specifies a list of pathnames, where the directories
+forming the path are combined using a catenation character. For example,
+dir1/dir2/dir3 could be a pathname, where the slash (/) is the catenation
+character. If it is looking for file afile.txt it will catenate the file name
+to the path name (e.g. dir1/dir2/dir3/afile.txt) and look for that. The
+pathnames in the list are separated by another character (in fact it can be
+one from a list of characters). For example here is a list of two pathnames;
+dir1/dir2;dir1/dir4, where the semi-colon (;) is the pathname separator.
+
+ By default, the program uses a slash (/) as the directory catenation
+character and the pathname separators can be a space, or a colon or a
+semi-colon (i.e., any of :;). All these characters can be altered via the
+program command line options, and should be set to match the conventions of
+your operating system.
+
+ The environment variable used by the program is LTX2XTABLES. On the
+operating system that I use, I set this in my login file like:
+
+setenv LTX2XTABLES .:/dir1/dir2:/dir3/dir4
+
+ Your system may have different conventions. Note that if the environment
+variable is not set, only files in the current directory are considered.
+
+
+
+
+SUB-SECTION: System components
+
+
+
+ The system consists of five main components --- a lexer, a parser, a
+library of support functions and command table parsing code, a user-defined
+library of functions, and an interpreter for the EXPRESS-A language.
+
+
+
+
+SUB-SUB-SECTION: The lexer
+
+
+
+ The lexer is generated by flex [ LEVINE92] (a more functional version of
+lex [ LESK75]). The source for the lexer is in file l2x.l. Its principal
+function is to read a LaTeX source file and recognize LaTeX commands. In
+general, it passes off the relevant command tokens to the parser for
+performing appropriate actions.
+
+ However, the lexer does do some processing of the source itself.
+
+ o It recognizes LaTeX comments (i.e. any text starting with a percent sign
+and ending with a newline). It silently ignores these comments, unless run
+with the -c option.
+ o It recognizes the `standard' LaTeX verbatims. It will write out the
+appropriate tags at the start and end of the verbatim text, while writing the
+verbatim text directly to the output file, bypassing the parser. It does not
+distinguish between the unstarred and starred versions of the verbatims.
+ o Newlines and whitespace are directly written to the output file, again
+bypassing the parser. The -p and -w options control the final appearance of
+whitespace, newlines and paragraphing.
+ o It recognizes the command \ i.e. a backslash followed by a space, and
+writes the tags defined in the SLASH_SPACE specification directly to the
+output file.
+
+
+ The lexer is designed to recognize four kinds of LaTeX commands.
+
+ o Commands of the form \begin{environment}
+ o Commands of the form \end{environment}
+ o Any other command of the form \command
+ o As special cases, commands that are 'verbatim-like' or `verb-like'.
+ When it finds a command, it looks up the command or environment name in the
+command table and sends the appropriate token and its command table location
+to the parser. As a special case the contents of verbatim-like environments
+and the argument of verb-like coommands are processesd within the lexer and
+not sent to the parser.
+
+
+
+
+SUB-SUB-SECTION: The parser
+
+
+
+ The parser is generated by bison [ LEVINE92] (a more powerful version of
+YACC [ JOHNSON75]). The source for the parser is in file l2x.y. Essentially it
+defines a very simple grammar for a LaTeX document. That is, the grammar is
+limited to generic kinds of commands and command arguments. It does not
+understand the `meaning' of any of the commands or arguments.
+
+ When the parser receives a token from the lexer it tries to match it with
+one of the grammar rules, performing the actions specified by the command
+table. Here is an extract from the parser grammar file, l2x.y, for a LaTeX
+command that has two required arguments followed by an optional argument.
+
+
+
+l2xComm2Opt: COMMAND_2_OPT
+ {
+ start_with_req($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_p_opt($1,2);
+ }
+ OptParam
+ {
+ action_last_opt($1);
+ }
+ ;
+
+
+
+ The actions are enclosed in braces, and are interspersed with the elements
+of the grammar.
+
+ The token COMMAND_2_OPT indicates that the lexer has found a command that
+takes two required arguments followed by an optional argument. The parser then
+performs some actions. The start_with_req function is the standard L2X
+function for the first action in a command production where the final argument
+is optional. The $1 refers to the location of the particular command in the
+command table, and its value is passed to the parser by the lexer.
+
+ The parser then expects a required argument (i.e. {, token LBRACE) as the
+start of the required argument, followed by the text of the argument and
+finished off by a right brace (i.e. }, token RBRACE); the grammar for all of
+this is specified in the production called ReqParam). If it finds these it
+performs some further actions, otherwise it reports an error. In this case the
+action is defined by the function action_p_p1, which is the standard action
+performed between two required arguments (the second argument in the function
+call specifies the Pth argument that has been recognized). Another required
+argument is then expected. In this case the action is defined by the function
+action_p_opt, which is the standard action performed between the end of the
+Pth required argument and the start of an optional argument. It then looks for
+an optional argument, the grammar for which is specified in the production
+called OptParam. The final action is specified by the standard function
+action_last_opt for finishing off a command that ends with an optional
+argument.
+
+ The grammar for a command that that has two required arguments, and
+possibly an initial optional argument is similar:
+
+
+
+l2xComm2: COMMAND_2
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_p_p1($1,1);
+ }
+ ReqParam
+ {
+ action_last_p($1,2);
+ }
+ ;
+
+
+
+
+
+
+SUB-SUB-SECTION: The support libraries
+
+
+
+ Source code for the C main program and support functions is in file
+l2xlib.c. The main program is responsible for reading in the command table and
+calling the lexer and parser to do the appropriate processing. The file also
+contains a variety of support functions that are, or could be, used in the
+lexer, parser, action library, or user-defined library.
+
+ The standard actions for the grammar are contained in file l2xacts.c.
+
+
+
+
+SUB-SUB-SECTION: The user-defined library
+
+
+
+ The intent of this library is that masochistic users can define their own
+functions for use within L2X when processing their SPECIAL_ commands, without
+having to modify the L2X support or action libraries.
+
+ Source code for the user-defined library should be maintained in a file
+called l2xusrlb.c and a corresponding header file called l2xusrlb.h.
+
+
+
+
+SUB-SUB-SECTION: The EXPRESS-A interpreter
+
+
+
+ The EXPRESS-A interpreter is based on algorithms originally developed by
+Ronald Mak [ MAKR91] for interpreting Pascal. His original algorithms have
+been modified and extended to cater for EXPRESS-A. The interpreter module has
+a minimal interface with the rest of the L2X system, and could easily be
+modified to be a stand-alone program (in fact it started that way in the first
+place). The interface between L2X and the interpreter is confined to the small
+l2xistup.c file.
+
+
+
+
+SECTION: The EXPRESS-A programming language
+
+ (sec:expressa)
+
+ EXPRESS is a language for information modeling and includes both
+declarative and procedural aspects [ EBOOK]. There are also two other
+companion languages called respectively EXPRESS-G and EXPRESS-I. The former of
+these is a graphical form of the declaritive aspects of EXPRESS, and the later
+is an instiation and test case specification language. These languages are
+either ISO international standards [ EXPRESSIS] or on the way to becoming so [
+EXPRESSITR].
+
+ Certain of the procedural aspects of EXPRESS and EXPRESS-I are relevent to
+the L2X concepts and so, together with some other reasons, it seemed
+appropriate to provide an interpreter for a similar language for use within
+L2X. EXPRESS-A provides a major subset of the EXPRESS procedural language,
+together with some Pascal-like additions for input and output. Of particular
+note, strings are a built-in type in EXPRESS-A. The language also supports
+three-valued logic and the concept of an `indeterminate' value of any type.
+
+ Earlier I gave an example command table to replace the text of a LaTeX
+document with the words `Goodbye document'. Here is an EXPRESS-A program that
+outputs `Goodbye document'.
+
+println('Goodbye document');
+END_CODE
+
+
+
+ The following gives a brief overview of EXPRESS-A. For more details
+consult Schenck & Wilson [ EBOOK].
+
+
+
+
+SUB-SECTION: Basic elements
+
+
+
+ EXPRESS-A is a case-insensitive language and uses the ASCII character set.
+Two kinds of comments are supported --- an end of line comment, which starts
+with a -- pair and continues until the end of the current line --- and an
+extended comment. An extended comment starts with a (* pair and is ended by a
+matching *) pair; extended comments may be nested.
+
+ The language contains many reserved words, some of which are only
+applicable to the EXPRESS and EXPRESS-I languages.
+
+ Identifiers are composed of an initial letter, possibly followed by any
+number of letters, digits, and the underscore character.
+
+ Literals are self defining constant values. An integer literal consists of
+one or more digits, the first of which shall not be zero. Real numbers start
+with one or more digits, followed by a decimal point. Further digits may occur
+after the point, and finaly there may be an exponent in the `e' notation
+format (e.g., 123.456e-78).
+
+ A string literal is any sequence of characters enclosed by single quote
+marks. If a single quote mark is meant to form part of the string, two quote
+marks must be used at that point.
+
+ Logical literals consists of one of these keywords: FALSE, UNKNOWN or
+TRUE.
+
+ EXPRESS-A also includes some other constants. PI stands for the value of
+the mathematical constant (3.1415...), and CONST_E stands for the value of
+the mathematical constant e (2.7182...), the base of natural logarithms. The
+special token ? stands for an indeterminate value of any type. The three
+constants THE_DAY, THE_MONTH and THE_YEAR are integer values for the current
+date holding the day of the month (1--31), the month of the year (1--12) and
+the year (four digits), respectively.
+
+
+
+
+SUB-SECTION: Data types
+
+
+
+ EXPRESS-A is a typed language. The simple data types are: INTEGER, REAL,
+STRING and LOGICAL.
+
+ The aggregation data types are ARRAY, BAG, LIST, and SET. The array data
+type is of a fixed size and must have declared lower and upper bounds (index
+range), such as ARRAY [-7:10] OF. The other aggregate data types are dynamic
+in size, but may have lower and upper bounds specified for the number of
+elements, such as SET [2:5] OF, meaning a set that should have between two and
+five members. For the dynamic aggregates the upper bound may be given as ?,
+which means an unlimited upper bound, such as LIST [2:?] OF. If a bound
+specification is absent, then the dynamic aggregate can hold from zero to any
+number of elements. (Footnote: The dynamic aggregates may not be fully
+implemented due to lack of time.)
+
+ Aggregates are one dimensional, but can be chained together for
+multi-dimensional aggregates, like
+
+ARRAY [1:4] OF LIST OF INTEGER;
+
+
+
+ The enumeration data type is a parenthesised comma seperated list of
+identifiers. These identifiers represent the values of the enumerated type;
+for instance
+
+ENUMERATION OF (red, green, blue)
+
+
+
+ A defined data type is one declared and named by the user using the TYPE
+and END_TYPE construct. For example
+
+TYPE length = REAL; END_TYPE;
+TYPE crowd_size = INTEGER; END_TYPE;
+TYPE signal_colour = ENUMERATION OF (red, amber, green); END_TYPE;
+
+
+
+ An entity data type consists of a list of attributes and their types,
+enclosed in a ENTITY and END_ENTITY pair. An entity type is named.
+
+ENTITY an_ent;
+ auditorium_width : length;
+ audience : crowd_size;
+ title : STRING;
+ profit : REAL;
+END_ENTITY;
+
+
+
+ EXPRESS-A provides for algorithms in the form of functions and procedures.
+
+
+ A FUNCTION is an algorithm that operates on parameters and returns a
+single resultant value of a specified data type. An invocation of a function
+in an expression evaluates to the resultant value at the point of invocation.
+For example:
+
+FUNCTION func (par1 : INTEGER; par2 : STRING) : STRING;
+ LOCAL
+ str : STRING;
+ -- other variable declarations
+ END_LOCAL;
+ -- the algorithm statements are here
+ RETURN(str);
+END_FUNCTION;
+
+ Note that the parameters are typed.
+
+ A PROCEDURE is an algorithm that receives parameters from the point of
+invocation and operates on them in some manner. Changes to the parameters
+within the procedure are only reflected to the point of invocation when the
+formal parameter is preceded by the keyword VAR. For example:
+
+PROCEDURE proc (par1 : INTEGER; VAR par2 : STRING);
+ -- local declarations and the algorithm statements
+END_PROCEDURE;
+
+ Note that the parameters are typed. In this case the value of par2 may be
+changed.
+
+ Variables are declared in a local block, enclosed by the keywords LOCAL
+and END_LOCAL. A variable declaration consists of an identifer and its type,
+such as:
+
+LOCAL
+ str : STRING;
+ e1, e2 : an_ent; -- e1 and e2 are both of type an_ent
+ e3 : an_ent; -- so is e3
+ num : INTEGER;
+ col : signal_colour;
+ matrix : ARRAY [1:15] OF ARRAY [1:15] OF REAL;
+END_LOCAL;
+
+
+
+ The above declarations must be in the following order:
+
+ (#) ENTITY and/or TYPE declarations
+ (#) FUNCTION and/or PROCEDURE declarations
+ (#) a LOCAL declaration block
+
+
+ After the above can come any number of statements.
+
+
+
+
+SUB-SECTION: Statements
+
+
+
+ EXPRESS-A supports the following statements:
+
+ o Null statement
+ o Assignment statement
+ o Call statement
+ o BEGIN ... END compound statement
+ o CASE ... END_CASE statement
+ o IF ... THEN ... ELSE ... END_IF statement
+ o REPEAT ... WHILE ... UNTIL ... END_REPEAT statement. This also includes
+the ESCAPE and SKIP statements
+ o RETURN statement
+
+
+ All the above statements are completed by a ; (semicolon). The null
+statement just consists of a semicolon.
+
+ The assignment statement is used to assign an instance to a local variable
+or parameter. The data types must be compatible.
+
+LOCAL
+ a, b, c : REAL;
+END_LOCAL;
+...
+ a := 2.3E-6;
+ b := a;
+ a := -27.0;
+ c := 33.3*b;
+
+
+
+ The call statement invokes a procedure or a function. The actual
+parameters provided with the call must agree in number, order and type with
+the formal parameters specified in the procedure or function declaration. The
+supplied parameter values must be assignment compatible with the formal
+parameters. This is an example of calling the EXPRESS-A defined INSERT
+procedure which takes three parameters:
+
+INSERT(my_list, list_element, 0);
+
+
+
+ The compound statement consists of one or more statements enclosed between
+a BEGIN and END pair. The enclosed statements are treated as a single
+statement.
+
+...
+ BEGIN
+ a := 2.3e-7;
+ b := a;
+ c := b*33.3;
+ END;
+
+
+
+ The case statement is a means of selectively executing statements based on
+the value of an expresion.
+
+LOCAL
+ a : INTEGER;
+ x, y : REAL;
+END_LOCAL;
+...
+ a := 2;
+ x := 21.9;
+ CASE 2*a OF
+ 1 : x := SIN{x};
+ 2 : x := SQRT(x);
+ 3 : x := LOG(x);
+ 4 : x := COS(x); -- this is executed
+ 5, 6 : y := y**x;
+ OTHERWISE : x := 0.0;
+ END_CASE;
+
+ The integer expression following the CASE keyword is evaluated. The result is
+compared to the values of the case labels and the statement following the
+first matching label is executed. Execution then continues at the statement
+following the END_CASE;. If no label matches, then no statements within the
+case block are executed, except if an OTHERWISE label is included, which will
+match anything. All other labels are examined before looking for the
+OTHERWISE.
+
+ The if ... then ... else statement allows the conditional execution of
+statements depending on the value of a LOGICAL expression. When the expression
+evaluates to TRUE the statement(s) following the THEN are executed, after
+which control passes to the statement following the closing END_IF. When the
+logical expression evaluates to FALSE or UNKNOWN the THEN statements are
+jumped over and execution starts at the statement(s) following the ELSE
+keyword if present, or at the statement following the END_IF keyword.
+
+IF a > 20 THEN
+ b := a + 2;
+ c := c - 1;
+ELSE
+ IF a > 10 THEN
+ b := a + 1;
+ ELSE
+ c := c + 1;
+ END_IF;
+END_IF;
+
+
+
+ The repeat statement is used to control the conditional repetition of a
+series of statements. The control conditions are:
+
+ o finite iteration until an integer expression reaches a specified value;
+ o WHILE a logical condition is TRUE;
+ o UNTIL a logical condition is TRUE.
+
+
+REPEAT i := 100 TO 0 BY -7 WHILE r >= 0.0 UNTIL err < 1.0e-8;
+ ...
+ r := ...;
+ err := ...;
+END_REPEAT;
+
+ At entry to the REPEAT statement the iteration variable is initialized to the
+first bound. If the variable less than or equal to the TO bound and the
+increment is positive, or the variable is less than the TO bound and the
+increment is negative, processing jumps to after the END_REPEAT, otherwise
+processing continues. The WHILE condition is checked and if TRUE then the
+statements in the body are executed. After these have been executed the UNTIL
+condition is checked. If this is not TRUE then processing continues by
+incrementing the iteration variable by either unity or by the BY value if
+present. The whole process then starts again with the checking of the
+iteration variable against the TO bound.
+
+ All three types of controls are optional. If none are given then the
+REPEAT statement will loop for ever. The escape statement causes an immediate
+transfer out of the REPEAT statement in which it occurs. The skip statement
+causes a jump to the end of the REPEAT statement in which it occurs (i.e., to
+the point where the UNTIL expression is tested).
+
+REPEAT UNTIL (a = 1);
+ ...
+ IF a = 0 THEN
+ ESCAPE;
+ END_IF;
+ ...
+ IF a > 10 THEN
+ SKIP;
+ END_IF;
+ ...
+ ...
+-- SKIP transfers control to here
+END_REPEAT;
+ -- ESCAPE transfers control to here
+
+
+
+ The return statement terminates the execution of a FUNCTION or PROCEDURE.
+The RETURN statement within a function must specify an expression, the value
+of which is the value returned by the function. A RETURN in a procedure must
+not specify an expression.
+
+RETURN(a <> b); -- example for within a function
+RETURN; -- example for within a procedure
+
+
+
+
+
+
+SUB-SECTION: Expressions
+
+
+
+ Expressions are combinations of operators, operands and function calls
+which are evaluated to produce a value. The simplest expression is either a
+literal value or the name of a variable.
+
+
+
+
+SUB-SUB-SECTION: Arithmetic operators
+
+
+
+ The arithmetic operators act on number values and produce a number result.
+If any operand is indeterminate (i.e., ?) then the result is also
+indeterminate. The operators are:
+
+ Unary : The operators + and -, the latter of which negates its following
+operand.
+ Binary : Addition (+), subtraction (-), multiplication (*), real division
+(/), exponentiation (**), integer division (DIV), and modulo (MOD).
+
+
+
+
+
+SUB-SUB-SECTION: Relational operators
+
+
+
+ The result of a relational expression is a LOGICAL value. If either
+operand is indeterminate, the expression evaluates to UNKNOWN.
+
+
+
+ Value comparison : Equal (=), not equal (<>), greater than (>), less than
+(<), greater than or equal (>=), and less than or equal (<=).
+
+
+ Membership : The IN operator tests an item for membership in a dynamic
+aggregate (e.g., IF fred IN mylist THEN ...).
+
+
+ Matching : The LIKE operator compares a string against a pattern,
+evaluating to TRUE if they match. The pattern characters are:
+
+ o @ Matches any letter.
+ o ^ Matches any upper-case letter.
+ o ? Matches any character.
+ o & Matches remainder of string.
+ o # Matches any digit.
+ o $ Matches a substring terminated by a space character or end-of-string.
+ o * Matches any number of characters.
+ o \ Begins a pattern escape sequence.
+ o ! Negation character (used with the other characters).
+ o Any other character matches itself.
+
+
+ Some examples:
+
+ o 'The quick red fox' LIKE '$$$$' is TRUE.
+ o 'Page 231' LIKE '$ ###' is TRUE.
+ o 'Page 27' LIKE 'Page ###' is FALSE.
+ o '\aaaa' LIKE '\\aaaa' is TRUE.
+ o '\aaaa' LIKE '\aaaa' is FALSE.
+ o 'aaaa' LIKE 'a@@a' is TRUE.
+
+
+
+
+
+
+
+
+SUB-SUB-SECTION: Logical operators
+
+
+
+ The logical operators produce a logical result. Except for the NOT
+operator which takes one logical operand (e.g., NOT op), they take two logical
+operands (e.g., op1 XOR op2).
+
+ The evaluation of the NOT operator is given in table (tab:not).
+
+
+
+ CAPTION: The NOT logical operator
+ (Table: tab:not)
+ Operand value | Result value
+ TRUE | FALSE
+ UNKNOWN | UNKNOWN
+ FALSE | TRUE
+
+
+
+ The evaluation of the AND, OR and XOR operators is given in table
+(tab:andorxor).
+
+
+
+ CAPTION: The AND, OR and XOR logical operators
+ (Table: tab:andorxor)
+ Op1 | Op2 | Op1 AND Op2 | Op1 OR Op2 | Op1 XOR Op2
+ TRUE | TRUE | TRUE | TRUE | FALSE
+ TRUE | UNKNOWN | UNKNOWN | TRUE | UNKNOWN
+ TRUE | FALSE | FALSE | TRUE | TRUE
+ UNKNOWN | TRUE | UNKNOWN | TRUE | UNKNOWN
+ UNKNOWN | UNKNOWN | UNKNOWN | UNKNOWN | UNKNOWN
+ UNKNOWN | FALSE | FALSE | UNKNOWN | UNKNOWN
+ FALSE | TRUE | FALSE | TRUE | TRUE
+ FALSE | UNKNOWN | FALSE | UNKNOWN | UNKNOWN
+ FALSE | FALSE | FALSE | FALSE | FALSE
+
+
+
+
+
+
+SUB-SUB-SECTION: Miscellaneous
+
+
+
+
+
+
+
+ Function call : A function may be called without the result necessarily
+being assigned to a variable. If fun is a function with two arguments (for
+simplicitly integer arguments) and returning a logical value, then
+
+log := fun(i1, i2);
+fun(i3, 24*i4);
+
+ are both legitimate calls.
+
+
+ Dot operator : The dot operator is used to access an attribute from an
+entity. If ent is an ENTITY type with an attribute att, then ent.attr
+evaluates to the value of the attr attribute within the ent.
+
+
+ String operators :
+ The + operator takes two strings as its operands and evaluates to the string
+that is the concatenation of its operands. For example:
+
+str1 := 'string1';
+str2 := 'string2';
+str1 := str1 + str2;
+-- str1 = 'string1string2' is TRUE
+
+
+
+ The substring operator [i1:i2] is a postfix operator that when applied to
+a string, evalutes to the string whose characters are composed of the i1'th
+through the i2'th characters, inclusively, of its operand. Note that i2 must
+be greater than or equal to i1, and both must be within the limits of the
+number of characters in the string. For example:
+
+str1 := 'string';
+str2 := str1[2:4];
+str1 := str1 + str2;
+-- str1 = 'tristring' is TRUE
+
+
+
+
+ Aggregate operators :
+ The index operator [i] is a postfix operator that can be applied to an
+aggregate operand; the expression evaluates to the value of the aggregate at
+the index position. For example, if lagg is a list of integers:
+
+insert(lagg, 20, 0);
+insert(lagg, 40, 0);
+insert(lagg, 60, 0);
+insert(lagg, 80, 0);
+-- lagg[2] = 60 is TRUE
+
+
+
+
+ Interval expression :
+ An interval expression is a LOGICAL expression consisting of three operands
+and two operators. It has the form:
+
+{ low op1 test op2 high }
+
+ where op1 and op2 are either of the two relational operators < or <=, and
+low, test and high are expressions of the same type. The interval expression
+is equivalent to:
+
+((low op1 test) AND (test op2 high))
+
+ The value of the interval expression is given by
+
+ (#) If any operand is indeterminate, then it evauates to UNKNOWN.
+ (#) If either of the logical relationships evaluates to FALSE, then it
+evauates to FALSE.
+ (#) If both logical relationships evalute to TRUE, then it evauates to
+TRUE.
+ (#) Otherwise it evaluates to UNKNOWN.
+ For example:
+
+i := 10;
+{1 <= i < 20} -- is TRUE
+{1 <= i < 10} -- is FALSE
+i := ?;
+{1 <= i < 10} -- is UNKNOWN
+
+
+
+
+
+
+
+
+
+SUB-SECTION: Built in procedures and functions
+
+
+
+
+
+
+SUB-SUB-SECTION: Procedures
+
+
+
+ The following procedures are an integral part of EXPRESS-A. They are shown
+as signatures to inidicate the data types of the formal parameters. For
+convenience, GENERIC is used to indicate any type.
+
+
+
+ o INSERT (VAR L:LIST OF GENERIC; E:GENERIC; P:INTEGER)
+ INSERT inserts the element E into a list L at position P. The insertion
+follows the existing element at P, so that if P=0, E will become the first
+element.
+
+
+ o REMOVE (VAR L:LIST OF GENERIC; P:INTEGER)
+ REMOVE modifies the list L by deleting the element at position P.
+
+
+ o SYSTEM (V:STRING)
+ SYSTEM passes the string V to the operating system. This is typically used to
+get the operating system to perform some action.
+
+
+ o READ(VAR V1, V2,...:GENERIC), READLN(VAR V1, V2,...:GENERIC)
+ These two procedures are similar to the Pascal procedures of the same name
+and put data from standard input into the variable(s) V1, etc.
+
+ The argument is a comma-seperated list of variables. The variables may be
+of different types, but the types are limited to INTEGER, REAL, LOGICAL, and
+STRING. The procedure gets the next value of the variable's type from standard
+input and assigns it to the variable. An integer is recognised as a set of
+digits, optinally preceeded by a sign. A real is in either decimal or
+scientific notation (e.g., 12.34 or 1.234e1). A logical is TRUE, FALSE or
+UNKNOWN (case independent, so TRUE could also be tRuE). A string is any
+non-empty set of characters ended by white space (e.g., string is one string
+but ball of str8 string is four strings). The difference between READ and
+READLN is that the former performs the actions described above, while the
+latter will discard any remaining characters in the input line after
+processing its arguments.
+
+
+ o WRITE(format), WRITELN(format)
+ These two procedures are similar to the Pascal procedures of the same name.
+They write data to standard output.
+
+ The format consists of a comma-seperated list of variables with optional
+spacing specifications. The variable types may be INTEGER, REAL, LOGICAL, or
+STRING. The LOGICAL and STRING types take no spacing declarations. An INTEGER
+variable can take one optional space specification which is an integer number
+specifying the minimum field width for printing the value (e.g., int:6 to
+specify a minimum field width of 6 characters). A REAL variable can take two
+optional space specifications. The first is the field width and the second is
+the number of digits to be printed (e.g., r:10:5 for printing with a field
+width of 10 characters and to a pecision of 5 digits). For example:
+
+BEGIN_LOCAL
+ int : INTEGER;
+ r : REAL;
+ log : LOGICAL;
+ str : STRING;
+END_LOCAL;
+ int := 23;
+ r := 23.0;
+ log := true;
+ str := 'This is a string.';
+WRITE('Example', int, r:10:5, ' ', log, ' ', str);
+
+ will produce:
+
+Example 23 23.000 TRUE This is a string.
+
+
+
+ The difference between WRITE and WRITELN is that the latter will end the
+output line after it has output the values of its arguments. (WRITELN need
+take no arguments, in which case it justs ends the current output line).
+
+
+ o PRINT(format), PRINTLN(format)
+ These PRINT procedures are the same as the WRITE procedures, except that they
+send the data to the current L2X output destination.
+
+
+
+
+
+
+
+SUB-SUB-SECTION: Functions
+
+
+
+ The following functions are supplied as part of EXPRESS-A. They are
+exhibited as signatures to show the formal parameters. For convenience, NUMBER
+is being used to denote either an INTEGER or a REAL number.
+
+
+
+ o ABS (V:NUMBER) : NUMBER;
+ ABS returns the absolute value of its argument.
+ o COS (V:NUMBER) : REAL;
+ Returns the cosine of an an angle specified in radians.
+ o EOF () : LOGICAL;
+ Returns TRUE if the next character from standard input is `end-of-file',
+otherwise it returns FALSE.
+ o EOLN () : LOGICAL;
+ Returns TRUE if the next character from standard input is `end-of-line',
+otherwise it returns FALSE.
+ o EXISTS (V:GENERIC) : LOGICAL;
+ The function EXISTS returns FALSE if its argument is indeterminate or does
+not exist, otherwise it returns TRUE.
+ o EXP (V:NUMBER) : REAL;
+ Returns e (the base of natural logarithms (CONST_E)) raised to the power of
+V.
+ o HIBOUND (V:AGGREGATE OF GENERIC) : INTEGER;
+ HIBOUND returns the declared upper index of an ARRAY or the declared upper
+bound of a BAG, LIST or SET.
+ o HIINDEX (V:AGGREGATE OF GENERIC) : INTEGER;
+ HIINDEX returns the declared upper index of an ARRAY or the number of
+elements in a BAG, LIST or SET.
+ o LENGTH (V:STRING) : INTEGER;
+ Returns the number of characters in its argument.
+ o LOBOUND (V:AGGREGATE OF GENERIC) : INTEGER;
+ LOBOUND returns the declared lower index of an ARRAY or the declared lower
+bound of a BAG, LIST or SET.
+ o LOG (V:NUMBER) : REAL;
+ Returns the natural logarithm of its argument.
+ o LOG2 (V:NUMBER) : REAL;
+ Returns the base 2 logarithm of its argument.
+ o LOG10 (V:NUMBER) : REAL;
+ Returns the base 10 logarithm of its argument.
+ o LOINDEX (V:AGGREGATE OF GENERIC) : INTEGER;
+ LOINDEX returns the declared lower index of an ARRAY or the value 1 for a
+BAG, LIST or SET.
+
+ The ..INDEX functions are useful for iterating over aggregates. For
+example, if lagg is a list of integer, then all the elements can be printed
+out as a comma-seperated list enclosed in parentheses by:
+
+writeln;
+write('lagg = (');
+REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ IF (i = HIINDEX(lagg)) THEN write(lagg[i]:1);
+ ELSE write(lagg[i]:1, ', ');
+ END_IF;
+END_REPEAT;
+writeln(')');
+
+
+ o NVL (V:GENERIC; SUBS:GENERIC) : GENERIC;
+ If the argument V exists then it is returned, otherwise the argument SUBS is
+returned. Both arguments must be of the same type.
+ o ODD (V:INTEGER) : LOGICAL;
+ Returns TRUE or FALSE depending on whether or not its argument is odd or
+even.
+ o REXPR (V:STRING; E:STRING) : LOGICAL;
+ This function tests whether the V string parameter matches a regular
+expression E. REXPR returns TRUE if there is a match, FALSE if there is not a
+match, or UNKNOWN if the regular expression is ill-formed.
+
+ In the regular expression, most characters stand for themselves, but \ can
+be used to escape any of the meta-characters.
+
+ o The meta-characters ( and ) are used for grouping sub-expressions.
+ o | between expressions means one or the other.
+ o + following an expression means match one or more times.
+ o * following an expression means match zero or more times.
+ o ? following an expression means match zero or one times.
+ o [...] is an expression indicating that any of the enclosed characters are
+acceptable.
+ o [^...] is an expression indicating that any characters except those
+enclosed are acceptable.
+ o Within a bracket expression a range of characters can be specified by
+providing the first and last with a seperating hyphen. For instance, [a-zA-Z]
+will match any alphabetic character.
+
+
+ Some examples:
+
+ o [a-zA-Z]+ match one or more letters.
+ o [0-9]+.[0-9]+([eE][\-\+]?[0-9]+)? match a floating point number
+ (e.g., 1.23e-27 or 0.987)
+ o [a-zA-Z][0-9a-zA-Z_]* match an EXPRESS-A variable.
+ o [^0-9a-zA-Z] match anything except letters or digits.
+ o (I|i)(F|f) case insensitive match for the word IF.
+
+
+
+ o ROUND (V:NUMBER) : INTEGER;
+ Returns the nearest integer to its argument value.
+ o SIN (V:NUMBER) : REAL;
+ Returns the sine of an an angle specified in radians.
+ o SIZEOF (V:AGGREGATE OF GENERIC) : INTEGER;
+ SIZEOF returns the number of elements in its argument. When V is an ARRAY
+this is the declared number of elements. When V is a BAG, LIST or SET this is
+the actual number of elements.
+ o SQRT (V:NUMBER) : REAL;
+ Returns the square root of its argument.
+ o TAN (V:NUMBER) : REAL;
+ Returns the tangent of an an angle specified in radians.
+ o TRUNC (V:NUMBER) : INTEGER;
+ Chops off any decimal part of its argument, returning the corresponding
+integer value.
+
+
+
+
+
+
+
+SUB-SECTION: Source level debugger
+
+ (sec:sld)
+
+ The EXPRESS-A interpreter includes a source level debugger for use when
+your code appears to be misbehaving. When in operation the debugger will
+prompt for a command to be entered. It understands the following commands.
+
+
+
+ o <return> Continue processing.
+ o break <number> Place a breakpoint at the statement on line <number>.
+ o break Print the line numbers of all the breakpoints.
+ o unbreak <number> Remove the breakpoint from line <number>.
+ o unbreak Remove all breakpoints.
+ o trace Turn on statement tracing.
+ o untrace Turn off statement tracing.
+ o entry Turn on tracing of entry to procedures and functions.
+ o unentry Turn off entry tracing.
+ o exit Turn on tracing of exits from procedures and functions.
+ o unexit Turn off exit tracing.
+ o traceall Turn on all tracing.
+ o untraceall Turn off all tracing.
+ o stack Turn on display of the runtime stack accesses.
+ o unstack Turn off stack display.
+ o step Turn on single-stepping.
+ o unstep Turn off single stepping.
+ o fetch <variable> Print data fetches for <variable>.
+ o store <variable> Print data stores for <variable>.
+ o watch <variable> Print both data fetches and stores for <variable>.
+ o watch Print the names of all variables being watched.
+ o unwatch <variable> Remove the watch from <variable>.
+ o unwatch Remove all watches.
+ o show <expression> Print the value of the EXPRESS-A expresion
+<expression>. The variables in the expression must have been declared in the
+EXPRESS-A code. For example:
+
+show (23.0 + LOG(num))/(PI*r**2)
+
+
+ o assign <variable := expression> Assign the value of <expression> to the
+EXPRESS-A variable <variable>. For example:
+
+assign num := SIN(theta/300.0)
+
+
+ o where Print the current line number and the text of the next statement to
+be executed.
+ o kill Terminate the execution of the L2X program.
+
+
+
+
+
+SUB-SECTION: Example EXPRESS-A code
+
+
+
+ The following demonstrates most of the functionality of EXPRESS-A. Most of
+this is not particularly interesting, except possibly for the algorithms for
+calculating the date of Easter and for generating magic squares.
+
+
+
+ c= fun.ct Test of CODE ltx2x
+
+CODE_SETUP=
+ ENTITY ent;
+ attr1, attr3 : INTEGER;
+ attr2 : STRING;
+ END_ENTITY;
+
+ TYPE joe = INTEGER;
+ END_TYPE;
+
+ TYPE colour = ENUMERATION OF (red, blue, green);
+ END_TYPE;
+
+
+PROCEDURE easter;
+(* calculates the date of Easter for the present year
+ The algorithm can be applied to any year between
+ 1900 and 2099 inclusive, but if so, then the year
+ should be checked to ensure that it is within this range. *)
+ LOCAL
+ n, a, b, m, q, w : INTEGER;
+ day : INTEGER;
+ month : STRING;
+ END_LOCAL;
+
+ n := THE_YEAR - 1900;
+ a := n MOD 19;
+ b := (7*a + 1) DIV 19;
+ m := (11*a + 4 - b) MOD 29;
+ q := n DIV 4;
+ w := (n + q + 31 - m) MOD 7;
+ day := 25 - m - w;
+ month := 'April';
+ IF (day < 1) THEN
+ month := 'March';
+ day := day + 31;
+ END_IF;
+ writeln('In ', THE_YEAR:1, ' Easter is on ', month, day:3);
+END_PROCEDURE;
+
+
+FUNCTION magic_square(order:INTEGER): LOGICAL;
+(* calculates magic squares from order 1 through 15.
+ The order must be an odd number. *)
+ LOCAL
+ row, col, num : INTEGER;
+ sqr_order : INTEGER;
+ magic : ARRAY[1:15] OF ARRAY[1:15] OF INTEGER;
+ END_LOCAL;
+
+ IF (order > 15) THEN -- only squares up to order 15
+ RETURN(FALSE);
+ ELSE
+ IF (order < 1) THEN -- squares have at least one entry
+ RETURN(FALSE);
+ ELSE
+ IF (NOT ODD(order)) THEN -- squares are odd
+ RETURN(FALSE);
+ END_IF;
+ END_IF;
+ END_IF;
+
+ sqr_order := order**2;
+ row := 1;
+ col := (order + 1) DIV 2;
+ REPEAT num := 1 TO sqr_order;
+ magic[row][col] := num;
+ IF ((num MOD order) <> 0) THEN
+ IF (row = 1) THEN row := order; ELSE row := row - 1; END_IF;
+ IF (col = order) THEN col := 1; ELSE col := col + 1; END_IF;
+ ELSE
+ IF (num <> sqr_order) THEN row := row + 1; END_IF;
+ END_IF;
+ END_REPEAT;
+
+ writeln(Magic square of order ',order:2);
+ REPEAT row := 1 TO order;
+ REPEAT col := 1 TO order;
+ write(magic[row][col]:4);
+ END_REPEAT;
+ writeln;
+ END_REPEAT;
+ writeln;
+
+ RETURN(TRUE);
+END_FUNCTION;
+
+FUNCTION month(mnum:INTEGER) : STRING;
+(* Given an integer representing the month in a year,
+ returns the name of the month. *)
+LOCAL
+ str : STRING;
+END_LOCAL;
+
+ CASE mnum OF
+ 1 : str := 'January';
+ 2 : str := 'February';
+ 3 : str := 'March';
+ 4 : str := 'April';
+ 5 : str := 'May';
+ 6 : str := 'June';
+ 7 : str := 'July';
+ 8 : str := 'August';
+ 9 : str := 'September';
+ 10 : str := 'October';
+ 11 : str := 'November';
+ 12 : str := 'December';
+ OTHERWISE : str := '';
+ END_CASE;
+RETURN(str);
+END_FUNCTION;
+
+ LOCAL
+ a : array[1:3] of integer;
+ lagg : list [0:5] of integer;
+ a23 : array[1:2] of array[1:3] of integer;
+ i, n : integer;
+ s1, s2 : string;
+ b : logical;
+ r1, r2 : real;
+ nega : array[-3:-1] of integer;
+ posa : array[3:5] of integer;
+ j : joe;
+ ex : ent;
+ END_LOCAL;
+
+ -- start with a massive compound statement
+ BEGIN
+
+ writeln;
+ println;
+
+ (* write today's date *)
+ writeln('Today is ', THE_DAY:1, ' ', month(THE_MONTH), ' ', THE_YEAR:1);
+ writeln;
+
+ (* The user might be interested in Easter *)
+ easter;
+ writeln;
+
+ (* Call some math functions *)
+ r1 := PI/4;
+ writeln('r1 = PI/4 (0.78539...)', r1);
+ writeln('cos(r1) (0.70710...)', cos(r1));
+ writeln('sin(r1) (0.70710...)', sin(r1));
+ writeln('tan(r1) (1.0)', tan(r1));
+
+ r1 := CONST_E;
+ writeln('r1 = CONST_E (2.7182...)', r1);
+ writeln('log(4.5) (1.50407...)', log(4.5));
+ writeln('log2(8) (3.0)', log2(8));
+ writeln('log10(10) (1.0)', log10(10));
+
+ r2 := exp(10);
+ writeln('exp(10) (2.203...e4)', r2);
+
+ r2 := sqrt(121);
+ writeln('sqrt(121) (11.0)', r2);
+
+ (* populate and print some arrays *)
+ writeln;
+ posa[3] := 10;
+ posa[4] := 20;
+ posa[5] := 30;
+ REPEAT i := LOINDEX(posa) TO HIINDEX(posa);
+ writeln('posa[', i:1, '] = ', posa[i]);
+ END_REPEAT;
+
+ writeln;
+ nega[-3] := 1;
+ nega[-2] := 2;
+ nega[-1] := 3;
+ REPEAT i := LOINDEX(nega) TO HIINDEX(nega);
+ writeln('nega[', i:1, '] = ', nega[i]);
+ END_REPEAT;
+
+ (* Do some things with a list *)
+
+ -- check the initial size (should be empty)
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+
+ -- insert elements at the front
+ INSERT(lagg, 10, 0);
+ i := SIZEOF(lagg);
+ writeln('no. of els in lagg = ', i);
+ INSERT(lagg, 20, 0);
+ writeln('no. of els in lagg = ', SIZEOF(lagg));
+
+ -- print some of the elements
+ i := lagg[1];
+ writeln('first in lagg = ', i);
+ writeln('lagg[2] = ', lagg[2]);
+
+ -- check if a value in in the list
+ b := 10 IN lagg;
+ writeln(b); -- should be TRUE
+ b := 30 IN lagg;
+ writeln(b); -- should be FALSE
+
+ -- write all the elements
+ REPEAT i := LOINDEX(lagg) TO HIINDEX(lagg);
+ writeln('lagg[', i:1, '] = ', lagg[i]);
+ println('lagg[', i:1, '] = ', lagg[i]);
+ END_REPEAT;
+
+ (* see what happens with an indeterminate value *)
+ b := FALSE;
+ b := ?;
+ writeln(b);
+ println(b);
+ (* Some more attempts with indeterminate *)
+ i := 2;
+ n := 3*i;
+ writeln(i, n); -- should be 2 6
+ n := 3*?;
+ writeln(i, n); -- should be 2 ?
+ i := ?;
+ n := 3*i;
+ writeln(i, n); -- should be ? ?
+
+END; -- end of compound statement
+ -- but we can have individual statements
+
+
+ (* Try to provide some excitement by making a magic square *)
+ writeln;
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ IF NOT magic_square(n) THEN
+ writeln('I did not like your number which was ', n:1);
+ writeln('If you get it right next time, something magic will happen.');
+ write('Enter an odd number between 1 and 15: ');
+ readln(n);
+ magic_square(n);
+ END_IF;
+
+
+ (* Try a couple of REPEAT statements *)
+ writeln('Test REPEAT (should print -2)');
+ i := -2;
+ REPEAT UNTIL i = 0;
+ writeln(i);
+ println(i);
+ ESCAPE;
+ i := i + 1;
+ END_REPEAT;
+
+ writeln('Test REPEAT (should print 3, 2, 1)');
+ REPEAT i := 3 TO 1 BY -1;
+ writeln(i);
+ END_REPEAT;
+
+
+ (* Try the LIKE operator *)
+ writeln('Test LIKE');
+ writeln(('A' LIKE 'A')); -- should be TRUE
+ writeln(('A' LIKE 'b')); -- should be FALSE
+ writeln(('Page 407' LIKE '$###')); -- should be TRUE
+ writeln(('Page 23' LIKE '$###')); -- should be FALSE
+
+
+ (* Try the REXPR function *)
+ writeln('Test rexpr');
+ writeln(rexpr('A', 'A')); -- should be TRUE
+ writeln(rexpr('A', 'b')); -- should be FALSE
+ writeln(rexpr('Page 407', '[a-zA-Z]+\ [0-9]+')); -- should be TRUE
+ writeln(rexpr('Page 23', '[a-zA-Z]+\ [0-9]')); -- should be FALSE
+
+
+ (* Try an ARRAY OF ARRAY *)
+ a23[1][1] := 11;
+ a23[1][2] := 12;
+ a23[1][3] := 13;
+ a23[2][1] := 21;
+ a23[2][2] := 22;
+ a23[2][3] := 23;
+
+ writeln('Test REPEAT (should be 1 1 11, 1 2 12, 1 3 13, 2 1 21, 2 2 22 etc)');
+ REPEAT n := 1 TO 2;
+ REPEAT i := 1 TO 3;
+ writeln(n, i, a23[n][i]);
+ END_REPEAT;
+ END_REPEAT;
+
+
+ (* do some simple string operations *)
+ s1 := 'string';
+ writeln(s1); -- should be string
+ s2 := s1[2:4];
+ writeln(s2); -- should be tri
+ b := s1 <> s2;
+ writeln(b); -- should be TRUE
+ writeln(s2 + s1); -- should be tristring
+
+
+ (* Assign and print to a user-defined type *)
+ j := 33;
+ writeln(j*3); -- should be 99
+
+ (* Do something with a variable of type ENTITY */
+ ex.attr1 := 33;
+ ex.attr2 := 'The attribute named attr2';
+ ex.attr3 := ex.attr1/3;
+ writeln('ex.attr1 should be 33 and is: ', ex.attr1);
+ writeln('ex.attr2 is: ', ex.attr2);
+ writeln('ex.attr3 should be 11 and is: ', ex.attr3);
+
+END_CODE
+
+
+
+
+
+
+SECTION: Specifying a SPECIAL_ command
+
+ (sec:special)
+
+ This section gives some hints on how to specify a LaTeX command that
+requires some special processing. The faint-hearted should skip this. It is
+assumed that the implementor will have knowledge of LaTeX, C programming, and
+lex and YACC style lexer and parser generator systems.
+
+ There are two ways of defining SPECIAL_ kinds of commands though neither
+is particularly simple. The easiest is by what is termed the coding method.
+This involves modifying the standard actions. The more complicated means is by
+the grammar method, which involves extending the production grammar and,
+typically, also coding new kinds of actions.
+
+ The process of specifying one of the SPECIAL_ kinds of command actions is:
+
+
+ o Seriously question the need for the special command. One is only required
+if the standard actions cannot be coerced into serving the needs of the
+command processing and/or the command grammar is not supported by the L2X
+system.
+ o Design the required entry for the command table.
+ o Decide whether the coding or the grammar method is to be used for
+extending L2X.
+
+ Coding method : Modify the actions in l2xusrlb.c, and possibly add new
+functions in l2xusrlb.c and l2xusrlb.h.
+
+
+ Grammar method : Extend the grammar in l2x.y. Typically it be necessary
+to add new functions to the user-defined library l2xusrlb as well.
+
+ o Compile the modified L2X system. A make file for this is given in
+Appendix (sec:install).
+ o Test the extensions and debug the program.
+
+
+ The l2xlib has many functions that may be of use in this process. Some of
+these are indicated below.
+
+
+
+ o char *strsave(char s[]) saves a string somewhere
+ o void myprint(char s[]) writes a string to the output medium. Its
+particular action is controlled by the set_print and reset_print functions, as
+well as the -p option.
+ o void verbatim_print(char s[]) like myprint, writes a string to the output
+medium. Its actions are controlled by the current print mode, and newlines are
+obeyed (i.e., it ignores any pretty-printing option).
+ o void yyerror(char s[]) used by the lexer and parser to print an error
+message string.
+ o void warning(char s[]) writes a warning message string.
+ o void do_newline() used within the lexer to set internal variables
+whenever a newline is encountered in the input.
+ o void initialise_sysbuf() initialises the system supplied string buffer.
+ o void print_sysbuf() writes the content of the system string buffer to the
+output file.
+ o void copy_sysbuf(char s[]) copies the contents of the system string
+buffer to the user-supplied string. It is the user's responsibility to ensure
+that the string is big enough.
+ o void set_print(PSTRWC pswitch) controls the action of myprint,
+print_newline and verbatim_print. If the input argument is p_default_print
+then the print functions should write to the output file; this is the default
+behavior. If the argument is p_no_print, then no writing occurs. If the
+argument is p_print_to_sysbuf, then the print functions write to the system
+string buffer.
+ o void reset_print() resets the behavior of the print functions. This
+function should always be used after a call to set_print.
+ o int lookup_entry(char s[], int kind) returns the location within the
+command table of the command name given in s of the command type given in
+kind. If kind is DONT_CARE then the position of the first occurrence of s is
+returned.
+ o void get_env_name(char s[]) extracts the name of a LaTeX environment
+from s, which is assumed to have the form \something { environment }. The name
+of the environment is put into the global string env_name.
+ o PSENTRY get_mode_sym(int loc) returns a pointer to the symbol table entry
+at position loc in the command table for the current mode.
+ o int command_type(int loc) returns the system defined kind of command at
+location loc in the command table.
+ o int get_user_type(int loc) returns the user input (TYPE=) kind of command
+at location loc in the command table.
+ o PSTRWC get_t(PSENTRY loc) returns a pointer to the START_TAG=
+specification for symbol entry loc. There are similar functions for other
+tagging specifications.
+ o PSTRWC get_tag_t(PSENTRY loc, int n) returns a pointer to the START_TAG_n
+specification for the n'th argument for symbol entry loc. There are similar
+functions for other argument tagging specifications.
+ o PSTRWC get_param_print(PSENTRY loc, int n) returns a pointer to the print
+control specification for the n'th required argument for symbol entry loc.
+There are similar functions for other print controls.
+ o int get_level(PSENTRY loc) returns the SECTIONING_LEVEL= value for symbol
+entry loc.
+
+
+ The process of specifying a SPECIAL_ is best described via an example.
+
+
+
+
+SUB-SECTION: Example
+
+
+
+ Assume that there is a `non-standard' LaTeX command which has one required
+argument. When this command is processed by LaTeX its effect is to start a new
+section in a document entitled Normative References. Some boilerplate text is
+then typeset (specified within the definition of the command). This
+boilerplate includes two instances of the text from the argument of the
+command. Finally, a description list environment is started.
+
+ In LaTeX terms, this command could have been defined as:
+
+\newcommand{\XXspecial}[1]{\section{Normative References}
+ Some boilerplate text with #1
+ in the middle. Now there is
+ some more boilerplate with #1
+ in the middle of it.
+ \begin{description} }
+
+
+
+ For the purposes of the example, it is desired to replace the occurrence
+of the \XXspecial command by the `normal' section heading for the output
+tagged style, and also print out the boilerplate text including the argument
+text in the right places. The start of the list environment has also to be
+taken into account. The \item optional argument text is to be enclosed in
+parentheses, with a dash before the main text. These requirements are not
+something that can be currently accomplished with the standard L2X system.
+
+ To make the requirements more concrete, if the input LaTeX source
+includes:
+
+....
+\XXspecial{REQ PARAM TEXT}
+
+\item[Ref 1] Text 1.
+\item[Ref 2] Text 2.
+\end{description}
+....
+
+ then the desired output is to look like:
+
+....
+
+</div.1>
+
+<div.1>
+<heading>Normative References</heading>
+
+Some boilerplate text with REQ PARAM TEXT
+in the middle. Now there is
+some more boilerplate with REQ PARAM TEXT
+in the middle of it.
+
+ (Ref 1) -- Text 1.
+ (Ref 2) -- Text 2.
+....
+
+
+
+ Now, let's write a specification for the command table, which we will do
+in pieces, starting with the sectioning tags. In this tagging style, end tags
+for sections take the form </div.1>, and start tags the form <div.1>. The
+titles of sections are enclosed between <heading> and </heading> tags. We also
+want some newlines in the output to set things off. If ? is used as the escape
+character, then we can specify for the sectioning tagging:
+
+SECTIONING_LEVEL= SECT
+START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+END_TAG= "?n</div.1>"
+
+
+
+ There is one required argument and no optional arguments, so we need:
+
+REQPARAMS= 1
+
+
+
+ The LaTeX command also starts off a description environment, so we have to
+set the tags for the \item commands that will follow. This is done by:
+
+START_ITEM= "?n"
+START_ITEM_PARAM= " ("
+END_ITEM_PARAM= ") -- "
+
+
+
+ Most of the work is now completed though we still have to give the command
+name, decide what sort of SPECIAL_ it will be and set the SPECIAL_TOKEN value.
+None of the provided SPECIAL_ types exactly fit this entry as it is a mixture
+of sectioning and list environment, so we will just call it a SPECIAL_COMMAND
+type. To summarize, the effective state of the command table entry is:
+
+TYPE= SPECIAL_COMMAND
+C= NAME= to be specified
+C= SPECIAL_TOKEN= to be specified
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+
+
+
+ For pedagogical purposes, this special will be implemented using both the
+grammar and code methods, and the command names used will be \GRAMMspecial and
+\CODEspecial respectively.
+
+
+
+
+SUB-SUB-SECTION: Grammar method implementation
+
+
+
+ The command name for this implementation will be \GRAMMspecial.
+
+ The grammar method requires changes to the grammar specified in l2x.y.
+
+
+
+ (#) A new token has to be defined, call it GRAMMSPECIAL, in the first part
+of the file. There is a slot for this under the comment /* specials */. An
+integer number, greater than or equal to 10,000 (ten thousand) and less than
+32,768 (2^15), has to be associated with this token. (Footnote: The upper
+limit of (2^15-1) is set by the bison processor.) Further, this number must
+not be the same as any other number associated with any other token. Let us
+use the maximum number 32,767. The relevant portion of l2x.y will look like
+
+ /* specials */
+%token <pos> /* other specials here */
+%token <pos> GRAMMSPECIAL 32767
+ /* precedences */
+
+ This number is used for communication within the L2X system, and is the
+number set as the value of the SPECIAL_TOKEN in the command table. We can now
+finalize the command table entry as:
+
+TYPE= SPECIAL_COMMAND
+NAME= \GRAMMspecial
+SPECIAL_TOKEN= 32767
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+
+
+
+
+ (#) A new production, or productions, has to be added to the grammar. There
+is a place for this at the end of the rules section in the file, under the
+predefined production l2xSpecials. Let us call our new production
+GrammSpecial, and add it as:
+
+l2xSpecials: ASpecial
+ | AnotherSpecial
+ | GrammSpecial
+ ;
+
+ where the ASpecial and AnotherSpecial are pre-existing specials.
+
+
+ (#) The production now has to be defined, specifying the expected syntax
+and required actions. This looks like:
+
+GrammSpecial: GRAMMSPECIAL
+ {
+ start_section($1);
+ myprint(get_t($1));
+ myprint(get_tag_t($1,1));
+ initialise_sysbuf();
+ set_print(p_print_to_sysbuf);
+ }
+ ReqParam
+ {
+ initialise_string(grammbuf);
+ copy_sysbuf(grammbuf);
+ reset_print();
+ prwboiler1();
+ print_sysbuf();
+ prwboiler2();
+ myprint(grammbuf);
+ prwboiler3();
+ start_list($1);
+ }
+ ;
+
+ The actions are enclosed in braces and are defined in terms of C code.
+
+ Once the parser has been given the GRAMMSPECIAL token from the lexer, it
+will attempt to perform the actions within the first set of braces. The first
+of these, start_section($1), is the L2X action for starting a sectioning
+command. Basically, this deals with any closing of prior sections of the
+document and remembering the closing tag for this section. The next two
+actions print the start tags for the command and its required argument, taking
+the strings from the command table. initialise_sysbuf() initializes the system
+string buffer ready for new input. Then the print control is set so that any
+output will be directed into the system string buffer rather than the output
+file. This finishes the first set of actions.
+
+ The production grammar for the required argument comes next. If this is
+incorrect, the parser automatically gives an (uninformative) error message.
+Otherwise, the last set of actions are done. At this point, the text of the
+required argument will be contained in the system string buffer. This is then
+copied to a temporary buffer grammbuf, that we have yet to define, by calling
+copy_sysbuf(grammbuf) having first made sure that this buffer has been cleared
+of any previous contents (the initialise_string(grammbuf) action). The
+printing control must now be reset (reset_print()), or things might get
+corrupted later. A function prwboiler1() is called to print the first part of
+the boilerplate text, followed by printing the contents of the system buffer
+by the action print_sysbuf() (remember that this should contain the text of
+the required argument). The second part of the boilerplate is written by the
+function prwboiler2(). Just for pedagogical purposes, the required argument
+text is written out using the text stored in the temporary buffer
+(myprint(grammbuf)) rather than from the system buffer. The penultimate action
+is the printing of the last piece of boilerplate.
+
+ The final action --- start_list($1) --- is the standard L2X action at the
+start of a list environment. This remembers the various tags for the list
+items to follow.
+
+ A character buffer, grammbuf, is now defined in the initial section of the
+l2x.y file, as:
+
+char grammbuf[80];
+
+ which is intended to be large enough to hold the text of the required
+argument of the command.
+
+ This completes the changes to the grammar file.
+
+
+ (#) The three functions called out in the above actions for printing the
+boilerplate are coded and placed in the user library file l2xusrlb.c and are
+also added to l2xusrlb.h. Here is the relevant code as it would appear in
+l2xusrlb.c.
+
+ /* demonstration string definition */
+
+STRING boiler_string_3 = "\nin the middle of it.\n\n";
+
+ /* demonstration functions */
+
+/* PRWBOILER1 print some demonstration boilerplate */
+void prwboiler1()
+{
+ myprint("\nSome boilerplate text with ");
+} /* end PRWBOILER1 */
+
+/* PRWBOILER2 print some demonstration boilerplate */
+void prwboiler2()
+{
+ myprint("\nin the middle. Now there is\n");
+ myprint("some more boilerplate with ");
+} /* end PRWBOILER2 */
+
+/* PRWBOILER3 yet more demonstration boilerplate */
+void prwboiler3()
+{
+ myprint(boiler_string_3);
+} /* end PRWBOILER1 */
+
+
+
+
+ (#) The system is recompiled, using make, and tested on some example LaTeX
+files.
+
+
+
+
+
+
+
+SUB-SUB-SECTION: Code method implementation
+
+
+
+ This method `merely' requires extending the standard actions to account
+for the new requirements. First, however, we must complete the definition of
+the command table entry. We will call the new command \CODEspecial. Also a
+unique value has to be assigned to the SPECIAL_TOKEN. This must have a value
+greater than or equal to 50,000 (fifty thousand). We will use a value 59,999.
+Later this value is used within the action code to identify the special. The
+command table entry is thus:
+
+TYPE= SPECIAL_COMMAND
+NAME= \CODEspecial
+SPECIAL_TOKEN= 59999
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+
+ which only differs from that for the grammar implemented special in the
+SPECIAL_TOKEN= and the NAME= values.
+
+ Before proceeding further, some explanation of the internals of the L2X
+system is in order.
+
+
+
+ Command table entry : Internally, an array of C structs is used for
+storing the data corresponding to the command table. The struct is fully
+defined in file l2xcom.h, and type PSENTRY is a pointer to an instance of the
+struct. There is an entry in the internal command table for each command.
+Where a command specification is mode-dependent, then the entries for this are
+stored as a list (the command table array is actually an array of lists of
+command specifications, one list per command).
+
+ For the purposes at hand, only a few of the elements are of concern; these
+are kind, parse_kind and special_token. The element kind contains an
+identifier of the TYPE= value; that is, the type of the command as specified
+by the user. The element special_token contains the SPECIAL_TOKEN= value. The
+parse_kind element contains an identifier of the type of command as assigned
+internally by L2X. This last identifier is generated by the table processing
+code in l2xlib.c and corresponds to one of the token values acceptable to the
+parser.
+
+
+ The lexer : The lexer reads the source LaTeX file, looking for LaTeX
+commands (essentially anything starting with a backslash). Each time it finds
+a command it looks it up in the command table array, and sends its parser
+token value (the parse_kind value) and the command table array position to the
+parser.
+
+
+ The parser : Given a token from the lexer, the parser finds the
+appropriate grammar production and performs the specified actions. It is able
+to access command information through having the command table position.
+
+
+ The grammar : The grammar used for the LaTeX general commands (and
+environments) is actually very simple --- the complexity is reserved for the
+lexer and the actions. At the grammar level, no distinction is made between a
+command and an environment. There are a total of 19 different command types
+(tokens), which fall into a smaller number of groups.
+
+ (#) A command with no arguments.
+ (#) A command with just a single optional argument.
+ (#) Commands with a final optional argument and between 1 and 8 required
+arguments.
+ (#) Commands with between 1 and 8 required arguments. In this case it is
+always assumed that there might be an initial optional argument.
+ (#) A command with 9 required arguments.
+ Note that this partitioning is based solely on the number of required
+arguments and the position (if any is declared) of an optional argument.
+
+ For example, if a command/environment is specified in the command table as
+having one required argument and no optional arguments, then this will be
+treated as a command with possibly an initial optional argument and one
+required argument. The grammar for this is:
+
+l2xComm1: COMMAND_1
+ {
+ start_with_opt($1);
+ }
+ OptParam
+ {
+ action_opt_first($1);
+ }
+ ReqParam
+ {
+ action_last_p($1,1);
+ }
+ ;
+
+ where the words in all upper case are grammar tokens, and words in mixed case
+are other grammar productions. The actions are enclosed between braces. The $1
+is the position of the command in the command table array.
+
+
+ Actions : The standard actions are contained in file l2xacts.c. Within
+the code for each standard action, provision is made for calling action code
+for specials. All the functions have the same general structure. Here, for
+instance, is the code for the standard action that is called between the start
+of a command and a first optional argument.
+
+/* START_WITH_OPT start action for command with optional param */
+void start_with_opt(pos)
+int pos; /* position of command in table */
+{
+ int user_kind; /* user-specified command type */
+
+ user_kind = get_user_type(pos);
+
+ switch(user_kind) {
+ case TEX_CHAR: /* the general, non-specials */
+ case CHAR_COMMAND:
+ case COMMAND:
+ case BEGIN_ENV:
+ case END_ENV:
+ case BEGIN_LIST_ENV:
+ case END_LIST_ENV:
+ case SECTIONING:
+ start_it(pos); /* command start action */
+ default_start_with_opt(pos); /* start optional param */
+ break;
+ case SPECIAL: /* the specials */
+ case SPECIAL_BEGIN_ENV:
+ case SPECIAL_END_ENV:
+ case SPECIAL_BEGIN_LIST:
+ case SPECIAL_END_LIST:
+ case SPECIAL_COMMAND:
+ case SPECIAL_SECTIONING:
+ special_start_with_opt(pos);
+ break;
+ default: /* should not be here! */
+ warning("(start_with_opt) Unrecognized command type");
+ break;
+ } /* end switch on user_kind */
+} /* end START_WITH_OPT */
+
+
+
+ The special actions code is in file l2xusrlib.c. The code for these all
+follow the same general pattern. For example, here is the code implementing
+the special action between the start of a command and a first optional
+argument.
+
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+
+ Note that the code as provided just issues a warning message.
+
+
+
+
+ With this background, we will now go on with the example.
+
+
+
+ (#) Decide on how the L2X system will translate your command/environment
+description into its internal grammar command type. In this case it will
+translate into a command with possibly an initial optional argument and one
+required argument.
+
+
+ (#) Examine the grammar for the command and hence determine which standard
+actions will be called. In this case there are three of these, namely
+start_with_opt, action_opt_first and action_last_p. These are the actions that
+might require modification.
+
+
+ (#) Determine what actions are required for your special. Conceptually
+replace the standard actions in the grammar by your actions. Then determine
+how these should be incorporated into the special action code in l2xusrlb. In
+plain language, the grammar and conceptual actions for the example are:
+
+l2xComm1: COMMAND_1
+ {
+ start of as a sectioning command
+ ignore the optional argument as there isn't one
+ }
+ OptParam
+ {
+ finish processing the non-existent optional
+ get ready to store the argument text in a buffer
+ }
+ ReqParam
+ {
+ print the boilerplate and argument text
+ start the description list
+ }
+ ;
+
+ Note that this is essentially the same as we did for the grammar
+implementation for \GRAMMspecial, except that there is the additional optional
+argument to be dealt with.
+
+
+ (#) Modify the requisite special action code.
+
+ In the example, three standard actions have to be modified. Here is the
+modification to special_start_with_opt:
+
+/* SPECIAL_START_WITH_OPT special start for command with opt param */
+void special_start_with_opt(pos)
+int pos; /* command position in table */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ codespecial_start(pos);
+ default_start_with_opt(pos);
+ break;
+
+ /* end of cases for specials */
+ default: /* should not be here! */
+ warning("(special_start_with_opt) Unrecognized SPECIAL");
+ tdebug_str_int("SPECIAL_TOKEN =",special_kind);
+ break;
+ } /* end of switch on user_kind */
+} /* end SPECIAL_START_WITH_OPT */
+
+ The addition is done by adding a new case 59999: together with appropriate
+code. The number 59999 is that corresponding to the value for SPECIAL_TOKEN=
+in the command table specification of \CODEspecial. The function
+codespecial_start is to be written, while default_start_with_opt is an L2X
+defined function which initiates processing of an initial optional argument.
+
+ Similarly, here is the modification to special_action_opt_first:
+
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ default_end_start_opt(pos);
+ codespecial_p1(pos);
+ break;
+
+ /* end of cases for specials */
+
+ where codespecial_p1 is to be written and default_end_start_opt is the
+standard L2X action at the end of an initial optional argument.
+
+ Finally, here is the modification to special_action_last_p:
+
+/* SPECIAL_ACTION_LAST_P action after last req argument */
+void special_action_last_p(pos,p)
+int pos; /* position of command in table */
+int p; /* number of last argument */
+{
+ int special_kind; /* user-specified special token */
+
+ special_kind = get_special_token(pos);
+
+ switch(special_kind) {
+ /* additional cases for specials added here */
+ case 59999: /* example coded special */
+ if (p == 1) { /* has only one req param */
+ codespecial_end(pos);
+ }
+ break;
+
+ /* end of cases for specials */
+ /* stuff deleted to save space */
+
+
+
+
+ (#) Code the functions for the new actions.
+
+ Code for these functions should be put into file l2xusrlb.c and file
+l2xusrlb.h modified accordingly.
+
+ Here is the code for the three codespecial_ functions.
+
+char codebuf[80]; /* a string buffer */
+
+/* CODESPECIAL_START actions for start of CODEspecial command */
+void codespecial_start(pos)
+int pos; /* command table position */
+{
+ start_section(pos); /* do start of sectioning */
+ myprint(get_t(pos)); /* print start tag */
+} /* end CODESPECIAL_START */
+
+/* CODESPECIAL_P1 actions at start of CODEspecial param 1 */
+void codespecial_p1(pos)
+int pos; /* command table position */
+{
+ myprint(get_tag_t(pos,1)); /* print 1st param start tag */
+ initialise_sysbuf(); /* clear system string buffer */
+ set_print(p_print_to_sysbuf); /* put arg text into sys buffer */
+} /* end CODESPECIAL_P1 */
+
+/* CODESPECIAL_END actions at end of CODEspecial command */
+void codespecial_end(pos)
+int pos; /* command table position */
+{
+ initialise_string(codebuf); /* clear this string buffer */
+ copy_sysbuf(codebuf); /* copy sys buffer into codebuf */
+ reset_print(); /* normal printing */
+ prwboiler1(); /* print some boilerplate */
+ print_sysbuf(); /* print system buffer */
+ prwboiler2(); /* print more boilerplate */
+ myprint(codebuf); /* print codebuff */
+ prwboiler3(); /* print yet more boilerplate */
+ start_list(pos); /* start a list environment */
+} /* end CODESPECIAL_END */
+
+ Note that these actions are almost identical to those that were used within
+the grammar when implementing the \GRAMMspecial command.
+
+
+ (#) Compile the modified system and test it on example LaTeX files.
+
+
+
+
+
+
+
+SUB-SECTION: Notes
+
+
+
+
+
+ (#) Installation of a SPECIAL_ can be limited to making changes to the
+parser (file l2x.y) and/or the user library (files l2xusrlb.c and l2xusrlb.h).
+It should not be necessary to touch any other part of the system.
+
+
+ (#) Changes to l2x.y will necessitate executing the parser generator on
+this file and system compilation. Changes to the other files will only
+necessitate compilation.
+
+
+ (#) Always use the myprint, verbatim_print or print_sysbuf functions for
+printing because they incorporate the print control capability.
+
+
+ (#) The printing in the above example is trivial. However, it is good
+practice to define printed output separately from the parser. It makes for
+easier maintenance. If, for example the boilerplate above was several thousand
+characters, it might have been an idea to store the text in a file, or files,
+and then have the boilerplate printing functions read from the file(s). If the
+text is in a state of flux this could be a good design decision in any case,
+as changing the text would only involve modifying the text file(s) and avoid
+recompilation of L2X.
+
+
+
+
+
+SUB-SUB-SECTION: An updated method
+
+
+
+ The above descriptions of installing a SPECIAL_ command were written for
+the original release of the L2X system, which did not have the input and
+output specification facilities currently available within a command table.
+Below is given a possible command table entry using these facilities.
+
+TYPE= SPECIAL_COMMAND
+NAME= \THIRDspecial
+ C= SPECIAL_TOKEN= set the appropriate number
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ RESET_SYSBUF:
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ PRINT_P1= TO_SYSBUF
+ END_TAG_1=
+ STRING: "?nSome boilerplate text with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle. Now there is?n"
+ STRING: "some more boilerplate with "
+ SOURCE: SYSBUF
+ STRING: "?nin the middle of it.?n"
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+
+ The actual implementation of this as either a grammar special or a code
+special is left as an exercise for the reader. Basically it involves the
+deletion of the specific print action and buffer code because this is now
+handled automatically via the command table specification.
+
+
+
+APPENDICES
+
+
+
+SECTION: Example command table file for de-TeX ing
+
+ (sec:detexing)
+
+ This appendix provides the skeleton of a command table file that could be
+used for de-TeX ing a LaTeX document.
+
+
+
+C= detex.ct command table file for ltx2x to deTeX source
+
+C= -----------------------------------escape sequences
+
+C= don't use default here as it may clash with command name output
+ESCAPE_CHAR= ?
+C= keep tye default vaues for the rest
+
+C= ----------------------------------- the built in commands
+TYPE= BEGIN_DOCUMENT
+END_TYPE
+
+TYPE= END_DOCUMENT
+END_TYPE
+
+TYPE= BEGIN_VERB
+END_TYPE
+
+TYPE= END_VERB
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= END_VERBATIM
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+END_TYPE
+
+TYPE= END_DOLLAR
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= " "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_BEGIN
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+TYPE= OTHER_END
+ PRINT_CONTROL= NO_PRINT
+END_TYPE
+
+C= throw away naked braces
+TYPE= LBRACE
+END_TYPE
+
+TYPE= RBRACE
+END_TYPE
+
+C= Pretty printing will probably be applied. Indent start of paragraphs
+TYPE= PARAGRAPH
+ START_TAG= "?n?n "
+END_TYPE
+
+C= -------------------------------------(La)TeX special characters
+
+C= hash (for use in \def s )
+TYPE= TEX_CHAR
+NAME= #
+END_TYPE
+
+C= ampersand (tabular column delimiter, replace by some spaces)
+TYPE= TEX_CHAR
+NAME= &
+ START_TAG= " "
+END_TYPE
+
+C= twiddle (unbreakable space)
+TYPE= TEX_CHAR
+NAME= ~
+ START_TAG= " "
+END_TYPE
+
+C= underscore (math subscript)
+TYPE= TEX_CHAR
+NAME= _
+ START_TAG= "_"
+END_TYPE
+
+C= caret (math superscript)
+TYPE= TEX_CHAR
+NAME= ^
+ START_TAG= "^"
+END_TYPE
+
+C= at
+TYPE= TEX_CHAR
+NAME= @
+ START_TAG= "@"
+END_TYPE
+
+C= ------------------------- default single character commands
+C= (replace by appropriate character)
+
+C= LaTeX start a new line
+TYPE= CHAR_COMMAND
+NAME= \\
+ START_TAG= "?n"
+END_TYPE
+
+C= small space
+TYPE= CHAR_COMMAND
+ NAME= \,
+START_TAG= " "
+END_TYPE
+
+C= end of sentence space
+TYPE= CHAR_COMMAND
+NAME= \@
+ START_TAG= " "
+END_TYPE
+
+C= hash
+TYPE= CHAR_COMMAND
+NAME= \#
+ START_TAG= "#"
+END_TYPE
+
+C= dollar
+TYPE= CHAR_COMMAND
+NAME= \$
+ START_TAG= "$"
+END_TYPE
+
+C= ampersand
+TYPE= CHAR_COMMAND
+NAME= \&
+ START_TAG= "&"
+END_TYPE
+
+C= underscore
+TYPE= CHAR_COMMAND
+NAME= \_
+ START_TAG= "_"
+END_TYPE
+
+C= percent
+TYPE= CHAR_COMMAND
+NAME= \%
+ START_TAG= "%"
+END_TYPE
+
+C= left brace
+TYPE= CHAR_COMMAND
+NAME= \{
+ START_TAG= "{"
+END_TYPE
+
+C= right brace
+TYPE= CHAR_COMMAND
+NAME= \}
+ START_TAG= "}"
+END_TYPE
+
+C= optional hyphenation
+TYPE= CHAR_COMMAND
+NAME= \-
+ START_TAG= ""
+END_TYPE
+
+C= ----------------------------- General LaTeX
+
+TYPE= COMMAND
+NAME= \caption
+ START_TAG= "?n CAPTION: "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+ START_ITEM= "?n o "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+ START_ITEM= "?n -- "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ START_TAG= "?n"
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "?n"
+ START_ITEM= "?n "
+ END_ITEM_PARAM= " : "
+END_TYPE
+
+TYPE= END_LIST_ENV
+ NAME= description
+START_TAG= "?n"
+END_TYPE
+
+C= replace \footnote with parenthesized text
+TYPE= COMMAND
+NAME= \footnote
+ START_TAG= " ("
+ END_TAG= ") "
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+END_TYPE
+
+C= ----------------------- sectioning (keep headers only)
+
+C= repeat for all the other sectioning commands
+TYPE= SECTIONING
+NAME= \section
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ OPT_PARAM= FIRST
+ PRINT_OPT= NO_PRINT
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= repeat for all the other starred sectioning commands
+TYPE= SECTIONING
+NAME= \section*
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n"
+ REQPARAMS= 1
+ END_TAG_1= "?n?n"
+END_TYPE
+
+C= and whatever else is interesting
+END_CTFILE=
+
+
+
+
+
+
+SECTION: LaTeX to HTML translation
+
+ (sec:htmling)
+
+ The command table file l2h.ct contains a set of commands that enable
+simple LaTeX documents to be translated into HTML tagged documents for display
+using a World Wide Web browser. At a minumum this command table can be used
+for conversion of the LaTeX source of this manual. It can also handle some
+very simple mathematics but not pictures. (Footnote: HTML itself cannot handle
+pictures directly (i.e., there is no equivalent to the LaTeX picture
+environment), and can only handle simple mathematics.) The specification for
+the HTML tags was taken from Musciano and Kennedy [ MUSCIANO96].
+
+ Generally speaking and subject to the above limitations, a LaTeX document
+can be translated to HTML without the document having been planned for this
+purpose, with one exception. The exception is that a new LaTeX command should
+be used in the document preamble. I have called this \mltitle and its purpose
+to to define the contents of the header for the HTML text. The definition of
+this command is:
+
+\newcommand{\mltitle}[1]{}
+
+ That is, as far as LaTeX is concerned, the argument to the command is thrown
+away and is a non-event. As far as the l2h.ct command table is concerned the
+argument is the header title. As an example, this manual starts with:
+
+...
+\mltitle{LaTeX to X translator}
+\begin{document}
+\title{\lx: A \LaTeX{} to X Auto-tagger}
+...
+
+ which gets converted into:
+
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+</h1>
+...
+
+ If the \mltitle command is not used, then the effect is to have an empty
+<title> in the <head> of the HTML document.
+
+ Several aspects of the design of l2h.ct in the context of the conversion
+of typical LaTeX documents have been discussed as examples in the body of the
+manual. However, there are some aspects specific to the translation of this
+document should be mentioned. These stem from the fact that HTML has no tags
+corresponding to to the LaTeX \verb command or verbatim environment which
+switch off the meanings of special characters.
+
+ HTML treats the characters <, >, & and # specially. Within a
+<pre>...</pre> the browser honours the line breaks but does not switch off the
+meanings of the special characters. In LaTeX, the \verb command switches off
+all special characters but prohibits any line breaking. The verbatim
+environment both honours line breaks and switches off all special characters.
+The difficulty with this particular document is that I want to show
+author-formatted HTML source, and that is not easly possible, unlike using the
+LaTeX verbatim environment for showing user-formatted LaTeX source.
+
+ The problem was solved through the use of two LaTeX environments. The
+first of these is latexonly which is used for input that is to be processed
+normally by LaTeX but which is to be totally ignored by L2X. The other
+environment is htmlverbatim which is used for input that is to be totally
+ignored by LaTeX but which is to be processed by L2X into an HTML <pre>
+environment.
+
+ A package file has been written which provides some addtional commands and
+environments.
+
+% ltx2html.sty --- Some useful commands and environments when using
+% ltx2x to convert from LaTeX to HTML tagging.
+%
+% Author: Peter Wilson August 1996
+%
+\ProvidesPackage{ltx2html}[1996/08/29 ltx2x HTMLing]
+\RequirePackage{html} % the package file for the Perl program
+ % latex2html
+
+% The document title for the WWW browser.
+% If used, must be placed in the preamble.
+\newcommand{\mltitle}[1]{}
+
+% argument is for processing by LaTeX only
+\providecommand{\latex}[1]{#1}
+
+% argument is for HTML processing only
+\providecommand{\html}[1]{}
+
+% print argument as an SGML/HTML start tag
+\newcommand{\ST}[1]{\texttt{<#1>}}
+
+% print argument as an SGML/HTML end tag
+\newcommand{\ET}[1]{\texttt{</#1>}}
+
+% print HTML special characters
+\newcommand{\Amp}{\&}
+\newcommand{\GT}{\texttt{>}}
+\newcommand{\LT}{\texttt{<}}
+\newcommand{\HASH}{\#}
+
+% treat contents as a LaTeX comment but
+% translate contents into an HTML "verbatim" environment
+% Use as: \begin{htmlverbatim} ... \end{htmlverbatim}
+\excludecomment{htmlverbatim}
+
+\endinput
+
+
+
+ | \excludecomment{htmlverbatim}
+
+ \endinput
+
+ The command table entries for some of these are:
+
+TYPE= COMMAND
+NAME= \Amp
+ START_TAG= "&amp;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \GT
+ START_TAG= "&gt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \LT
+ START_TAG= "&lt;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \HASH
+ START_TAG= "&#035;"
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ST
+ START_TAG= "&lt;"
+ END_TAG= "&gt;"
+ REQPARAMS= 1
+END_TYPE
+
+TYPE= COMMAND
+NAME= \ET
+ START_TAG= "&lt;/"
+ END_TAG= "&gt;"
+ REQPARAMS= 1
+END_TYPE
+
+
+
+ Finally, as an example, this is how some of the prior example text could
+be written in the source of this document.
+
+\begin{latexonly}
+\begin{verbatim}
+<html>
+<head>
+<title>LaTeX to X translator</title>
+</head>
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+</h1>
+...
+
+ \end{verbatim}
+ \end{latexonly}
+
+
+\begin{htmlverbatim}
+<html>
+<head>
+<title>LaTeX to X translator\ET{title}
+\ET{head}
+<body>
+
+<h1 align=center>
+ LTX2X: A LaTeX to X Auto-tagger
+\ET{h1}
+...
+\end{htmlverbatim}
+
+
+
+ |
+
+ Reading the LaTeX source of this document will reveal some other details.
+Admittedly the problem was compounded by the fact that this document contains
+demonstrations of both LaTeX and HTML commands which will be processed through
+both LaTeX and HTML browsers, thus a modicum of care is required to
+appropriately process both sets of special characters.
+
+
+
+
+SECTION: Known limitations
+
+ (sec:limitations)
+
+ L2X does not do everything that it might (and probably never will). The
+following are some of the things that it does not do.
+
+
+
+ o It does not understand the LaTeX \input or \include commands --- it just
+reads the source file as given. It may be useful to pre-process the source
+file through a program that will automatically incorporate included files into
+a LaTeX root file [ PRW94b].
+
+
+ o The \newcommand and friends do not readily fit into the command patterns
+that L2X can deal with. In particular, if it comes across a \newcommand
+specification for a command that is specified in the command table,
+interesting results might occur (for example, all the following output could
+be thrown away if the command takes any arguments).
+
+ For instance, if the document and the command table contain:
+
+\newcommand{\lx}{LTX2X}
+....
+The \lx\ program ...
+
+TYPE= COMMAND
+NAME= \lx
+ START_TAG= "LTX2X"
+END_TYPE
+
+ then there is usually no problem. On the other hand, if the document and the
+command table contain:
+
+\newcommand{\fd}[1]{\texttt{#1}}
+....
+where \fd{InputFile} is the name ...
+
+TYPE= COMMAND
+NAME= \fd
+ REQPARAMS= 1
+END_TYPE
+
+ then there may be a problem, which might be as `minor' as L2X reporting a
+parse error when it has reached \newcommand{\fd} in the input file and then
+carrying on, or it may be more serious.
+
+
+ o There is a slight problem with optional arguments. L2X always takes the
+first close bracket (]) after the opening bracket as signalling the end of the
+argument text. This occurs even if the close bracket is enclosed in braces
+(i.e. {]}). Opening brackets within optional argument text are handled
+correctly.
+
+
+ o It cannot sensibly handle LaTeX constructs of the form {\em emph text}.
+That is, except for command arguments, it does not recognize {...} as a
+grouping construct, so cannot successfully tag the end of the emph text in the
+example. On the other hand, if constructs like \emph{emph text} or
+\begin{em}emph text\end{em} are used instead, start and end tags can be
+generated, given appropriate specifications in the command table.
+
+
+ o It assumes that all commands that take arguments are written so that each
+argument is enclosed in braces. For example, the superscripting command should
+be written as ^{2} and not as ^2. Similarly, accent commands should be written
+as \={o} rather than \=o, and so on.
+
+
+ o There has not been time to test all aspects of the EXPRESS-A interpreter.
+It is possible that this may not perform quite as advertised. In particular
+dynamic aggregates have not been fully implemented. For example:
+
+LIST OF INTEGER;
+
+ appears to be handled correctly. More complicated constructs involving
+dynamic aggregates, such as
+
+ARRAY [1:7] OF LIST OF ARRAY [-21:21] OF INTEGER;
+
+ have not been tested. It is improbable that BAG will work; the status of SET
+is similar and additionally the uniqueness test for set membership has not
+been implemented.
+ o No doubt other limitations will come to light as L2X gets more use. On
+the other hand, L2X has been able to handle a broader range of cases than it
+was designed to address.
+
+
+
+
+
+
+
+SECTION: Command table summary
+
+ (sec:summary)
+
+ This section summarizes the commands and specifications available for
+defining a command table.
+
+
+
+
+SUB-SECTION: Special print characters
+
+
+
+ The combination of an escape character and another character can be used
+to specify certain non-visible characters within a tag string. The commands
+are given in Table (tab:spc).
+
+
+
+ CAPTION: Special print character commands.
+ (Table: tab:spc)
+ Command | Default
+ AUDIBLE_ALERT_CHAR= | a
+ BACKSPACE_CHAR= | b
+ CARRIAGE_RETURN_CHAR= | r
+ ESCAPE_CHAR= | \
+ FORMFEED_CHAR= | f
+ HEX_CHAR= | x
+ HORIZONTAL_TAB_CHAR= | t
+ NEWLINE_CHAR= | n
+ VERTICAL_TAB_CHAR= | v
+
+
+
+ These commands take one character as their value. If any commands are not
+specified, then the default value is used. These commands, if used, must be at
+the beginning of the command table before any TYPE= commands, although their
+ordering is not significant among themselves.
+
+
+
+
+SUB-SECTION: EXPRESS-A code initialization
+
+
+
+ The keyword CODE_SETUP= indicates that the following part of the command
+table, up until the END_CODE keyword, contains EXPRESS-A code declarations
+and/or statements. If used, this block must come before any of the TYPE=
+commands.
+
+
+
+
+SUB-SECTION: Comments and file inclusion
+
+
+
+ A comment within a command table file is any line starting with C= .
+
+ A file can be included within another command table file with the command
+line
+
+INCLUDE= FileName
+
+ where FileName is the name of the file to be included. The INCLUDE= command
+cannot appear between the command pair TYPE= and its following END_TYPE.
+
+ The end of a command table file is either the physical end of the file or
+the command END_CTFILE=, whichever occurs first.
+
+
+
+
+SUB-SECTION: Command types
+
+
+
+ All command type specifications have the general form:
+
+TYPE= CommandType
+NAME= CommandName
+ C= a possibly empty list of mode-independent commands
+ C= possibly sets of mode-dependent commands
+END_TYPE
+
+ where CommandType is a keyword identifying the kind of command being
+specified and CommandName is the identifier of a LaTeX command or environment.
+The potential set of commands that can be used between the TYPE= and END_TYPE
+commands depends on the kind of command being specified, but the special print
+character commands, Table (tab:spc), and the INCLUDE= command cannot appear
+within a type specification. All command specifications, except for the built
+in command types (see Table (tab:rct)), must include at least a NAME= command.
+The ordering of commands within a type specification is not significant. The
+ordering of type specifications within a command table file is not
+significant.
+
+ The NAME= command takes as its value the name of a LaTeX command or
+environment. The name must be written exactly as it would appear in a LaTeX
+source file. That is, \command for any command except \begin{} or \end{}, and
+as env for an environment begun as \begin{env} or ended by \end{env}.
+
+
+
+
+SUB-SUB-SECTION: Built in command types
+
+
+
+ Table (tab:rct) lists the keywords for the built in command types.
+
+
+
+ CAPTION: Built in command type keywords.
+ (Table: tab:rct)
+ Keyword | LaTeX command
+ BEGIN_DOCUMENT | \begin{document}
+ BEGIN_DOLLAR | $ at start of in-text math
+ BEGIN_VERB | \verb or \verb* and its following character
+ BEGIN_VERBATIM | \begin{verbatim} or \begin{verbatim*}
+ END_DOCUMENT | \end{document}
+ END_DOLLAR | $ at end of in-text math
+ END_VERB | the ending character for \verb or \verb*
+ END_VERBATIM | \end{verbatim} or \end{verbatim*}
+ LBRACE | {
+ OTHER_BEGIN | of the form \begin{env} not specified elsewhere
+ OTHER_COMMAND | of the form \comm not specified elsewhere
+ OTHER_END | of the form \end{env} not specified elsewhere
+ PARAGRAPH | blank source line
+ RBRACE | }
+ SLASH_SPACE | \
+
+
+
+ The built in command type specifications can only sensibly use two kinds
+of actions --- those specified at the start of the command (e.g., PC_AT_START=
+and START_TAG=) and/or actions at the end of the command (e.g., PC_AT_END and
+END_TAG=). The NAME= command must not be used.
+
+ The OTHER_ types are an exception to the above, in that they can include
+the command line PRINT_CONTROL= NO_PRINT.
+
+ L2X checks the command table for the presence of these required types. If
+one or more have not been specified, then they are automatically added to the
+command table with default values (e.g. empty strings) for the tags, and a
+warning message is printed giving the default value(s).
+
+
+
+
+SUB-SUB-SECTION: Optional command types
+
+
+
+ For discussion purposes, the optional command types have been tabulated in
+different categories. The basic distinction between these categories is the
+sets of commands that are permissible within the command specification.
+
+ At a minimum, all the specifications must include a NAME= command and must
+not contain any PRINT_CONTROL= or INCLUDE= commands or the special print
+character commands listed in Table (tab:spc).
+
+ The keywords for the general command types are given Table (tab:gct).
+
+
+
+ CAPTION: General command type keywords.
+ (Table: tab:gct)
+ Keyword | LaTeX command form
+ TEX_CHAR | LaTeX special characters (except { } $)
+ CHAR_COMMAND | \c, where c is non-alphabetic
+ COMMAND | \command except for sectioning or picture commands
+ BEGIN_ENV | \begin{env} except for \item lists
+ END_ENV | \end{env} except for \item lists
+ VCOMMAND | a \verb-like command
+ BEGIN_VENV | start of a verbatim-like environment
+ END_VENV | end of a verbatim-like environment
+
+
+
+ A general command type specification can include any of the tagging and
+print option commands. They cannot contain a SECTION_LEVEL= command, nor can
+they contain any of the _ITEM_ commands.
+
+ The keywords for the specific command types are given in Table (tab:sct).
+
+
+
+ CAPTION: Specific command type keywords.
+ (Table: tab:sct)
+ Keyword | LaTeX command form
+ BEGIN_LIST_ENV | \begin{env} for \item lists
+ BEGIN_PICTURE_CC | \begin{pic}()()
+ END_LIST_ENV | \end{env} for \item lists
+ END_PICTURE | \end{pic}
+ PICTURE_CCPP | \pic()(){}{}
+ PICTURE_CO | \pic()[]
+ PICTURE_COP | \pic()[]{}
+ PICTURE_CP | \pic(){}
+ PICTURE_OCC | \pic[]()()
+ PICTURE_OCCC | \pic[]()()()
+ PICTURE_OCO | \pic[]()[]
+ PICTURE_PCOP | \pic{}()[]{}
+ SECTIONING | \command for a document section
+ COMMAND_OOP | \com[][]{}
+ COMMAND_OOOPP | \com[][][]{}{}
+ COMMAND_OPO | \com[]{}[]
+ COMMAND_POOOP | \com{}[][][]{}
+ COMMAND_POOP | \com{}[][]{}
+ COMMAND_POOPP | \com{}[][]{}{}
+
+
+
+ A BEGIN_LIST_ENV specification should include at least a START_ITEM=
+command. The other _ITEM_ commands are optional. Other commands follow the
+rules for the general command types.
+
+ The potential commands for the _PICTURE_ commands are the same as for the
+general commands, with the exception that commands related to optional
+argument processing are not available for use.
+
+ A SECTIONING command specification must include a SECTIONING_LEVEL=
+command. Other commands follow the rules for the general command types.
+
+ The keywords for the special command types are given in Table
+(tab:specct).
+
+
+
+ CAPTION: Special command type keywords.
+ (Table: tab:specct)
+ Keyword | LaTeX command form
+ SPECIAL | reserved for possible future use
+ SPECIAL_BEGIN_ENV | \begin{env} except for \item lists
+ SPECIAL_BEGIN_LIST | \begin{env} for \item lists
+ SPECIAL_COMMAND | \command
+ SPECIAL_END_ENV | \end{env} except for \item lists
+ SPECIAL_END_LIST | \end{env} for \item lists
+ SPECIAL_SECTIONING | \command for a document section
+
+
+
+ Apart from the general restrictions on the allowed commands within a
+specification, there are no restrictions on the commands that can be included
+within the specification of a SPECIAL_ command. It is up to the creator of the
+special to decide what is appropriate. However, each SPECIAL_ specification
+must include the command
+
+SPECIAL_TOKEN= N
+
+ where N is an integer number (with 10000 <= N <= 32767 for a grammar
+special, or N > 50000 for a code special) that has been specified within L2X
+as being identified with the grammar and actions corresponding to the value of
+the NAME= command for the SPECIAL_.
+
+
+
+
+SUB-SECTION: Tag specification commands
+
+
+
+
+
+
+SUB-SUB-SECTION: Arguments
+
+
+
+ The commands relating to the specification of LaTeX command arguments are
+given in Table (tab:param).
+
+
+
+ CAPTION: Argument commands.
+ (Table: tab:param)
+ Command | Value
+ OPT_PARAM= | FIRST or LAST
+ REQPARAMS= | Integer. The number of required arguments
+
+
+
+ The OPT_PARAM= command specifies that the LaTeX command takes one optional
+argument and it is the FIRST or LAST in the argument list.
+
+ The REQPARAMS= command specifies that the LaTeX command has Integer number
+of required arguments. Integer must be between one and nine (Footnote: Or
+eight if OPT_PARAM= is specified.) inclusive.
+
+ Absence of these commands implies that the relevant LaTeX command has no
+arguments of the unspecified kind.
+
+
+
+
+SUB-SUB-SECTION: Tag actions
+
+
+
+ The commands for specifying the tag actions are summarized in Table
+(tab:tag). The _ITEM_ commands can only be used within a BEGIN_LIST_ENV or a
+SPECIAL_ command specification.
+
+
+
+ CAPTION: Tag commands.
+ (Table: tab:tag)
+ Command | Application
+ END_ITEM= | actions after \item text
+ END_ITEM_PARAM= | actions after \item optional argument
+ END_OPT= | actions after optional argument
+ END_TAG= | actions after all arguments processed
+ END_TAG_n= | actions after n'th required argument
+ START_ITEM= | actions before \item
+ START_ITEM_PARAM= | actions before \item optional argument
+ START_OPT= | actions before optional argument
+ START_TAG= | actions at start of command
+ START_TAG_n= | actions before n'th required argument
+
+
+
+ Each of these commands can specify a list of actions to be performed;
+typically this is just to print a text string. A string is any set of
+characters enclosed in double quote marks. The string can include any special
+printing characters. The text string starts immediately after the first double
+quote and ends immediately before the last double quote. The string cannot
+include a physical linebreak within the command table file. If the first
+action is to print a string then the string may be placed on the same line as
+the keyword.
+
+ The actions are listed one per line and are performed in the order they
+are listed. Table (tab:tagaction) lists the action commands.
+
+
+
+ CAPTION: Tag actions.
+ (Table: tab:tagaction)
+ Keyword | Value | Application
+ STRING: | text string | Print the string
+ SOURCE: | BUFFER num | Print the contents of buffer number num
+ SOURCE: | FILE name | Print the contents of file name
+ SOURCE: | SYSBUF | Print the contents of the system buffer
+ RESET_BUFFER: | num | Reset the buffer num
+ RESET_FILE: | name | Reset the file name
+ RESET_SYSBUF: | | Reset the system buffer
+ SWITCH_TO_BUFFER: | num | Print to buffer number num
+ SWITCH_TO_FILE: | name | Print to file called name
+ SWITCH_TO_SYSBUF: | | Print to the system buffer
+ SWITCH_BACK: | | Reset the print mode
+ SET_MODE: | name | Set the mode to name
+ RESET_MODE: | | Reset the mode to its prior value
+ CODE: | | Start of a set of EXPRESS-A statements
+
+
+
+
+
+
+SUB-SUB-SECTION: Print control
+
+
+
+ The print control commands are summarized in Table (tab:print). These are
+used to set the print mode at the start and end of a command, and for each
+argument. The exception is the PRINT_CONTROL= command which can only be used
+within an OTHER_ command type specification, and which is the only print
+control that can be specified for the OTHER_ commands.
+
+
+
+ CAPTION: Print control commands.
+ (Table: tab:print)
+ Command | Application
+ PRINT_CONTROL= | printing of OTHER_ commands
+ PC_AT_START= | set printing at start of command
+ PC_AT_END= | set printing at end of command
+ PRINT_OPT= | printing of optional argument
+ PRINT_Pn= | printing of n'th required argument
+
+
+
+ The values that these commands may take are given in Table (tab:pcvalues).
+These direct where any print output is to be directed. The default is to send
+all output the the file named as the output on the command line when starting
+L2X.
+
+
+
+ CAPTION: Print control values.
+ (Table: tab:pcvalues)
+ Value | Application
+ NO_PRINT | Do not print at all
+ TO_SYSBUF | Print to the system buffer
+ TO_BUFFER num | Print to buffer number num
+ TO_FILE name | Print to file called name
+ NO_OP | Do not do any processing
+ RESET | Reset the print mode
+
+
+
+ NO_PRINT and NO_OP both produce no printed output. However, in the NO_OP
+case the lexer handles all the processing, and effectively just ignores the
+source document text. In the NO_PRINT case, the source text is processed as
+normal, but the printing is directed to a black hole.
+
+
+
+
+SUB-SUB-SECTION: Sectioning
+
+
+
+ SECTIONING command specifications require a SECTIONING_LEVEL= command.
+The values that this can take are listed in Table (tab:level).
+
+
+
+ CAPTION: Sectioning level values.
+ (Table: tab:level)
+ Value | Application
+ PART | sectioning equivalent to \part
+ CHAPTER | sectioning equivalent to \chapter
+ SECT | sectioning equivalent to \section
+ SUBSECT | sectioning equivalent to \subsection
+ SUBSUBSECT | sectioning equivalent to \subsubsection
+ PARA | sectioning equivalent to \paragraph
+ SUBPARA | sectioning equivalent to \subprargraph
+
+
+
+ A sectioning command specification uses the END_TAG= text tag differently
+from its use by any other specification. In this case, the tag is printed at
+the closure of the text forming the body of the section of the document. A
+document section is considered to be closed when it is followed by a higher
+level sectioning command. The values in Table (tab:level) are listed in
+decreasing level. That is, a section at level CHAPTER is at a higher level
+than a section at level PARA.
+
+
+
+ NOTE : For the use of writers of SPECIAL_ command specifications,
+SECTIONING_LEVEL= can be given some additional values. These are PARTm2 and
+PARTm1 for levels respectively two and one higher than PART, and SUBPARAp1 and
+SUBPARAp2 for levels respectively one and two lower than SUBPARA.
+
+
+
+
+
+SECTION: System installation
+
+ (sec:install)
+
+ This section describes how to install the L2X program and some of the
+internal size limits within L2X.
+
+ The basic L2X system requires the following source files:
+
+ l2x.l : the lexer source.
+ l2x.y : the parser source.
+ l2xlib.c, l2xlib.h : main program and support functions.
+ l2xlibtc.h : header file containing keywords and their representations as
+strings.
+ l2xcom.h : header file for all system components (except for getopt,
+srchenv and the interpreter).
+ l2xacts.c, l2xacts.h : standard action functions.
+ l2xusrlb.c, l2xusrlb.h : special actions and user-defined functions.
+ strtypes.h : header file with some type definitions.
+ getopt.c, getopt.h : functions for handling command line options [Chapter
+6 LIBES93].
+ srchenv.c, srchenv.h : functions for searching directories for files
+[page 747 HOLUB90].
+
+
+ The EXPRESS-A interpreter also requires the following files:
+
+ l2xistup.c : the interface between the main part of L2X and the
+interpreter.
+ l2xicmon.h : header file for the interface.
+ l2xirtne.c, l2xistd.c, l2xidecl.c, l2xistmt.c, l2xiexpr.c : the files
+that contain the code for parsing EXPRESS-A. Respectively they deal with
+functions and procedures, the built-in functions, declarations, statements,
+and expressions.
+ l2xiprse.h : header file for parsing.
+ l2xixutl.c, l2xiexec.h : utility routines supporting the execution module
+and for managing the interpreter's stack.
+ l2xixstd.c, l2xixstm.c, l2xixxpr.c : functions for executing the
+EXPRESS-A built in functions, statements and expressions.
+ l2xirexp.c, l2xirexpr.h : general functions for processing and executing
+regular expressions.
+ listsetc.c, listsetc.h : general functions for processing lists.
+ l2xiscan.c, l2xiscan.h : lexing routines for the interpreter.
+ l2xisymt.c, l2xisymt.h : routines for managing the interpreter's symbol
+tables.
+ l2xidbug.c : the source level debugger.
+ l2xierr.c, l2xierr.h : EXPRESS-A language error handling and diagnostic
+output for the user.
+ l2xiidbg.c, l2xiidbg.h, l2xisdcl.c : diagnostics for a developer of the
+interpreter.
+ licomsym.h : general header file for the interpreter modules.
+ l2xidftc.h, l2xiertc.h, l2xisctc.h, l2xisftc.h : header files containing
+keywords and their representations as strings.
+
+
+ The following files may be useful:
+
+ man : the manpage
+ printct.c : a program to print and update command table files;
+ ltx2html.sty : a LaTeX package file to assist in retagging a LaTeX
+document to an HTML document.
+
+
+ Essentially, installing L2X consists of processing the file l2x.l through
+a lexer generator, processing the file l2x.y through a parser generator, and
+then compiling the results together with the other supplied source files.
+
+ The lexer source file l2x.l and the parser source file l2x.y have to be
+processed by flex (or equivalent) and bison (or equivalent) respectively to
+generate C code. This code, together with the code in the other source files
+must then be compiled and linked to form the executable.
+
+ The executable must then, after suitable testing, be moved to its final
+place in your system and the manpage (file man) also copied to its final
+position in your directory structure.
+
+ Included in the L2X distribution are several command table files. One is
+detex.ct which provides an example of commands for de-TeX ing a document.
+(Footnote: You may wish to try using detex.ct on the LaTeX source of this
+document to see what the effect is. This can also serve as a check on the
+system installation.) Another is remcom.ct which provides an example of
+commands to remove comments from a LaTeX document. The command table file
+bye.ct replaces a LaTeX document by "Goodbye document". Another is ltx2x.ct
+which does nothing except try and include another file named ZiLcH, which
+presumably is not on anyone's system. Running L2X with this file will prompt
+for another name of a file if it cannot find ZiLcH; enter an existing file
+(like detex.ct) at the prompt. (Footnote: This is one way of setting up L2X
+for interactive specification of the desired command table file(s).)
+
+ The command table file l2h.ct has proven to be adequate for converting the
+LaTeX source of this manual, and other LaTeX documents without pictures and
+only limited mathematics, into an ASCII file with HTML tags instead.
+
+ The file fun.ct contains some test code for the EXPRESS-A interpreter. The
+contents are similar to the example shown at the end of section
+(sec:expressa).
+
+ The l2xusrlb files are skeletons. The system does include the functions
+and parser constructs for the \GRAMMspecial and \CODEspecial commands used as
+examples previously. The last two entries in remcom.ct are the specification
+of these, and the implementation is as described previously.
+
+
+
+
+SUB-SECTION: Command table printing
+
+
+
+ The grammar of the command table has been changed slightly since the
+initial release of L2X. The utility C program in printct.c may be used to:
+
+ o Pretty-print a command table;
+ o Convert an original command table to one that conforms to the new
+grammar.
+
+
+ The syntax for running printct is:
+
+printct [-D dir_cat_char] [-P path_seperators] [-f table_file] [-t]
+
+ where elements in square brackets are options. These options are identical to
+the corresponding ones for L2X and are as follows:
+
+ -f : By default, printct reads the command table from a file called
+ltx2x.ct. If the required command table is in a file with another name this
+option is used to change from the default file. For example,
+
+> printct
+
+ reads a command table from ltx2x.ct, while
+
+> printct -f detex.ct
+
+ reads a command table from file detex.ct.
+
+
+ -t : This generates some diagnostics related to the processing of the
+command table file.
+
+
+ -D : The value of this option is the character that the operating system
+uses to catenate directory names to form a path (see (sec:search)). The
+default value is a slash (i.e. /). The default could be changed to a
+backslash, for example, by -D \.
+
+
+ -P : The environment variable (see (sec:search)) contains a list of
+directories (also known as path names). In the operating system that I use,
+these are separated by the colon (:) character which, together with the
+semi-colon and space characters, form the L2X default separators. The path
+separator characters can be changed with this option. For example, -P : will
+make the separators be a colon or a space (space is automatically included in
+the separator list).
+
+
+ printct only reads a single command table file and outputs the
+pretty-printed and updated version to file printct.lis. It performs a very
+limited amount of error checking and writes error messages and statistics to
+the file printct.err.
+
+
+
+
+SUB-SECTION: A make file
+
+
+
+ Here is a UNIX make file [ ORAM91] for the L2X system.
+
+
+
+# makefile for program ltx2x --- LaTeX to X autotagger
+#
+##################### Change the following for your setup
+# The compiler
+CC = cc
+
+# We use flex (or equivalent, but not lex) to generate the lexer
+LEX = flex
+# and the options
+LEXFLAGS = -v
+
+# We use bison (or equivalent) to generate the parser
+YACC = bison
+# and the options
+YACCFLAGS = -y -d -v
+
+# Libraries to be used
+LIBS = -ly -ll -lm
+
+# The root directory for the installation (e.g., /usr/local )
+ROOTDIR = /proj/ltx/teTeX033
+
+# Where to place the running code (e.g. /usr/local/bin )
+BINDIR = ${ROOTDIR}/bin
+
+# Where to place the manpage (e.g., /usr/local/man/man1 )
+MANEXT = 1
+MANDIR = ${ROOTDIR}/man/man${MANEXT}
+
+# Just in case you want to change the name of the binary
+# (and then you should also change the man page and documentation).
+# So, do not change this.
+PROG = ltx2x
+
+# Where to place the user documentation (e.g., /usr/local/doc/ltx2x )
+DOCDIR = ${ROOTDIR}/doc/${PROG}
+
+# Where to place the example command tables (e.g., /usr/local/lib/config/ltx2x )
+CTDIR = ${ROOTDIR}/lib/config/${PROG}
+
+# The file copy command (copy but do not delete original)
+COPY = cp
+
+# The file move command (move and delete original)
+MOVE = mv
+
+# The file delete command
+DELETE = rm
+
+# The make directory (hierarchy) command
+MAKEDIR = mkdirhier
+
+# The stream editor command
+SED = sed
+
+# Command to write to the terminal (stdout)
+ECHO = echo
+
+################### You should not have to change anything after this
+
+# The source modules
+L2XSRCS = l2xytab.c l2xlexyy.c l2xlib.c l2xacts.c l2xusrlb.c
+getopt.c srchenv.c
+
+INTSRCS = l2xirtne.c l2xistd.c l2xidecl.c l2xistmt.c l2xiexpr.c
+l2xiscan.c l2xisymt.c l2xierr.c l2xiidbg.c l2xistup.c l2xistm.c
+l2xixxpr.c l2xixstd.c l2xidbug.c l2xisdcl.c l2xirexp.c listsetc.c
+
+# The object modules
+L2XOBJS = l2xytab.o l2xlexyy.o l2xlib.o l2xacts.o l2xusrlb.o
+ getopt.o srchenv.o
+
+INTSRCS = l2xirtne.o l2xistd.o l2xidecl.o l2xistmt.o l2xiexpr.o
+l2xiscan.o l2xisymt.o l2xierr.o l2xiidbg.o l2xistup.o l2xistm.o
+l2xixxpr.o l2xixstd.o l2xidbug.o l2xisdcl.o l2xirexp.o listsetc.o
+
+OBJS = ${L2XOBJS} ${INTOBJS}
+
+# Link object code together into PROG
+ltx2x : ${OBJS}
+ ${CC} -o ${PROG} ${OBJS} ${LIBS}
+
+# Compile C source code into object code
+getopt.o : getopt.c getopt.h
+ ${CC} -c getopt.c
+l2xytab.o : l2xytab.c l2xlib.h l2xusrlb.h l2xacts.h strtypes.h l2xcom.h
+ ${CC} -c l2xytab.c
+l2xlexyy.o : l2xlexyy.c l2xytab.h l2xlib.h l2xusrlb.h l2xcom.h
+ ${CC} -c l2xlexyy.c
+l2xlib.o : l2xlib.c getopt.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xlib.c
+l2xusrlb.o : l2xusrlb.c l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xusrlb.c
+l2xacts.o : l2xacts.c l2xusrlb.h l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xacts.c
+srchenv.o : srchenv.c srchenv.h
+ ${CC} -c srchenv.c
+
+# Generate C code for parsing
+l2xytab.c l2xytab.h: l2x.y
+ @ ${ECHO} "Expect 10 shift/reduce conflicts to be reported"
+ ${YACC} ${YACCFLAGS} l2x.y
+ ${MOVE} y.tab.c l2xytab.c
+ ${MOVE} y.tab.h l2xytab.h
+
+# Generate C code for lexing
+l2xlexyy.c : l2x.l
+ ${LEX} ${LEXFLAGS} l2x.l
+ ${MOVE} lex.yy.c l2xlexyy.c
+
+# the interpreter modules
+
+# compiler flags for analyze and execute modules
+ANLFLAG = -Danalyze
+RUNFLAG = -Dtrace
+
+# interpreter header files
+SOMEH = l2xicmon.h l2xierr.h l2xiscan.h l2xisymt.h licomsym.h l2xiidbg.h
+MOSTH = ${SOMEH} l2xiprse.h
+ALLH = ${MOSTH} l2xicpr.h l2xiexec.h
+
+# interpreter interface
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+# the parser module
+
+l2xirtne.o : l2xirtne.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xirtne.c
+
+l2xistd.o : l2xistd.c ${MOSTH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c l2xistd.c
+
+l2xidecl.o : l2xidecl.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xisdecl.c
+
+l2xistmt.o : l2xistmt.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xistmt.c
+
+l2xiexpr.o : l2xiexpr.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiexpr.c
+
+# the scanner module
+
+l2xiscan.o : l2xiscan.c ${SOMEH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiscan.c
+
+# symbol table module
+
+l2xisymt.o : l2xisymt.c l2xicmon.h l2xierr.h l2xisymt.h licomsym.h l2xiidbg.h
+ ${CC} -c l2xisymt.c
+
+# executor module
+
+l2xixutl.o : l2xixutl.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixutl.c
+
+l2xixstm.o : l2xixstm.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstm.c
+
+l2xixxpr.o : l2xixxpr.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixxpr.c
+
+l2xixstd.o : l2xixstd.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstd.c
+
+l2xidbug.o : l2xidbug.c ${SOMEH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xidbug.c
+
+# error and miscellaneous
+
+l2xisdcl.o : l2xisdcl.c ${SOMEH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xisdcl.c
+
+l2xiidbg.o : l2xiidbg.c ${SOMEH} l2xiexec.h
+ ${CC} -c l2xiidbg.c
+
+l2xirexp.o : l2xirexp.c l2xirexp.h
+ ${CC} -c l2xirexp.c
+
+listsetc.o : listsetc.c listsetc.h
+ ${CC} -c listsetc.c
+
+# only call make install if BINDIR has been set
+install : ltx2x
+ ${MAKEDIR} ${BINDIR}
+ ${MOVE} ${PROG} ${BINDIR}
+
+# Edit the file man to replace DOCUMENTDIR by the actual directory
+# where the user manual is to be placed, and CTDIR by the location
+# of the example command table files.
+# Then copy the manpage to the proper place
+manpage :
+ ${SED} 's!DOCUMENTDIR!${DOCDIR}!; s!CTDIR!${CTDIR}!' man > tman
+ ${MAKEDIR} ${MANDIR}
+ ${COPY} tman ${MANDIR}/${PROG}.${MANEXT}
+
+# Copy the user manuals to the proper place
+doc :
+ ${MAKEDIR} ${DOCDIR}
+ ${COPY} ltx2x.tex ${DOCDIR}/${PROG}.tex
+ ${COPY} ltx2x.ps ${DOCDIR}/${PROG}.ps
+ ${COPY} ltx2x.txt ${DOCDIR}/${PROG}.txt
+ ${COPY} ltx2x.html ${DOCDIR}/${PROG}.html
+
+# Copy the example command tables to their final location
+ctables :
+ ${MAKEDIR} ${CTDIR}
+ ${COPY} ltx2x.ct ${CTDIR}/ltx2x.ct
+ ${COPY} detex.ct ${CTDIR}/detex.ct
+ ${COPY} remcom.ct ${CTDIR}/remcom.ct
+ ${COPY} l2h.ct ${CTDIR}/l2h.ct
+ ${COPY} bye.ct ${CTDIR}/bye.ct
+ ${COPY} fun.ct ${CTDIR}/fun.ct
+
+# Do almost everything except clean up
+all : ltx2x install manpage doc ctables
+
+# call make clean to remove the object files, info from YACC,
+# and the edited version of the manpage
+clean :
+ ${DELETE} *.o
+ ${DELETE} y.output
+ ${DELETE} tman
+
+# Compile the command table printer
+printct : printct.o getopt.o srchenv.o
+ ${CC} -o printct printct.o getopt.o srchenv.o
+
+printct.o : printct.c getopt.h strtypes.h l2xcom.h
+ ${CC} -c printct.c
+
+
+
+ If you use the above makefile then the first part should be edited to
+reflect your system's configuration. You could do make all which should do
+everything for you, except the cleaning up. A more conservative approach is
+recommended. First just do make which will generate the executable. This can
+then be tested. When all is well do make install and make manpage which will
+put the executable and the manpage into their final positions. Finally, make
+clean will remove the intermediate files generated during the build process.
+
+ The above make file uses flex as the lexer generator. You can use your
+favorite one instead but it must, unlike lex, support exclusive start states.
+Also, bison is used above as the parser generator. Again, you can use your
+favorite one. As far as I am aware, there is nothing remarkable about the
+grammar, except that during early development I exceeded the size limits of
+yacc. The grammar has been simplified since then, so this may no longer be a
+problem.
+ NOTE: If bison is used it reports that there are 10 shift/reduce conflicts.
+It appears that these can be safely ignored.
+
+ One compilation problem has been noted by Uwe Sassenberg (Footnote:
+<sassen@hal1.physik.uni-dortmund.de>) on AIX 3.2 and IRIX 5.3 systems, but I
+could not reproduce it on a SunOS 4.1.3 system. This is when the main
+procedure of L2X is processing the optional command line arguments. For some
+reason it had difficulties with the C EOF. The symptom was that the program
+compiled but when it was run it sat there absorbing CPU cycles and doing
+nothing as it had got into an infinite while loop. The cure was to insert the
+following line of code in file l2xlib.c:
+
+main(argc,argv)
+...
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv, "l:ty:f:cp:wE:P:D:"))) {
+/* insert this line of code: if (optchar == 255) break; end insert */
+ switch(optchar) {
+...
+
+ This code line which you may need to insert is supplied as a comment in the
+distributed source.
+
+
+
+
+SUB-SECTION: Limits and errors
+
+
+
+ The L2X system has some built-in limits which are defined in l2xlib.c. The
+following is a listing of the relevant sizes.
+
+
+
+ CLAUSE_STACK_SIZE : The maximum nesting depth of document sectioning.
+This is set somewhat larger than the number of standard LaTeX sectioning
+command types. (Default 10)
+
+
+ EVERY_N_LINES : Controls the frequency of printing processed line numbers
+to the terminal. (Default 100)
+
+
+ LIST_STACK_SIZE : The maximum nesting depth of list environments. This is
+set somewhat larger than the standard LaTeX nesting depth. (Default 10)
+
+
+ MAX_BUFFER : The maximum number of characters that can be held in the
+system buffer, and also the maximum number of characters in a pretty-printed
+output line. (Default 2000)
+
+
+ MAX_CT_STACK : The maximum nesting depth for included command table
+files. (Default 20)
+
+
+ MAX_ERRORS : The maximum number of non-fatal errors discovered in command
+table processing or in source file processing before L2X quits. (Default 10)
+
+
+ MAX_LINE : The maximum number of characters in a line of a LaTeX source
+file. (Default 2000)
+
+
+ MAX_PRINT_STACK : The maximum nesting depth for print control commands.
+(Default 100)
+
+
+ MAX_TABLE_ENTRIES : The maximum number of TYPE specifications in a
+command table (including the built in type specifications). (Default 1000)
+
+
+ MAX_TABLE_LINE : The maximum number of characters in a line in a command
+table file. (Default 254)
+
+
+ MAX_USER_BUFFS : The maximum number of user buffers. (Default 20)
+
+
+ MAX_UBUFF_LEN : The maximum number of characters that can be stored in a
+user buffer. (Default 510)
+
+
+ MAX_USER_FILES : The maximum number of user files. (Default 16)
+
+
+ L2X prints out a summary of the program statistices at the end of the
+ltx2x.err file. If the limits are not suitable for your purposes, then they
+may be changed and the system rebuilt.
+
+ L2X can produce a variety of error and warning messages, for example when
+any of the above limits are exceeded. Some of the messages are related to
+command table processing, while others are related to LaTeX document
+processing. Both these kinds of messages are targeted to the normal end user.
+There is another set of messages that are aimed at the implementor of new
+SPECIAL_ commands. An implementor may also find some of the debugging options
+useful if things really fall apart.
+
+
+
+
+SUB-SECTION: Availability
+
+
+
+ Source code and documentation for L2X is available from the NIST SOLIS
+(SC4 On-Line Information Service) system [ RINAUDOT94] in directory
+ /subject/sc4/editing/latex/programs/ltx2x.
+ SOLIS can be accessed by:
+
+ o Anonymous ftp to ftp.cme.nist.gov (cd to /pub/subject/sc4...)
+http://www.nist.gov/sc4 o URL
+
+
+ Any comments should be directed to apde@cme.nist.gov.
+
+
+
+
+SUB-SUB-SECTION: Copyright
+
+
+
+ Development of this software was funded by the United States Government
+and is not subject to copyright. It was developed by the Manufacturing Systems
+Integration Division (MSID) of the Manufacturing Engineering Laboratory (MEL)
+of the National Institute of Standards and Technology (NIST).
+
+
+
+
+SUB-SUB-SECTION: Disclaimer
+
+
+
+ There is no warranty for the L2X software. If the L2X software is modified
+by someone else and passed on, NIST requests that the software's recipients be
+notified that what they have is not what NIST distributed.
+
+
+
+ Policies :
+
+ (#) Anyone may copy and distribute verbatim copies of the source code as
+received in any medium.
+ (#) Anyone may modify your copy or copies of the L2X source code or any
+portion of it, and copy and distribute such modifications provided that all
+modifications are clearly associated with the entity that performs the
+modifications.
+
+
+
+ NO WARRANTY :
+
+ NIST PROVIDES ABSOLUTELY NO WARRANTY. THE L2X SOFTWARE IS PROVIDED `AS IS'
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+PROGRAM IS WITH YOU. SHOULD ANY PORTION OF THE L2X SOFTWARE PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, INCLUDING ANY LOST PROFITS,
+LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT
+OF THE USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
+DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY NIST) THE
+PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR
+FOR ANY CLAIM BY ANY OTHER PARTY.
+
+
+
+
+
+SECTION: A grammar for the command table
+
+ (sec:ctabgrammar)
+
+
+
+
+SUB-SECTION: Notation
+
+
+
+ The syntactical constructs used correspond to a derivative of the Wirth
+Syntax Notation (WSN) [ WIRTH77]. The semantics of the enclosing braces are:
+
+ o curly braces `{ }' indicate xero or more repetitions;
+ o square brackets `[ ]' indicate an optional element;
+ o parenthesis `( )' indicates a group;
+ o vertical bar `|' indicates that exactly one of the terms in the
+expression shall be chosen.
+
+
+ Here is the grammar for WSN defined in itself.
+
+syntax = { production } .
+production = identifier '=' expression '.' .
+expression = term { '|' term } .
+term = factor { factor } .
+factor = identifier | literal | group | option | repetition .
+identifier = character { character } .
+literal = '''' character { character } '''' .
+group = '(' expression ')' .
+option = '[' expression ']' .
+repetition = '{' expression '}' .
+
+
+
+ We also use the following shorthand notation for particular characters:
+
+ o \c --- any printable character
+ o \n --- the end of line character(s)
+ o eof --- the end of file character(s)
+
+
+
+
+
+SUB-SECTION: Grammar
+
+
+
+ First, the keywords. Note that these are case insensitive.
+
+AudibleAlertChar = 'AUDIBLE_ALERT_CHAR=' .
+BackspaceChar = 'BACKSPACE_CHAR=' .
+BeginDocument = 'BEGIN_DOCUMENT' .
+BeginDollar = 'BEGIN_DOLAR' .
+BeginEnv = 'BEGIN_ENV' .
+BeginListEnv = 'BEGIN_LIST_ENV' .
+BeginPictureCc = 'BEGIN_PICTURE_CC' .
+BeginVenv = 'BEGIN_VENV' .
+BeginVerb = 'BEGIN_VERB' .
+BeginVerbatim = 'BEGIN_VERBATIM' .
+Buffer = 'BUFFER' .
+CarriageReturnChar = 'CARRIAGE_RETURN_CHAR=' .
+Chapter = 'CHAPTER' .
+CharCommand = 'CHAR_COMMAND' .
+Command = 'COMMAND' .
+CommandOop = 'COMMAND_OOP' .
+CommandOoopp = 'COMMAND_OOOPP' .
+CommandOpo = 'COMMAND_OPO' .
+CommandPooop = 'COMMAND_POOOP' .
+CommandPoop = 'COMMAND_POOP' .
+CommandPoopp = 'COMMAND_POOPP' .
+Comment = 'C=' .
+EndCtfile = 'END_CTFILE=' .
+EndDocument = 'END_DOCUMENT' .
+EndDollar = 'END_DOLAR' .
+EndEnv = 'END_ENV' .
+EndItem = 'END_ITEM=' .
+EndItemParam = 'END_ITEM_PARAM=' .
+EndListEnv = 'END_LIST_ENV' .
+EndMode = 'END_MODE' .
+EndOpt = 'END_OPT=' .
+EndPicture = 'END_PICTURE' .
+EndTag = 'END_TAG=' .
+EndTag1 = 'END_TAG_1=' .
+EndTag2 = 'END_TAG_2=' .
+EndTag3 = 'END_TAG_3=' .
+EndTag4 = 'END_TAG_4=' .
+EndTag5 = 'END_TAG_5=' .
+EndTag6 = 'END_TAG_6=' .
+EndTag7 = 'END_TAG_7=' .
+EndTag8 = 'END_TAG_8=' .
+EndTag9 = 'END_TAG_9=' .
+EndType = 'END_TYPE' .
+EndVenv = 'END_VENV' .
+EndVerb = 'END_VERB' .
+EndVerbatim = 'END_VERBATIM' .
+EscapeChar = 'ESCAPE_CHAR=' .
+File = 'FILE' .
+First = 'FIRST' .
+FormfeedChar = 'FORMFEED_CHAR=' .
+HexChar = 'HEX_CHAR=' .
+HorizontalTabChar = 'HORIZONTAL_TAB_CHAR=' .
+Include = 'INCLUDE=' .
+InMode = 'IN_MODE=' .
+Last = 'LAST' .
+Lbrace = 'LBRACE' .
+Name = 'NAME=' .
+NewlineChar = 'NEWLINE_CHAR=' .
+NoOp = 'NO_OP' .
+NoPrint = 'NO_PRINT' .
+OptParam = 'OPT_PARAM=' .
+OtherBegin = 'OTHER_BEGIN' .
+OtherCommand = 'OTHER_COMMAND' .
+OtherEnd = 'OTHER_END' .
+Para = 'PARA' .
+Paragraph = 'PARAGRAPH' .
+Part = 'PART' .
+Partm1 = 'PARTm1' .
+Partm2 = 'PARTm2' .
+PcAtEnd = 'PC_AT_END=' .
+PcAtStart = 'PC_AT_START=' .
+PictureCcpp = 'PICTURE_CCPP' .
+PictureCo = 'PICTURE_CO' .
+PictureCop = 'PICTURE_COP' .
+PictureCp = 'PICTURE_CP' .
+PictureOcc = 'PICTURE_OCC' .
+PictureOccc = 'PICTURE_OCCC' .
+PictureOco = 'PICTURE_OCO' .
+PicturePcop = 'PICTURE_PCOP' .
+PrintControl = 'PRINT_CONTROL=' .
+PrintP1 = 'PRINT_P1=' .
+PrintP2 = 'PRINT_P2=' .
+PrintP3 = 'PRINT_P3=' .
+PrintP4 = 'PRINT_P4=' .
+PrintP5 = 'PRINT_P5=' .
+PrintP6 = 'PRINT_P6=' .
+PrintP7 = 'PRINT_P7=' .
+PrintP8 = 'PRINT_P8=' .
+PrintP9 = 'PRINT_P9=' .
+PrintOpt = 'PRINT_OPT=' .
+Rbrace = 'RBRACE' .
+Reqparams = 'REQPARAMS=' .
+Reset = 'RESET' .
+ResetBuffer = 'RESET_BUFFER:' .
+ResetMode = 'RESET_MODE:' .
+Sect = 'SECT' .
+Sectioning = 'SECTIONING' .
+SectioningLevel = 'SECTIONING_LEVEL=' .
+SetMode = 'SET_MODE:' .
+SlashSpace = 'SLASH_SPACE' .
+Source = 'SOURCE:' .
+Special = 'SPECIAL' .
+SpecialBeginEnv = 'SPECIAL_BEGIN_ENV' .
+SpecialBeginList = 'SPECIAL_BEGIN_LIST' .
+SpecialCommand = 'SPECIAL_COMMAND' .
+SpecialEndEnv = 'SPECIAL_END_ENV' .
+SpecialEndList = 'SPECIAL_END_LIST' .
+SpecialSectioning = 'SPECIAL_SECTIONING' .
+StartItem = 'START_ITEM=' .
+StartItemParam = 'START_ITEM_PARAM=' .
+StartOpt = 'START_OPT=' .
+StartTag = 'START_TAG=' .
+StartTag1 = 'START_TAG_1=' .
+StartTag2 = 'START_TAG_2=' .
+StartTag3 = 'START_TAG_3=' .
+StartTag4 = 'START_TAG_4=' .
+StartTag5 = 'START_TAG_5=' .
+StartTag6 = 'START_TAG_6=' .
+StartTag7 = 'START_TAG_7=' .
+StartTag8 = 'START_TAG_8=' .
+StartTag9 = 'START_TAG_9=' .
+String = 'STRING:' .
+SubPara = 'SUBPARA' .
+SubParap1 = 'SUBPARAp1' .
+SubParap2 = 'SUBPARAp2' .
+SubSect = 'SUBSECT' .
+SubSubSect = 'SUBSUBSECT' .
+SwitchBack = 'SWITCH_BACL: ' .
+SwitchToBuffer = 'SWITCH_TO_BUFFER: ' .
+SwitchToFile = 'SWITCH_TO_FILE: ' .
+SwitchToSysbuf = 'SWITCH_TO_SYSBUF: ' .
+Sysbuf = 'SYSBUF' .
+TexChar = 'TEX_CHAR' .
+ToBuffer = 'TO_BUFFER' .
+ToFile = 'TO_FILE' .
+ToSysbuf = 'TO_SYSBUF' .
+Type = 'TYPE=' .
+Vcommand = 'VCOMMAND' .
+VerticalTabChar = 'VERTICAL_TAB_CHAR=' .
+
+
+
+ Some utility productions.
+
+latex_id = \c { \c } .
+name = \c { \c } .
+text = '"' { \c } '"' .
+Eol = \n .
+digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+integer = digit { digit } .
+ct_file_name = name .
+file_id = name .
+buffer_id = integer .
+mode_id = name .
+
+
+
+ The starting production.
+
+table = [ special_chars ] { specification | inclusion | comment } eof .
+
+
+
+ Productions for inclusion and comment and eof.
+
+inclusion = Include ct_file_name Eol .
+comment = Comment { \c } Eol .
+eof = EndCtfile { \c } Eol .
+
+
+
+ Productions for special_chars.
+
+special_chars = [ escape ] [ alert ] [ backspace ] [ return ] [ feed ]
+ [ hex ] [ htab ] [ newline ] [ vtab ] { comment } .
+escape = EscapeChar \c Eol Eol .
+alert = AudibleAlertChar \c Eol .
+backspace = BackspaceChar \c Eol .
+return = CarriageReturnChar \c Eol .
+feed = FormfeedChar \c Eol .
+hex = HexChar \c Eol .
+htab = HorizontalTabChar \c Eol .
+newline = NewlineChar \c Eol .
+vtab = VerticalTabChar \c Eol .
+
+
+
+ Productions for specification.
+
+specification = built_in | normal | list | section | special | picture | odd .
+built_in = (Type built_in_type Eol) [ built_in_body ] end_type .
+end_type = EndType Eol .
+built_in_type = BeginDocument | BeginDollar | BeginVerb | BeginVerbatim |
+ EndDocument | EndDollar | EndVerb | EndVerbatim |
+ Lbrace | OtherBegin | OtherCommand | OtherEnd |
+ Paragraph | Rbrace | SlashSpace .
+normal = (Type normal_type Eol) type_name [ normal_body ] end_type .
+type_name = Name latex_id Eol .
+normal_type = BeginEnv | BeginVenv | CharCommand | Command |
+ EndEnv | EndVenv | TexChar | Vcommand .
+list = (Type list_type Eol) type_name [ list_body ] end_type .
+list_type = BeginListEnv | EndListEnv .
+section = (Type Sectioning Eol) type_name [ section_body ] end_type .
+special = (Type special_type Eol) type_name [ special_body ] end_type .
+special_type = Special | SpecialBeginEnv | SpecialBeginList |
+ SpecialCommand | SpecialEndEnv | SpecialEndList |
+ SpecialSectioning .
+picture = (Type picture_type Eol) type_name [ picture_body ] end_type .
+picture_type = BeginPictureCc | EndPicture | PictureCcpp | PictureCo |
+ PictureCop | PictureCp | PictureOcc |
+ PictureOccc | PictureOco | PicturePcop .
+odd = (Type odd_type Eol) type_name [ odd_body ] end_type .
+odd_type = CommandOop | CommandOoopp | CommandOpo |
+ CommandPooop | CommandPoop | CommandPoopp .
+
+
+
+ The X_body productions.
+
+built_in_body = [ basic_body ]
+ { start_mode [ basic_body ] end_mode } .
+start_mode = InMode mode_id Eol .
+end_mode = EndMode Eol .
+normal_body = [ basic_norm_body ]
+ { start_mode [ basic_norm_body ] end_mode } .
+sect_body = [ basic_sect_body ]
+ { start_mode [ basic_sect_body ] end_mode } .
+list_body = [ basic_list_body ]
+ { start_mode [ basic_list_body ] end_mode } .
+picture_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+odd_body = [ basic_defarg_body ]
+ { start_mode [ basic_defarg_body ] end_mode } .
+special_body = [ basic_special_body ]
+ { start_mode [ basic_special_body ] end_mode } .
+
+
+
+ Note: the ordering of the components of the following basic_X_body
+productions is immaterial.
+
+basic_body = [ start_it ] [ end_it ] .
+basic_norm_body = [ basic_body ] [ no_req_arg ] [ opt_arg_pos ]
+ { arg_print } { arg_action } .
+basic_sect_body = sect_level [ basic_norm_body ] .
+sect_level = SectioningLevel div_level Eol .
+div_level = Chapter | Para | Part | Partm1 | Partm2 | Sect | Subpara |
+ Subparap1 | Subparap2 | Subsect | Subsubsect .
+basic_defarg_body = [ basic_body ] { arg_print } { arg_action } .
+basic_list_body = [ basic_norm_body ] { item_action } .
+basic_special_body = [ sect_level ] [ basic_list_body ] .
+no_req_arg = Reqparams integer Eol .
+opt_arg_pos = OptParam ( First | Last ) Eol .
+
+
+
+ The start_it and end_it productions.
+
+start_it = [ start_print ] [start_action ] .
+start_print = PcAtStart ( basic_pc_kind | Reset ) Eol .
+basic_pc_kind = NoPrint | ToSysbuf | print_to_buffer | print_to_file .
+print_to_buffer = ToBuffer buffer_id .
+print_to_file = ToFile file_id .
+start_action = StartTag [ text ] Eol { tag_action } .
+tag_action = ( String text |
+ Source ( Sysbuf | user_buffer | user_file ) |
+ ResetBuffer buffer_id |
+ ResetFile file_id |
+ ResetSysbuf |
+ SwitchToBuffer buffer_id |
+ SwitchToFile file_id |
+ SwitchToSysbuf |
+ SwitchBack |
+ SetMode mode_id |
+ ResetMode )
+ Eol .
+user_buffer = Buffer buffer_id .
+user_file = File file_id .
+end_it = [ end_print ] [ end_action ] .
+end_print = PcAtEnd (basic_pc_kind | Reset) Eol .
+end_action = EndTag [ text ] Eol { tag_action } .
+
+
+
+ The arg_print productions.
+
+arg_print = print_arg_kind (basic_pc_kind | NoOp ) Eol .
+print_arg_kind = PrintOpt | PrintP1 | PrintP2 | PrintP3 | PrintP4 |
+ PrintP5 | PrintP6 | PrintP7 | PrintP8 | PrintP9 .
+
+
+
+ The arg_action productions.
+
+arg_action = arg_tag_kind [ text ] Eol { tag_action } .
+arg_tag_kind = EndOpt | EndTag1 | EndTag2 | EndTag3 | EndTag4 |
+ EndTag5 | EndTag6 | EndTag7 | EndTag8 | EndTag9 |
+ StartOpt | StartTag1 | StartTag2 | StartTag3 | StartTag4 |
+ StartTag5 | StartTag6 | StartTag7 | StartTag8 | StartTag9 .
+
+
+
+ The item_action productions.
+
+item_action = item_tag_kind [ text ] Eol { tag_action } .
+item_tag_kind = EndItem | EndItemParam | StartItem | StartItemParam .
+
+
+
+ The parser in L2X for the command table is very simple. For each TYPE= in
+the command table it creates a struct to hold the specification data. If any
+type is multiply defined, then which one will be finally used is somewhat
+random because of the sorting and searching algorithms employed internally. No
+checks are made for multiply defined entries.
+
+ Each command in the command table starts on a seperate line. The parser
+reads only as much of a table line as is necessary to parse that line
+according to the first token that it finds on the line. The data in each line
+after parsing is added to the current struct for the LaTeX command. If any of
+the command lines within an entry are multiply defined, then the latest one
+will overwrite any earlier ones.
+
+ This line-based parsing means that effectively anything between the end of
+the required data on the line is ignored by the parser, and so could be
+treated as a comment. There is no guarantee that this behaviour will be
+maintained in future releases of L2X.
+
+
+
+
+SECTION: A grammar for EXPRESS-A
+
+ (sec:expgrammar)
+
+ The same WSN notation is used for the grammar for EXPRESS-A as for the
+command table grammar.
+
+ First the keywords. Note that these are case insensitive. Also not all of
+the keywords have been used in this implementation of EXPRESS-A; those that
+have not been used are reserved for the future.
+
+
+
+ ABS = 'abs' .
+ ABSTRACT = 'abstract' .
+ ACOS = 'acos' .
+ AGGREGATE = 'aggregate' .
+ ALIAS = 'alias' .
+ AND = 'and' .
+ ANDOR = 'andor' .
+ ARRAY = 'array' .
+ AS = 'as' .
+ ASIN = 'asin' .
+
+
+
+
+
+ ATAN = 'atan' .
+ BAG = 'bag' .
+ BEGIN = 'begin' .
+ BINARY = 'binary' .
+ BLENGTH = 'blength' .
+ BOOLEAN = 'boolean' .
+ BY = 'by' .
+ CALL = 'call' .
+ CASE = 'case' .
+ CONSTANT = 'constant' .
+
+
+
+
+
+ CONST_E = 'const_e' .
+ CONTEXT = 'context' .
+ COS = 'cos' .
+ CRITERIA = 'criteria' .
+ DERIVE = 'derive' .
+ DIV = 'div' .
+ ELSE = 'else' .
+ END = 'end' .
+ END_ALIAS = 'end_alias' .
+ END_CALL = 'end_call' .
+
+
+
+
+
+ END_CASE = 'end_case' .
+ END_CODE = 'end_code' .
+ END_CONSTANT = 'end_constant' .
+ END_CONTEXT = 'end_context' .
+ END_CRITERIA = 'end_criteria' .
+ END_ENTITY = 'end_entity' .
+ END_FUNCTION = 'end_function' .
+ END_IF = 'end_if' .
+ END_LOCAL = 'end_local' .
+ END_MODEL = 'end_model' .
+
+
+
+
+
+ END_NOTES = 'end_notes' .
+ END_OBJECTIVE = 'end_objective' .
+ END_PARAMETER = 'end_parameter' .
+ END_PROCEDURE = 'end_procedure' .
+ END_PURPOSE = 'end_purpose' .
+ END_REALIZATION = 'end_realization' .
+ END_REFERENCES = 'end_references' .
+ END_REPEAT = 'end_repeat' .
+ END_RULE = 'end_rule' .
+ END_SCHEMA = 'end_schema' .
+
+
+
+
+
+ END_SCHEMA_DATA = 'end_schema_data' .
+ END_TEST_CASE = 'end_test_case' .
+ END_TYPE = 'end_type' .
+ ENTITY = 'entity' .
+ ENUMERATION = 'enumeration' .
+ EOF = 'eof' .
+ EOLN = 'eoln' .
+ ESCAPE = 'escape' .
+ EXISTS = 'exists' .
+ EXP = 'exp' .
+ FALSE = 'false' .
+
+
+
+
+
+ FIXED = 'fixed' .
+ FOR = 'for' .
+ FORMAT = 'format' .
+ FROM = 'from' .
+ FUNCTION = 'function' .
+ GENERIC = 'generic' .
+ HIBOUND = 'hibound' .
+ HIINDEX = 'hiindex' .
+ IF = 'if' .
+ IMPORT = 'import' .
+
+
+
+
+
+ IN = 'in' .
+ INSERT = 'insert' .
+ INTEGER = 'integer' .
+ INVERSE = 'inverse' .
+ LENGTH = 'length' .
+ LIKE = 'like' .
+ LIST = 'list' .
+ LOBOUND = 'lobound' .
+ LOINDEX = 'loindex' .
+ LOCAL = 'local' .
+
+
+
+
+
+ LOG = 'log' .
+ LOG10 = 'log10' .
+ LOG2 = 'log2' .
+ LOGICAL = 'logical' .
+ MOD = 'mod' .
+ MODEL = 'model' .
+ NOT = 'not' .
+ NOTES = 'notes' .
+ NUMBER = 'number' .
+ NVL = 'nvl' .
+
+
+
+
+
+ OBJECTIVE = 'objective' .
+ ODD = 'odd' .
+ OF = 'of' .
+ ONEOF = 'oneof' .
+ OPTIONAL = 'optional' .
+ OR = 'or' .
+ ORD = 'ord' .
+ OTHERWISE = 'otherwise' .
+ PARAMETERi = 'parameter' .
+ PI = 'pi' .
+
+
+
+
+
+ PRED = 'pred' .
+ PROCEDURE = 'procedure' .
+ PURPOSE = 'purpose' .
+ QUERY = 'query' .
+ READ = 'read' .
+ READLN = 'readln' .
+ REAL = 'real' .
+ REALIZATION = 'realization' .
+ REFERENCE = 'reference' .
+ REFERENCES = 'references' .
+
+
+
+
+
+ REMOVE = 'remove' .
+ REPEAT = 'repeat' .
+ RETURN = 'return' .
+ REXPR = 'rexpr' .
+ ROLESOF = 'rolesof' .
+ ROUND = 'round' .
+ RULE = 'rule .
+ SCHEMA = 'schema' .
+ SCHEMA_DATA = 'schema_data' .
+ SELECT = 'select' .
+
+
+
+
+
+ SELF = 'self' .
+ SET = 'set' .
+ SIN = 'sin' .
+ SIZEOF = 'sizeof' .
+ SKIP = 'skip' .
+ SQRT = 'sqrt' .
+ STRING = 'string' .
+ SUBOF = 'subof' .
+ SUBTYPE = 'subtype' .
+ SUCC = 'succ' .
+
+
+
+
+
+ SUPERTYPE = 'supertype' .
+ SUPOF = 'supof' .
+ SYSTEM = 'system' .
+ TAN = 'tan' .
+ TEST_CASE = 'test_case' .
+ THE_DAY = 'the_day' .
+ THE_MONTH = 'the_month' .
+ THE_YEAR = 'the_year' .
+ THEN = 'then' .
+ TO = 'to' .
+
+
+
+
+
+ TRUE = 'true' .
+ TRUNC = 'trunc' .
+ TYPE = 'type' .
+ TYPEOF = 'typeof' .
+ UNIQUE = 'unique' .
+ UNKNOWN = 'unknown' .
+ UNTIL = 'until' .
+ USE = 'use' .
+ USEDIN = 'usedin' .
+ USING = 'using' .
+
+
+
+
+
+ VALUE = 'value' .
+ VALUE_IN = 'value_in' .
+ VALUE_UNIQUE = 'value_unique' .
+ VAR = 'var' .
+ WHERE = 'where' .
+ WHILE = 'while' .
+ WITH = 'with' .
+ WRITE = 'write' .
+ WRITELN = 'writeln' .
+ XOR = 'xor' .
+
+
+
+ The following rules define various classes of characters which are used in
+constructing the tokens.
+
+
+
+ digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
+ digits = digit { digit } .
+ letter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' |
+ 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' |
+ 'w' | 'x' | 'y' | 'z' .
+ lparen_not_star = '(' not_star .
+ not_lparen_star = not_paren_star | ')' .
+ not_paren_star = letter | digit | not_paren_star_special .
+ not_paren_star_quote_special = '!' | '"' | '#' | '$' | '%' | '&' | '+' |
+ ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' |
+ '@' | '[' | '\' | ']' | '^' | '_' | '`' | '{' | '|' | '}' |
+ '~' .
+ not_paren_star_special = not_paren_star_quote_special | '''' .
+ not_quote = not_paren_star_quote_special | letter | digit | '(' | ')' | '*' .
+ not_rparen = not_paren_star | '*' | '(' .
+
+
+
+
+
+ not_star = not_paren_star | '(' | ')' .
+ octet = hex_digit hex_digit .
+ special = not_paren_star_quote_special | '(' | ')' | '*' | '''' .
+ star_not_rparen = '*' not_rparen .
+
+
+
+ The following rules specify how certain combinations of characters are
+interpreted as lexical elements within the language.
+
+
+
+ integer_literal = digits .
+ real_literal = digits '.' [ digits ] [ 'e' [ sign ] digits ] .
+ simple_id = letter { letter | digit | '_' } .
+ simple_string_literal = \q { ( \q \q ) | not_quote | \s | \o } \q .
+
+
+
+ The following rules specify the syntax of comments in EXPRESS-A.
+
+
+
+ embedded_remark = '(*' { not_lparen_star | lparen_not_star |
+ star_not_rparen | embedded_remark } '*)' .
+ remark = embedded_remark | tail_remark .
+ tail_remark = '--' { \a | \s | \o } \n .
+
+
+
+ The following rules represent identifiers which are known to have a
+particular meaning (i.e., to be declared elsewhere as types or functions,
+etc.).
+
+
+
+ attribute_ref = attribute_id .
+ constant_ref = constant_id .
+ entity_ref = entity_id .
+ enumeration_ref = enumeration_id .
+ function_ref = function_id .
+ parameter_ref = parameter_id .
+ procedure_ref = procedure_id .
+ type_ref = type_id .
+ variable_ref = variable_id .
+
+
+
+ The following rules specify how the previous lexical elements may be
+combined into constructs of EXPRESS-A. White space and/or remark(s) may appear
+between any two tokens in these rules. The primary syntax rule for EXPRESS-A
+is express_a.
+
+
+
+ actual_parameter_list = '(' parameter { ',' parameter } ')' .
+ add_like_op = '+' | '-' | OR | XOR .
+ aggregation_types = array_type | bag_type | list_type | set_type .
+ algorithm_head = { declaration } [ local_decl ] .
+ array_type = ARRAY bound_spec OF base_type .
+ assignment_stmt = general_ref { qualifier } ':=' expression ';' .
+ attribute_decl = attribute_id .
+ attribute_id = simple_id .
+ attribute_qualifier = '.' attribute_ref .
+ bag_type = BAG [ bound_spec ] OF base_type .
+
+
+
+
+
+ base_type = aggregation_types | simple_types | named_types .
+ boolean_type = BOOLEAN .
+ bound_1 = numeric_expression .
+ bound_2 = numeric_expression .
+ bound_spec = '[' bound_1 ':' bound_2 ']' .
+ built_in_constant = CONST_E | PI | THE_DAY | THE_MONTH | THE_YEAR | '?' .
+ built_in_function = ABS | COS | EOF | EOLN | EXISTS | EXP |
+ HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX |
+ LOG | LOG2 | LOG10 | NVL | ODD | ORD | PRED |
+ REXPR | ROUND | SIN | SIZEOF |
+ SQRT | SUCC | TAN | TRUNC .
+ built_in_procedure = INSERT | PRINT | PRINTLN | READ | READLN | REMOVE |
+ SYSTEM | WRITE | WRITELN .
+ case_action = case_label { ',' case_label } ':' stmt .
+ case_label = expression .
+
+
+
+
+
+ case_stmt = CASE selector OF { case_action } [ OTHERWISE ':' stmt ]
+ END_CASE ';' .
+ compound_stmt = BEGIN stmt { stmt } END ';' .
+ constant_factor = built_in_constant .
+ constructed_types = enumeration_type .
+ declaration = entity_decl | function_decl | procedure_decl | type_decl .
+ entity_body = { explicit_attr } .
+ entity_decl = entity_head entity_body END_ENTITY ';' .
+ entity_head = ENTITY entity_id ';' .
+ entity_id = simple_id .
+ enum_id = simple_id .
+
+
+
+
+
+ enumeration_reference = enum_id .
+ enumeration_type = ENUMERATION OF '(' enum_id { ',' enum_id } ')' .
+ escape_stmt = ESCAPE ';' .
+ explicit_attr = attribute_decl { ',' attribute_decl } ':' base_type ';' .
+ express_a = { declaration } [ local_decl ] { stmt } END_CODE .
+ expression = simple_expression [ rel_op_extended simple_expression ] .
+ factor = simple_factor [ '**' simple_factor ] .
+ formal_parameter = parameter_id { ',' parameter_id } ':' parameter_type .
+ function_call = ( built_in_function | function_ref )
+ [ actual_parameter_list ] .
+ function_decl = function_head [ algorithm_head ] stmt { stmt }
+ END_FUNCTION ';' .
+
+
+
+
+
+ function_head = FUNCTION function_id [ '(' formal_parameter
+ { ';' formal_parameter } ')' ] ':' parameter_type ';' .
+ function_id = simple_id .
+ generalized_types = general_aggregation_types .
+ general_aggregation_types = general_array_type | general_bag_type |
+ general_list_type | general_set_type .
+ general_array_type = ARRAY [ bound_spec ] OF parameter_type .
+ general_bag_type = BAG [ bound_spec ] OF parameter_type .
+ general_list_type = LIST [ bound_spec ] OF parameter_type .
+ general_ref = parameter_ref | variable_ref .
+ general_set_type = SET [ bound_spec ] OF parameter_type .
+ if_stmt = IF logical_expression THEN stmt { stmt } [ ELSE stmt { stmt } ]
+ END_IF ';' .
+
+
+
+
+
+ increment = numeric_expression .
+ increment_control = variable_id ':=' bound_1 TO bound_2 [ BY increment ] .
+ index = numeric_expression .
+ index_1 = index .
+ index_2 = index .
+ index_qualifier = '[' index_1 [ ':' index_2 ] ']' .
+ integer_type = INTEGER .
+ interval = '{' interval_low interval_op interval_item interval_op
+ interval_high '}' .
+ interval_high = simple_expression .
+ interval_item = simple_expression .
+
+
+
+
+
+ interval_low = simple_expression .
+ interval_op = '<' | '<=' .
+ list_type = LIST [ bound_spec ] OF base_type .
+ literal = integer_literal | logical_literal | real_literal |
+ string_literal .
+ local_decl = LOCAL local_variable { local_variable } END_LOCAL ';' .
+ local_variable = variable_id { ',' variable_id } ':' parameter_type ';' .
+ logical_expression = expression .
+ logical_literal = FALSE | TRUE | UNKNOWN .
+ logical_type = LOGICAL .
+ multiplication_like_op = '*' | '/' | DIV | MOD | AND | '||' .
+
+
+
+
+
+ named_types = entity_ref | type_ref .
+ null_stmt = ';' .
+ numeric_expression = simple_expression .
+ parameter = expression .
+ parameter_id = simple_id .
+ parameter_type = generalized_types | named_types | simple_types .
+ population = entity_ref .
+ primary = literal | ( qualifiable_factor { qualifier } ) .
+ procedure_call_stmt = ( built_in_procedure | procedure_ref )
+ [ actual_parameter_list ] ';' .
+ procedure_decl = procedure_head [ algorithm_head ] { stmt } END_PROCEDURE ';' .
+
+
+
+
+
+ procedure_head = PROCEDURE procedure_id [ '(' [ VAR ] formal_parameter
+ { ';' [ VAR ] formal_parameter } ')' ] ';' .
+ procedure_id = simple_id .
+ qualifiable_factor = attribute_ref | constant_factor | function_call |
+ general_ref | population .
+ qualifier = attribute_qualifier | index_qualifier .
+ real_type = REAL .
+ referenced_attribute = attribute_ref | qualified_attribute .
+ rel_op = '<' | '>' | '<=' | '>=' | '<>' | '=' | ':<>:' | ':=:' .
+ rel_op_extended = rel_op | IN | LIKE .
+ repeat_control = [ increment_control ] [ while_control ] [ until_control ] .
+ repeat_stmt = REPEAT repeat_control ';' stmt { stmt } END_REPEAT ';' .
+
+
+
+
+
+ return_stmt = RETURN [ '(' expression ')' ] ';' .
+ selector = expression .
+ set_type = SET [ bound_spec ] OF base_type .
+ sign = '+' | '-' .
+ simple_expression = term { add_like_op term } .
+ simple_factor = enumeration_reference | interval |
+ ( [ unary_op ] ( '(' expression ')' | primary ) ) .
+ simple_types = integer_type | logical_type | real_type | string_type .
+ skip_stmt = SKIP ';' .
+ stmt = assignment_stmt | case_stmt | compound_stmt | escape_stmt |
+ if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt |
+ skip_stmt .
+ string_literal = simple_string_literal .
+
+
+
+
+
+ string_type = STRING .
+ term = factor { multiplication_like_op factor } .
+ type_decl = TYPE type_id '=' underlying_type ';' END_TYPE ';' .
+ type_id = simple_id .
+ unary_op = '+' | '-' | NOT .
+ underlying_type = constructed_types | aggregation_types | simple_types |
+ type_ref .
+ until_control = UNTIL logical_expression .
+ variable_id = simple_id .
+ while_control = WHILE logical_expression .
+
+
+
+
+
+
+
+REFERENCES
+
+
+
+
+[LAMPORT94] Leslie Lamport. LaTeX: A Document Preparation System.
+Addison-Wesley Publishing Company, second edition, 1994.
+
+
+[KNUTH84a] Donald E. Knuth. The TeXbook. Addison-Wesley Publishing Company,
+1984.
+
+
+[STEPIS] ISO 10303. Industrial automation systems and integration ---
+Product data representation and exchange, 1994.
+
+
+[GOLDFARB90] C. A. Goldfarb. The SGML Handbook. Oxford University Press,
+1990. (Edited and with a foreword by Yuri Rubinsky).
+
+
+[MUSCIANO96] Chuck Musciano and Bill Kennedy. . O'Reilly & Associates,
+Inc., 1996.
+
+
+[KERNIGHAN88] Brian W. Kernighan and Dennis M. Ritchie. The C Programming
+Language. Prentice Hall, second edition, 1988.
+
+
+[EBOOK] Douglas A. Schenck and Peter R. Wilson. Information Modeling the
+EXPRESS Way. Oxford University Press (ISBN 0-19-308714-3), 1994.
+
+
+[EXPRESSIS] ISO 10303-11:1994. Industrial automation systems and integration
+--- Product data representation and exchange --- Part 11: Description methods:
+The EXPRESS language reference manual, 1994.
+
+
+[LEVINE92] John R. Levine, Tony Mason, and Doug Brown. lex & yacc. O'Reilly
+& Associates, Inc., second edition, 1992.
+
+
+[LESK75] M. E. Lesk and E. Schmidt. `LEX --- A Lexical Analyser Generator'.
+In UNIX Programmer's Manual 2. AT&T Bell Laboratories, Murray Hill, NJ, 1975.
+
+
+[JOHNSON75] S. C. Johnson. YACC --- Yet Another Compiler Compiler. C S
+Technical Report 32, Bell Telephone Laboratories, Murray Hill, NJ, 1975.
+
+
+[EXPRESSITR] ISO/TR 10303-12:1997. Industrial automation systems and
+integration --- Product data representation and exchange --- Part 12:
+Description method: The EXPRESS-I language reference manual, 1997.
+
+
+[PRW94b] Peter R. Wilson. `FLaTTeN: A Program to Flatten LaTeX Source
+Files'. NIST, Gaithersburg, MD 20899, December 1994. (In draft).
+
+
+[LIBES93] Don Libes. Obfuscated C and Other Mysteries. John Wiley & Sons,
+Inc., 1993.
+
+
+[HOLUB90] A. I. Holub. Compiler Design in C. Prentice-Hall, Inc., 1990.
+
+
+[ORAM91] Andrew Oram and Steve Talbott. Managing Projects with make.
+O'Reilly & Associates, Inc., second edition, 1991.
+
+
+[RINAUDOT94] Gaylen R. Rinaudot. . NISTIR 5511, NIST, Gaithersburg, MD
+20899, October 1994.
+
+
+[WIRTH77] N. Wirth. `What Can We Do About the Unnecessary Diversity of
+Notation for Syntactic Definitions?'. Communications of the ACM,
+20(11):822--823, November 1977.
+
+
+[MAKR91] Ronald Mak. Writing Compilers & Interpreters --- An Applied
+Approach. John Wiley & Sons, Inc., 1991.
+
+
+
+
+
+
diff --git a/support/ltx2x/makefile b/support/ltx2x/makefile
new file mode 100644
index 0000000000..3f606c3c08
--- /dev/null
+++ b/support/ltx2x/makefile
@@ -0,0 +1,290 @@
+# makefile for program ltx2x --- LaTeX to X autotagger
+# November 1999
+#
+##################### Change the following for your setup
+# The compiler
+CC = gcc
+
+# We use flex (or equivalent, but not lex) to generate the lexer
+LEX = flex
+# and the options
+LEXFLAGS = -v
+
+# We use bison (or equivalent) to generate the parser
+YACC = bison
+# and the options
+YACCFLAGS = -y -d -v
+
+# Libraries to be used
+LIBS = -ly -ll -lm
+
+# The root directory for the installation (e.g., /usr/local )
+ROOTDIR = /opt/GNU/gnu
+
+# Where to place the running code (e.g. /usr/local/bin )
+BINDIR = ${ROOTDIR}/bin
+
+# Where to place the manpage (e.g., /usr/local/man/man1 )
+MANEXT = 1
+MANDIR = ${ROOTDIR}/man/man${MANEXT}
+
+# Just in case you want to change the name of the binary
+# (and then you should also change the man page and documentation).
+# So, do not change this.
+PROG = ltx2x
+
+# Where to place the user documentation (e.g., /usr/local/doc/ltx2x )
+DOCDIR = ${ROOTDIR}/doc/${PROG}
+
+# Where to place the example command tables (e.g., /usr/local/lib/config/ltx2x )
+CTDIR = ${ROOTDIR}/lib/config/${PROG}
+
+# The code checking program
+LINT = lint
+
+# Code checking program options
+LINTOPTS = -achqux
+
+# Assume getopt is present on the system
+GETOPTC =
+GETOPTO =
+GETOPTH =
+# If you do not have getopt already on your system, uncomment the next three linws
+# GETOPTC = getopt.c
+# GETOPTO = getopt.o
+# GETOPTO = getopt.h
+
+
+# The file copy command (copy but do not delete original)
+COPY = cp
+
+# The file move command (move and delete original)
+MOVE = mv
+
+# The file delete command
+DELETE = rm
+
+# The make directory (hierarchy) command
+MAKEDIR = mkdirhier
+
+# The stream editor command
+SED = sed
+
+# Command to write to the terminal (stdout)
+ECHO = echo
+
+################### You should not have to change anything after this
+################### but read on just in case
+
+# The source modules
+L2XSRCS = l2xytab.c l2xlexyy.c l2xlib.c l2xacts.c l2xusrlb.c srchenv.c \
+ ${GETOPTC}
+
+INTSRCS = l2xirtne.c l2xistd.c l2xidecl.c l2xistmt.c l2xiexpr.c l2xiscan.c \
+ l2xisymt.c l2xierr.c l2xiidbg.c l2xistup.c l2xixutl.c l2xixstm.c \
+ l2xixxpr.c l2xixstd.c l2xidbug.c l2xisdcl.c l2xirexp.c listsetc.c
+
+# The object modules
+L2XOBJS = l2xytab.o l2xlexyy.o l2xlib.o l2xacts.o l2xusrlb.o srchenv.o \
+ ${GETOPTO}
+
+INTOBJS = l2xirtne.o l2xistd.o l2xidecl.o l2xistmt.o l2xiexpr.o l2xiscan.o \
+ l2xisymt.o l2xierr.o l2xiidbg.o l2xistup.o l2xixutl.o l2xixstm.o \
+ l2xixxpr.o l2xixstd.o l2xidbug.o l2xisdcl.o l2xirexp.o listsetc.o
+
+OBJS = ${L2XOBJS} ${INTOBJS}
+
+# Link object code together into PROG
+ltx2x : ${OBJS}
+ ${CC} -o ${PROG} ${OBJS} ${LIBS}
+
+# Compile C source code into object code
+getopt.o : getopt.c getopt.h
+ ${CC} -c getopt.c
+l2xytab.o : l2xytab.c l2xlib.h l2xusrlb.h l2xacts.h strtypes.h l2xcom.h
+ ${CC} -c l2xytab.c
+l2xlexyy.o : l2xlexyy.c l2xytab.h l2xlib.h l2xusrlb.h l2xcom.h
+ ${CC} -c l2xlexyy.c
+l2xlib.o : l2xlib.c l2xytab.h strtypes.h l2xcom.h ${GETOPTH}
+ ${CC} -c l2xlib.c
+l2xusrlb.o : l2xusrlb.c l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xusrlb.c
+l2xacts.o : l2xacts.c l2xusrlb.h l2xlib.h l2xytab.h strtypes.h l2xcom.h
+ ${CC} -c l2xacts.c
+srchenv.o : srchenv.c srchenv.h
+ ${CC} -c srchenv.c
+
+# Generate C code for parsing
+l2xytab.c l2xytab.h: l2x.y
+ @ ${ECHO} "Expect 10 shift/reduce conflicts to be reported"
+ ${YACC} ${YACCFLAGS} l2x.y
+ ${MOVE} y.tab.c l2xytab.c
+ ${MOVE} y.tab.h l2xytab.h
+
+# Generate C code for lexing
+l2xlexyy.c : l2x.l
+ ${LEX} ${LEXFLAGS} l2x.l
+ ${MOVE} lex.yy.c l2xlexyy.c
+
+# stuff for interpreter modules
+
+# compiler flags for analyze and execute programs
+ANLFLAG = -Danalyze
+RUNFLAG = -Dtrace
+
+# interpreter commons
+
+SOMEH = l2xicmon.h l2xierr.h l2xiscan.h l2xisymt.h licomsym.h l2xiidbg.h
+MOSTH= ${SOMEH} l2xiprse.h
+ALLH = ${MOSTH} l2xicpr.h l2xiexec.h
+
+# interpreter setup
+
+l2xistup.o : l2xistup.c ${ALLH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xistup.c
+
+# The parser module
+
+l2xirtne.o : l2xirtne.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xirtne.c
+
+l2xistd.o : l2xistd.c ${MOSTH}
+ ${CC} -c l2xistd.c
+
+l2xidecl.o : l2xidecl.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xidecl.c
+
+l2xistmt.o : l2xistmt.c ${ALLH}
+ ${CC} -c ${ANLFLAG} l2xistmt.c
+
+l2xiexpr.o : l2xiexpr.c ${MOSTH} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiexpr.c
+
+# scanner module
+
+l2xiscan.o : l2xiscan.c ${SOME} l2xicpr.h
+ ${CC} -c ${ANLFLAG} l2xiscan.c
+
+# symbol table module
+
+l2xisymt.o : l2xisymt.c l2xicmon.h l2xierr.h l2xisymt.h licomsym.h l2xiidbg.h
+ ${CC} -c l2xisymt.c
+
+# executor module
+
+l2xixutl.o : l2xixutl.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixutl.c
+
+l2xixstm.o : l2xixstm.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstm.c
+
+l2xixxpr.o : l2xixxpr.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixxpr.c
+
+l2xixstd.o : l2xixstd.c ${MOSTH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xixstd.c
+
+l2xidbug.o : l2xidbug.c ${SOMEH} l2xiexec.h listsetc.h
+ ${CC} -c ${RUNFLAG} l2xidbug.c
+
+# error and miscellaneous module
+
+l2xisdcl.o : l2xisdcl.c ${SOMEH}
+ ${CC} -c ${ANLFLAG} ${RUNFLAG} l2xisdcl.c
+
+l2xiidbg.o : l2xiidbg.c ${SOMEH} l2xiexec.h
+ ${CC} -c l2xiidbg.c
+
+l2xirexp.o : l2xirexp.c l2xirexp.h
+ ${CC} -c l2xirexp.c
+
+listsetc.o : listsetc.c listsetc.h
+ ${CC} -c listsetc.c
+
+
+# Checking the sources
+
+# Original ltx2x
+checkl2x :
+ ${LINT} ${LINTOPTS} -o l2x.lint ${L2XSRCS}
+# Interpreter
+checkinterp :
+ ${LINT} ${LINTOPTS} -o interp.lint ${INTSRCS}
+# The lot!
+checkall :
+ ${LINT} ${LINTOPTS} -o ltx2x.lint ${L2XSRCS} ${INTSRCS}
+
+
+# only call make install if BINDIR has been set
+install : ltx2x
+ ${MAKEDIR} ${BINDIR}
+ ${COPY} ${PROG} ${BINDIR}
+
+# Edit the file man to replace DOCUMENTDIR by the actual directory
+# where the user manual is to be placed, and CTDIR by the location
+# of the example command table files.
+# Then copy the manpage to the proper place
+manpage :
+ ${SED} 's!DOCUMENTDIR!${DOCDIR}!; s!CTDIR!${CTDIR}!' man > tman
+ ${MAKEDIR} ${MANDIR}
+ ${COPY} tman ${MANDIR}/${PROG}.${MANEXT}
+
+# Copy the user manuals to the proper place
+doc :
+ ${MAKEDIR} ${DOCDIR}
+ ${COPY} ltx2x.tex ${DOCDIR}/${PROG}.tex
+ ${COPY} ltx2x.ps ${DOCDIR}/${PROG}.ps
+ ${COPY} ltx2x.txt ${DOCDIR}/${PROG}.txt
+ ${COPY} ltx2x.html ${DOCDIR}/${PROG}.html
+
+# Copy the example command tables to their final location
+ctables :
+ ${MAKEDIR} ${CTDIR}
+ ${COPY} ltx2x.ct ${CTDIR}/ltx2x.ct
+ ${COPY} detex.ct ${CTDIR}/detex.ct
+ ${COPY} remcom.ct ${CTDIR}/remcom.ct
+ ${COPY} l2h.ct ${CTDIR}/l2h.ct
+ ${COPY} bye.ct ${CTDIR}/bye.ct
+
+# Do almost everything except clean up
+all : ltx2x install manpage doc ctables
+
+# call make clean to remove the compiled program, the object files,
+# info from YACC, and the edited version of the manpage
+clean :
+ - ${DELETE} ${PROG}
+ - ${DELETE} *.o
+ - ${DELETE} y.output
+ - ${DELETE} tman
+
+
+#### For the printct program (best to do this after the ltx2x program)
+
+# compile the printct program
+# printct : printct.o getopt.o srchenv.o
+# ${CC} -o printct printct.o getopt.o srchenv.o
+printct : printct.o srchenv.o ${GETOPTO}
+ ${CC} -o printct printct.o srchenv.o ${GETOPTO}
+
+printct.o : printct.c strtypes.h l2xcom.h ${GETOPTH}
+ ${CC} -c printct.c
+
+# call make installprintct to move the printct binary to its final location
+installprintct :
+ ${COPY} printct ${BINDIR}
+
+# call make cleanprintct to remove the compiled program and its object file
+cleanprintct :
+ - ${DELETE} printct
+ - ${DELETE} printct.o
+ - ${DELETE} srchenv.o
+ - ${DELETE} getopt.o
+
+testlist : testlist.o listsetc.o
+ ${CC} -o testlist testlist.o listsetc.o -lm
+
+testlist.o : testlist.c listsetc.h
+ ${CC} -c testlist.c
+
+
+
diff --git a/support/ltx2x/man b/support/ltx2x/man
new file mode 100644
index 0000000000..fb168f5ed9
--- /dev/null
+++ b/support/ltx2x/man
@@ -0,0 +1,203 @@
+.TH LTX2X 1 "21 January 1997"
+.SH NAME
+ltx2x \- replaces LaTeX commands by user-defined strings, such as HTML tags
+.SH SYNOPSIS
+.B ltx2x
+[
+.I options
+]
+.IR infile
+.IR outfile
+.br
+.SH DESCRIPTION
+The program
+.B ltx2x
+takes a LaTeX source file
+.I infile
+and replaces LaTeX commands by user-defined strings. For each command
+strings may be inserted at the start and end of the command and between
+any parameters that the command might take. Note that
+.I infile
+must be the complete name of the LaTeX source file
+including the extension (e.g., root.tex).
+The result is written to file
+.IR outfile.
+.PP
+The user-defined replacement strings are specified in a
+.I command table file
+which is read at runtime. This file is a formatted text
+file which can be edited by any text editor. Example command table
+files are provided for at least de-TeXing a LaTeX
+document and for conversion from LaTeX to HTML tags
+so that the document can be read via a WWW browser.
+.PP
+.B Ltx2x
+will not recognize the LaTeX \\include and \\input commands
+as requiring the inclusion of another LaTeX file, so all
+the LaTeX source to be processed should be in a single file.
+(A program such as
+.B flatten
+can be used to generate a single LaTeX file from multiple sources.)
+.PP
+.B Ltx2x automatically produces an error log file called
+.I ltx2x.err
+and a listing of the command table as processed is
+automatically generated as file
+.I ltx2xct.lis
+Either of these files can be examined with a text editor after each run.
+.PP
+Ltx2x also includes an interpreter and a source level debugger for the
+EXPRESS-A programming language which is based on the ISO standard
+ISO 10303-11:1994 "Industrial automation systems and integration ---
+Product data representation and exchange --- Part 11: Description
+methods: The EXPRESS language reference manual", and also
+Douglas Schenck and Peter Wilson, "Information Modeling the
+EXPRESS Way", Oxford University Press, 1994 (ISBN 0-19-508714-3).
+.PP
+The program
+.B printct
+can be used to pretty-print a command table file, and this will
+also update any old command table file to the current syntax.
+.PP
+For more information see the manual: Peter Wilson,
+"LTX2X: A LaTeX to X Auto-tagger",
+the source for which should be in directory DOCUMENTDIR
+in various formats. In fact it is highly desirable that you read
+the manual before running the program --- it gives full details
+of the syntax and capabilities of command tables, and advice
+on how to extend the program when the provided capabilities are
+insufficient.
+.SH OPTIONS
+.TP
+.B -c
+By default,
+.B ltx2x
+ignores all LaTeX comments in the
+.IR infile.
+This option causes
+.B ltx2x
+to write the comments to the output
+.IR outfile.
+.TP
+.B -f ctname
+By default the command table is read from file
+.I ltx2x.ct.
+This option will cause the command table to be read from file
+.I ctname
+instead.
+.TP
+.B -i num
+Print interpreter diagnostic information to the error file
+.I ltx2x.err.
+The value of
+.I num
+should be between 1 and 9 inclusive, with larger numbers producing
+increasing amounts of diagnostic information.
+.TP
+.B -l num
+Print diagnostic information to the error file
+.I ltx2x.err.
+The value of
+.I num
+should be between 1 and 9 inclusive, with larger numbers producing
+increasing amounts of diagnostic information.
+.TP
+.B -p num
+This option requests
+.B ltx2x to pretty-print the output file (at least as far as it
+is able to).
+.I num
+is the desired maximum number of characters per output line.
+.TP
+.B -t
+Generate diagnostics related to processing the command table file.
+.TP
+.B -w
+By default,
+.B ltx2x
+outputs source white space to the output file just as it reads it.
+This option causes it to collapse any amount of contiguous
+white space to a single space. The
+.B -p
+option includes this option.
+.TP
+.B -y
+Like the
+.B -l
+option but only produces parser related diagnostics. (This is currently
+a null option, but may be implemented in a future release.)
+.TP
+.B -C
+If the
+.B -i
+option is used, then this option cancels diagnostic printing for the
+interpreter's parser module.
+.TP
+.B -D character
+The
+.I character
+the operating system uses for catenating directory names when
+forming a pathname.
+The default is the slash (/) character.
+.TP
+.B -E
+If the
+.B -i
+option is used, then this option cancels diagnostic printing for the
+interpreter's runtime executor module.
+.TP
+.B -P characters
+The
+.I characters
+the operating system uses when seperating pathnames in a list of
+pathnames. The default characters are space ( ), colon (:) and
+semi-colon (;). The space is always set as one of the
+.IR characters.
+.TP
+.B -S
+This option enables the intractive source level debugger for the
+EXPRESS-A interpreter.
+.SH ENVIRONMENT
+.B Ltx2x
+searches for command table files in the directories in the paths defined by
+the LTX2XTABLES environment variable. If this variable is not
+set then it only searches in the current directory. Note that
+.I infile
+is always assumed to be located in the current directory.
+.SH FILES
+.I ltx2x.ct
+--- Skeleton command table file for interactive command file inclusion.
+.PP
+.I bye.ct
+--- Command table file for replacing a document with "Goodbye document".
+.PP
+.I detex.ct
+--- Skeleton command table file for deTeXing a LaTeX document.
+.PP
+.I remcom.ct
+--- Skeleton command table file for removing comments from a LaTeX document.
+.PP
+.I l2h.ct
+--- Command table for conversion from LaTeX to HTML.
+.PP
+.I fun.ct
+--- Examples of EXPRESS-A code.
+.PP
+These example command table files should be in directory CTDIR.
+.SH SOURCES
+Complete source files and documentation for
+.B ltx2x
+are maintained on the NIST SOLIS (STEP On Line Information Service)
+system in directory pub/subject/sc4/editing/latex/programs/ltx2x. SOLIS is
+accessible via:
+.br
+Anonymous ftp to ftp.cme.nist.gov
+.br
+the URL http://www.nist.gov/sc4
+.SH SEE ALSO
+.BR latex(1), flatten(1)
+.SH AUTHOR
+Peter Wilson, Catholic University of America and the National
+Institute of Standards and Technology (pwilson@cme.nist.gov).
+
+
diff --git a/support/ltx2x/printct.c b/support/ltx2x/printct.c
new file mode 100644
index 0000000000..d546f6f1ce
--- /dev/null
+++ b/support/ltx2x/printct.c
@@ -0,0 +1,1091 @@
+/* printct.c Main and support routines for printing ltx2x ct file */
+/* Written by Peter Wilson (Catholic University and NIST) */
+/* pwilson@cme.nist.gov */
+/* Version 0.1, July 1996 */
+/* 0.2, November 1996 */
+/*---------------------------------------------------------------------*/
+
+char FILE_VERSION[] = "Version 0.2";
+char FILE_DATE[] = "November 1996";
+
+/* VERSION HISTORY:
+ * Version 0.1 (July 1996): First release
+ * Version 0.2 (November 1996): Added SWITCH_TO_XXX and SWITCH_BACK
+ * Added CODE and friends
+ *
+ */
+
+/* Development of this software was funded by the United States Government,
+ * and is not subject to copyright.
+ */
+
+/* National Institute of Standards and Technology (NIST)
+ * Manufacturing Engineering Laboratory (MEL)
+ * Manufacturing Systems Integration Division (MSID)
+ * ********************************************************************
+ * D I S C L A I M E R
+ *
+ * There is no warranty for the PRINTCT software.
+ * If the PRINTCT software is modified by someone else and passed on,
+ * NIST wants the software's recipients to know that what they
+ * have is not what NIST distributed.
+ *
+ * Policies
+ *
+ * 1. Anyone may copy and distribute verbatim copies of the
+ * source code as received in any medium.
+ *
+ * 2. Anyone may modify your copy or copies of the PRINTCT source
+ * code or any portion of it, and copy and distribute such modifications
+ * provided that all modifications are clearly associated with the entity
+ * that performs the modifications.
+ *
+ * NO WARRANTY
+ * ===========
+ *
+ * NIST PROVIDES ABSOLUTELY NO WARRANTY. THE PRINTCT SOFTWARE
+ * IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
+ * WITH YOU. SHOULD ANY PORTION OF THE PRINTCT SOFTWARE PROVE DEFECTIVE,
+ * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+ *
+ * IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES,
+ * INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
+ * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+ * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+ * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
+ * FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
+ * NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+ */
+
+#include <string.h>
+#include "getopt.h"
+#include <stdio.h>
+#include <ctype.h>
+#ifndef STRTYPES_H
+#include "strtypes.h"
+#endif
+/* typedef char *STRING; A pointer-to-a-char */
+/* typedef STRING *PTRADR; A pointer-to-a-pointer-to-a-char */
+/* define SNUL '\0' end of a string */
+
+# define MAX_ERRORS 10
+
+FILE *filerr; /* Error file */
+FILE *filtabin; /* Table input file */
+FILE *filtabout; /* Table output file */
+
+
+int TDEBUG = FALSE; /* for debugging command table */
+
+ /* length of a user buffer */
+# define MAX_UBUFF_LEN 514
+
+char errstr[MAX_UBUFF_LEN]; /* buffer for assembling error/warning text */
+
+/* keywords */
+enum key_word{AUDIBLE_ALERT_CHAR,
+ BACKSPACE_CHAR,
+ CA,
+ CARRIAGE_RETURN_CHAR,
+ CODE,
+ CODE_SETUP,
+ COMMENT,
+ CONTINUE,
+ END_CODE,
+ END_CTFILE,
+ END_ITEM,
+ END_ITEM_PARAM,
+ END_MODE,
+ END_OPT,
+ END_TAG,
+ END_TAG_1,
+ END_TAG_2,
+ END_TAG_3,
+ END_TAG_4,
+ END_TAG_5,
+ END_TAG_6,
+ END_TAG_7,
+ END_TAG_8,
+ END_TAG_9,
+ END_TYPE,
+ ESCAPE_CHAR,
+ FORMFEED_CHAR,
+ HEX_CHAR,
+ HORIZONTAL_TAB_CHAR,
+ INCLUDE,
+ IN_MODE,
+ NAMEK,
+ NEWLINE_CHAR,
+ OPT_PARAM,
+ PC_AT_END,
+ PC_AT_START,
+ PRINT_CONTROL,
+ PRINT_OPT,
+ PRINT_P1,
+ PRINT_P2,
+ PRINT_P3,
+ PRINT_P4,
+ PRINT_P5,
+ PRINT_P6,
+ PRINT_P7,
+ PRINT_P8,
+ PRINT_P9,
+ REQPARAMS,
+ RESET_BUFFER,
+ RESET_FILE,
+ RESET_MODE,
+ RESET_SYSBUF,
+ SECTIONING_LEVEL,
+ SET_MODE,
+ SOURCE,
+ SPECIAL_TOKEN,
+ START_ITEM,
+ START_ITEM_PARAM,
+ START_OPT,
+ START_TAG,
+ START_TAG_1,
+ START_TAG_2,
+ START_TAG_3,
+ START_TAG_4,
+ START_TAG_5,
+ START_TAG_6,
+ START_TAG_7,
+ START_TAG_8,
+ START_TAG_9,
+ STRINGG,
+ SWITCH_BACK,
+ SWITCH_TO_BUFFER,
+ SWITCH_TO_FILE,
+ SWITCH_TO_SYSBUF,
+ TYPE,
+ VERTICAL_TAB_CHAR,
+ MAX_KEYSTR};
+int max_keystr = MAX_KEYSTR;
+STRING key_array[MAX_KEYSTR];
+
+
+void strtouc(); /* convert string to upper case */
+int lookup_string(); /* finds posn. of string in an ordered array of strings */
+void init_print_control();
+void init_keys();
+int key_to_int();
+STRING key_to_string();
+
+enum cont_enum {CONT_UNKNOWN_ENUM,
+ CONT_TAG};
+
+#define MAX_TABLE_LINE 1000
+char table_line[MAX_TABLE_LINE];
+#define MAX_TABLE_ENTRIES 1000
+int num_table_errors = 0;
+
+
+STRING unk = "ERROR";
+
+enum print_control{BUFFER,
+ DEFAULT_PRINT,
+ FFILE,
+ FIRST_STRING,
+ MODE,
+ NO_OP,
+ NO_PRINT,
+ PRINT_UNDERFLOW,
+ RESET,
+ SOURCE_STRING,
+ SYSBUF,
+ TO_BUFFER,
+ TO_FILE,
+ TO_SYSBUF,
+ UNKNOWN_PRINT,
+ MAX_PCSTR};
+int max_pcstr = MAX_PCSTR;
+STRING pc_array[MAX_PCSTR];
+
+
+void delete_to_chars();
+void table_error();
+void tdebug_tline();
+void tdebug_str_str_int();
+void tdebug_str_int();
+void tdebug_str();
+void process_table();
+void process_pc();
+int ct_lineno = 0; /* table line number */
+
+
+/* Environment variable defined search path stuff */
+void initialise_senv();
+char path_name[257]; /* name of a path */
+char sys_envname[20]; /* name of environment variable */
+char path_sep[10]; /* path name seperators */
+char dir_cat; /* directory catenation char */
+int senv_debug; /* =1 for debug searchenv() */
+
+
+
+
+
+/*-----------------------------------------------------------------*/
+
+/* MAIN the main program ----------------------------------------- */
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int optchar;
+ FILE *file;
+ char tabnam[100];
+
+ /* print banner */
+ fprintf(stdout, "\n printct: An ltx2x command table printer\n");
+ fprintf(stdout, "\n (%s, %s)\n", FILE_VERSION, FILE_DATE);
+
+ /* open error log file */
+ file = fopen("printct.err", "w");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file printct.err\n");
+ exit(1);
+ }
+ filerr = file;
+ fprintf(stdout, "Error file is printct.err\n");
+ fprintf(filerr, "Error file for program printct (%s, %s)\n", FILE_VERSION, FILE_DATE);
+ fprintf(filerr, "Author: Peter Wilson (Catholic University and NIST)\n");
+ fprintf(filerr, "Email any comments or suggestions to pwilson@cme.nist.gov\n\n");
+ /* open Table output file */
+ file = fopen("printct.lis", "w");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file printct.lis\n");
+ exit(1);
+ }
+ filtabout = file;
+ fprintf(stdout, "Table output file is printct.lis\n");
+ fprintf(filerr, "Table output file is printct.lis\n");
+
+ /* set up for Table input file */
+ strcpy(tabnam, "ltx2x.ct");
+ initialise_senv(); /* initialise directory searching */
+
+ /* get command line optional parameters */
+ opterr = 1; /* getopt prints errors if opterr is 1 */
+ while (EOF != (optchar =
+ getopt(argc,argv,"tf:P:D:"))) {
+ /* Uwe Sassenberg sassen@hal1.physik.uni-dortmund.de found
+ * that he had to add this next line of code to stop an infinite
+ * loop of this while (It did not seem to recognise EOF !!)
+ * If it compiles but just sits there chewing CPU cycles, try
+ * uncommenting the next line of code
+ */
+ /* if (optchar == 255) break; */
+ switch(optchar) {
+ case '?': /* command line error */
+ fprintf(stderr, "\nUsage: [-t] [-f tablename] [-P chars] [-D char]\n");
+ fprintf(filerr, "\nUsage: [-t] [-f tablename] [-P chars] [-D char]\n");
+ break;
+ case 't': /* switch on command table & SEARCHENV debugging */
+ TDEBUG = TRUE;
+ senv_debug = 1;
+ fprintf(stdout, "Command table debugging set ON\n");
+ fprintf(filerr, "Command table debugging set ON\n");
+ break;
+ case 'f': /* special Table input file */
+ strcpy(tabnam, optarg);
+ break;
+ case 'P': /* pathname seperators */
+ strcpy(path_sep, optarg);
+ strcat(path_sep, " ");
+ fprintf(stdout, "Pathname seperators set to (%s)\n", path_sep);
+ fprintf(filerr, "Pathname seperators set to (%s)\n", path_sep);
+ break;
+ case 'D': /* directory catenation char */
+ dir_cat = optarg[0];
+ fprintf(stdout, "Directory catenation character set to %c\n", dir_cat);
+ fprintf(filerr, "Directory catenation character set to %c\n", dir_cat);
+ break;
+ } /* end of switch */
+ } /* end of optional parameter processing */
+
+ /* open Table file */
+ if (!searchenv(tabnam, sys_envname, path_name, path_sep, dir_cat, senv_debug)) {
+ fprintf(stderr, "Fatal Error: Could not find file %s\n", tabnam);
+ exit(1);
+ }
+ file = fopen(path_name, "r");
+ if (!file) {
+ fprintf(stderr, "Fatal Error: Could not open file %s\n", path_name);
+ exit(1);
+ }
+ filtabin = file;
+ fprintf(stdout, "Table input file is %s\n", path_name);
+ fprintf(filerr, "Table input file is %s\n", path_name);
+
+ /* No other parameters */
+
+ /* do some initialisations */
+ init_keys(); /* 6/96 initialise command keywords */
+ init_print_control(); /* initialise pc keywords */
+
+ process_table(filtabin, filtabout);
+ fclose(filtabin);
+ fclose(filtabout);
+ exit(0);
+
+} /* end MAIN */
+/*------------------------------------------------------------------------*/
+
+
+ /*-----------STRING FUNCTIONS-------------------------*/
+
+/* DELETE_TO_CHARS deletes all chars through first occurrence of "c" */
+void delete_to_chars(c,s)
+char c[];
+char s[];
+{
+ int len;
+ int pos;
+ int i, n;
+
+ len = strlen(s);
+ pos = strcspn(s, c);
+ if (pos > 0 && pos < len) { /* = found */
+ n = 0;
+ for (i = (pos+1); i <= len; i++ ) {
+ s[n] = s[i];
+ n++;
+ }
+ }
+} /* end DELETE_TO_CHARS */
+
+
+/* STRTOUC converts a string in place to upper case */
+void strtouc(str)
+char str[];
+{
+ int i;
+ for (i = 0; str[i] != SNUL; i++) {
+ str[i] = toupper(str[i]);
+ }
+ return;
+} /* end STRTOUC */
+
+
+
+ /*---------------ERROR AND DEBUG PRINTING-------------*/
+
+
+/* TABLE_ERROR prints Command table error message */
+void table_error(s)
+char *s;
+{
+ fprintf(stderr, "\nCommand table: %s line\n%d: %s\n",
+ s, ct_lineno, table_line);
+ fprintf(filerr, "\nCommand table: %s line\n%d: %s\n",
+ s, ct_lineno, table_line);
+ fflush(stderr);
+ fflush(filerr);
+ num_table_errors++;
+ if (num_table_errors >= MAX_ERRORS) {
+ fprintf(stderr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ fprintf(filerr, "\n** Table processing ended with at least %d errors **\n",
+ num_table_errors);
+ exit(1);
+ }
+} /* end TABLE_ERROR */
+
+/* TDEBUG_TLINE prints table line */
+void tdebug_tline(str)
+char str[];
+{
+ fprintf(stderr, "\nline %d: %s", ct_lineno, str);
+ fprintf(filerr, "\nline %d: %s", ct_lineno, str);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_TLINE */
+
+
+/* TDEBUG_STR prints diagnostics */
+void tdebug_str(str)
+char str[];
+{
+ fprintf(stderr, "LD: (Read_table) %s", str);
+ fprintf(filerr, "LD: (Read_table) %s", str);
+ fflush(stderr);
+ fflush(filerr);
+} /* end TDEBUG_STR */
+
+/* PROCESS_TABLE reads and writes a command table */
+/* Just checks keyword at start of line then prints the line out */
+/* Keywords are specified in key_word enumeration */
+/*-----------------------------------------------------------------------*/
+
+int in_code; /* global flag TRUE while processing CODE */
+void process_table(fin, fout)
+ FILE *fin; /* input file */
+ FILE *fout; /* output file */
+{
+
+ char line[MAX_TABLE_LINE];
+ char code_name[MAX_TABLE_LINE];
+ int num_names;
+ int num;
+ char str[MAX_TABLE_LINE];
+ int last_string = CONT_UNKNOWN_ENUM;
+ char *cin;
+ int key; /* command keyword */
+
+ STRING tab0 = "";
+ STRING tab1 = " ";
+ STRING tab2 = " ";
+ STRING tab3 = " ";
+ char code_tab[20];
+
+ in_code = FALSE; /* flag for CODE processing */
+
+
+ for (;;) { /* loop over all files */
+ line[0] = SNUL;
+ cin = fgets(line, MAX_TABLE_LINE, fin); /* read a line */
+ ct_lineno++;
+ if (TDEBUG) {
+ tdebug_tline(line);
+ }
+ if (feof(fin) != 0) { /* end of this file */
+ return;
+ }
+ strcpy(table_line, line);
+ /* get first name on line */
+ num_names = sscanf(line, "%s", code_name);
+ if (num_names <= 0) { /* blank line */
+ fprintf(fout, "\n");
+ continue; /* ignore */
+ }
+ strtouc(code_name); /* convert to upper case for comparisons */
+ key = key_to_int(code_name);
+ switch (key) {
+ case END_CTFILE : { /* end of file */
+ if (TDEBUG) {
+ tdebug_str("END_CTFILE=\n");
+ }
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case CA :
+ case COMMENT : { /* comment line */
+ if (TDEBUG) {
+ tdebug_str("C=\n");
+ }
+ delete_to_chars("=:", line);
+ fprintf(fout, "%sc=%s", tab3, line); /* print lower case c= */
+ break;
+ }
+
+ case INCLUDE : { /* file inclusion */
+ if (TDEBUG) {
+ tdebug_str(code_name);
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case TYPE : { /* start of a record */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case END_TYPE : { /* end of a record */
+ last_string = CONT_UNKNOWN_ENUM;
+/* delete_to_chars("=:", line); */
+ fprintf(fout, "%s%s", tab0, line);
+ break;
+ }
+
+ case NAMEK : { /* process NAME= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case PRINT_CONTROL : { /* process PRINT_CONTROL= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ fprintf(fout, "%s%s", tab1, key_to_string(key));
+ process_pc(fout, line);
+ break;
+ }
+
+ case START_TAG :
+ case END_TAG : { /* process START/END__TAG= */
+ last_string = CONT_TAG;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case OPT_PARAM : { /* process OPT_PARAM= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case PRINT_OPT : { /* process PRINT_OPT= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case START_OPT :
+ case END_OPT : { /* process START/END_OPT= */
+ last_string = CONT_TAG;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case REQPARAMS : { /* process REQPARAMS= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ sscanf(line, "%d", &num);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %d\n", code_name, num);
+ tdebug_str(errstr);
+ }
+ if (num >= 0 && num <= 9 ) {
+ ;
+ }
+ else {
+ table_error("REQPARAMS out of range (0-9)");
+ }
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case START_TAG_1 :
+ case END_TAG_1 :
+ case START_TAG_2 :
+ case END_TAG_2 :
+ case START_TAG_3 :
+ case END_TAG_3 :
+ case START_TAG_4 :
+ case END_TAG_4 :
+ case START_TAG_5 :
+ case END_TAG_5 :
+ case START_TAG_6 :
+ case END_TAG_6 :
+ case START_TAG_7 :
+ case END_TAG_7 :
+ case START_TAG_8 :
+ case END_TAG_8 :
+ case START_TAG_9 :
+ case END_TAG_9 : { /* process START/END_TAG_N= */
+ last_string = CONT_TAG;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case PRINT_P1 :
+ case PRINT_P2 :
+ case PRINT_P3 :
+ case PRINT_P4 :
+ case PRINT_P5 :
+ case PRINT_P6 :
+ case PRINT_P7 :
+ case PRINT_P8 :
+ case PRINT_P9 : { /* process PRINT_PN= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s", tab1, key_to_string(key));
+ process_pc(fout, line);
+ break;
+ }
+
+ case START_ITEM :
+ case END_ITEM : { /* process START/END_ITEM= */
+ last_string = CONT_TAG;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case START_ITEM_PARAM :
+ case END_ITEM_PARAM : { /* process START/END_ITEM_PARAM= */
+ last_string = CONT_TAG;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ break;
+ }
+
+ case CONTINUE : /* process CONTINUE= */
+ case STRINGG : { /* process STRING= */
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab2, key_to_string(STRINGG), line);
+ break;
+ }
+
+ case SOURCE : { /* 6/96 process SOURCE= */
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab2, key_to_string(key), line);
+ break;
+ }
+
+ case PC_AT_START :
+ case PC_AT_END : { /* 6/96 process PC_AT_START/END= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s", tab1, key_to_string(key));
+ process_pc(fout, line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, line);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+
+ case SECTIONING_LEVEL : { /* process SECTIONING_LEVEL= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab1, key_to_string(key), line);
+ if (TDEBUG) {
+ sprintf(errstr, "%s %s\n", code_name, str);
+ tdebug_str(errstr);
+ }
+ break;
+ }
+
+ case RESET_SYSBUF :
+ case RESET_BUFFER :
+ case RESET_FILE :
+ case RESET_MODE :
+ case SET_MODE : { /* process (RE)SET_X= */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab2, key_to_string(key), line);
+ break;
+ }
+
+ case SWITCH_BACK :
+ case SWITCH_TO_BUFFER :
+ case SWITCH_TO_FILE :
+ case SWITCH_TO_SYSBUF : { /* 11/96 process SWITCH-XXX */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab2, key_to_string(key), line);
+ break;
+ }
+
+ case IN_MODE : { /* 6/96 process IN_MODE */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case END_MODE : { /* 6/96 process END_MODE */
+ last_string = CONT_UNKNOWN_ENUM;
+/* delete_to_chars("=:", line); */
+ fprintf(fout, "%s%s", tab0, line);
+ break;
+ }
+
+ case SPECIAL_TOKEN : { /* process SPECIAL_TOKEN= */
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case ESCAPE_CHAR :
+ case NEWLINE_CHAR :
+ case HORIZONTAL_TAB_CHAR :
+ case VERTICAL_TAB_CHAR :
+ case BACKSPACE_CHAR :
+ case CARRIAGE_RETURN_CHAR :
+ case FORMFEED_CHAR :
+ case AUDIBLE_ALERT_CHAR :
+ case HEX_CHAR : { /* process characters */
+ if (TDEBUG) {
+ tdebug_str(code_name);
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ delete_to_chars("=:", line);
+ fprintf(fout, "%s%s%s", tab0, key_to_string(key), line);
+ break;
+ }
+
+ case CODE_SETUP : { /* CODE_SETUP added for code interp */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ fprintf(fout, "%s%s\n", tab0, key_to_string(key));
+ strcpy(code_tab, tab0);
+ in_code = TRUE;
+ break;
+ }
+
+ case CODE : { /* CODE added for code interp */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ if (last_string == CONT_UNKNOWN_ENUM) {
+ sprintf(errstr, "Can not use %s at this point", code_name);
+ table_error(errstr);
+ }
+ fprintf(fout, "%s%s\n", tab2, key_to_string(key));
+ strcpy(code_tab, tab2);
+ in_code = TRUE;
+ break;
+ }
+
+
+ default : { /* possibly unrecognised */
+ if (!in_code) { /* unrecognised! */
+ if (TDEBUG) {
+ tdebug_str("UNRECOGNISED CODE NAME\n");
+ }
+ last_string = CONT_UNKNOWN_ENUM;
+ table_error("Unrecognised code");
+ break;
+ }
+ /* are in CODE processing */
+ if (key == END_CODE) { /* end of CODE */
+ if (TDEBUG) {
+ sprintf(errstr, "%s\n", code_name);
+ tdebug_str(errstr);
+ }
+ fprintf(fout, "%s%s\n", code_tab, key_to_string(key));
+ in_code = FALSE;
+ break;
+ }
+ else { /* still in CODE, just print */
+ fprintf(fout, "%s%s", code_tab, table_line);
+ break;
+ }
+ break;
+ } /* end of default case */
+ } /* end of switch */
+ fflush(fout);
+
+ } /* end of loop over all files */
+} /* end PROCESS_TABLE */
+
+
+ /*---------------FILE INCLUSION-------------------*/
+
+/* INITIALISE_SENV initialises path searching */
+void initialise_senv()
+{
+ strcpy(sys_envname,"LTX2XTABLES"); /* environment variable name */
+ strcpy(path_sep," :;"); /* path seperators */
+ dir_cat = '/'; /* dir catenation char */
+ senv_debug = 0; /* debugging off */
+} /* end INITIALISE_SENV */
+
+
+
+
+
+/*---------------------------------------------------------------*/
+/* 6/96 extras */
+
+
+
+/* PARSE_PC parses print control and returns new structure */
+void process_pc(fout, a_line)
+ FILE *fout;
+ char a_line[];
+{
+ char key_name[MAX_TABLE_LINE];
+ int key_enum;
+
+
+ /* get first keyword on line */
+ sscanf(a_line, "%s", key_name);
+ strtouc(key_name);
+ /* convert to enumeration type */
+ key_enum = printc_to_int(key_name);
+ /* switch to get all the data */
+ switch (key_enum) {
+ case DEFAULT_PRINT: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+ case NO_PRINT: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+ case TO_SYSBUF: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+ case PRINT_UNDERFLOW: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+ case UNKNOWN_PRINT: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case TO_BUFFER: { /* get buffer number */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case TO_FILE: { /* get file */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case SYSBUF: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case BUFFER: { /* get buffer number */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case FFILE: { /* get file */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case FIRST_STRING: { /* get string */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case RESET: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ case NO_OP: { /* got it all */
+ fprintf(fout, "%s", a_line);
+ return;
+ }
+
+ default: {
+ fprintf(fout, "**** %s", a_line);
+ return;
+ }
+ }
+} /* end PROCESS_PC */
+
+/* LOOKUP_STRING returns position of string in an array of strings */
+int lookup_string(str, array, numstr)
+STRING str; /* string to search for */
+STRING array[]; /* array of strings */
+int numstr; /* number of strings in array */
+{
+ int low, mid, high, result;
+
+ low = 0;
+ high = numstr - 1;
+ while (low <= high) {
+ mid = (low + high)/2;
+ result = strcmp(str, array[mid]);
+ if (result < 0) { /* not in top half */
+ high = mid - 1;
+ }
+ else if (result > 0) { /* not in bottom half */
+ low = mid + 1;
+ }
+ else { /* found it */
+ return(mid);
+ }
+ }
+ return(-1); /* str not in array */
+} /* end LOOKUP_STRING */
+
+/* INIT_PRINT_CONTROL initialises print control stuff */
+void init_print_control()
+{
+
+ /* set up enum/str array */
+ pc_array[BUFFER] = "BUFFER";
+ pc_array[DEFAULT_PRINT] = "DEFAULT_PRINT";
+ pc_array[FFILE] = "FILE";
+ pc_array[FIRST_STRING] = "FIRST_STRING";
+ pc_array[MODE] = "MODE";
+ pc_array[NO_OP] = "NO_OP";
+ pc_array[NO_PRINT] = "NO_PRINT";
+ pc_array[PRINT_UNDERFLOW] = "PRINT_UNDERFLOW";
+ pc_array[RESET] = "RESET";
+ pc_array[SOURCE_STRING] = "SOURCE_STRING";
+ pc_array[SYSBUF] = "SYSBUF";
+ pc_array[TO_BUFFER] = "TO_BUFFER";
+ pc_array[TO_FILE] = "TO_FILE";
+ pc_array[TO_SYSBUF] = "TO_SYSBUF";
+ pc_array[UNKNOWN_PRINT] = "UNKNOWN_PRINT";
+
+
+} /* end INIT_PRINT_CONTROL */
+
+/* PRINTC_TO_INT converts print control string to enum */
+int printc_to_int(s)
+STRING s;
+{
+ int pos;
+
+ pos = lookup_string(s, pc_array, max_pcstr);
+ if (pos == -1) { /* unknown string */
+ table_error("PRINT_CONTROL unrecognised");
+ return(UNKNOWN_PRINT);
+ }
+ return(pos);
+} /* end PRINTC_TO_INT */
+
+
+
+/* INIT_KEYS initialises keyword stuff */
+void init_keys()
+{
+
+ /* set up enum/string array */
+ key_array[AUDIBLE_ALERT_CHAR] = "AUDIBLE_ALERT_CHAR=";
+ key_array[BACKSPACE_CHAR] = "BACKSPACE_CHAR=";
+ key_array[CA] = "C=";
+ key_array[CARRIAGE_RETURN_CHAR] = "CARRIAGE_RETURN_CHAR=";
+ key_array[CODE] = "CODE:";
+ key_array[CODE_SETUP] = "CODE_SETUP=";
+ key_array[COMMENT] = "COMMENT=";
+ key_array[CONTINUE] = "CONTINUE=";
+ key_array[END_CODE] = "END_CODE";
+ key_array[END_CTFILE] = "END_CTFILE=";
+ key_array[END_ITEM] = "END_ITEM=";
+ key_array[END_ITEM_PARAM] = "END_ITEM_PARAM=";
+ key_array[END_MODE] = "END_MODE";
+ key_array[END_OPT] = "END_OPT=";
+ key_array[END_TAG] = "END_TAG=";
+ key_array[END_TAG_1] = "END_TAG_1=";
+ key_array[END_TAG_2] = "END_TAG_2=";
+ key_array[END_TAG_3] = "END_TAG_3=";
+ key_array[END_TAG_4] = "END_TAG_4=";
+ key_array[END_TAG_5] = "END_TAG_5=";
+ key_array[END_TAG_6] = "END_TAG_6=";
+ key_array[END_TAG_7] = "END_TAG_7=";
+ key_array[END_TAG_8] = "END_TAG_8=";
+ key_array[END_TAG_9] = "END_TAG_9=";
+ key_array[END_TYPE] = "END_TYPE";
+ key_array[ESCAPE_CHAR] = "ESCAPE_CHAR=";
+ key_array[FORMFEED_CHAR] = "FORMFEED_CHAR=";
+ key_array[HEX_CHAR] = "HEX_CHAR=";
+ key_array[HORIZONTAL_TAB_CHAR] = "HORIZONTAL_TAB_CHAR=";
+ key_array[INCLUDE] = "INCLUDE=";
+ key_array[IN_MODE] = "IN_MODE=";
+ key_array[NAMEK] = "NAME=";
+ key_array[NEWLINE_CHAR] = "NEWLINE_CHAR=";
+ key_array[OPT_PARAM] = "OPT_PARAM=";
+ key_array[PC_AT_END] = "PC_AT_END=";
+ key_array[PC_AT_START] = "PC_AT_START=";
+ key_array[PRINT_CONTROL] = "PRINT_CONTROL=";
+ key_array[PRINT_OPT] = "PRINT_OPT=";
+ key_array[PRINT_P1] = "PRINT_P1=";
+ key_array[PRINT_P2] = "PRINT_P2=";
+ key_array[PRINT_P3] = "PRINT_P3=";
+ key_array[PRINT_P4] = "PRINT_P4=";
+ key_array[PRINT_P5] = "PRINT_P5=";
+ key_array[PRINT_P6] = "PRINT_P6=";
+ key_array[PRINT_P7] = "PRINT_P7=";
+ key_array[PRINT_P8] = "PRINT_P8=";
+ key_array[PRINT_P9] = "PRINT_P9=";
+ key_array[REQPARAMS] = "REQPARAMS=";
+ key_array[RESET_BUFFER] = "RESET_BUFFER:";
+ key_array[RESET_FILE] = "RESET_FILE:";
+ key_array[RESET_MODE] = "RESET_MODE:";
+ key_array[RESET_SYSBUF] = "RESET_SYSBUF:";
+ key_array[SECTIONING_LEVEL] = "SECTIONING_LEVEL=";
+ key_array[SET_MODE] = "SET_MODE:";
+ key_array[SOURCE] = "SOURCE:";
+ key_array[SPECIAL_TOKEN] = "SPECIAL_TOKEN=";
+ key_array[START_ITEM] = "START_ITEM=";
+ key_array[START_ITEM_PARAM] = "START_ITEM_PARAM=";
+ key_array[START_OPT] = "START_OPT=";
+ key_array[START_TAG] = "START_TAG=";
+ key_array[START_TAG_1] = "START_TAG_1=";
+ key_array[START_TAG_2] = "START_TAG_2=";
+ key_array[START_TAG_3] = "START_TAG_3=";
+ key_array[START_TAG_4] = "START_TAG_4=";
+ key_array[START_TAG_5] = "START_TAG_5=";
+ key_array[START_TAG_6] = "START_TAG_6=";
+ key_array[START_TAG_7] = "START_TAG_7=";
+ key_array[START_TAG_8] = "START_TAG_8=";
+ key_array[START_TAG_9] = "START_TAG_9=";
+ key_array[STRINGG] = "STRING:";
+ key_array[SWITCH_BACK] = "SWITCH_BACK:";
+ key_array[SWITCH_TO_BUFFER] = "SWITCH_TO_BUFFER:";
+ key_array[SWITCH_TO_FILE] = "SWITCH_TO_FILE:";
+ key_array[SWITCH_TO_SYSBUF] = "SWITCH_TO_SYSBUF:";
+ key_array[TYPE] = "TYPE=";
+ key_array[VERTICAL_TAB_CHAR] = "VERTICAL_TAB_CHAR=";
+
+} /* end INIT_KEYS */
+
+
+/* KEY_TO_INT converts a keyword string to an integer */
+int key_to_int(s, no_error)
+STRING s;
+{
+ int pos;
+
+ pos = lookup_string(s, key_array, max_keystr);
+ if (pos == -1) { /* unknown string */
+ if (!in_code) {
+ table_error("KEYWORD unrecognised");
+ }
+ }
+ return(pos);
+} /* end KEY_TO_INT */
+
+
+/* KEY_TO_STRING converts a keyword integer to a string */
+STRING key_to_string(pos)
+int pos;
+{
+ if (pos >= 0 && pos < max_keystr) {
+ return(key_array[pos]);
+ }
+ table_error("KEYWORD out of range");
+ return(unk);
+} /* end KEY_TO_STRING */
+
diff --git a/support/ltx2x/remcom.ct b/support/ltx2x/remcom.ct
new file mode 100644
index 0000000000..6d43294835
--- /dev/null
+++ b/support/ltx2x/remcom.ct
@@ -0,0 +1,133 @@
+ c= remcom.ct skeleton file for ltx2x to de-comment LaTeX source
+ c= Author: Peter Wilson (pwilson@cme.nist.gov) August 1996
+
+ESCAPE_CHAR= ?
+
+ c= ----------------required built in commands
+ c= tag with their source strings
+TYPE= BEGIN_DOCUMENT
+ START_TAG= "\begin{document}"
+END_TYPE
+
+TYPE= END_DOCUMENT
+ START_TAG= "\end{document}"
+END_TYPE
+
+TYPE= BEGIN_VERB
+ c= assume that the verb character is |
+ START_TAG= "\verb|"
+END_TYPE
+
+TYPE= END_VERB
+ START_TAG= "|"
+END_TYPE
+
+TYPE= BEGIN_VERBATIM
+ START_TAG= "\begin{verbatim}"
+END_TYPE
+
+TYPE= END_VERBATIM
+ START_TAG= "\end{verbatim}"
+END_TYPE
+
+TYPE= BEGIN_DOLLAR
+ START_TAG= "$"
+END_TYPE
+
+TYPE= END_DOLLAR
+ START_TAG= "$"
+END_TYPE
+
+TYPE= SLASH_SPACE
+ START_TAG= "\ "
+END_TYPE
+
+TYPE= OTHER_COMMAND
+END_TYPE
+
+TYPE= OTHER_BEGIN
+END_TYPE
+
+TYPE= OTHER_END
+END_TYPE
+
+TYPE= LBRACE
+ START_TAG= "{"
+END_TYPE
+
+TYPE= RBRACE
+ START_TAG= "}"
+END_TYPE
+
+TYPE= PARAGRAPH
+ c= use the default tag
+END_TYPE
+
+ c= ------------------ define '\item' tags within lists
+
+TYPE= BEGIN_LIST_ENV
+NAME= itemize
+ START_TAG= "\begin{itemize}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= enumerate
+ START_TAG= "\begin{enumerate}"
+ START_ITEM= "\item "
+END_TYPE
+
+TYPE= BEGIN_LIST_ENV
+NAME= description
+ START_TAG= "\begin{description}"
+ START_ITEM= "\item"
+ START_ITEM_PARAM= "["
+ END_ITEM_PARAM= "] "
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= itemize
+ START_TAG= "\end{itemize}"
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= enumerate
+ START_TAG= "\end{enumerate}"
+END_TYPE
+
+TYPE= END_LIST_ENV
+NAME= description
+ START_TAG= "\end{description}"
+END_TYPE
+
+ c= ----------------------- test demonstration specials
+
+ c= spcial defined as a grammar special
+TYPE= SPECIAL_COMMAND
+NAME= \GRAMMspecial
+SPECIAL_TOKEN= 32767
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+
+ c= spcial defined as a code special
+TYPE= SPECIAL_COMMAND
+NAME= \CODEspecial
+SPECIAL_TOKEN= 59999
+ SECTIONING_LEVEL= SECT
+ START_TAG= "?n?n<div.1>?n"
+ STRING: "<heading>Normative References</heading>?n"
+ END_TAG= "?n</div.1>"
+ REQPARAMS= 1
+ START_ITEM= "?n"
+ START_ITEM_PARAM= " ("
+ END_ITEM_PARAM= ") -- "
+END_TYPE
+
+END_CTFILE= end of remcom.ct
diff --git a/support/ltx2x/srchenv.c b/support/ltx2x/srchenv.c
new file mode 100644
index 0000000000..fa3e8d8079
--- /dev/null
+++ b/support/ltx2x/srchenv.c
@@ -0,0 +1,392 @@
+/* file srchenv.c */
+/* searchenv() from Holub's "Compiler Design in C" */
+/* strtoul() from C standard library (not all compilers find this) */
+/* strtol() from C standard library (not all compilers find this) */
+
+
+#include <stdio.h>
+
+
+
+/* searchenv(filename, envname, pathname, ...) searches for a file along an
+ * environment declared path. Modification of Alan Holub "Compiler Design in C"
+ * Prentice Hall, 1990, page 747.
+ *
+ * Searches for a file by looking in the directories listed in the envname
+ * environment. Puts the full path name (if found) into pathname
+ * and returns 1.
+ * Otherwise, set *pathname to 0 and return 0. User specified characters are used
+ * to seperate directory names. The directory seperator character is
+ * also user specified. The pathname array must be at least 128 characters.
+ * Prints diagnostic trace if debug == 1.
+ */
+
+#define PBUF_SIZE 129 /* max length of pathname - 1 */
+
+int searchenv(filename, envname, pathname, sepchars, dirchar, debug)
+char *filename; /* file name to search for */
+char *envname; /* environment name to use as path */
+char *pathname; /* place to put path name when found (min 128 chars) */
+char *sepchars; /* path name seperators */
+char dirchar; /* directory catenation char */
+int debug; /* print diagnostics if equals 1 */
+{
+ char pbuf[PBUF_SIZE];
+ char *p;
+ char *strpbrk(), *strtok(), *getenv(), *strchr();
+
+ if (debug == 1) {
+ fprintf(stderr, "\nSEARCHENV: filename is: %s\n", filename);
+ }
+
+ strcpy(pathname, filename);
+ if (access(pathname, 0) != -1 ) { /* search current directory */
+ if (debug == 1) {
+ fprintf(stderr, "SEARCHENV: Found it in current directory\n");
+ }
+ return(1); /* found filename */
+ }
+
+ /* Filename not in current directory. If a path was requested
+ * (i.e. filename contains dirchar) or if environment not set,
+ * return a NULL, else search for filename on path.
+ */
+
+ if (debug == 1) {
+ fprintf(stderr, "SEARCHENV: envname is: %s with value of: %s\n",
+ envname, getenv(envname));
+ }
+
+/* if (strpbrk(filename, "\\/") || !(p = getenv(envname)) ) { */
+ if (strchr(filename, dirchar) || !(p = getenv(envname)) ) {
+ *pathname = '\0';
+ return(0);
+ }
+
+ strncpy(pbuf, p, PBUF_SIZE);
+ if (p = strtok(pbuf, sepchars) ) {
+ do {
+ sprintf(pathname, "%0.90s%c%0.20s", p, dirchar, filename);
+ if (debug == 1) {
+ fprintf(stderr, "SEARCHENV: looking for pathname: %s\n", pathname);
+ }
+ if (access(pathname, 0) >= 0 ) { /* found it */
+ if (debug == 1) {
+ fprintf(stderr, "SEARCHENV: Found file (pathname): %s\n", pathname);
+ }
+ return(1);
+ }
+ }
+ while (p = strtok(NULL, sepchars) );
+ }
+ if (debug == 1) {
+ fprintf(stderr, "SEARCHENV: RETURNED WITH NO PATHNAME\n");
+ }
+ *pathname = '\0';
+ return(0);
+} /* end SEARCHENV */
+
+
+/*
+ * strtoul.c --
+ *
+ * Source code for the "strtoul" library procedure.
+ *
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/* PRW: deleted lint stuff
+ * #ifndef lint
+ * static char rcsid[] = "$Header: /user6/ouster/tcl/compat/RCS/strtoul.c,v 1.3 93/03/19 15:25:41 ouster Exp $ SPRITE (Berkeley)";
+ * #endif
+ */
+
+#include <ctype.h>
+
+/*
+ * The table below is used to convert from ASCII digits to a
+ * numerical equivalent. It maps from '0' through 'z' to integers
+ * (100 for non-digit characters).
+ */
+
+static char cvtIn[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */
+ 100, 100, 100, 100, 100, 100, 100, /* punctuation */
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35,
+ 100, 100, 100, 100, 100, 100, /* punctuation */
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strtoul --
+ *
+ * Convert an ASCII string into an integer.
+ *
+ * Results:
+ * The return value is the integer equivalent of string. If endPtr
+ * is non-NULL, then *endPtr is filled in with the character
+ * after the last one that was part of the integer. If string
+ * doesn't contain a valid integer value, then zero is returned
+ * and *endPtr is set to string.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned long int
+strtoul(string, endPtr, base)
+ char *string; /* String of ASCII digits, possibly
+ * preceded by white space. For bases
+ * greater than 10, either lower- or
+ * upper-case digits may be used.
+ */
+ char **endPtr; /* Where to store address of terminating
+ * character, or NULL. */
+ int base; /* Base for conversion. Must be less
+ * than 37. If 0, then the base is chosen
+ * from the leading characters of string:
+ * "0x" means hex, "0" means octal, anything
+ * else means decimal.
+ */
+{
+ register char *p;
+ register unsigned long int result = 0;
+ register unsigned digit;
+ int anyDigits = 0;
+
+ /*
+ * Skip any leading blanks.
+ */
+
+ p = string;
+ while (isspace(*p)) {
+ p += 1;
+ }
+
+ /*
+ * If no base was provided, pick one from the leading characters
+ * of the string.
+ */
+
+ if (base == 0)
+ {
+ if (*p == '0') {
+ p += 1;
+ if (*p == 'x') {
+ p += 1;
+ base = 16;
+ } else {
+
+ /*
+ * Must set anyDigits here, otherwise "0" produces a
+ * "no digits" error.
+ */
+
+ anyDigits = 1;
+ base = 8;
+ }
+ }
+ else base = 10;
+ } else if (base == 16) {
+
+ /*
+ * Skip a leading "0x" from hex numbers.
+ */
+
+ if ((p[0] == '0') && (p[1] == 'x')) {
+ p += 2;
+ }
+ }
+
+ /*
+ * Sorry this code is so messy, but speed seems important. Do
+ * different things for base 8, 10, 16, and other.
+ */
+
+ if (base == 8) {
+ for ( ; ; p += 1) {
+ digit = *p - '0';
+ if (digit > 7) {
+ break;
+ }
+ result = (result << 3) + digit;
+ anyDigits = 1;
+ }
+ } else if (base == 10) {
+ for ( ; ; p += 1) {
+ digit = *p - '0';
+ if (digit > 9) {
+ break;
+ }
+ result = (10*result) + digit;
+ anyDigits = 1;
+ }
+ } else if (base == 16) {
+ for ( ; ; p += 1) {
+ digit = *p - '0';
+ if (digit > ('z' - '0')) {
+ break;
+ }
+ digit = cvtIn[digit];
+ if (digit > 15) {
+ break;
+ }
+ result = (result << 4) + digit;
+ anyDigits = 1;
+ }
+ } else {
+ for ( ; ; p += 1) {
+ digit = *p - '0';
+ if (digit > ('z' - '0')) {
+ break;
+ }
+ digit = cvtIn[digit];
+ if (digit >= base) {
+ break;
+ }
+ result = result*base + digit;
+ anyDigits = 1;
+ }
+ }
+
+ /*
+ * See if there were any digits at all.
+ */
+
+ if (!anyDigits) {
+ p = string;
+ }
+
+ if (endPtr != 0) {
+ *endPtr = p;
+ }
+
+ return result;
+}
+
+
+/*
+ * strtol.c --
+ *
+ * Source code for the "strtol" library procedure.
+ *
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/* PRW: deleted lint stuff
+ * #ifndef lint
+ * static char rcsid[] = "$Header: /user6/ouster/tcl/compat/RCS/strtol.c,v 1.2 93/03/19 15:25:43 ouster Exp $ SPRITE (Berkeley)";
+ * #endif
+ */
+
+#include <ctype.h>
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strtol --
+ *
+ * Convert an ASCII string into an integer.
+ *
+ * Results:
+ * The return value is the integer equivalent of string. If endPtr
+ * is non-NULL, then *endPtr is filled in with the character
+ * after the last one that was part of the integer. If string
+ * doesn't contain a valid integer value, then zero is returned
+ * and *endPtr is set to string.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+long int
+strtol(string, endPtr, base)
+ char *string; /* String of ASCII digits, possibly
+ * preceded by white space. For bases
+ * greater than 10, either lower- or
+ * upper-case digits may be used.
+ */
+ char **endPtr; /* Where to store address of terminating
+ * character, or NULL. */
+ int base; /* Base for conversion. Must be less
+ * than 37. If 0, then the base is chosen
+ * from the leading characters of string:
+ * "0x" means hex, "0" means octal, anything
+ * else means decimal.
+ */
+{
+ register char *p;
+ int result;
+
+ /*
+ * Skip any leading blanks.
+ */
+
+ p = string;
+ while (isspace(*p)) {
+ p += 1;
+ }
+
+ /*
+ * Check for a sign.
+ */
+
+ if (*p == '-') {
+ p += 1;
+ result = -(strtoul(p, endPtr, base));
+ } else {
+ if (*p == '+') {
+ p += 1;
+ }
+ result = strtoul(p, endPtr, base);
+ }
+ if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
+ *endPtr = string;
+ }
+ return result;
+}
diff --git a/support/ltx2x/srchenv.h b/support/ltx2x/srchenv.h
new file mode 100644
index 0000000000..e064db298d
--- /dev/null
+++ b/support/ltx2x/srchenv.h
@@ -0,0 +1,7 @@
+/* srchenv.h from Alan Holub's "Compiler Design in C" */
+#ifndef SRCHENV_H
+#define SRCHENV_H
+extern int searchenv();
+extern unsigned long int strtoul();
+extern long int strtol();
+#endif /* SRCHENV_H */
diff --git a/support/ltx2x/strtypes.h b/support/ltx2x/strtypes.h
new file mode 100644
index 0000000000..89f70dda70
--- /dev/null
+++ b/support/ltx2x/strtypes.h
@@ -0,0 +1,16 @@
+/* strtypes.h some typedefs for strings and TRUE/FALSE */
+
+#ifndef STRTYPES_H
+#define STRTYPES_H
+typedef char *STRING; /* a pointer-to-a-char */
+typedef STRING *PTRADR; /* A pointer-to-a-pointer-to-a-char */
+#define SNUL '\0'
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
diff --git a/support/ltx2x/url.sty b/support/ltx2x/url.sty
new file mode 120000
index 0000000000..93d02c6df2
--- /dev/null
+++ b/support/ltx2x/url.sty
@@ -0,0 +1 @@
+../../macros/latex/contrib/url/url.sty \ No newline at end of file