diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/ltx2x |
Initial commit
Diffstat (limited to 'support/ltx2x')
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= "&" +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= ( < --> < ) + START_TAG= "<" +END_TYPE + +TYPE= TEX_CHAR +NAME= > + c= ( > --> > ) + START_TAG= ">" +END_TYPE + +TYPE= COMMAND +NAME= \dag + START_TAG= "†" +END_TYPE + +TYPE= COMMAND +NAME= \ddag + START_TAG= "‡" +END_TYPE + +TYPE= COMMAND +NAME= \OE + START_TAG= "Œ" +END_TYPE + +TYPE= COMMAND +NAME= \oe + START_TAG= "œ" +END_TYPE + +TYPE= COMMAND +NAME= \pounds + START_TAG= "£" +END_TYPE + +TYPE= COMMAND +NAME= \S + START_TAG= "§" +END_TYPE + +TYPE= COMMAND +NAME= \copyright + START_TAG= "©" +END_TYPE + +TYPE= COMMAND +NAME= \neg + START_TAG= "¬" +END_TYPE + +TYPE= COMMAND +NAME= \pm + START_TAG= "±" +END_TYPE + +TYPE= COMMAND +NAME= \mu + START_TAG= "µ" +END_TYPE + +TYPE= COMMAND +NAME= \P + START_TAG= "¶" +END_TYPE + +TYPE= COMMAND +NAME= \AA + START_TAG= "Å" +END_TYPE + +TYPE= COMMAND +NAME= \AE + START_TAG= "Æ" +END_TYPE + +TYPE= COMMAND +NAME= \times + START_TAG= "×" +END_TYPE + +TYPE= COMMAND +NAME= \O + START_TAG= "Ø" +END_TYPE + +TYPE= COMMAND +NAME= \ss + START_TAG= "ß" +END_TYPE + +TYPE= COMMAND +NAME= \aa + START_TAG= "å" +END_TYPE + +TYPE= COMMAND +NAME= \ae + START_TAG= "æ" +END_TYPE + +TYPE= COMMAND +NAME= \div + START_TAG= "÷" +END_TYPE + +TYPE= COMMAND +NAME= \o + START_TAG= "ø" +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= " <= " +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= \supseteq + 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= " <i>in</i> " +END_TYPE + +TYPE= COMMAND +NAME= \emptyset + START_TAG= "Ø" +END_TYPE + +TYPE= COMMAND +NAME= \forall + START_TAG= " <i>forall</i> " +END_TYPE + +TYPE= COMMAND +NAME= \Rightarrow + START_TAG= " => " +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} --> <first> ) + START_TAG= "<" + END_TAG= ">" + REQPARAMS= 1 +END_TYPE + +TYPE= COMMAND +NAME= \ET + c= ( \ET{first} --> </first> ) + START_TAG= "</" + END_TAG= ">" + REQPARAMS= 1 +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 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> +<p><center><table border> +<caption>A simple table typeset by LaTeX.</caption> <a name="tab:lxtab"></a> + + +<p><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> +</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><table></samp> and <samp></table></samp> tags. +Each row of the table is enclosed between +<samp><tr></samp> and <samp></tr></samp> tags, +and each element in a row is enclosed between +<samp><td></samp> and <samp></td></samp> tags. +Under certain circumstances the closing tags (i.e., +those like <samp></...></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><td colspan=num> text </td></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><table></samp> and + <samp></table></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><tr><td></samp> and end <samp></tr></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></tr>?n<tr><td></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></td><td></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>... & text & ...</samp> maps to <br> + <samp>... </td><td> text </td><td> ...</samp>. <br> + However, when a multicolumn is involved the translation is <br> +<samp>... & \multicolumn{N}{P}{text} & ...</samp> maps to <br> +<samp>... </td><td colspan=N> text </td><td> ...</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= "<center><table border>" + 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= "</table></center>" +END_TYPE + + +<p>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 + + +<p>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 + + +<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= "<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 + + +<p>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 +</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>&</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><div.1></samp> and <samp></div.1></samp> +for sections, <samp><div.2></samp> for clauses, etc., and surround the +headings with tags <samp><heading></samp> and <samp></heading></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<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 + + +<p>TYPE= SECTIONING +NAME= <samp>\clause</samp> + 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 +</pre> + + + +<p>An example output resulting from this command table (if it had been applied to this +document) is: + + +<pre> +... +</div.2> +</div.1> + + +<p><div.1> +<heading>The command table file</heading> + + +<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= "<math>" +END_TYPE + + +<p>TYPE= END_DOLLAR + START_TAG= "</math>" +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><sup></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></sup></samp>. + + + +<p> +<pre> +TYPE= TEX_CHAR +NAME= <samp>^</samp> + START_TAG= "<sup>" + REQPARAMS= 1 + END_TAG= "</sup>" +END_TYPE +</pre> + + + +<p>Given the above specifications, then <samp>$(2^{15} - 1)$</samp> will be transformed +into <br> +<samp><math>(2<sup>15</sup> - 1)</math></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= "<a href="" + SOURCE: BUFFER 7 + STRING: "">" + SOURCE: BUFFER 7 + STRING: "</a>" + 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 +<a href="http://www.cdrom.com/pub/tex">http://www.cdrom.com/pub/tex</a> +</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 & 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><return></samp> Continue processing. + + <li> <samp>break</samp> <samp><number></samp> Place a breakpoint at the statement + on line <samp><number></samp>. + + <li> <samp>break</samp> Print the line numbers of all the breakpoints. + + <li> <samp>unbreak</samp> <samp><number></samp> Remove the breakpoint from line + <samp><number></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><variable></samp> Print data fetches for + <samp><variable></samp>. + + <li> <samp>store</samp> <samp><variable></samp> Print data stores for + <samp><variable></samp>. + + <li> <samp>watch</samp> <samp><variable></samp> Print both data fetches and + stores for <samp><variable></samp>. + + <li> <samp>watch</samp> Print the names of all variables being watched. + + <li> <samp>unwatch</samp> <samp><variable></samp> Remove the watch from + <samp><variable></samp>. + + <li> <samp>unwatch</samp> Remove all watches. + + <li> <samp>show</samp> <samp><expression></samp> Print the value of + the EXPRESS-A expresion <samp><expression></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><variable := expression></samp> Assign the value + of <samp><expression></samp> to the EXPRESS-A variable <samp><variable></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></div.1></samp>, and start tags the form <samp><div.1></samp>. +The titles of sections are enclosed between <samp><heading></samp> and +<samp></heading></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<div.1>?n" + STRING: "<heading>Normative References</heading>?n" +END_TAG= "?n</div.1>" +</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<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 +</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 <pos> /* other specials here */ +%token <pos> 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<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 +</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<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 +</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<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 +</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> +<html> +<head> +<title>LaTeX to X translator</title> +</head> +<body> + + +<p><h1 align=center> + LTX2X: A LaTeX to X Auto-tagger +</h1> +... +</pre> + +If the <samp>\mltitle</samp> command is not used, then the effect is to have +an empty <title> in the <head> 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 <, >, & 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 <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 <pre> 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>{#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]{<#1>} + + +<p>% print argument as an SGML/HTML end tag +<samp>\newcommand{\ET}</samp>[1]{</#1>} + + +<p>% print HTML special characters +<samp>\newcommand{\Amp}</samp>{&} +<samp>\newcommand{\GT}</samp>{>} +<samp>\newcommand{\LT}</samp>{<} +<samp>\newcommand{\HASH}</samp>{#} + + +<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= & + START_TAG= "&amp;" +END_TYPE + + +<p>TYPE= COMMAND +NAME= > + START_TAG= "&gt;" +END_TYPE + + +<p>TYPE= COMMAND +NAME= < + START_TAG= "&lt;" +END_TYPE + + +<p>TYPE= COMMAND +NAME= # + START_TAG= "&#035;" +END_TYPE + + +<p>TYPE= COMMAND +NAME= <samp>\ST</samp> + START_TAG= "&lt;" + END_TAG= "&gt;" + REQPARAMS= 1 +END_TYPE + + +<p>TYPE= COMMAND +NAME= <samp>\ET</samp> + START_TAG= "&lt;/" + END_TAG= "&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> +<html> +<head> +<title>LaTeX to X translator</title> +</head> +<body> + + +<p><h1 align=center> + LTX2X: A LaTeX to X Auto-tagger +</h1> +... +<samp>\end{verbatim}</samp> +<samp>\end{latexonly}</samp> + + +<p><samp>\begin{htmlverbatim}</samp> +<html> +<head> +<title>LaTeX to X translator<samp>\ET{title}</samp> +<samp>\ET{head}</samp> +<body> + + +<p><h1 align=center> +<title>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 <= N <= 32767 for a +grammar special, or N > 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><sassen@hal1.physik.uni-dortmund.de></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 & 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 & yacc. + O'Reilly & 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&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 & 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 & 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 & Interpreters --- An Applied Approach. + John Wiley & 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("&")150 3289 +y(END_TYPE)150 3488 y(TYPE=)i(COMMAND)150 3588 y(NAME=)g(\\GT)237 +3688 y(START_TAG=)e(">")150 3787 y(END_TYPE)150 3986 +y(TYPE=)i(COMMAND)150 4086 y(NAME=)g(\\LT)237 4186 y(START_TAG=)e +("<")150 4285 y(END_TYPE)150 4485 y(TYPE=)i(COMMAND)150 +4584 y(NAME=)g(\\HASH)237 4684 y(START_TAG=)e("#")150 +4783 y(END_TYPE)150 4983 y(TYPE=)i(COMMAND)150 5082 y(NAME=)g(\\ST)237 +5182 y(START_TAG=)e("<")237 5282 y(END_TAG=)g(">")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("</")237 1171 y(END_TAG=)g(">")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= "&" +END_TYPE + +TYPE= COMMAND +NAME= \GT + START_TAG= ">" +END_TYPE + +TYPE= COMMAND +NAME= \LT + START_TAG= "<" +END_TYPE + +TYPE= COMMAND +NAME= \HASH + START_TAG= "#" +END_TYPE + +TYPE= COMMAND +NAME= \ST + START_TAG= "<" + END_TAG= ">" + REQPARAMS= 1 +END_TYPE + +TYPE= COMMAND +NAME= \ET + START_TAG= "</" + END_TAG= ">" + 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= "&" +END_TYPE + +TYPE= COMMAND +NAME= \GT + START_TAG= ">" +END_TYPE + +TYPE= COMMAND +NAME= \LT + START_TAG= "<" +END_TYPE + +TYPE= COMMAND +NAME= \HASH + START_TAG= "#" +END_TYPE + +TYPE= COMMAND +NAME= \ST + START_TAG= "<" + END_TAG= ">" + REQPARAMS= 1 +END_TYPE + +TYPE= COMMAND +NAME= \ET + START_TAG= "</" + END_TAG= ">" + 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 |