1
- """Recursince decend parser"""
1
+ """Recursive decent parser"""
2
2
# pylint: disable=too-few-public-methods
3
3
4
4
import json
5
5
import re
6
6
7
+
7
8
class State (object ):
8
9
"""Current parser state"""
9
10
text = ""
10
11
position = 0
11
12
rules = []
12
- lastExpectations = []
13
+ last_expectations = []
14
+
13
15
def __init__ (self , ** kwargs ):
14
16
self .__dict__ .update (kwargs )
15
17
16
18
def to_json (self ):
17
19
"""returns json string"""
18
20
return json .dumps (self , default = lambda o : o .__dict__ , sort_keys = False , indent = 2 )
19
21
22
+
20
23
class Node (object ):
21
24
"""Node of AST"""
22
25
match = ""
23
26
children = None
24
27
action = None
28
+
25
29
def __init__ (self , ** kwargs ):
26
30
self .__dict__ .update (kwargs )
27
31
@@ -32,26 +36,28 @@ def to_json(self):
32
36
33
37
class Expectation (object ):
34
38
"""Expectation object"""
39
+
35
40
def __init__ (self , ** kwargs ):
36
41
self .__dict__ .update (kwargs )
37
42
38
43
def to_json (self ):
39
44
"""returns json string"""
40
45
return json .dumps (self , default = lambda o : o .__dict__ , sort_keys = False , indent = 2 )
41
46
42
- def getLastError (state ):
43
- if len (state .lastExpectations ) < 1 :
47
+
48
+ def get_last_error (state ):
49
+ if len (state .last_expectations ) < 1 :
44
50
return False
45
51
lines = state .text .split ('\n ' )
46
- last_exp_position = max ([exp .position for exp in state .lastExpectations ])
52
+ last_exp_position = max ([exp .position for exp in state .last_expectations ])
47
53
last_position = 0
48
54
line_of_error = ''
49
55
error_line_number = None
50
56
position_of_error = 0
51
57
i = 0
52
58
while i < len (lines ):
53
59
line_lenght = len (lines [i ]) + 1
54
- if last_exp_position >= last_position and last_exp_position < last_position + line_lenght :
60
+ if last_position <= last_exp_position < last_position + line_lenght :
55
61
line_of_error = lines [i ]
56
62
position_of_error = last_exp_position - last_position
57
63
error_line_number = i + 1
@@ -64,15 +70,16 @@ def getLastError(state):
64
70
if last_exp_position < len (state .text ):
65
71
unexpected_char = state .text [last_exp_position ]
66
72
unexpected = 'Unexpected "' + unexpected_char + '"'
67
- expected_rules = [exp .rule for exp in state .lastExpectations ]
73
+ expected_rules = [exp .rule for exp in state .last_expectations ]
68
74
expected = ' expected (' + ' or ' .join (expected_rules ) + ')'
69
75
pointer = ('-' * (position_of_error + 2 + error_ln_length )) + '^'
70
76
extra = line_of_error + '\n ' + pointer
71
77
return unexpected + expected + '\n ' + str_error_ln + ': ' + extra
72
78
79
+
73
80
def string (rule ):
74
81
def _ (state ):
75
- state .lastExpectations = []
82
+ state .last_expectations = []
76
83
if state .text [state .position :state .position + len (rule )] == rule :
77
84
start_position = state .position
78
85
state .position += len (rule )
@@ -83,17 +90,18 @@ def _(state):
83
90
end_position = state .position
84
91
)
85
92
else :
86
- state .lastExpectations = [Expectation (
93
+ state .last_expectations = [Expectation (
87
94
type = 'string' ,
88
95
rule = rule ,
89
96
position = state .position
90
97
)]
91
98
return False
92
99
return _
93
100
101
+
94
102
def regex_char (rule ):
95
103
def _ (state ):
96
- state .lastExpectations = []
104
+ state .last_expectations = []
97
105
match = re .match (rule , state .text [state .position :])
98
106
if match and match .start () == 0 :
99
107
start_position = state .position
@@ -105,14 +113,15 @@ def _(state):
105
113
end_position = state .position
106
114
)
107
115
else :
108
- state .lastExpectations = [Expectation (
116
+ state .last_expectations = [Expectation (
109
117
type = 'regex_char' ,
110
118
rule = rule ,
111
119
position = state .position
112
120
)]
113
121
return False
114
122
return _
115
123
124
+
116
125
def sequence (parsers ):
117
126
def _ (state ):
118
127
asts = []
@@ -135,6 +144,7 @@ def _(state):
135
144
)
136
145
return _
137
146
147
+
138
148
def ordered_choice (parsers ):
139
149
def _ (state ):
140
150
expectations = []
@@ -154,12 +164,13 @@ def _(state):
154
164
else :
155
165
state .text = initial_text
156
166
state .position = initial_position
157
- expectations = expectations + state .lastExpectations
167
+ expectations = expectations + state .last_expectations
158
168
i += 1
159
- state .lastExpectations = expectations
169
+ state .last_expectations = expectations
160
170
return False
161
171
return _
162
172
173
+
163
174
def zero_or_more (parser ):
164
175
def _ (state ):
165
176
asts = []
@@ -172,7 +183,7 @@ def _(state):
172
183
asts .append (ast )
173
184
else :
174
185
state .position = state_position
175
- state .lastExpectations = []
186
+ state .last_expectations = []
176
187
match = '' .join ([(ast .match if ast .match is not None else '' ) for ast in asts ])
177
188
return Node (
178
189
type = 'zero_or_more' ,
@@ -183,6 +194,7 @@ def _(state):
183
194
)
184
195
return _
185
196
197
+
186
198
def one_or_more (parser ):
187
199
def _ (state ):
188
200
asts = []
@@ -196,7 +208,7 @@ def _(state):
196
208
else :
197
209
state .position = state_position
198
210
if len (asts ) > 0 :
199
- state .lastExpectations = []
211
+ state .last_expectations = []
200
212
match = '' .join ([(ast .match if ast .match is not None else '' ) for ast in asts ])
201
213
return Node (
202
214
type = 'one_or_more' ,
@@ -209,6 +221,7 @@ def _(state):
209
221
return False
210
222
return _
211
223
224
+
212
225
def optional (parser ):
213
226
def _ (state ):
214
227
start_position = state .position
@@ -227,6 +240,7 @@ def _(state):
227
240
)
228
241
return _
229
242
243
+
230
244
def and_predicate (parser ):
231
245
def _ (state ):
232
246
current_text = state .text
@@ -246,6 +260,7 @@ def _(state):
246
260
return False
247
261
return _
248
262
263
+
249
264
def not_predicate (parser ):
250
265
def _ (state ):
251
266
current_text = state .text
@@ -254,14 +269,14 @@ def _(state):
254
269
if ast :
255
270
state .text = current_text
256
271
state .position = current_position
257
- state .lastExpectations = [Expectation (
272
+ state .last_expectations = [Expectation (
258
273
type = 'not_predicate' ,
259
274
children = [ast ],
260
275
position = state .position
261
276
)]
262
277
return False
263
278
else :
264
- state .lastExpectations = []
279
+ state .last_expectations = []
265
280
return Node (
266
281
type = 'not_predicate' ,
267
282
match = None ,
@@ -271,6 +286,7 @@ def _(state):
271
286
)
272
287
return _
273
288
289
+
274
290
def end_of_file ():
275
291
def _ (state ):
276
292
if len (state .text ) == state .position :
@@ -282,16 +298,17 @@ def _(state):
282
298
end_position = state .position
283
299
)
284
300
else :
285
- state .lastExpectations = [Expectation (
301
+ state .last_expectations = [Expectation (
286
302
type = 'end_of_file' ,
287
303
rule = 'EOF' ,
288
304
position = state .position
289
305
)]
290
306
return False
291
307
return _
292
308
309
+
293
310
def rec (func ):
294
- """Allows you to do recurrcive currying"""
311
+ """Allows you to do recursive currying"""
295
312
def _ (* args , ** kwargs ):
296
313
return func ()(* args , ** kwargs )
297
314
return _
@@ -305,6 +322,7 @@ def _(*args, **kwargs):
305
322
return ast
306
323
return _
307
324
325
+
308
326
def call_rule_by_name (name ):
309
327
def _ (state ):
310
328
rule = next ((x for x in state .rules if x .name == name ), None )
0 commit comments