Advertisement
Guest User

Untitled

a guest
Dec 19th, 2018
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 5.58 KB | None | 0 0
  1. /* Ocamlyacc Parser for AP++ compiler */
  2.  
  3. %{
  4. open Ast
  5. %}
  6.  
  7. %token COLON COMMA SEMICOLON LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK
  8. %token PLUS MINUS TIMES DIVIDE ASSIGN MOD
  9. %token PLUSPLUS MINUSMINUS
  10. %token NOT AND OR
  11. %token EQ NEQ LT LEQ GT GEQ
  12. %token RETURN IF ELSE WHILE FOR INT BOOL FLOAT STRING VOID
  13. %token LIST_PUSH LIST_GET LIST_SET LIST_POP LIST_SIZE HASH LIST_SLICE LIST_CLEAR LIST_REVERSE LIST_INSERT LIST_REMOVE LIST_FIND
  14. %token <int> ILITERAL
  15. %token <bool> BLITERAL
  16. %token <string> SLITERAL
  17. %token <float> FLITERAL
  18. %token <string> ID
  19. %token LIST
  20. %token EOF
  21.  
  22. %start program
  23. %type <Ast.program> program
  24.  
  25. %nonassoc NOELSE
  26. %nonassoc ELSEIF
  27. %nonassoc ELSE
  28. %right ASSIGN
  29. %left OR
  30. %left AND
  31. %left EQ NEQ
  32. %left LT GT LEQ GEQ
  33. %left PLUS MINUS
  34. %left TIMES DIVIDE MOD
  35. %right NOT PLUSPLUS MINUSMINUS
  36.  
  37. %%
  38.  
  39. program:
  40.   decls EOF { $1 }
  41.  
  42. decls:
  43.   /* nothing */   { ([], [])}
  44. | decls var_decl  { (($2 :: fst $1), snd $1) }
  45. | decls func_decl { (fst $1, ($2 :: snd $1)) }
  46.  
  47. /* e.g. int foo(int x, int y) {} */
  48. func_decl:
  49.   typ ID LPAREN func_formals_opt RPAREN LBRACE var_decl_list stmt_list RBRACE
  50.   { { typ     = $1;
  51.       fname   = $2;
  52.       formals = List.rev $4;
  53.       locals  = List.rev $7;
  54.       body    = List.rev $8 } }
  55.  
  56. func_formals_opt:
  57.    /* nothing */    { [] }
  58. |  func_formals_list { $1 }
  59.  
  60. /* int x, bool y */
  61. func_formals_list:
  62.   typ ID                         { [($1, $2)] }
  63. | func_formals_list COMMA typ ID { ($3, $4) :: $1 }
  64.  
  65. typ:
  66.   INT             { Int }
  67. | BOOL            { Bool }
  68. | FLOAT           { Float }
  69. | STRING          { String }
  70. | VOID            { Void }
  71. | LIST LT typ GT  { List($3) }
  72.  
  73. /* e.g. int x; int y; */
  74. var_decl_list:
  75.   /* nothing */ { [] }
  76. |  var_decl_list var_decl { $2 :: $1 }
  77.  
  78. /* e.g. int x; */
  79. var_decl:
  80.   typ ID SEMICOLON { ($1, $2) }
  81.  
  82. stmt_list:
  83.   /* nothing */  { [] }
  84. | stmt_list stmt { $2 :: $1 }
  85.  
  86. /* executes code logic but do not evaluate to any value */
  87. stmt:
  88.   expr SEMICOLON                            { Expr $1 }
  89. | RETURN expr_opt SEMICOLON                 { Return $2 }
  90. | LBRACE stmt_list RBRACE                   { Block(List.rev $2) }
  91. | IF LPAREN expr RPAREN stmt %prec NOELSE   { If($3, $5, Block([])) }
  92. | IF LPAREN expr RPAREN stmt ELSE stmt      { If($3, $5, $7) }
  93. | FOR LPAREN expr_opt SEMICOLON expr SEMICOLON expr_opt RPAREN stmt
  94.                                             { For($3, $5, $7, $9) }
  95. | WHILE LPAREN expr RPAREN stmt             { While($3, $5) }
  96. | LIST_PUSH LPAREN ID COMMA expr RPAREN SEMICOLON { ListPush($3, $5) }
  97. | LIST_SET LPAREN ID COMMA expr COMMA expr RPAREN SEMICOLON { ListSet($3, $5, $7) }
  98. | ID LBRACK expr RBRACK ASSIGN expr SEMICOLON         { ListSet($1, $3, $6) }
  99. | LIST_CLEAR LPAREN ID RPAREN SEMICOLON     { ListClear($3) }
  100. | LIST_REMOVE LPAREN ID COMMA expr RPAREN SEMICOLON { ListRemove($3, $5) }  
  101. | LIST_INSERT LPAREN ID COMMA expr COMMA expr RPAREN SEMICOLON { ListInsert($3, $5, $7) }
  102. | LIST_REVERSE LPAREN ID RPAREN SEMICOLON       { ListReverse($3) }
  103.  
  104. expr_opt:
  105.   /* nothing */ { Noexpr }
  106. | expr          { $1 }
  107.  
  108. /* executes code logic and evaluates to a value */
  109. expr:
  110.   ILITERAL                                { ILiteral($1) }
  111. | BLITERAL                                { BLiteral($1) }
  112. | SLITERAL                                { SLiteral($1) }
  113. | FLITERAL                                { FLiteral($1) }
  114. | ID                                      { Id($1) }
  115. | expr PLUS   expr                        { Binop($1, Add, $3) }
  116. | expr MINUS  expr                        { Binop($1, Sub, $3) }
  117. | expr TIMES  expr                        { Binop($1, Mult, $3) }
  118. | expr DIVIDE expr                        { Binop($1, Div, $3) }
  119. | expr MOD expr                           { Binop($1, Mod, $3) }
  120. | PLUSPLUS ID                             { Unop(PlusPlusPre, Id($2)) }
  121. | MINUSMINUS ID                           { Unop(MinusMinusPre, Id($2)) }
  122. | ID PLUSPLUS                             { Unop(PlusPlusPost, Id($1)) }
  123. | ID MINUSMINUS                           { Unop(MinusMinusPost, Id($1)) }
  124. | expr EQ expr                            { Binop($1, Equal, $3) }
  125. | expr NEQ expr                           { Binop($1, Neq, $3) }
  126. | expr LT expr                            { Binop($1, Less, $3) }
  127. | expr GT expr                            { Binop($1, Greater, $3) }
  128. | expr LEQ expr                           { Binop($1, Leq, $3) }
  129. | expr GEQ expr                           { Binop($1, Geq, $3) }
  130. | MINUS expr %prec NOT                    { Unop(Neg, $2)      }
  131. | NOT expr                                { Unop(Not, $2) }
  132. | expr AND expr                           { Binop($1, And, $3) }
  133. | expr OR expr                            { Binop($1, Or, $3) }
  134. | LPAREN expr RPAREN                      { $2 }
  135. | ID ASSIGN expr                          { Assign($1, $3) }
  136. | ID LPAREN args_opt RPAREN                 { Call($1, $3) }
  137. | LIST_GET LPAREN ID COMMA expr RPAREN    { ListGet($3, $5) }
  138. | ID LBRACK expr RBRACK                   { ListGet($1, $3) }
  139. | LIST_POP LPAREN ID RPAREN               { ListPop($3) }
  140. | LIST_SIZE LPAREN ID RPAREN              { ListSize($3) }
  141. | HASH ID                                 { ListSize($2) }
  142. | LIST_SLICE LPAREN ID COMMA expr COMMA expr RPAREN { ListSlice($3, $5, $7) }
  143. | ID LBRACK expr_opt COLON expr_opt RBRACK        { ListSlice($1, $3, $5) }
  144. | LIST_FIND LPAREN ID COMMA expr RPAREN   { ListFind($3, $5) }
  145. | LBRACK args_opt RBRACK                  { ListLiteral($2) }
  146.  
  147. args_opt:
  148.     /* nothing */ { [] }
  149.   | args_list  { List.rev $1 }
  150.  
  151. /* args used for function calls */
  152. args_list:
  153.     expr                    { [$1] }
  154.   | args_list COMMA expr { $3 :: $1 }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement