-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.mly
165 lines (138 loc) · 6.16 KB
/
parser.mly
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* Ocamlyacc parser for DIC */
%{
open Ast
%}
%token SEMI LPAREN RPAREN LBRACE RBRACE LANGLE RANGLE COMMA LBRACK RBRACK COLON QUOTE
%token PLUS MINUS TIMES TIMES_M DIVIDE DIVIDE_M ASSIGN MOD TRANSPOSE INVERSE DOT
%token INC DEC
%token NOT EQ PEQ NEQ LT LEQ GT GEQ TRUE FALSE AND OR NULL FUNC
%token RETURN IF ELSE FOR WHILE
%token INT BOOL FLOAT VOID LIST DICT STRING CHAR INTM FLOATM CHARM BOOLM STRINGM FPOINT
%token <int> LITERAL
%token <bool> BLIT
%token <string> ID FLIT SLIT CHLIT
%token CLASS EOF
%nonassoc NOELSE
%nonassoc ELSE
%right ASSIGN
%left OR
%left AND
%left EQ NEQ PEQ
%left LT GT LEQ GEQ
%left PLUS MINUS
%left TIMES DIVIDE MOD DOT TIMES_M DIVIDE_M
%left INC DEC
%right NOT NEG TRANSPOSE INVERSE
%start program
%type <Ast.program> program
%%
program:
| CLASS ID LBRACE decls RBRACE EOF { ($2, $4) }
decls:
/* nothing */ { ([], []) }
| decls stmt { ([], []) }
| decls vdecl { (($2 :: fst $1), snd $1) }
| decls fdecl { (fst $1, List.rev ($2 :: snd $1)) }
fdecl:
FUNC typ ID LPAREN formals_opt RPAREN LBRACE stmt_list RBRACE
{{ typ = $2;
fname = $3;
formals = $5;
body = List.rev $8 }}
formals_opt:
/* nothing */ { [] }
| formal_list { List.rev $1 }
formal_list:
typ ID { [($1, $2)] }
| formal_list COMMA typ ID { ($3, $4) :: $1 }
typ:
INT { Int }
| INTM { IntM }
| BOOL { Bool }
| BOOLM { BoolM }
| FLOAT { Float }
| FLOATM { FloatM }
| VOID { Void }
| STRING { String }
| STRINGM{ StringM}
| CHAR { Char }
| CHARM { CharM }
| FPOINT { FPoint }
vdecl:
typ ID SEMI { ($1, $2, Noexpr) }
| typ ID ASSIGN expr SEMI { ($1, $2, $4) }
stmt_list:
/* nothing */ { [] }
| stmt_list stmt { $2 :: $1 }
| stmt_list vdecl { Vdecl($2) :: $1}
for_first_arg:
| vdecl { Vdecl $1 }
| expr SEMI { Expr $1 }
/* | expr_opt SEMI { Expr $1 } */
stmt:
| expr SEMI { Expr $1 }
| RETURN expr_opt SEMI { Return $2 }
| LBRACE stmt_list 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 for_first_arg expr SEMI expr_opt RPAREN stmt
{ For($3, $4, $6, $8) }
| WHILE LPAREN expr RPAREN stmt { While($3, $5) }
expr_opt:
/* nothing */ { Noexpr }
| expr { $1 }
expr:
LITERAL { Literal($1) }
| CHLIT { Cliteral($1) }
| FLIT { Fliteral($1) }
| TRUE { BoolLit(true) }
| FALSE { BoolLit(false) }
| SLIT { StringLit($1) }
| ID { Id($1) }
| LBRACK args_opt RBRACK { ListLit($2) }
| ID LBRACK expr RBRACK ASSIGN expr { ListIndexAssign ($1, $3, $6) }
| ID LBRACK expr RBRACK { ListIndex ($1, $3) }
| LBRACK rows RBRACK { MatLit($2) }
| ID mat_indices ASSIGN expr { MatIndexAssign ($1, $2, $4) }
| ID mat_indices { MatIndex ($1, $2) }
| LANGLE ID RANGLE LPAREN args_opt RPAREN
{ FpointLit($2, $5) }
| expr PLUS expr { Binop($1, Add, $3) }
| expr MINUS expr { Binop($1, Sub, $3) }
| expr TIMES expr { Binop($1, Mult, $3) }
| expr TIMES_M expr { Binop($1, Mult_M, $3) }
| expr DOT expr { Binop($1, Dot, $3) }
| expr DIVIDE expr { Binop($1, Div, $3) }
| expr DIVIDE_M expr { Binop($1, Div_M, $3) }
| expr MOD expr { Binop($1, Mod, $3) }
| expr EQ expr { Binop($1, Eq, $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 NEG { Unop(Neg, $2) }
/* | INC expr { Unop(Increment, $2) } */
/* | DEC expr { Unop(Decrement, $2) } */
| ID INC { Punop($1, Increment) }
| ID DEC { Punop( $1, Decrement) }
| NOT expr { Unop(Not, $2) }
| TRANSPOSE expr { Unop(Trans_M, $2) }
/* | INVERSE expr { Unop(Inv_M, $2) } */
| ID ASSIGN expr { Assign($1, $3) }
| ID LPAREN args_opt RPAREN { Call($1, $3) }
| LPAREN expr RPAREN { $2 }
mat_indices:
| LBRACK expr RBRACK LBRACK expr RBRACK { $5 :: [$2] }
| mat_indices LBRACK expr RBRACK { $3 :: $1 }
args_opt:
{ [Noexpr] }
| args_list { List.rev $1 }
args_list:
expr { [$1] }
| args_list COMMA expr { $3 :: $1 }
rows:
args_opt COLON args_opt { $3 :: [$1] }
| rows COLON args_opt { $3 :: $1 }