%{
/* 
 * 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);
	}
	;


%%






