| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- %{
- open Ast
- let loc lexbuf =
- (0, 0, 0, 0)
- sprintf "%s:%d:%d" pos.pos_fname pos.pos_lnum
- (pos.pos_cnum - pos.pos_bol + 1)
- %}
- /* Tokens */
- %token LPAREN RPAREN LBRACK RBRACK LBRACE RBRACE SEMICOL COMMA
- %token NOT ADD SUB MUL DIV MOD
- %token EQ NE LT LE GT GE
- %token AND OR
- %token ASSIGN IF ELSE WHILE DO FOR RETURN EXTERN EXPORT
- %token INT BOOL FLOAT VOID
- %token EOF
- %token <bool> BOOL_CONST
- %token <float> FLOAT_CONST
- %token <int> INT_CONST
- %token <string> ID
- /* Precedence */
- %right ASSIGN
- %left OR
- %left AND
- %left EQ NE
- %left LT LE GT GE
- %left ADD SUB
- %left MUL DIV MOD
- %right NOT NEG CAST
- %nonassoc IF
- %nonassoc ELSE
- /* Start symbol */
- %type <Ast.node> program
- %start program
- %%
- basic_type : FLOAT { Float }
- | INT { Int }
- | BOOL { Bool }
- program : decl*; EOF
- { Program $1 }
- decl : EXTERN; fun_header; SEMICOL
- { let (t, n, p) = $2 in FunDec(t, n, p) }
- | boption(EXPORT); fun_header; LBRACE; fun_body; RBRACE
- { let (t, n, p) = $2 in FunDef ($1, t, n, p, $4) }
- | EXTERN; basic_type; ID; SEMICOL
- { GlobalDec ($2, $3) }
- | EXTERN; t=basic_type; LBRACK; d=separated_list(COMMA, ID); RBRACK; n=ID; SEMICOL
- { GlobalDec (ArrayDec (t, d), n) }
- | boption(EXPORT); basic_type; ID; SEMICOL
- { GlobalDef ($1, $2, $3, None) }
- | boption(EXPORT); basic_type; ID; ASSIGN; expr; SEMICOL
- { GlobalDef ($1, $2, $3, Some $5) }
- | e=boption(EXPORT); t=basic_type; LBRACK; d=separated_list(COMMA, expr); RBRACK; n=ID; SEMICOL
- { GlobalDef (e, ArrayDef (t, d), n, None) }
- | e=boption(EXPORT); t=basic_type; LBRACK; d=separated_list(COMMA, expr); RBRACK; n=ID; ASSIGN; v=expr; SEMICOL
- { GlobalDef (e, ArrayDef (t, d), n, Some v) }
- fun_header : ret=basic_type; name=ID; LPAREN; params=separated_list(COMMA, param); RPAREN
- { (ret, name, params) }
- | VOID; name=ID; LPAREN; params=separated_list(COMMA, param); RPAREN
- { (Void, name, params) }
- param : basic_type; ID { Param ($1, $2) }
- fun_body : var_dec* local_fun_dec* statement* loption(return_statement)
- { $1 @ $2 @ $3 }
- local_fun_dec : fun_header; LBRACE; fun_body; RBRACE
- { let (t, n, p) = $1 in FunDef (false, t, n, p, $3) }
- var_dec : basic_type; ID; SEMICOL
- { VarDec ($1, $2, None) }
- | basic_type; ID; ASSIGN; expr; SEMICOL
- { VarDec ($1, $2, Some $4) }
- | t=basic_type; LBRACK; d=separated_list(COMMA, expr); RBRACK; n=ID; SEMICOL
- { VarDec (ArrayDef (t, d), n, None) }
- | t=basic_type; LBRACK; d=separated_list(COMMA, expr); RBRACK; n=ID; ASSIGN; v=expr; SEMICOL
- { VarDec (ArrayDef (t, d), n, Some v) }
- statement : ID; ASSIGN; expr; SEMICOL
- { Assign ($1, $3) }
- | name=ID; LPAREN; params=separated_list(COMMA, expr); RPAREN; SEMICOL
- { Expr (FunCall (name, params)) }
- | IF; LPAREN; expr; RPAREN; block
- { If ($3, $5) } %prec IF
- | IF; LPAREN; expr; RPAREN; block; ELSE; block
- { IfElse ($3, $5, $7) } %prec ELSE
- | WHILE; LPAREN; expr; RPAREN; block
- { While ($3, $5) }
- | DO; block; WHILE; LPAREN; expr; RPAREN; SEMICOL
- { DoWhile ($5, $2) }
- | FOR; LPAREN; INT; id=ID; ASSIGN; start=expr; COMMA; stop=expr; RPAREN; body=block
- { For (id, start, stop, IntConst 1, body) }
- | FOR; LPAREN; INT; id=ID; ASSIGN; start=expr; COMMA; stop=expr; COMMA; step=expr; RPAREN; body=block
- { For (id, start, stop, step, body) }
- return_statement : RETURN; expr; SEMICOL { [Return ($2)] }
- block : LBRACE; statement*; RBRACE { $2 }
- | statement { [$1] }
- expr : LPAREN; expr; RPAREN { $2 }
- | name=ID; LPAREN; params=separated_list(COMMA, expr); RPAREN
- { FunCall (name, params) }
- | ID { Var $1 }
- | l=expr; op=binop; r=expr { Binop (op, l, r) }
- | SUB; expr { Monop (Neg, $2) } %prec NEG
- | NOT; expr { Monop (Not, $2) }
- | LPAREN; basic_type; RPAREN; expr { TypeCast ($2, $4) } %prec CAST
- | FLOAT_CONST { FloatConst $1 }
- | INT_CONST { IntConst $1 }
- | BOOL_CONST { BoolConst $1 }
- | ID; array_const { Deref ($1, $2) }
- | array_const { ArrayConst $1 }
- array_const : LBRACK; values=separated_list(COMMA, expr); RBRACK { values }
- %inline binop : ADD { Add }
- | SUB { Sub }
- | MUL { Mul }
- | DIV { Div }
- | MOD { Mod }
- | EQ { Eq }
- | NE { Ne }
- | LT { Lt }
- | LE { Le }
- | GT { Gt }
- | GE { Ge }
- | AND { And }
- | OR { Or }
- %%
|