-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetalang.grm
138 lines (112 loc) · 5.25 KB
/
metalang.grm
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
%name MetaLang;
%tokens : VarName of string
| Number of int
| Operator_QUERY of string
| Keyword_fun ("fun")
| Keyword_val ("val")
| Keyword_if ("if")
| Keyword_then ("then")
| Keyword_else ("else")
| Keyword_datatype ("datatype")
| Keyword_of ("of")
| Operator_LAMBDA ("\\") | Operator_ALT ("|") | Operator_EQ ("=") |
Operator_AND ("and") | Operator_OR ("or") | Operator_NOT ("not") |
Operator_GT (">") | Operator_LT ("<") | Operator_GE (">=") | Operator_LE ("<=") | Operator_NEQ ("/=") |
Operator_MULT ("*") | Operator_ADD ("+") | Operator_SUB ("-") | Operator_DIV ("/") | Operator_MOD ("%") |
Operator_COMMA (",") | Operator_GET ("::") |
Operator_LP ("(") | Operator_RP (")") |
SEMICOLON (";") |
Verbatim of string
;
%keywords "fun", "val", "if", "then", "else", "datatype", "of";
%defs (
structure AST = MetaLangAST;
fun apply_op expr sr =
List.foldl (fn ((f,x), y) => f(y,x)) expr sr
);
stmts : (statement)* ;
statement
: (datatype_binding | val_binding | function_definition | verbatim)
;
datatype_binding
: "datatype" VarName ("of" member_list) ? => (
case SR of
NONE => AST.DatatypeBinding (VarName, [])
| SOME ls => AST.DatatypeBinding (VarName, ls)
);
val_binding
: "val" VarName "=" expression => ( AST.ValBinding (VarName, expression) );
function_definition
: "fun" VarName "(" expression_list ")" "=" compound_expression
("|" "(" expression_list ")" "=" compound_expression
=> (AST.FunDef (expression_list, compound_expression)) )*
=> ( AST.FunBinding (VarName, AST.FunDef(expression_list, compound_expression) :: SR) ) ;
verbatim
: Verbatim => (AST.Verbatim Verbatim) ;
expression
: logical_expression
| "\\" "(" argument_list ")" "=" expression => ( AST.Lambda (argument_list, expression) )
| "if" expression "then" compound_expression "else" compound_expression => (
AST.IfThenElse (expression, compound_expression1, compound_expression2) ) ;
compound_expression
: ((statement)+ ";")? expression => (
case SR of
NONE => ( AST.CompoundExpr ([], expression) )
| SOME decl => ( AST.CompoundExpr (decl, expression) ) );
expression_list
: ( expression ("," expression)* => ( expression :: SR ) ) ? => (
case SR of
NONE => []
| SOME es => es
) ;
argument_list
: ( VarName ("," VarName)* => ( VarName :: SR ) ) ? => (
case SR of
NONE => []
| SOME ss => ss
) ;
member_list
: ( VarName ("*" VarName)* => ( VarName :: SR ) ) ? => (
case SR of
NONE => []
| SOME ss => ss
) ;
logical_expression
: relative_expression ( "and" relative_expression => ( (AST.opAND, relative_expression) )
| "or" relative_expression => ( (AST.opOR, relative_expression) ) )*
=> ( apply_op relative_expression SR );
relative_expression
: additive_expression ( "<" additive_expression => ( (AST.opLT, additive_expression) )
| ">" additive_expression => ( (AST.opGT, additive_expression) )
| "<=" additive_expression => ( (AST.opLE, additive_expression) )
| ">=" additive_expression => ( (AST.opGE, additive_expression) )
| "=" additive_expression => ( (AST.opEQ, additive_expression) )
| "/=" additive_expression => ( (AST.opNE, additive_expression) ) )*
=> ( apply_op additive_expression SR );
additive_expression
: multiplicative_expression ( "+" multiplicative_expression => ( (AST.opADD, multiplicative_expression) )
| "-" multiplicative_expression => ( (AST.opSUB, multiplicative_expression) ) )*
=> ( apply_op multiplicative_expression SR);
multiplicative_expression
: unary_expression ( "*" unary_expression => ( (AST.opMUL, unary_expression) )
| "/" unary_expression => ( (AST.opDIV, unary_expression) )
| "%" unary_expression => ( (AST.opMOD, unary_expression) ) )*
=> ( apply_op unary_expression SR );
unary_expression
: "not" postfix_expression => ( AST.opNOT postfix_expression )
| "-" postfix_expression => ( AST.opNEG postfix_expression )
| Operator_QUERY postfix_expression => ( AST.opISA (Operator_QUERY, postfix_expression) )
| postfix_expression
;
postfix_expression
: primary_expression ( ("::" VarName)+ => ( List.foldl (fn (x,y) => AST.opMEM(y,x)) primary_expression SR )
| "(" expression_list ")" => ( AST.Funcall (primary_expression, expression_list) ) ) ? => (
case SR of
NONE => primary_expression
| SOME expr => expr
);
primary_expression
: VarName => ( AST.Identifier VarName )
| Number => ( AST.Integer Number )
| "(" expression ")"
;