%{ (* WHILEpar.grm: parser specification for a simple WHILE language *) open Absyn; %} %token INT %token VAR %token TRUE FALSE %token PLUS MINUS TIMES EQ LT %token NEG AND %token ASS SKIP SEMI IF THEN ELSE WHILE DO %token LPAR RPAR %token EOF %left SEMI /* lowest precedence */ %left AND %nonassoc NEG %left LE EQ %left MINUS PLUS %left TIMES /* highest precedence */ %nonassoc HIGHEST %start Main %type AExp %type BExp %type Main Stm %% Main: Stm EOF { $1 } ; Stm: VAR ASS AExp { <-($1,$3) } | SKIP { Skip } | LPAR Stm RPAR { $2 } | Stm SEMI Stm { ^^($1,$3) } | IF BExp THEN Stm ELSE Stm %prec HIGHEST { ITE($2,$4,$6) } | WHILE BExp DO Stm %prec HIGHEST { While($2,$4) } ; AExp: VAR { V $1 } | INT { N $1 } | LPAR AExp RPAR { $2 } | AExp PLUS AExp { ++($1,$3) } | AExp TIMES AExp { **($1,$3) } | AExp MINUS AExp { --($1,$3) } ; BExp: TRUE { TT } | FALSE { FF } | AExp EQ AExp { ==($1,$3) } | AExp LT AExp { <<($1,$3) } | LPAR BExp RPAR { $2 } | NEG BExp { !! $2 } | BExp AND BExp { &&($1,$3) } ;