-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.mly
More file actions
151 lines (125 loc) · 4.36 KB
/
parser.mly
File metadata and controls
151 lines (125 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* Ocamlyacc parser for MicroC */
%{ open Ast %}
%token SEMI LPAREN RPAREN LBRACE RBRACE COMMA PLUS MINUS TIMES DIVIDE ASSIGN COLON
%token NOT EQ NEQ LT LEQ GT GEQ AND OR DOT
%token RETURN IF ELSE FOR WHILE INT BOOL FLOAT VOID
%token LSQURE RSQURE
%token LAMBDA
%token ARROW STRUCT /* Not sure about precedence or associativity*/
%token <int> LITERAL
%token <bool> BLIT
%token <string> ID FLIT TYPVAR
%token EOF
%start program
%type <Ast.program> program
%nonassoc NOELSE
%nonassoc ELSE
%right ASSIGN
%left DOT
%left OR
%left AND
%left EQ NEQ
%left LT GT LEQ GEQ
%left PLUS MINUS
%left TIMES DIVIDE
%left ARROW /* Menhir says the precedence is never used */
%right NOT
%nonassoc LPAREN
%%
program:
sdecl_opt vdecl_opt stmt_opt EOF {$1, $2, $3}
formals_opt:
/* nothing */ { [] }
| formal_list { $1 }
formal_list:
typ ID { [($1,$2)] }
| formal_list COMMA typ ID { ($3,$4) :: $1 }
typaram_list_opt:
/* nothing */ { [] }
| LT typaram_list GT { $2 }
typaram_list:
TYPVAR { [$1] }
| typaram_list COMMA TYPVAR { $3 :: $1 }
typ_list:
/* nothing */ { [] }
| typ { [$1] }
| typ_list COMMA typ { $3 :: $1 }
typ:
INT { Int }
| BOOL { Bool }
| FLOAT { Float }
| VOID { Void }
| typaram_list_opt LSQURE typ_list RSQURE ARROW typ
{ Arrow($1, List.rev $3, $6) }
| TYPVAR { TypVar $1 }
| TYPVAR LT typ_list GT { PolyTyp($1, $3)}
vdecl_opt:
/* nothing */ { [] }
| vdecl_list { List.rev $1 }
vdecl_list:
| vdecl_list vdecl { $2 :: $1 }
| vdecl { [$1] }
vdecl:
typ ID SEMI { ($1, $2) }
sdecl_opt:
/* nothing */ { [] }
| sdecl_list { List.rev $1 }
sdecl_list:
| sdecl_list sdecl { $2 :: $1 }
| sdecl { [$1] }
sdecl:
STRUCT typaram_list_opt TYPVAR LBRACE vdecl_list RBRACE SEMI { ($2, $3, $5) }
stmt_opt:
/* nothing */ { [] }
| stmt_list { List.rev $1 }
stmt_list:
| stmt { [$1] }
| stmt_list stmt { $2 :: $1 }
stmt:
expr SEMI { Expr $1 }
| RETURN expr_opt SEMI { Return $2 }
| LBRACE stmt_opt RBRACE { Block(List.rev $2) }
| IF LPAREN expr RPAREN stmt %prec NOELSE { If($3, $5, Block([])) }
| IF LPAREN expr RPAREN stmt ELSE stmt { If($3, $5, $7) }
| FOR LPAREN expr_opt SEMI expr SEMI expr_opt RPAREN stmt
{ For($3, $5, $7, $9) }
| WHILE LPAREN expr RPAREN stmt { While($3, $5) }
expr_opt:
/* nothing */ { Noexpr }
| expr { $1 }
expr:
LITERAL { Literal($1) }
| FLIT { Fliteral($1) }
| BLIT { BoolLit($1) }
| ID { Id($1) }
| expr PLUS expr { Binop($1, Add, $3) }
| expr MINUS expr { Binop($1, Sub, $3) }
| expr TIMES expr { Binop($1, Mult, $3) }
| expr DIVIDE expr { Binop($1, Div, $3) }
| expr EQ expr { Binop($1, Equal, $3) }
| expr NEQ expr { Binop($1, Neq, $3) }
| expr LT expr { Binop($1, Less, $3) }
| expr LEQ expr { Binop($1, Leq, $3) }
| expr GT expr { Binop($1, Greater, $3) }
| expr GEQ expr { Binop($1, Geq, $3) }
| expr AND expr { Binop($1, And, $3) }
| expr OR expr { Binop($1, Or, $3) }
| MINUS expr %prec NOT { Unop(Neg, $2) }
| NOT expr { Unop(Not, $2) }
| expr ASSIGN expr { Assign($1, $3) }
| LBRACE assign_list RBRACE {AssignList(List.rev $2)}
| expr DOT ID { RecordAccess($1, $3) }
| expr LPAREN args_opt RPAREN
{ Call($1, $3) }
| LPAREN expr RPAREN { $2 }
| LAMBDA typaram_list_opt LPAREN formals_opt RPAREN ARROW typ LBRACE vdecl_opt stmt_opt RBRACE
{ Lambda($2, $7, $4, $9, $10) }
assign_list:
ID COLON expr { [($1, $3)] }
| assign_list COMMA ID COLON expr { ($3, $5)::$1 }
args_opt:
/* nothing */ { [] }
| args_list { List.rev $1 }
args_list:
expr { [$1] }
| args_list COMMA expr { $3 :: $1 }