open ImpAst

%%
%eop EOF
%pos int

%name Imp

%term INT of int | NAME of string | PLUS | EOF 
  | LPAREN | RPAREN | TRUE | FALSE | LESS  
  | SKIP | ASSIGN | SEMI | IF | THEN | ELSE | WHILE | GOTO | BREAK | CONTINUE
  | LBRACE | RBRACE | COLON | DO

%nonterm c of com
  | a of aexp
  | b of bexp
  | program of com

%verbose
%start program

%keyword TRUE FALSE SKIP IF THEN ELSE WHILE GOTO BREAK CONTINUE

%value INT (1)
%value NAME ("")

%noshift EOF
 
%left SEMI
%nonassoc COLON
%left LESS 
%left PLUS 

%%

a : INT              (Int(INT))
  | NAME              (Var(NAME))
  | a PLUS a         (Plus(a1, a2))
  | LPAREN a RPAREN  (a)

b : TRUE             (True)
  | FALSE            (False)
  | a LESS a         (Less(a1, a2))
  | LPAREN b RPAREN  (b)

c : SKIP             (Skip)
  | NAME ASSIGN a     (Assign(NAME, a))
  | c SEMI c         (Seq(c1, c2))
  | IF LPAREN b RPAREN THEN LBRACE c RBRACE ELSE LBRACE c RBRACE   
                     (If(b, c1, c2))
  | WHILE LPAREN b RPAREN DO LBRACE c RBRACE     
                     (While(b, c))
  | NAME COLON c     (Label(NAME, c))
  | GOTO NAME        (Goto(NAME))
  | BREAK            (Break)
  | CONTINUE         (Continue)
    
program : c          (c)