parser.cpp.mly 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #define LOC (let pstart = $startpos in \
  2. let pend = $endpos in ( \
  3. pstart.pos_fname, \
  4. pstart.pos_lnum, \
  5. pend.pos_lnum, \
  6. (pstart.pos_cnum - pstart.pos_bol + 1), \
  7. (pend.pos_cnum - pend.pos_bol) \
  8. ))
  9. %{
  10. open Lexing
  11. open Ast
  12. %}
  13. /* Tokens */
  14. %token LPAREN RPAREN LBRACK RBRACK LBRACE RBRACE SEMICOL COMMA
  15. %token NOT ADD SUB MUL DIV MOD
  16. %token EQ NE LT LE GT GE
  17. %token AND OR
  18. %token ASSIGN IF ELSE WHILE DO FOR RETURN EXTERN EXPORT
  19. %token INT BOOL FLOAT VOID
  20. %token EOF
  21. %token <bool> BOOL_CONST
  22. %token <float> FLOAT_CONST
  23. %token <int> INT_CONST
  24. %token <string> ID
  25. /* Precedence */
  26. %right ASSIGN
  27. %left OR
  28. %left AND
  29. %left EQ NE
  30. %left LT LE GT GE
  31. %left ADD SUB
  32. %left MUL DIV MOD
  33. %right NOT NEG CAST
  34. %nonassoc IF
  35. %nonassoc ELSE
  36. /* Start symbol */
  37. %type <Ast.node> program
  38. %start program
  39. %%
  40. basic_type : FLOAT { Float }
  41. | INT { Int }
  42. | BOOL { Bool }
  43. program : decl*; EOF
  44. { Program ($1, LOC) }
  45. decl : EXTERN; fun_header; SEMICOL
  46. { let (t, n, p) = $2 in FunDec(t, n, p, LOC) }
  47. | boption(EXPORT); fun_header; LBRACE; fun_body; RBRACE
  48. { let (t, n, p) = $2 in FunDef ($1, t, n, p, Block $4, LOC) }
  49. | EXTERN; basic_type; ID; SEMICOL
  50. { GlobalDec ($2, $3, LOC) }
  51. | EXTERN; t=basic_type; LBRACK; d=separated_list(COMMA, ID); RBRACK; n=ID; SEMICOL
  52. { GlobalDec (ArrayDec (t, d), n, LOC) }
  53. | boption(EXPORT); basic_type; ID; SEMICOL
  54. { GlobalDef ($1, $2, $3, None, LOC) }
  55. | boption(EXPORT); basic_type; ID; ASSIGN; expr; SEMICOL
  56. { GlobalDef ($1, $2, $3, Some $5, LOC) }
  57. | e=boption(EXPORT); t=basic_type; LBRACK; d=separated_list(COMMA, expr);
  58. RBRACK; n=ID; SEMICOL
  59. { GlobalDef (e, ArrayDef (t, d), n, None, LOC) }
  60. | e=boption(EXPORT); t=basic_type; LBRACK; d=separated_list(COMMA, expr);
  61. RBRACK; n=ID; ASSIGN; v=expr; SEMICOL
  62. { GlobalDef (e, ArrayDef (t, d), n, Some v, LOC) }
  63. fun_header : ret=basic_type; name=ID; LPAREN; params=separated_list(COMMA, param); RPAREN
  64. { (ret, name, params) }
  65. | VOID; name=ID; LPAREN; params=separated_list(COMMA, param); RPAREN
  66. { (Void, name, params) }
  67. param : basic_type; ID { Param ($1, $2, LOC) }
  68. fun_body : var_dec* local_fun_dec* statement* loption(return_statement)
  69. { $1 @ $2 @ $3 @ $4 }
  70. local_fun_dec : fun_header; LBRACE; fun_body; RBRACE
  71. { let (t, n, p) = $1 in FunDef (false, t, n, p, Block $3, LOC) }
  72. var_dec : basic_type; ID; SEMICOL
  73. { VarDec ($1, $2, None, LOC) }
  74. | basic_type; ID; ASSIGN; expr; SEMICOL
  75. { VarDec ($1, $2, Some $4, LOC) }
  76. | t=basic_type; LBRACK; d=separated_list(COMMA, expr); RBRACK; n=ID; SEMICOL
  77. { VarDec (ArrayDef (t, d), n, None, LOC) }
  78. | t=basic_type; LBRACK; d=separated_list(COMMA, expr); RBRACK; n=ID; ASSIGN; v=expr; SEMICOL
  79. { VarDec (ArrayDef (t, d), n, Some v, LOC) }
  80. statement : ID; ASSIGN; expr; SEMICOL
  81. { Assign ($1, $3, LOC) }
  82. | name=ID; LPAREN; params=separated_list(COMMA, expr); RPAREN; SEMICOL
  83. { Expr (FunCall (name, params, LOC)) }
  84. | IF; LPAREN; expr; RPAREN; block
  85. { If ($3, Block $5, LOC) } %prec IF
  86. | IF; LPAREN; expr; RPAREN; block; ELSE; block
  87. { IfElse ($3, Block $5, Block $7, LOC) } %prec ELSE
  88. | WHILE; LPAREN; expr; RPAREN; block
  89. { While ($3, Block $5, LOC) }
  90. | DO; block; WHILE; LPAREN; expr; RPAREN; SEMICOL
  91. { DoWhile ($5, Block $2, LOC) }
  92. | FOR; LPAREN; INT; id=ID; ASSIGN; start=expr; COMMA; stop=expr; RPAREN; body=block
  93. { For (id, start, stop, IntConst (1, noloc), Block body, LOC) }
  94. | FOR; LPAREN; INT; id=ID; ASSIGN; start=expr; COMMA; stop=expr;
  95. COMMA; step=expr; RPAREN; body=block
  96. { For (id, start, stop, step, Block body, LOC) }
  97. return_statement : RETURN; expr; SEMICOL { [Return ($2, LOC)] }
  98. block : LBRACE; statement*; RBRACE { $2 }
  99. | statement { [$1] }
  100. expr : LPAREN; expr; RPAREN { $2 }
  101. | name=ID; LPAREN; params=separated_list(COMMA, expr); RPAREN
  102. { FunCall (name, params, LOC) }
  103. | ID { Var ($1, LOC) }
  104. | l=expr; op=binop; r=expr { Binop (op, l, r, LOC) }
  105. | SUB; expr { Monop (Neg, $2, LOC) } %prec NEG
  106. | NOT; expr { Monop (Not, $2, LOC) }
  107. | LPAREN; basic_type; RPAREN; expr { TypeCast ($2, $4, LOC) } %prec CAST
  108. | FLOAT_CONST { FloatConst ($1, LOC) }
  109. | INT_CONST { IntConst ($1, LOC) }
  110. | BOOL_CONST { BoolConst ($1, LOC) }
  111. | ID; array_const { Deref ($1, $2, LOC) }
  112. | array_const { ArrayConst ($1, LOC) }
  113. array_const : LBRACK; values=separated_list(COMMA, expr); RBRACK { values }
  114. %inline binop : ADD { Add }
  115. | SUB { Sub }
  116. | MUL { Mul }
  117. | DIV { Div }
  118. | MOD { Mod }
  119. | EQ { Eq }
  120. | NE { Ne }
  121. | LT { Lt }
  122. | LE { Le }
  123. | GT { Gt }
  124. | GE { Ge }
  125. | AND { And }
  126. | OR { Or }
  127. %%