-
Notifications
You must be signed in to change notification settings - Fork 1
/
jsgrammar.py
executable file
·145 lines (133 loc) · 3.7 KB
/
jsgrammar.py
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
import ply.yacc as yacc
from jstokens import tokens
start = 'js'
precedence = (
('left', 'OROR'),
('left', 'ANDAND'),
('left', 'EQUALEQUAL'),
('left', 'LT', 'LE', 'GT', 'GE'),
('left', 'PLUS', 'MINUS'),
('left', 'TIMES', 'DIVIDE', 'MOD'),
('right', 'NOT'),
('nonassoc', 'LOWER_THAN_ELSE') ,
('nonassoc', 'ELSE') ,
)
def p_js(p):
'js : element js'
p[0] = [p[1]] + p[2]
def p_js_empty(p):
'js : '
p[0] = [ ]
def p_element_function(p):
'element : FUNCTION IDENTIFIER LPAREN optparams RPAREN compoundstmt'
p[0] = ("function",p[2],p[4],p[6])
def p_element_stmt(p):
'element : sstmt'
p[0] = ("stmt",p[1])
def p_optparams(p):
'optparams : params'
p[0] = p[1]
def p_optparams_empty(p):
'optparams : '
p[0] = [ ]
def p_params(p):
'params : IDENTIFIER COMMA params'
p[0] = [p[1]] + p[3]
def p_params_one(p):
'params : IDENTIFIER'
p[0] = [p[1]]
def p_compoundstmt(p):
'compoundstmt : LBRACE stmts RBRACE'
p[0] = p[2]
def p_stmts(p):
'stmts : sstmt stmts'
p[0] = [p[1]] + p[2]
def p_stmt_or_compound(p):
'stmt_or_compound : sstmt'
p[0] = [p[1]]
def p_stmt_or_compound_c(p):
'stmt_or_compound : compoundstmt'
p[0] = p[1]
def p_optsemi_none(p):
'optsemi : '
p[0] = p[0]
def p_optsemi_some(p):
'optsemi : SEMICOLON'
p[0] = p[0]
def p_stmts_empty(p):
'stmts : '
p[0] = [ ]
def p_sstmt_if(p):
'sstmt : IF exp stmt_or_compound optsemi %prec LOWER_THAN_ELSE'
p[0] = ("if-then",p[2],p[3])
def p_sstmt_while(p):
'sstmt : WHILE exp compoundstmt optsemi'
p[0] = ("while",p[2],p[3])
def p_sstmt_if_else(p):
'sstmt : IF exp compoundstmt ELSE stmt_or_compound optsemi'
p[0] = ("if-then-else",p[2],p[3],p[5])
def p_sstmt_assigment(p):
'sstmt : IDENTIFIER EQUAL exp SEMICOLON'
p[0] = ("assign",p[1],p[3])
def p_sstmt_return(p):
'sstmt : RETURN exp SEMICOLON'
p[0] = ("return",p[2])
def p_sstmt_var(p):
'sstmt : VAR IDENTIFIER EQUAL exp SEMICOLON'
p[0] = ("var",p[2],p[4])
def p_sstmt_exp(p):
'sstmt : exp SEMICOLON'
p[0] = ("exp",p[1])
def p_exp_identifier(p):
'exp : IDENTIFIER'
p[0] = ("identifier",p[1])
def p_exp_paren(p):
'exp : LPAREN exp RPAREN'
p[0] = p[2]
def p_exp_number(p):
'exp : NUMBER'
p[0] = ("number",p[1])
def p_exp_string(p):
'exp : STRING'
p[0] = ("string",p[1])
def p_exp_true(p):
'exp : TRUE'
p[0] = ("true","true")
def p_exp_false(p):
'exp : FALSE'
p[0] = ("false","true")
def p_exp_not(p):
'exp : NOT exp'
p[0] = ("not",p[2])
def p_exp_lambda(p):
'exp : FUNCTION LPAREN optparams RPAREN compoundstmt'
p[0] = ("function",p[3],p[5])
def p_exp_binop(p):
'''exp : exp PLUS exp
| exp MINUS exp
| exp TIMES exp
| exp MOD exp
| exp DIVIDE exp
| exp EQUALEQUAL exp
| exp LE exp
| exp LT exp
| exp GE exp
| exp GT exp
| exp ANDAND exp
| exp OROR exp'''
p[0] = ("binop",p[1],p[2],p[3])
def p_exp_call(p):
'exp : IDENTIFIER LPAREN optargs RPAREN'
p[0] = ("call",p[1],p[3])
def p_optargs(p):
'optargs : args'
p[0] = p[1]
def p_optargs_empty(p):
'optargs : '
p[0] = [ ]
def p_args(p):
'args : exp COMMA args'
p[0] = [p[1]] + p[3]
def p_args_one(p):
'args : exp'
p[0] = [p[1]]