6.9.3. mkntfirstmap

6.9.3. mkntfirstmap

Computes all nonterms A, first of (strings n) such that some nonterminal B derives [A, n] in zero or more steps of (rightmost) derivation. used to help make epsilon productions quickly calculable. (B may == A)

This is to help mak epsilon productions work with kernel items and to compute goto transitions from kernel.

Start python section to interscript/parsers/lalr1.py[12]
   269: #line 422 "lalr1_parser.ipk"
   270:   def calc_ntfirstmap(self):
   271:     res = {}
   272:     for p in self.productions:
   273:       if p.RHS and p.RHS[0] in self.nonterms:
   274:         fos = self.firstofstring(p.RHS[1:])
   275:         fos.sort()
   276:         if not res.has_key(p.LHS):
   277:           res[p.LHS] = {}
   278:         if not res[p.LHS].has_key(p.RHS[0]):
   279:           res[p.LHS][p.RHS[0]] = []
   280:         for i in fos:
   281:           if i not in res[p.LHS].get(p.RHS[0], []):
   282:             res[p.LHS][p.RHS[0]] = fos
   283: 
   284:     while 1:
   285:       foundmore = 0
   286:       reskeys = res.keys()
   287:       for nt in reskeys:
   288:         rhsdict = res[nt]
   289:         for rnt in rhsdict.keys():
   290:           if rnt in reskeys:
   291:             d = res[rnt]
   292:             for k in d.keys():
   293:               if not res[nt].has_key(k):
   294:                 fos = self.firstofstring(d[k]+ res[nt][rnt])
   295:                 foundmore = 1
   296:                 fos.sort()
   297:                 res[nt][k] = fos
   298:               else:
   299:                 fos = self.firstofstring(d[k] + res[nt][rnt])
   300:                 fos.sort()
   301:                 if fos != res[nt][k]:  # then res[nt][k] is contained in fos
   302:                   foundmore = 1
   303:                   res[nt][k] = fos
   304:       if not foundmore: break
   305:     #
   306:     # this part accounts for the fact that a nonterminal will
   307:     # produce exactly itself in zero steps
   308:     #
   309:     for p in self.productions:
   310:       if res.has_key(p.LHS):
   311:         res[p.LHS][p.LHS] = [EPS]
   312:       else:
   313:         res[p.LHS] = {p.LHS: [EPS]}
   314:     self.ntfirstmap = res
   315: 
End python section to interscript/parsers/lalr1.py[12]


6.9.3.1. newmkntfirstmap
6.9.3.2. mktfirstmap
6.9.3.3. goto
6.9.3.4. lookaheads
6.9.3.5. kernelsoflalr1items
6.9.3.6. Calculate LALR1items
6.9.3.7. Calculate Action Table
6.9.3.8. Calculate goto table
6.9.3.9. Parser