program : YPROGRAM decls YBEGIN stmts YEND
                        {$2.symtab = {["integer", "type", "integer"], ...};
                         $4.symtab = $2.symtab';
                         $$.type = $4.type;}
                ;

decls           : /* empty */
                        {$$.symtab' = $$.symtab;}
                | decl ';' decls
                        {$1.symtab = $$.symtab;
                         $3.symtab = $1.symtab';
                         $$.symtab' = $3.symtab';
                ;

decl            : vardecl
                        {$1.symtab = $$.symtab;
                         $$.symtab' = $$.symtab U $1.symtab';}
                | procdecl
                        {$1.symtab = $$.symtab;
                         $$.symtab' = $$.symtab U $1.symtab';}
                ;       

vardecl : YVAR vars ':' type
                        {$2.type = $4.type;
                         $2.class = "var";
                         $4.symtab = $$.symtab;
                         $$.symtab' = $2.symtab';}
                ;

type            : Yidentifier
                        {$$.type = Lookup($$.symtab, $1.text)[3];}
                ;

vars            : var
                        {/** OLD: Enter($1.text, $$.class, $$.type); **/
                         $$.symtab' = {[$1.text, $$.class, $$.type]};}
                | var ',' vars
                        {/** OLD: Enter($1.text, $$.class, $$.type); **/
                         $$.symtab' = {[$1.text, $$.class, $$.type]} U $3.symtab';}
                ;

var             : Yidentifier
                        {$$.text = $1;}
                           /* The lexer provides Yidentifier as a string */
                ;

        ...

stmts           : stmt ';'
                        {$$.type = $1.type;
                         $1.symtab = $$.symtab;}
                | stmt ';' stmts
                        {$$.type = if ($1.type = "OK" and $3.type = "OK")
                                        then "OK" else "ERROR";
                         $1.symtab = $$.symtab;
                         $3.symtab = $$.symtab;}
                ;

stmt            : /* empty */
                | var YASSMNT_OP expr
                        {$3.symtab = $$.symtab;
                         $$.type = 
                             (if Lookup($$.symtab, $1.text)[3] = $3.type
                              then "OK" else "ERROR";
                         }
        ...
                ;

expr            : number
                        {$$.type = $1.type;}
                | char
                        {$$.type = $1.type;}
                | bool
                        {$$.type = $1.type;}
                | var
                        {$$.type = Lookup($$.symtab, $1.text);}

        ...
                ;