@@ -15,8 +15,9 @@ class RobotFrameworkParser(object):
15
15
tokens = Token .DATA_TOKENS
16
16
17
17
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 [])
20
21
21
22
def p_sections (self , p ):
22
23
'''sections : section
@@ -43,7 +44,7 @@ def p_settings(self, p):
43
44
append_to_list_value (p )
44
45
45
46
def p_setting (self , p ):
46
- '''setting : documentation_setting EOS
47
+ '''setting : documentation_setting
47
48
| suite_setup_setting EOS
48
49
| suite_teardown_setting EOS
49
50
| metadata_setting EOS
@@ -66,7 +67,7 @@ def p_setting(self, p):
66
67
p [0 ] = p [1 ]
67
68
68
69
def p_documentation (self , p ):
69
- '''documentation_setting : DOCUMENTATION arguments'''
70
+ '''documentation_setting : DOCUMENTATION arguments EOS '''
70
71
p [0 ] = DocumentationSetting (p [2 ])
71
72
72
73
def p_suite_setup (self , p ):
@@ -121,29 +122,24 @@ def p_variables_import(self, p):
121
122
p [0 ] = VariablesSetting (name , args )
122
123
123
124
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 ])
127
127
128
128
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 ])
132
131
133
132
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 ])
137
135
138
136
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 ])
142
139
143
140
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 ])
147
143
148
144
def p_arguments_setting (self , p ):
149
145
'''arguments_setting : ARGUMENTS arguments'''
@@ -161,14 +157,12 @@ def p_variable_section(self, p):
161
157
162
158
def p_variables (self , p ):
163
159
'''variables : variable
164
- | variables variable'''
160
+ | variables variable'''
165
161
append_to_list_value (p )
166
162
167
163
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 ])
172
166
173
167
def p_testcase_section (self , p ):
174
168
'''testcase_section : TESTCASE_HEADER EOS
@@ -219,25 +213,19 @@ def p_body_item(self, p):
219
213
| setting
220
214
| step
221
215
| templatearguments
216
+ | invalid_forloop
222
217
'''
223
218
p [0 ] = p [1 ]
224
219
225
220
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 ])
232
223
233
224
def p_step_with_assignment (self , p ):
234
225
'''step : assignments EOS
235
- | assignments KEYWORD EOS
236
226
| assignments KEYWORD arguments EOS'''
237
227
if len (p ) == 3 :
238
228
p [0 ] = KeywordCall (p [1 ], None )
239
- elif len (p ) == 4 :
240
- p [0 ] = KeywordCall (p [1 ], p [2 ])
241
229
else :
242
230
p [0 ] = KeywordCall (p [1 ], p [2 ], p [3 ])
243
231
@@ -253,17 +241,11 @@ def p_forloop(self, p):
253
241
254
242
def p_for_header (self , p ):
255
243
'''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'''
259
245
if len (p ) == 6 :
260
246
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' , [])
265
247
else :
266
- p [0 ] = ForLoop ([ ], 'IN' , [])
248
+ p [0 ] = ForLoop (p [ 2 ], 'IN' , [])
267
249
268
250
def p_for_body (self , p ):
269
251
'''for_body : step
@@ -277,16 +259,30 @@ def p_templatearguments(self, p):
277
259
'''templatearguments : arguments EOS'''
278
260
p [0 ] = TemplateArguments (p [1 ])
279
261
262
+ def p_invalid_for_loop (self , p ):
263
+ '''invalid_forloop : for_header for_body'''
264
+ p [0 ] = p [1 ]
265
+
280
266
def p_assignments (self , p ):
281
267
'''assignments : ASSIGN
282
- | assignments ASSIGN'''
268
+ | assignments ASSIGN'''
283
269
append_to_list_value (p )
284
270
285
271
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'''
288
280
append_to_list_value (p )
289
281
282
+ def p_empty_arg (self , p ):
283
+ '''empty_arg : '''
284
+ p [0 ] = []
285
+
290
286
def p_error (self , e ):
291
287
if e :
292
288
print (e .type )
@@ -296,11 +292,14 @@ def p_error(self, e):
296
292
297
293
298
294
def append_to_list_value (p ):
299
- if len (p ) == 2 :
295
+ if len (p ) == 1 :
296
+ p [0 ] = []
297
+ elif len (p ) == 2 :
300
298
p [0 ] = [p [1 ]]
301
299
else :
302
300
value = p [1 ]
303
- if (p [2 ]) is not None :
301
+ # TODO: IS this check needed??
302
+ if p [2 ] is not None :
304
303
value .append (p [2 ])
305
304
p [0 ] = value
306
305
0 commit comments