comparison python/yacc.py @ 334:6f4753202b9a

Added more recipes
author Windel Bouwman
date Thu, 13 Feb 2014 22:02:08 +0100
parents e9fe6988497c
children c7cc54c0dfdf
comparison
equal deleted inserted replaced
333:dcae6574c974 334:6f4753202b9a
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 """ 3 """
4 Parser generator utility. This script can generate a python script from a 4 Parser generator utility. This script can generate a python script from a
5 grammar description. 5 grammar description.
6 6
7 Invoke the script on a grammar specification file: 7 Invoke the script on a grammar specification file:
8 8
9 .. code:: 9 .. code::
40 import sys 40 import sys
41 import datetime 41 import datetime
42 import types 42 import types
43 import io 43 import io
44 import logging 44 import logging
45 from pyyacc import Grammar, print_grammar 45 from pyyacc import Grammar
46 46
47 47
48 class XaccLexer: 48 class XaccLexer:
49 def __init__(self): 49 def __init__(self):
50 pass 50 pass
242 self.print(' self.action_table[{}] = {}'.format(state, action)) 242 self.print(' self.action_table[{}] = {}'.format(state, action))
243 self.print('') 243 self.print('')
244 244
245 # Fill goto table: 245 # Fill goto table:
246 self.print(' self.goto_table = {}') 246 self.print(' self.goto_table = {}')
247 for gt in self.goto_table: 247 for state_number in self.goto_table:
248 to = self.goto_table[gt] 248 to = self.goto_table[state_number]
249 self.print(' self.goto_table[{}] = {}'.format(gt, to)) 249 self.print(' self.goto_table[{}] = {}'.format(state_number, to))
250 self.print('') 250 self.print('')
251 251
252 # Generate a function for each action: 252 # Generate a function for each action:
253 for rule in self.grammar.productions: 253 for rule in self.grammar.productions:
254 M = len(rule.symbols) 254 num_symbols = len(rule.symbols)
255 args = ', '.join('arg{}'.format(n + 1) for n in range(M)) 255 args = ', '.join('arg{}'.format(n + 1) for n in range(num_symbols))
256 self.print(' def {}(self, {}):'.format(rule.f_name, args)) 256 self.print(' def {}(self, {}):'.format(rule.f_name, args))
257 if rule.f == None: 257 if rule.f == None:
258 semantics = 'pass' 258 semantics = 'pass'
259 else: 259 else:
260 semantics = str(rule.f) 260 semantics = str(rule.f)
261 if semantics.strip() == '': 261 if semantics.strip() == '':
262 semantics = 'pass' 262 semantics = 'pass'
263 for n in range(M): 263 for n in range(num_symbols):
264 semantics = semantics.replace('${}'.format(n + 1), 'arg{}'.format(n + 1)) 264 semantics = semantics.replace('${}'.format(n + 1), 'arg{}'.format(n + 1))
265 self.print(' {}'.format(semantics)) 265 self.print(' {}'.format(semantics))
266 self.print('') 266 self.print('')
267 267
268 268
296 generator = XaccGenerator() 296 generator = XaccGenerator()
297 297
298 # Sequence source through the generator parts: 298 # Sequence source through the generator parts:
299 lexer.feed(src) 299 lexer.feed(src)
300 grammar = parser.parse_grammar() 300 grammar = parser.parse_grammar()
301 # TODO: optionize this: print_grammar(grammar)
302 generator.generate(grammar, parser.headers, args.output) 301 generator.generate(grammar, parser.headers, args.output)
303 302
304 303
305 if __name__ == '__main__': 304 if __name__ == '__main__':
306 args = make_argument_parser().parse_args() 305 args = make_argument_parser().parse_args()