program of A.program
| programx of A.program
| stms of A.stm list
+ | stringcat of string
| stm of A.stm
| simp of A.stm
| return of A.stm
block : stm ([stm])
| LBRACE stms RBRACE (stms)
+stringcat : STRING (STRING)
+ | STRING stringcat (STRING ^ stringcat)
+
exp : LPAREN exp RPAREN (exp)
| INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
- | STRING (mark (A.StringExp(STRING),(STRINGleft,STRINGright)))
+ | stringcat (mark (A.StringExp(stringcat),(stringcatleft,stringcatright)))
| IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
| LBRACKET vtype RBRACKET exp %prec UNARY (mark (A.Cast (vtype, exp), (LBRACKETleft, expright)))
| exp DOT IDENT (mark (A.Member(exp, IDENT), (expleft, IDENTright)))