A MiniC++ (C++ subset) compiler for a course.

parser.mly 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* Analyseur syntaxique pour MiniC++ */
  2. %{
  3. open Ast
  4. open Lexhack
  5. %}
  6. %token <int> INT
  7. %token <string> STRING
  8. %token <string> IDENT
  9. %token <string> TIDENT
  10. %token EOF
  11. %token INCLUDE
  12. %token COUT
  13. %token ENDL
  14. %token IN /* << */
  15. %token COLON COMMA SEMICOLON LBRACE RBRACE
  16. %token ASSIGN
  17. %token OR
  18. %token AND
  19. %token EQ NEQ
  20. %token LT LEQ GT GEQ
  21. %token PLUS MINUS
  22. %token TIMES DIV MOD
  23. %token NOT INCR DECR ECOMM
  24. %token ARROW DOT
  25. %token LPAREN RPAREN
  26. %token UPLUS UMINUS UTIMES
  27. %token CLASS ELSE FALSE FOR IF TINT NEW NULL PUBLIC RETURN THIS TRUE VIRTUAL VOID WHILE
  28. /* Priorités et associativités des tokens */
  29. %right ASSIGN
  30. %left OR
  31. %left AND
  32. %left EQ NEQ
  33. %left LT LEQ GT GEQ
  34. %left PLUS MINUS
  35. %left TIMES DIV MOD
  36. %right NOT INCR DECR ECOMM
  37. %right UPLUS UMINUS UTIMES
  38. %left ARROW DOT
  39. (* Conflicts solving *)
  40. %nonassoc IF
  41. %nonassoc ELSE
  42. %left LPAREN
  43. (* ==== *)
  44. /* Point d'entrée de la grammaire */
  45. %start fichier
  46. /* Type des valeurs retournées par l'analyseur syntaxique */
  47. %type <Ast.program> fichier
  48. %%
  49. fichier:
  50. x=boption(INCLUDE) main=decl* EOF
  51. {
  52. {
  53. includes = x;
  54. program = main;
  55. program_loc = $startpos, $endpos;
  56. }
  57. }
  58. decl:
  59. x=decl_vars { DVar x }
  60. | x=decl_class { Class x }
  61. | x=proto y=bloc { Fonction { fonction_content = (x, y); fonction_loc = $startpos, $endpos } }
  62. decl_vars:
  63. x=type_rule y=separated_nonempty_list(COMMA, var) SEMICOLON
  64. { { decl_vars_content = (x, y); decl_vars_loc = $startpos,$endpos } }
  65. lexhack_class:
  66. CLASS x=IDENT y=supers?
  67. {
  68. Lexhack.types_lexhack := x :: !(Lexhack.types_lexhack);
  69. (x,y)
  70. }
  71. decl_class:
  72. x=lexhack_class LBRACE PUBLIC COLON z=member* RBRACE SEMICOLON
  73. {
  74. { decl_class_content = (fst x, snd x, z); decl_class_loc = $startpos,$endpos }
  75. }
  76. supers:
  77. COLON x=separated_nonempty_list(COMMA, preceded(PUBLIC, TIDENT))
  78. { x }
  79. member:
  80. x = decl_vars { MVar x }
  81. | VIRTUAL y=proto SEMICOLON
  82. {
  83. Proto (true, y)
  84. }
  85. | y=proto SEMICOLON
  86. {
  87. Proto (false, y)
  88. }
  89. proto:
  90. x=type_rule y=qvar z=paren(separated_list(COMMA, argument))
  91. {
  92. {
  93. ident = Qvar (x, y);
  94. args = z;
  95. proto_loc = $startpos, $endpos;
  96. }
  97. }
  98. | x=TIDENT y=paren(separated_list(COMMA, argument))
  99. {
  100. {
  101. ident = Type x;
  102. args = y;
  103. proto_loc = $startpos, $endpos;
  104. }
  105. }
  106. | x=TIDENT COLON COLON y=TIDENT z=paren(separated_list(COMMA, argument))
  107. {
  108. {
  109. ident = Herit (x, y);
  110. args = z;
  111. proto_loc = $startpos, $endpos;
  112. }
  113. }
  114. paren(X):
  115. LPAREN x=X RPAREN { x }
  116. type_rule:
  117. VOID { Void }
  118. | TINT { Int }
  119. | x=TIDENT { ASTTident x }
  120. argument:
  121. x=type_rule y=var
  122. { (x, y) }
  123. var:
  124. x=IDENT { VIdent x }
  125. | TIMES x=var { VUTimes x } %prec UTIMES
  126. | ECOMM x=var { VEComm x }
  127. qvar:
  128. x=qident { Qident x }
  129. | TIMES x=qvar { QUTimes x } %prec UTIMES
  130. | ECOMM x=qvar { QEComm x }
  131. qident:
  132. x=IDENT { Ident x }
  133. | x=TIDENT COLON COLON y=IDENT { Tident (x, y) }
  134. expr:
  135. x=INT { EInt x }
  136. | THIS { EThis }
  137. | FALSE { EInt 0 }
  138. | TRUE { EInt 1 }
  139. | NULL { ENull }
  140. | x=qident { EQident x }
  141. | TIMES x=expr { UOp (UTimes, x) } %prec UTIMES
  142. | x=expr y=paren(separated_list(COMMA, expr)) { Apply (x, y) }
  143. | x=expr DOT y=IDENT { Dot (x, y) }
  144. | x=expr ARROW y=IDENT { Dot (UOp(UTimes, x), y)}
  145. | x=expr ASSIGN y=expr { Assign (x, y) }
  146. | NEW t=TIDENT x=paren(separated_list(COMMA, expr))
  147. {
  148. Instance (t, x)
  149. }
  150. | INCR x=expr { Incr (IncrL, x) }
  151. | DECR x=expr { Incr (DecrL, x) }
  152. | x=expr INCR { Incr (IncrR, x) }
  153. | x=expr DECR { Incr (DecrR, x) }
  154. | ECOMM x=expr { UOp (EComm, x) }
  155. | NOT x=expr { UOp (Not, x) }
  156. | MINUS x=expr { UOp (UMinus, x) } %prec UMINUS
  157. | PLUS x=expr { UOp (UPlus, x) } %prec UPLUS
  158. | x=expr y=operateur z=expr { Op (y, x, z) }
  159. | x=paren(expr) { x }
  160. %inline operateur:
  161. EQ { Eq }
  162. | NEQ { Neq }
  163. | LT { Lt }
  164. | LEQ { Leq }
  165. | GT { Gt }
  166. | GEQ { Geq }
  167. | PLUS { Plus }
  168. | MINUS { Minus }
  169. | TIMES { Times }
  170. | DIV { Div }
  171. | MOD { Mod }
  172. | AND { And }
  173. | OR { Or }
  174. instruction:
  175. SEMICOLON { {instruction_content = Nop; instruction_loc = $startpos, $endpos} }
  176. | x=expr SEMICOLON { {instruction_content = IExpr x ; instruction_loc = $startpos, $endpos} }
  177. | x=type_rule y=var SEMICOLON { {instruction_content = IVar (x, y, NoAssign) ; instruction_loc = $startpos, $endpos} }
  178. | x=type_rule y=var z=preceded(ASSIGN, expr) SEMICOLON { {instruction_content = IVar (x, y, SAExpr z) ; instruction_loc = $startpos, $endpos} }
  179. | x=type_rule y=var z=preceded(ASSIGN, TIDENT) t=paren(separated_nonempty_list(COMMA, expr)) SEMICOLON
  180. { let tid = SATident (z, t) in {instruction_content = IVar (x, y, tid) ; instruction_loc = $startpos, $endpos} }
  181. | IF x=paren(expr) y=instruction ELSE z=instruction { {instruction_content = IfElse (x, y, z) ; instruction_loc = $startpos, $endpos} }
  182. | IF x=paren(expr) y=instruction { {instruction_content = If (x, y) ; instruction_loc = $startpos, $endpos} }
  183. | WHILE x=paren(expr) y=instruction { {instruction_content = While (x, y) ; instruction_loc = $startpos, $endpos} }
  184. | FOR LPAREN x=separated_list(COMMA, expr) SEMICOLON y=expr? SEMICOLON z=separated_list(COMMA, expr) RPAREN t=instruction { {instruction_content = For (x, y, z, t) ; instruction_loc = $startpos, $endpos} }
  185. | x=bloc { {instruction_content = IBloc x ; instruction_loc = $startpos, $endpos} }
  186. | COUT x=nonempty_list(preceded(IN, expr_str)) SEMICOLON
  187. { {instruction_content = Cout x ; instruction_loc = $startpos, $endpos} }
  188. | RETURN x=expr? SEMICOLON { {instruction_content = Return x ; instruction_loc = $startpos, $endpos} }
  189. expr_str:
  190. x=expr { Expr x }
  191. | x=STRING { String x }
  192. | ENDL { String "\n" }
  193. bloc:
  194. LBRACE x=instruction* RBRACE { { bloc_content = Bloc_content x; bloc_loc = $startpos, $endpos} }