-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparser.mly
150 lines (119 loc) · 3.6 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
%{ open Ast %}
%token COMMA SEMI LPAREN RPAREN LBRACKET RBRACKET LBRACE RBRACE EOF
%token CONS CAT HEAD TAIL ISEMPTY
%token PLUS MINUS MULT DIV MOD ASSIGN EQUAL LESS GREATER LEQ GEQ NEQ ARROW
%token IN LET IF THEN ELSE WHERE FOR BY OVER ONION STRICT FUN
%token NONE WILDCARD
%token AND OR NOT UMINUS
%token TYPE COLON INTTYPE FLOATTYPE STRTYPE BOOLTYPE LISTTYPE
%token <int> INTLIT
%token <bool> BOOLLIT
%token <float> FLOATLIT
%token <string> ID STRINGLIT
// %left SEMI
%left IN
%left FOR IF
%right ARROW
%left OR AND
%left EQUAL GREATER LESS LEQ GEQ NEQ
%left ELSE
%right ASSIGN
%left PLUS MINUS
%left MULT DIV MOD
%nonassoc UMINUS NOT
%left CONS CAT
%nonassoc TAIL HEAD ISEMPTY
%start program
%type <Ast.program> program
// %%
%%
program:
expr EOF { Expr $1 }
expr:
// Conditional
IF expr THEN expr ELSE expr { CondExp($2, $4, $6) }
// Let Expression
| LET ID ASSIGN expr IN expr { Assign($2, $4, $6) }
| LET ONION ID ASSIGN expr IN expr { AssignRec($3, $5, $7) }
// Function Definition
| FUN LPAREN formals_opt RPAREN ARROW expr { FunExp($3, $6) }
// Syntactic Sugar Function Def
| LET ID LPAREN formals_opt RPAREN ASSIGN expr IN expr { Assign($2, FunExp($4, $7), $9)}
| LET ONION ID LPAREN formals_opt RPAREN ASSIGN expr IN expr { AssignRec($3, FunExp($5, $8), $10) }
// Function Application
| ID LPAREN args_opt RPAREN { FunApp(Var($1), $3) }
| LPAREN expr RPAREN LPAREN args_opt RPAREN { FunApp($2, $5) }
// Variable
| ID { Var $1 }
// Arithmetic Operations
| expr PLUS expr { InfixOp($1, Add, $3) }
| expr MINUS expr { InfixOp($1, Sub, $3) }
| expr MULT expr { InfixOp($1, Mul, $3) }
| expr DIV expr { InfixOp($1, Div, $3) }
| expr MOD expr { InfixOp($1, Mod, $3) }
// Boolean Operations
| expr EQUAL expr { InfixOp($1, Eq, $3) }
| expr GREATER expr { InfixOp($1, Greater, $3) }
| expr GEQ expr { InfixOp($1, Geq, $3) }
| expr LESS expr { InfixOp($1, Less, $3) }
| expr LEQ expr { InfixOp($1, Leq, $3) }
| expr NEQ expr { InfixOp($1, Neq, $3) }
| expr AND expr { InfixOp($1, And, $3) }
| expr OR expr { InfixOp($1, Or, $3) }
// Unary Operations
| NOT expr { UnaryOp(Not, $2) }
| MINUS expr %prec UMINUS { UnaryOp(UMinus, $2) }
// List Operations
| expr CONS expr { InfixOp($1, Cons, $3) }
| expr CAT expr { InfixOp($1, Cat, $3) }
| HEAD expr { UnaryOp(Head, $2) }
| TAIL expr { UnaryOp(Tail, $2) }
| ISEMPTY expr { UnaryOp(IsEmpty, $2) }
// Literals
| INTLIT { IntLit $1 }
| BOOLLIT { BoolLit $1 }
| FLOATLIT { FloatLit $1 }
| STRINGLIT { StringLit $1 }
// Parenthesized Expressions
| LPAREN expr RPAREN { ParenExp($2) }
// Lists
| LBRACKET typ RBRACKET { EmptyList($2) }
| LBRACKET iter RBRACKET { ListExp($2) }
| LBRACKET comp RBRACKET { $2 }
iter:
expr { [$1] }
| expr SEMI iter { $1 :: $3 }
| { [] }
comp:
expr FOR ID IN expr qual { ListComp($1, CompFor($3, $5) :: $6) }
qual:
FOR ID IN expr qual { CompFor($2, $4) :: $5 }
| IF expr qual { CompIf($2) :: $3 }
| { [] }
formals_opt:
/*nothing*/ { [] }
| formals_list { $1 }
formals_list:
| formal { [$1] }
| formal COMMA formals_list { $1::$3 }
formal:
ID COLON typ { Formal($1, $3) }
typ:
INTTYPE { Int }
| FLOATTYPE { Float }
| STRTYPE { String }
| BOOLTYPE { Bool }
| LISTTYPE LESS typ GREATER { List($3) }
| LPAREN typ_opt ARROW typ RPAREN { Function($2, $4) }
typ_opt:
/*nothing*/ { [] }
| typ_list { $1 }
typ_list:
| typ { [$1] }
| typ COMMA typ_list { $1::$3 }
args_opt:
/*nothing*/ { [] }
| args_list { $1 }
args_list:
| expr { [$1] }
| expr COMMA args_list { $1::$3 }