Skip to content

Commit c88b49f

Browse files
committed
parser: simplify grammar
introducing empty_arg simplifies all rules using arguments
1 parent d09436b commit c88b49f

File tree

2 files changed

+144
-149
lines changed

2 files changed

+144
-149
lines changed

src/robot/parsing/newparser/parser.py

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ class RobotFrameworkParser(object):
1515
tokens = Token.DATA_TOKENS
1616

1717
def p_datafile(self, p):
18-
'''datafile : sections'''
19-
p[0] = DataFile(p[1])
18+
'''datafile :
19+
| sections'''
20+
p[0] = DataFile(p[1] if len(p) == 2 else [])
2021

2122
def p_sections(self, p):
2223
'''sections : section
@@ -43,7 +44,7 @@ def p_settings(self, p):
4344
append_to_list_value(p)
4445

4546
def p_setting(self, p):
46-
'''setting : documentation_setting EOS
47+
'''setting : documentation_setting
4748
| suite_setup_setting EOS
4849
| suite_teardown_setting EOS
4950
| metadata_setting EOS
@@ -66,7 +67,7 @@ def p_setting(self, p):
6667
p[0] = p[1]
6768

6869
def p_documentation(self, p):
69-
'''documentation_setting : DOCUMENTATION arguments'''
70+
'''documentation_setting : DOCUMENTATION arguments EOS'''
7071
p[0] = DocumentationSetting(p[2])
7172

7273
def p_suite_setup(self, p):
@@ -121,29 +122,24 @@ def p_variables_import(self, p):
121122
p[0] = VariablesSetting(name, args)
122123

123124
def p_setup(self, p):
124-
'''setup_setting : SETUP
125-
| SETUP arguments'''
126-
p[0] = SetupSetting(p[2] if len(p) == 3 else None)
125+
'''setup_setting : SETUP arguments'''
126+
p[0] = SetupSetting(p[2])
127127

128128
def p_teardown(self, p):
129-
'''teardown_setting : TEARDOWN
130-
| TEARDOWN arguments'''
131-
p[0] = TeardownSetting(p[2] if len(p) == 3 else None)
129+
'''teardown_setting : TEARDOWN arguments'''
130+
p[0] = TeardownSetting(p[2])
132131

133132
def p_template(self, p):
134-
'''template_setting : TEMPLATE
135-
| TEMPLATE arguments'''
136-
p[0] = TemplateSetting(p[2] if len(p) == 3 else None)
133+
'''template_setting : TEMPLATE arguments'''
134+
p[0] = TemplateSetting(p[2])
137135

138136
def p_timeout(self, p):
139-
'''timeout_setting : TIMEOUT
140-
| TIMEOUT arguments'''
141-
p[0] = TimeoutSetting(p[2] if len(p) == 3 else None)
137+
'''timeout_setting : TIMEOUT arguments'''
138+
p[0] = TimeoutSetting(p[2])
142139

143140
def p_tags(self, p):
144-
'''tags_setting : TAGS
145-
| TAGS arguments'''
146-
p[0] = TagsSetting(p[2] if len(p) == 3 else None)
141+
'''tags_setting : TAGS arguments'''
142+
p[0] = TagsSetting(p[2])
147143

148144
def p_arguments_setting(self, p):
149145
'''arguments_setting : ARGUMENTS arguments'''
@@ -161,14 +157,12 @@ def p_variable_section(self, p):
161157

162158
def p_variables(self, p):
163159
'''variables : variable
164-
| variables variable'''
160+
| variables variable'''
165161
append_to_list_value(p)
166162

167163
def p_variable(self, p):
168-
'''variable : VARIABLE arguments EOS
169-
| VARIABLE EOS'''
170-
arguments = p[2] if len(p) == 4 else []
171-
p[0] = Variable(p[1], arguments)
164+
'''variable : VARIABLE arguments EOS'''
165+
p[0] = Variable(p[1], p[2])
172166

173167
def p_testcase_section(self, p):
174168
'''testcase_section : TESTCASE_HEADER EOS
@@ -219,25 +213,19 @@ def p_body_item(self, p):
219213
| setting
220214
| step
221215
| templatearguments
216+
| invalid_forloop
222217
'''
223218
p[0] = p[1]
224219

225220
def p_step(self, p):
226-
'''step : KEYWORD EOS
227-
| KEYWORD arguments EOS'''
228-
if len(p) == 3:
229-
p[0] = KeywordCall(None, p[1], [])
230-
else:
231-
p[0] = KeywordCall(None, p[1], p[2])
221+
'''step : KEYWORD arguments EOS'''
222+
p[0] = KeywordCall(None, p[1], p[2])
232223

233224
def p_step_with_assignment(self, p):
234225
'''step : assignments EOS
235-
| assignments KEYWORD EOS
236226
| assignments KEYWORD arguments EOS'''
237227
if len(p) == 3:
238228
p[0] = KeywordCall(p[1], None)
239-
elif len(p) == 4:
240-
p[0] = KeywordCall(p[1], p[2])
241229
else:
242230
p[0] = KeywordCall(p[1], p[2], p[3])
243231

@@ -253,17 +241,11 @@ def p_forloop(self, p):
253241

254242
def p_for_header(self, p):
255243
'''for_header : FOR arguments FOR_SEPARATOR arguments EOS
256-
| FOR arguments FOR_SEPARATOR EOS
257-
| FOR arguments EOS
258-
| FOR EOS'''
244+
| FOR arguments EOS'''
259245
if len(p) == 6:
260246
p[0] = ForLoop(p[2], p[3], p[4])
261-
elif len(p) == 5:
262-
p[0] = ForLoop(p[2], p[3], [])
263-
elif len(p) == 4:
264-
p[0] = ForLoop(p[2], 'IN', [])
265247
else:
266-
p[0] = ForLoop([], 'IN', [])
248+
p[0] = ForLoop(p[2], 'IN', [])
267249

268250
def p_for_body(self, p):
269251
'''for_body : step
@@ -277,16 +259,30 @@ def p_templatearguments(self, p):
277259
'''templatearguments : arguments EOS'''
278260
p[0] = TemplateArguments(p[1])
279261

262+
def p_invalid_for_loop(self, p):
263+
'''invalid_forloop : for_header for_body'''
264+
p[0] = p[1]
265+
280266
def p_assignments(self, p):
281267
'''assignments : ASSIGN
282-
| assignments ASSIGN'''
268+
| assignments ASSIGN'''
283269
append_to_list_value(p)
284270

285271
def p_arguments(self, p):
286-
'''arguments : ARGUMENT
287-
| arguments ARGUMENT'''
272+
'''arguments : args
273+
| empty_arg
274+
'''
275+
p[0] = p[1]
276+
277+
def p_args(self, p):
278+
'''args : ARGUMENT
279+
| arguments ARGUMENT'''
288280
append_to_list_value(p)
289281

282+
def p_empty_arg(self, p):
283+
'''empty_arg : '''
284+
p[0] = []
285+
290286
def p_error(self, e):
291287
if e:
292288
print(e.type)
@@ -296,11 +292,14 @@ def p_error(self, e):
296292

297293

298294
def append_to_list_value(p):
299-
if len(p) == 2:
295+
if len(p) == 1:
296+
p[0] = []
297+
elif len(p) == 2:
300298
p[0] = [p[1]]
301299
else:
302300
value = p[1]
303-
if (p[2]) is not None:
301+
# TODO: IS this check needed??
302+
if p[2] is not None:
304303
value.append(p[2])
305304
p[0] = value
306305

0 commit comments

Comments
 (0)