Mercurial > lcfOS
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 |