/* pretzel formatted grammar for simple PASCAL. */

%token SEMI
%token BEG
%token END
%token MATH           // token should only be used in math mode
%token SIMP           // other simple tokens
%token OPEN
%token CLOSE
%token ALPHA
%token OMEGA
%token UNTIL
%token INTRO
%token PROC
%token COLON
%token ELSE
%token COMMENT
%token ID_TYPE
%token RECORD
%token CASE


%%

stmt_list    : stmt                // collect everything on a
             | stmt_list  stmt     // list of `statements'
;
    // what can statements be?
stmt         : COMMENT             {cancel + $1}
             | proc                // procedure heading
             | SEMI                // empty statement
                                   {cancel + $1 + force }
             | BEG stmt_list END   // a block
                            { $1 + indent + force + $2 +
                              cancel + outdent + force + $3 }
             | math                // an expression
;
math         : MATH                // build something like an
             | math math           // `expression'
             | simp
             | COLON
             | OPEN decl_list CLOSE
             | RECORD stmt_list END
;
simp         : SIMP
             | identifier     { "{\\it " + $1 + "}" }
;
identifier   : ID_TYPE             // put together identifiers
             | identifier ID_TYPE
;
decl_list    : math                // parameter lists
             | INTRO math                   // for var-parameters
             | decl_list SEMI math    {$1 + $2 + " " + $3 }
             | decl_list SEMI INTRO math    // for var-parameters
;
stmt         : ALPHA math OMEGA stmt  // if then/while do etc.
                                 { $1 + " " + $2 + " " + $3 +
                                   indent + force + $4 + outdent }
             | ALPHA math OMEGA stmt ELSE stmt   // if then else
                           {$1 + " " + $2 + " " + $3 +
                            indent + force + $4 + outdent +
                            force + $5 + indent + force + $6 +
                            outdent }
             | CASE math OMEGA stmt_list END     // case of end
             | BEG stmt_list UNTIL math          // repeat until
                                { $1 + indent + force +
                                  $2 + cancel + outdent + force +
                                  $3 + " " + $4 }
;
proc         : proc INTRO math SEMI   {$1 + $2 + $3 + $4 + force}
             | PROC            // procedure heading
;
stmt         : INTRO math SEMI  // variable and type declarations
                           {$1 + $2 + $3 + force}
;


