6.9.3.7. Calculate Action Table

Start python section to interscript/parsers/lalr1.py[19 /24 ] Next Prev Last
   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: 
End python section to interscript/parsers/lalr1.py[19]