516: #line 686 "lalr1_parser.ipk" 517: def pr_conflict(self,state,sym,rej,acc): 518: if rej[0]=='r' and acc[0]=='s': 519: print "Shift/Reduce Conflict, Use Shift [%d,%s]:" % (state, repr(sym)), rej, "->", acc 520: elif rej[0]=='s' and acc[0]=='r': 521: print "WARNING! Shift/Reduce Conflict, Use Reduce [%d,%s]:" % (state, repr(sym)), rej, "->", acc 522: elif rej[0]=='s' and acc[0]=='s': 523: print "WARNING! Shift/Shift Conflict[%d,%s]:" % (state, repr(sym)), rej, "->", acc 524: elif rej[0]=='r' and acc[0]=='r': 525: print "WARNING! Reduce/Reduce Conflict[%d,%s]:" % (state, repr(sym)), rej, "->", acc 526: else: 527: print "WARNING! WEIRD Conflict[%d,%s]:" % (state, repr(sym)), rej, "->", acc 528: 529: def resolve(self,at,sym,new,state_i): 530: old = at.get(sym) 531: # new entry 532: if not old: 533: at[sym] = new 534: return 535: 536: # same entry 537: if old == new: return 538: 539: # resolve shift/reduce conflict in favour of shift 540: if old[0]=='s' and new[0] =='r': 541: self.pr_conflict(state_i,sym,new,old) 542: return 543: if old[0]=='r' and new[0] =='s': 544: self.pr_conflict(state_i,sym,old,new) 545: at[sym] = new 546: return 547: 548: if old[0]=='r' and new[0]=='r': 549: oldp = self.productions[old[1]] 550: newp = self.productions[new[1]] 551: oldpri = None 552: newpri = None 553: if hasattr(oldp,'priority'): oldpri = oldp.priority 554: if hasattr(newp,'priority'): newpri = newp.priority 555: if oldpri > newpri: return 556: elif newpri > oldpri: 557: at[sym]=new 558: return 559: 560: # resolve reduce/reduce conflict in favour of earlier production 561: if old[1] > new[1]: 562: at[sym]=new 563: self.pr_conflict(state_i,sym,old,new) 564: else: 565: self.pr_conflict(state_i,sym,new,old) 566: return 567: 568: self.pr_conflict(state_i,sym,old,new) 569: at[sym] = new 570: 571: def calc_action_table(self): 572: items = self.LALRitems 573: res = [] 574: state_i = 0 575: terms = self.terms.list() 576: terms.append(EOF) 577: for state in items: 578: at = {} 579: res.append(at) 580: for (prodind, rhsind), term in state: 581: if (rhsind ) == len(self.productions[prodind].RHS): 582: if prodind != 0: new = ("r", prodind) 583: else: new = ("a", None) 584: self.resolve(at,term,new,state_i) 585: # calculate reduction by epsilon productions 586: # 587: elif self.productions[prodind].RHS[rhsind] in self.nonterms: 588: nt = self.productions[prodind].RHS[rhsind] 589: ntfirst = self.firstmap[nt] 590: ntfirsts = self.ntfirstmap.get(nt, {}) 591: for k in ntfirsts.keys(): 592: if self.epslhs.contains(k): 593: reduceterms = self.followmap[k] 594: print `((prodind, rhsind), term)`, reduceterms 595: for r in reduceterms: 596: new = ("r", self.epslhs[k]) 597: self.resolve(at,r,new,state_i) 598: # 599: # calculate the shifts that occur but whose normal items aren't in the kernel 600: # 601: tfirsts = self.tfirstmap[nt] 602: for t in tfirsts: 603: g = self.goto(self.kernelitems[state_i], t) 604: try: 605: news = self.kernelitems.index(g) 606: except ValueError: 607: continue 608: new = ("s", news) 609: self.resolve(at,t,new,state_i) 610: # 611: # compute the rest of the shifts that occur 'normally' in the kernel 612: # 613: else: 614: t = self.productions[prodind].RHS[rhsind] 615: gt = self.goto(self.kernelitems[state_i], t) 616: if gt in self.kernelitems: 617: news = self.kernelitems.index(gt) 618: new = ("s", news) 619: self.resolve(at,t,new,state_i) 620: state_i = state_i + 1 621: self.action_table = res 622: