-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.mly
82 lines (66 loc) · 1.88 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
%{
open Syntax
%}
%token EQUAL
%token COMMA COLON
%token PLUS MINUS ASTERISK SLASH
%token LANGLE RANGLE LANGLE_EQ RANGLE_EQ EQEQ NOTEQ
%token LPAREN RPAREN LBRACE RBRACE
%token EOF
%token DEF
%token IF ELSE
%token TRUE FALSE
%token <int> NUM
%token <string> ID
%start toplevel
%type <Syntax.exp> toplevel
%%
toplevel:
|Expr* EOF { MultiExpr($1) }
Expr:
|AssignExpr { $1 }
AssignExpr:
|DEF id=ID EQUAL exp=Arithmetic { Assign(id, None, exp) }
|DEF id=ID COLON t=Typ EQUAL exp=Arithmetic { Assign(id, Some(t), exp) }
|Arithmetic { $1 }
Arithmetic:
|Arithmetic PLUS Term { Call ("+", [$1; $3]) }
|Arithmetic MINUS Term { Call ("-", [$1; $3]) }
|Term { $1 }
Term:
|Term ASTERISK Factor { Call ("*", [$1; $3]) }
|Term SLASH Factor { Call ("/", [$1; $3]) }
|Compare { $1 }
Compare:
|Compare EQEQ Factor { Call ("==", [$1; $3]) }
|Compare NOTEQ Factor { Call ("!=", [$1; $3]) }
|Compare LANGLE Factor { Call ("<", [$1; $3]) }
|Compare RANGLE Factor { Call (">", [$1; $3]) }
|Compare LANGLE_EQ Factor { Call ("<=", [$1; $3]) }
|Compare RANGLE_EQ Factor { Call (">=", [$1; $3]) }
|Factor { $1 }
Factor:
|MINUS Factor { Call("__neg", [$2]) }
|Num { $1 }
|IfExpr { $1 }
|fname = ID LPAREN args = separated_list(COMMA, Expr) RPAREN { Call (fname, args) }
|LBRACE list(Expr) RBRACE { MultiExpr ( $2 ) }
|LPAREN Expr RPAREN { $2 }
|DefunExpr { $1 }
DefunExpr:
|DEF name = ID LPAREN args = separated_list(COMMA, Arg)
RPAREN EQUAL body = Expr { Defun(name, args, None, body) }
|DEF name = ID LPAREN args = separated_list(COMMA, Arg)
RPAREN COLON rett=Typ EQUAL body = Expr { Defun(name, args, Some(rett), body) }
Arg:
|name=ID { (name, None) }
|name=ID COLON t=Typ { (name, Some(t)) }
IfExpr:
|IF cond = Expr t = Expr ELSE e = Expr { If(cond, t, e) }
Num:
|ID { Var $1 }
|NUM { Int $1 }
|TRUE { Bool(true) }
|FALSE { Bool(false) }
Typ:
|ID { $1 }