comparison python/pyyacc.py @ 195:37ac6c016e0f

Expanded asm subsystem
author Windel Bouwman
date Fri, 31 May 2013 21:06:44 +0200
parents b01429a5d695
children 494828a7adf1
comparison
equal deleted inserted replaced
194:b01429a5d695 195:37ac6c016e0f
207 nextstate = transitions[(states.index(state), item.Next)] 207 nextstate = transitions[(states.index(state), item.Next)]
208 setAction(states.index(state), item.Next, (SHIFT, nextstate)) 208 setAction(states.index(state), item.Next, (SHIFT, nextstate))
209 if item.IsReduce: 209 if item.IsReduce:
210 if item.production.name == self.start_symbol and item.look_ahead == EOF: 210 if item.production.name == self.start_symbol and item.look_ahead == EOF:
211 # Rule 3: accept: 211 # Rule 3: accept:
212 setAction(states.index(state), item.look_ahead, (ACCEPT, None)) 212 setAction(states.index(state), item.look_ahead, (ACCEPT, item.production))
213 else: 213 else:
214 # Rule 2, reduce item: 214 # Rule 2, reduce item:
215 setAction(states.index(state), item.look_ahead, (REDUCE, item.production)) 215 setAction(states.index(state), item.look_ahead, (REDUCE, item.production))
216 for nt in self.nonterminals: 216 for nt in self.nonterminals:
217 key = (states.index(state), nt) 217 key = (states.index(state), nt)
218 if key in transitions: 218 if key in transitions:
219 goto_table[key] = transitions[key] 219 goto_table[key] = transitions[key]
220 220
221 return LRParser(action_table, goto_table) 221 return LRParser(action_table, goto_table, self.start_symbol)
222 222
223 223
224 class Production: 224 class Production:
225 """ Production rule for a grammar """ 225 """ Production rule for a grammar """
226 def __init__(self, name, symbols, f=None): 226 def __init__(self, name, symbols, f=None):
297 return '[{0} -> {1} . {2} -> {3}]'.format(*args) 297 return '[{0} -> {1} . {2} -> {3}]'.format(*args)
298 298
299 299
300 class LRParser: 300 class LRParser:
301 """ LR parser """ 301 """ LR parser """
302 def __init__(self, action_table, goto_table): 302 def __init__(self, action_table, goto_table, start_symbol):
303 self.action_table = action_table 303 self.action_table = action_table
304 self.goto_table = goto_table 304 self.goto_table = goto_table
305 self.start_symbol = start_symbol
305 306
306 def parse(self, toks): 307 def parse(self, toks):
307 """ Parse an iterable with tokens """ 308 """ Parse an iterable with tokens """
308 assert hasattr(toks, '__iter__'), '{0} not iter type'.format(type(toks)) 309 assert hasattr(toks, '__iter__'), '{0} not iter type'.format(type(toks))
309 stack = [0] 310 stack = [0]
311 r_data_stack = []
310 try: 312 try:
311 look_ahead = toks.__next__() 313 look_ahead = toks.__next__()
312 except StopIteration: 314 except StopIteration:
313 look_ahead = Token(EOF, EOF) 315 look_ahead = Token(EOF, EOF)
314 assert type(look_ahead) is Token 316 assert type(look_ahead) is Token
315 while True: 317 # TODO: exit on this condition:
318 while stack != [0, self.start_symbol, 2222]:
319 #print(stack)
316 state = stack[-1] # top of stack 320 state = stack[-1] # top of stack
317 key = (state, look_ahead.typ) 321 key = (state, look_ahead.typ)
318 if not key in self.action_table: 322 if not key in self.action_table:
319 raise ParserException('Error parsing at character {0}'.format(look_ahead)) 323 raise ParserException('Error parsing at character {0}'.format(look_ahead))
320 action, param = self.action_table[key] 324 action, param = self.action_table[key]
321 if action == REDUCE: 325 if action == REDUCE:
322 #print('reduce', param)
323 f_args = [] 326 f_args = []
324 for s in param.symbols: 327 for s in param.symbols:
325 stack.pop() 328 stack.pop()
326 stack.pop() 329 stack.pop()
327 f_args.append(0) 330 f_args.append(r_data_stack.pop())
331 f_args.reverse()
332 r_data = None
328 if param.f: 333 if param.f:
329 param.f(*f_args) 334 r_data = param.f(*f_args)
330 state = stack[-1] 335 state = stack[-1]
331 stack.append(param.name) 336 stack.append(param.name)
332 stack.append(self.goto_table[(state, param.name)]) 337 stack.append(self.goto_table[(state, param.name)])
338 r_data_stack.append(r_data)
333 elif action == SHIFT: 339 elif action == SHIFT:
334 stack.append(look_ahead.typ) 340 stack.append(look_ahead.typ)
335 stack.append(param) 341 stack.append(param)
342 r_data_stack.append(look_ahead.val)
336 try: 343 try:
337 look_ahead = toks.__next__() 344 look_ahead = toks.__next__()
338 except StopIteration: 345 except StopIteration:
339 look_ahead = Token(EOF, EOF) 346 look_ahead = Token(EOF, EOF)
340 assert type(look_ahead) is Token 347 assert type(look_ahead) is Token
341 elif action == ACCEPT: 348 elif action == ACCEPT:
349 # Pop last rule data off the stack:
350 f_args = []
351 for s in param.symbols:
352 stack.pop()
353 stack.pop()
354 f_args.append(r_data_stack.pop())
355 f_args.reverse()
356 if param.f:
357 param.f(*f_args)
358 # Break out!
342 break 359 break
343 360 # At exit, the stack must be 1 long
361 # TODO: fix that this holds:
362 #assert len(stack) == 1, 'stack {0} not totally reduce'.format(stack)
363