Back to index

enigmail  1.4.3
Public Member Functions | Public Attributes | Private Attributes
ply.yacc.LRGeneratedTable Class Reference
Inheritance diagram for ply.yacc.LRGeneratedTable:
Inheritance graph
[legend]
Collaboration diagram for ply.yacc.LRGeneratedTable:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def lr0_closure
def lr0_goto
def lr0_items
def compute_nullable_nonterminals
def find_nonterminal_transitions
def dr_relation
def reads_relation
def compute_lookback_includes
def compute_read_sets
def compute_follow_sets
def add_lookaheads
def add_lalr_lookaheads
def lr_parse_table
def write_table
def pickle_table
def read_table
def read_pickle
def bind_callables

Public Attributes

 grammar
 lr_method
 log
 lr_action
 lr_goto
 lr_productions
 lr_goto_cache
 lr0_cidhash
 sr_conflict
 rr_conflict
 conflicts
 sr_conflicts
 rr_conflicts

Private Attributes

 _add_count

Detailed Description

Definition at line 1939 of file yacc.py.


Constructor & Destructor Documentation

def ply.yacc.LRGeneratedTable.__init__ (   self,
  grammar,
  method = 'LALR',
  log = None 
)

Definition at line 1940 of file yacc.py.

01940 
01941     def __init__(self,grammar,method='LALR',log=None):
01942         if method not in ['SLR','LALR']:
01943             raise LALRError("Unsupported method %s" % method)
01944 
01945         self.grammar = grammar
01946         self.lr_method = method
01947 
01948         # Set up the logger
01949         if not log:
01950             log = NullLogger()
01951         self.log = log
01952 
01953         # Internal attributes
01954         self.lr_action     = {}        # Action table
01955         self.lr_goto       = {}        # Goto table
01956         self.lr_productions  = grammar.Productions    # Copy of grammar Production array
01957         self.lr_goto_cache = {}        # Cache of computed gotos
01958         self.lr0_cidhash   = {}        # Cache of closures
01959 
01960         self._add_count    = 0         # Internal counter used to detect cycles
01961 
01962         # Diagonistic information filled in by the table generator
01963         self.sr_conflict   = 0
01964         self.rr_conflict   = 0
01965         self.conflicts     = []        # List of conflicts
01966 
01967         self.sr_conflicts  = []
01968         self.rr_conflicts  = []
01969 
01970         # Build the tables
01971         self.grammar.build_lritems()
01972         self.grammar.compute_first()
01973         self.grammar.compute_follow()
01974         self.lr_parse_table()


Member Function Documentation

Definition at line 2338 of file yacc.py.

02338 
02339     def add_lalr_lookaheads(self,C):
02340         # Determine all of the nullable nonterminals
02341         nullable = self.compute_nullable_nonterminals()
02342 
02343         # Find all non-terminal transitions
02344         trans = self.find_nonterminal_transitions(C)
02345 
02346         # Compute read sets
02347         readsets = self.compute_read_sets(C,trans,nullable)
02348 
02349         # Compute lookback/includes relations
02350         lookd, included = self.compute_lookback_includes(C,trans,nullable)
02351 
02352         # Compute LALR FOLLOW sets
02353         followsets = self.compute_follow_sets(trans,readsets,included)
02354 
02355         # Add all of the lookaheads
02356         self.add_lookaheads(lookd,followsets)

Here is the call graph for this function:

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.add_lookaheads (   self,
  lookbacks,
  followset 
)

Definition at line 2321 of file yacc.py.

02321 
02322     def add_lookaheads(self,lookbacks,followset):
02323         for trans,lb in lookbacks.items():
02324             # Loop over productions in lookback
02325             for state,p in lb:
02326                  if not state in p.lookaheads:
02327                       p.lookaheads[state] = []
02328                  f = followset.get(trans,[])
02329                  for a in f:
02330                       if a not in p.lookaheads[state]: p.lookaheads[state].append(a)

Here is the caller graph for this function:

def ply.yacc.LRTable.bind_callables (   self,
  pdict 
) [inherited]

Definition at line 1870 of file yacc.py.

01870 
01871     def bind_callables(self,pdict):
01872         for p in self.lr_productions:
01873             p.bind(pdict)
01874     
01875 # -----------------------------------------------------------------------------
01876 #                           === LR Generator ===
01877 #
01878 # The following classes and functions are used to generate LR parsing tables on 
01879 # a grammar.
01880 # -----------------------------------------------------------------------------
01881 
01882 # -----------------------------------------------------------------------------
01883 # digraph()
01884 # traverse()
01885 #
01886 # The following two functions are used to compute set valued functions
01887 # of the form:
01888 #
01889 #     F(x) = F'(x) U U{F(y) | x R y}
01890 #
01891 # This is used to compute the values of Read() sets as well as FOLLOW sets
01892 # in LALR(1) generation.
01893 #
01894 # Inputs:  X    - An input set
01895 #          R    - A relation
01896 #          FP   - Set-valued function
01897 # ------------------------------------------------------------------------------

def ply.yacc.LRGeneratedTable.compute_follow_sets (   self,
  ntrans,
  readsets,
  inclsets 
)

Definition at line 2303 of file yacc.py.

02303 
02304     def compute_follow_sets(self,ntrans,readsets,inclsets):
02305          FP = lambda x: readsets[x]
02306          R  = lambda x: inclsets.get(x,[])
02307          F = digraph(ntrans,R,FP)
02308          return F

Here is the call graph for this function:

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.compute_lookback_includes (   self,
  C,
  trans,
  nullable 
)

Definition at line 2207 of file yacc.py.

02207 
02208     def compute_lookback_includes(self,C,trans,nullable):
02209 
02210         lookdict = {}          # Dictionary of lookback relations
02211         includedict = {}       # Dictionary of include relations
02212 
02213         # Make a dictionary of non-terminal transitions
02214         dtrans = {}
02215         for t in trans:
02216             dtrans[t] = 1
02217 
02218         # Loop over all transitions and compute lookbacks and includes
02219         for state,N in trans:
02220             lookb = []
02221             includes = []
02222             for p in C[state]:
02223                 if p.name != N: continue
02224 
02225                 # Okay, we have a name match.  We now follow the production all the way
02226                 # through the state machine until we get the . on the right hand side
02227 
02228                 lr_index = p.lr_index
02229                 j = state
02230                 while lr_index < p.len - 1:
02231                      lr_index = lr_index + 1
02232                      t = p.prod[lr_index]
02233 
02234                      # Check to see if this symbol and state are a non-terminal transition
02235                      if (j,t) in dtrans:
02236                            # Yes.  Okay, there is some chance that this is an includes relation
02237                            # the only way to know for certain is whether the rest of the
02238                            # production derives empty
02239 
02240                            li = lr_index + 1
02241                            while li < p.len:
02242                                 if p.prod[li] in self.grammar.Terminals: break      # No forget it
02243                                 if not p.prod[li] in nullable: break
02244                                 li = li + 1
02245                            else:
02246                                 # Appears to be a relation between (j,t) and (state,N)
02247                                 includes.append((j,t))
02248 
02249                      g = self.lr0_goto(C[j],t)               # Go to next set
02250                      j = self.lr0_cidhash.get(id(g),-1)     # Go to next state
02251 
02252                 # When we get here, j is the final state, now we have to locate the production
02253                 for r in C[j]:
02254                      if r.name != p.name: continue
02255                      if r.len != p.len:   continue
02256                      i = 0
02257                      # This look is comparing a production ". A B C" with "A B C ."
02258                      while i < r.lr_index:
02259                           if r.prod[i] != p.prod[i+1]: break
02260                           i = i + 1
02261                      else:
02262                           lookb.append((j,r))
02263             for i in includes:
02264                  if not i in includedict: includedict[i] = []
02265                  includedict[i].append((state,N))
02266             lookdict[(state,N)] = lookb
02267 
02268         return lookdict,includedict

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2093 of file yacc.py.

02093 
02094     def compute_nullable_nonterminals(self):
02095         nullable = {}
02096         num_nullable = 0
02097         while 1:
02098            for p in self.grammar.Productions[1:]:
02099                if p.len == 0:
02100                     nullable[p.name] = 1
02101                     continue
02102                for t in p.prod:
02103                     if not t in nullable: break
02104                else:
02105                     nullable[p.name] = 1
02106            if len(nullable) == num_nullable: break
02107            num_nullable = len(nullable)
02108         return nullable

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.compute_read_sets (   self,
  C,
  ntrans,
  nullable 
)

Definition at line 2281 of file yacc.py.

02281 
02282     def compute_read_sets(self,C, ntrans, nullable):
02283         FP = lambda x: self.dr_relation(C,x,nullable)
02284         R =  lambda x: self.reads_relation(C,x,nullable)
02285         F = digraph(ntrans,R,FP)
02286         return F

Here is the call graph for this function:

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.dr_relation (   self,
  C,
  trans,
  nullable 
)

Definition at line 2140 of file yacc.py.

02140 
02141     def dr_relation(self,C,trans,nullable):
02142         dr_set = { }
02143         state,N = trans
02144         terms = []
02145 
02146         g = self.lr0_goto(C[state],N)
02147         for p in g:
02148            if p.lr_index < p.len - 1:
02149                a = p.prod[p.lr_index+1]
02150                if a in self.grammar.Terminals:
02151                    if a not in terms: terms.append(a)
02152 
02153         # This extra bit is to handle the start state
02154         if state == 0 and N == self.grammar.Productions[0].prod[0]:
02155            terms.append('$end')
02156 
02157         return terms

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2120 of file yacc.py.

02120 
02121     def find_nonterminal_transitions(self,C):
02122          trans = []
02123          for state in range(len(C)):
02124              for p in C[state]:
02125                  if p.lr_index < p.len - 1:
02126                       t = (state,p.prod[p.lr_index+1])
02127                       if t[1] in self.grammar.Nonterminals:
02128                             if t not in trans: trans.append(t)
02129              state = state + 1
02130          return trans

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.lr0_closure (   self,
  I 
)

Definition at line 1977 of file yacc.py.

01977 
01978     def lr0_closure(self,I):
01979         self._add_count += 1
01980 
01981         # Add everything in I to J
01982         J = I[:]
01983         didadd = 1
01984         while didadd:
01985             didadd = 0
01986             for j in J:
01987                 for x in j.lr_after:
01988                     if getattr(x,"lr0_added",0) == self._add_count: continue
01989                     # Add B --> .G to J
01990                     J.append(x.lr_next)
01991                     x.lr0_added = self._add_count
01992                     didadd = 1
01993 
01994         return J

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.lr0_goto (   self,
  I,
  x 
)

Definition at line 2002 of file yacc.py.

02002 
02003     def lr0_goto(self,I,x):
02004         # First we look for a previously cached entry
02005         g = self.lr_goto_cache.get((id(I),x),None)
02006         if g: return g
02007 
02008         # Now we generate the goto set in a way that guarantees uniqueness
02009         # of the result
02010 
02011         s = self.lr_goto_cache.get(x,None)
02012         if not s:
02013             s = { }
02014             self.lr_goto_cache[x] = s
02015 
02016         gs = [ ]
02017         for p in I:
02018             n = p.lr_next
02019             if n and n.lr_before == x:
02020                 s1 = s.get(id(n),None)
02021                 if not s1:
02022                     s1 = { }
02023                     s[id(n)] = s1
02024                 gs.append(n)
02025                 s = s1
02026         g = s.get('$end',None)
02027         if not g:
02028             if gs:
02029                 g = self.lr0_closure(gs)
02030                 s['$end'] = g
02031             else:
02032                 s['$end'] = gs
02033         self.lr_goto_cache[(id(I),x)] = g
02034         return g

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2036 of file yacc.py.

02036 
02037     def lr0_items(self):
02038 
02039         C = [ self.lr0_closure([self.grammar.Productions[0].lr_next]) ]
02040         i = 0
02041         for I in C:
02042             self.lr0_cidhash[id(I)] = i
02043             i += 1
02044 
02045         # Loop over the items in C and each grammar symbols
02046         i = 0
02047         while i < len(C):
02048             I = C[i]
02049             i += 1
02050 
02051             # Collect all of the symbols that could possibly be in the goto(I,X) sets
02052             asyms = { }
02053             for ii in I:
02054                 for s in ii.usyms:
02055                     asyms[s] = None
02056 
02057             for x in asyms:
02058                 g = self.lr0_goto(I,x)
02059                 if not g:  continue
02060                 if id(g) in self.lr0_cidhash: continue
02061                 self.lr0_cidhash[id(g)] = len(C)
02062                 C.append(g)
02063 
02064         return C

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2362 of file yacc.py.

02362 
02363     def lr_parse_table(self):
02364         Productions = self.grammar.Productions
02365         Precedence  = self.grammar.Precedence
02366         goto   = self.lr_goto         # Goto array
02367         action = self.lr_action       # Action array
02368         log    = self.log             # Logger for output
02369 
02370         actionp = { }                 # Action production array (temporary)
02371         
02372         log.info("Parsing method: %s", self.lr_method)
02373 
02374         # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
02375         # This determines the number of states
02376 
02377         C = self.lr0_items()
02378 
02379         if self.lr_method == 'LALR':
02380             self.add_lalr_lookaheads(C)
02381 
02382         # Build the parser table, state by state
02383         st = 0
02384         for I in C:
02385             # Loop over each production in I
02386             actlist = [ ]              # List of actions
02387             st_action  = { }
02388             st_actionp = { }
02389             st_goto    = { }
02390             log.info("")
02391             log.info("state %d", st)
02392             log.info("")
02393             for p in I:
02394                 log.info("    (%d) %s", p.number, str(p))
02395             log.info("")
02396 
02397             for p in I:
02398                     if p.len == p.lr_index + 1:
02399                         if p.name == "S'":
02400                             # Start symbol. Accept!
02401                             st_action["$end"] = 0
02402                             st_actionp["$end"] = p
02403                         else:
02404                             # We are at the end of a production.  Reduce!
02405                             if self.lr_method == 'LALR':
02406                                 laheads = p.lookaheads[st]
02407                             else:
02408                                 laheads = self.grammar.Follow[p.name]
02409                             for a in laheads:
02410                                 actlist.append((a,p,"reduce using rule %d (%s)" % (p.number,p)))
02411                                 r = st_action.get(a,None)
02412                                 if r is not None:
02413                                     # Whoa. Have a shift/reduce or reduce/reduce conflict
02414                                     if r > 0:
02415                                         # Need to decide on shift or reduce here
02416                                         # By default we favor shifting. Need to add
02417                                         # some precedence rules here.
02418                                         sprec,slevel = Productions[st_actionp[a].number].prec
02419                                         rprec,rlevel = Precedence.get(a,('right',0))
02420                                         if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
02421                                             # We really need to reduce here.
02422                                             st_action[a] = -p.number
02423                                             st_actionp[a] = p
02424                                             if not slevel and not rlevel:
02425                                                 log.info("  ! shift/reduce conflict for %s resolved as reduce",a)
02426                                                 self.sr_conflicts.append((st,a,'reduce'))
02427                                             Productions[p.number].reduced += 1
02428                                         elif (slevel == rlevel) and (rprec == 'nonassoc'):
02429                                             st_action[a] = None
02430                                         else:
02431                                             # Hmmm. Guess we'll keep the shift
02432                                             if not rlevel:
02433                                                 log.info("  ! shift/reduce conflict for %s resolved as shift",a)
02434                                                 self.sr_conflicts.append((st,a,'shift'))
02435                                     elif r < 0:
02436                                         # Reduce/reduce conflict.   In this case, we favor the rule
02437                                         # that was defined first in the grammar file
02438                                         oldp = Productions[-r]
02439                                         pp = Productions[p.number]
02440                                         if oldp.line > pp.line:
02441                                             st_action[a] = -p.number
02442                                             st_actionp[a] = p
02443                                             chosenp,rejectp = pp,oldp
02444                                             Productions[p.number].reduced += 1
02445                                             Productions[oldp.number].reduced -= 1
02446                                         else:
02447                                             chosenp,rejectp = oldp,pp
02448                                         self.rr_conflicts.append((st,chosenp,rejectp))
02449                                         log.info("  ! reduce/reduce conflict for %s resolved using rule %d (%s)", a,st_actionp[a].number, st_actionp[a])
02450                                     else:
02451                                         raise LALRError("Unknown conflict in state %d" % st)
02452                                 else:
02453                                     st_action[a] = -p.number
02454                                     st_actionp[a] = p
02455                                     Productions[p.number].reduced += 1
02456                     else:
02457                         i = p.lr_index
02458                         a = p.prod[i+1]       # Get symbol right after the "."
02459                         if a in self.grammar.Terminals:
02460                             g = self.lr0_goto(I,a)
02461                             j = self.lr0_cidhash.get(id(g),-1)
02462                             if j >= 0:
02463                                 # We are in a shift state
02464                                 actlist.append((a,p,"shift and go to state %d" % j))
02465                                 r = st_action.get(a,None)
02466                                 if r is not None:
02467                                     # Whoa have a shift/reduce or shift/shift conflict
02468                                     if r > 0:
02469                                         if r != j:
02470                                             raise LALRError("Shift/shift conflict in state %d" % st)
02471                                     elif r < 0:
02472                                         # Do a precedence check.
02473                                         #   -  if precedence of reduce rule is higher, we reduce.
02474                                         #   -  if precedence of reduce is same and left assoc, we reduce.
02475                                         #   -  otherwise we shift
02476                                         rprec,rlevel = Productions[st_actionp[a].number].prec
02477                                         sprec,slevel = Precedence.get(a,('right',0))
02478                                         if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')):
02479                                             # We decide to shift here... highest precedence to shift
02480                                             Productions[st_actionp[a].number].reduced -= 1
02481                                             st_action[a] = j
02482                                             st_actionp[a] = p
02483                                             if not rlevel:
02484                                                 log.info("  ! shift/reduce conflict for %s resolved as shift",a)
02485                                                 self.sr_conflicts.append((st,a,'shift'))
02486                                         elif (slevel == rlevel) and (rprec == 'nonassoc'):
02487                                             st_action[a] = None
02488                                         else:
02489                                             # Hmmm. Guess we'll keep the reduce
02490                                             if not slevel and not rlevel:
02491                                                 log.info("  ! shift/reduce conflict for %s resolved as reduce",a)
02492                                                 self.sr_conflicts.append((st,a,'reduce'))
02493 
02494                                     else:
02495                                         raise LALRError("Unknown conflict in state %d" % st)
02496                                 else:
02497                                     st_action[a] = j
02498                                     st_actionp[a] = p
02499 
02500             # Print the actions associated with each terminal
02501             _actprint = { }
02502             for a,p,m in actlist:
02503                 if a in st_action:
02504                     if p is st_actionp[a]:
02505                         log.info("    %-15s %s",a,m)
02506                         _actprint[(a,m)] = 1
02507             log.info("")
02508             # Print the actions that were not used. (debugging)
02509             not_used = 0
02510             for a,p,m in actlist:
02511                 if a in st_action:
02512                     if p is not st_actionp[a]:
02513                         if not (a,m) in _actprint:
02514                             log.debug("  ! %-15s [ %s ]",a,m)
02515                             not_used = 1
02516                             _actprint[(a,m)] = 1
02517             if not_used:
02518                 log.debug("")
02519 
02520             # Construct the goto table for this state
02521 
02522             nkeys = { }
02523             for ii in I:
02524                 for s in ii.usyms:
02525                     if s in self.grammar.Nonterminals:
02526                         nkeys[s] = None
02527             for n in nkeys:
02528                 g = self.lr0_goto(I,n)
02529                 j = self.lr0_cidhash.get(id(g),-1)
02530                 if j >= 0:
02531                     st_goto[n] = j
02532                     log.info("    %-30s shift and go to state %d",n,j)
02533 
02534             action[st] = st_action
02535             actionp[st] = st_actionp
02536             goto[st] = st_goto
02537             st += 1
02538 

Here is the call graph for this function:

def ply.yacc.LRGeneratedTable.pickle_table (   self,
  filename,
  signature = "" 
)

Definition at line 2666 of file yacc.py.

02666 
02667     def pickle_table(self,filename,signature=""):
02668         try:
02669             import cPickle as pickle
02670         except ImportError:
02671             import pickle
02672         outf = open(filename,"wb")
02673         pickle.dump(__tabversion__,outf,pickle_protocol)
02674         pickle.dump(self.lr_method,outf,pickle_protocol)
02675         pickle.dump(signature,outf,pickle_protocol)
02676         pickle.dump(self.lr_action,outf,pickle_protocol)
02677         pickle.dump(self.lr_goto,outf,pickle_protocol)
02678 
02679         outp = []
02680         for p in self.lr_productions:
02681             if p.func:
02682                 outp.append((p.str,p.name, p.len, p.func,p.file,p.line))
02683             else:
02684                 outp.append((str(p),p.name,p.len,None,None,None))
02685         pickle.dump(outp,outf,pickle_protocol)
02686         outf.close()
02687 
02688 # -----------------------------------------------------------------------------
02689 #                            === INTROSPECTION ===
02690 #
02691 # The following functions and classes are used to implement the PLY
02692 # introspection features followed by the yacc() function itself.
02693 # -----------------------------------------------------------------------------
02694 
02695 # -----------------------------------------------------------------------------
02696 # get_caller_module_dict()
02697 #
02698 # This function returns a dictionary containing all of the symbols defined within
02699 # a caller further down the call stack.  This is used to get the environment
02700 # associated with the yacc() call if none was provided.
02701 # -----------------------------------------------------------------------------

def ply.yacc.LRTable.read_pickle (   self,
  filename 
) [inherited]

Definition at line 1845 of file yacc.py.

01845 
01846     def read_pickle(self,filename):
01847         try:
01848             import cPickle as pickle
01849         except ImportError:
01850             import pickle
01851 
01852         in_f = open(filename,"rb")
01853 
01854         tabversion = pickle.load(in_f)
01855         if tabversion != __tabversion__:
01856             raise VersionError("yacc table file version is out of date")
01857         self.lr_method = pickle.load(in_f)
01858         signature      = pickle.load(in_f)
01859         self.lr_action = pickle.load(in_f)
01860         self.lr_goto   = pickle.load(in_f)
01861         productions    = pickle.load(in_f)
01862 
01863         self.lr_productions = []
01864         for p in productions:
01865             self.lr_productions.append(MiniProduction(*p))
01866 
01867         in_f.close()
01868         return signature

def ply.yacc.LRTable.read_table (   self,
  module 
) [inherited]

Definition at line 1821 of file yacc.py.

01821 
01822     def read_table(self,module):
01823         if isinstance(module,types.ModuleType):
01824             parsetab = module
01825         else:
01826             if sys.version_info[0] < 3:
01827                 exec("import %s as parsetab" % module)
01828             else:
01829                 env = { }
01830                 exec("import %s as parsetab" % module, env, env)
01831                 parsetab = env['parsetab']
01832 
01833         if parsetab._tabversion != __tabversion__:
01834             raise VersionError("yacc table file version is out of date")
01835 
01836         self.lr_action = parsetab._lr_action
01837         self.lr_goto = parsetab._lr_goto
01838 
01839         self.lr_productions = []
01840         for p in parsetab._lr_productions:
01841             self.lr_productions.append(MiniProduction(*p))
01842 
01843         self.lr_method = parsetab._lr_method
01844         return parsetab._lr_signature

def ply.yacc.LRGeneratedTable.reads_relation (   self,
  C,
  trans,
  empty 
)

Definition at line 2164 of file yacc.py.

02164 
02165     def reads_relation(self,C, trans, empty):
02166         # Look for empty transitions
02167         rel = []
02168         state, N = trans
02169 
02170         g = self.lr0_goto(C[state],N)
02171         j = self.lr0_cidhash.get(id(g),-1)
02172         for p in g:
02173             if p.lr_index < p.len - 1:
02174                  a = p.prod[p.lr_index + 1]
02175                  if a in empty:
02176                       rel.append((j,a))
02177 
02178         return rel

Here is the call graph for this function:

Here is the caller graph for this function:

def ply.yacc.LRGeneratedTable.write_table (   self,
  modulename,
  outputdir = '',
  signature = "" 
)

Definition at line 2545 of file yacc.py.

02545 
02546     def write_table(self,modulename,outputdir='',signature=""):
02547         basemodulename = modulename.split(".")[-1]
02548         filename = os.path.join(outputdir,basemodulename) + ".py"
02549         try:
02550             f = open(filename,"w")
02551 
02552             f.write("""
02553 # %s
02554 # This file is automatically generated. Do not edit.
02555 _tabversion = %r
02556 
02557 _lr_method = %r
02558 
02559 _lr_signature = %r
02560     """ % (filename, __tabversion__, self.lr_method, signature))
02561 
02562             # Change smaller to 0 to go back to original tables
02563             smaller = 1
02564 
02565             # Factor out names to try and make smaller
02566             if smaller:
02567                 items = { }
02568 
02569                 for s,nd in self.lr_action.items():
02570                    for name,v in nd.items():
02571                       i = items.get(name)
02572                       if not i:
02573                          i = ([],[])
02574                          items[name] = i
02575                       i[0].append(s)
02576                       i[1].append(v)
02577 
02578                 f.write("\n_lr_action_items = {")
02579                 for k,v in items.items():
02580                     f.write("%r:([" % k)
02581                     for i in v[0]:
02582                         f.write("%r," % i)
02583                     f.write("],[")
02584                     for i in v[1]:
02585                         f.write("%r," % i)
02586 
02587                     f.write("]),")
02588                 f.write("}\n")
02589 
02590                 f.write("""
02591 _lr_action = { }
02592 for _k, _v in _lr_action_items.items():
02593    for _x,_y in zip(_v[0],_v[1]):
02594       if not _x in _lr_action:  _lr_action[_x] = { }
02595       _lr_action[_x][_k] = _y
02596 del _lr_action_items
02597 """)
02598 
02599             else:
02600                 f.write("\n_lr_action = { ");
02601                 for k,v in self.lr_action.items():
02602                     f.write("(%r,%r):%r," % (k[0],k[1],v))
02603                 f.write("}\n");
02604 
02605             if smaller:
02606                 # Factor out names to try and make smaller
02607                 items = { }
02608 
02609                 for s,nd in self.lr_goto.items():
02610                    for name,v in nd.items():
02611                       i = items.get(name)
02612                       if not i:
02613                          i = ([],[])
02614                          items[name] = i
02615                       i[0].append(s)
02616                       i[1].append(v)
02617 
02618                 f.write("\n_lr_goto_items = {")
02619                 for k,v in items.items():
02620                     f.write("%r:([" % k)
02621                     for i in v[0]:
02622                         f.write("%r," % i)
02623                     f.write("],[")
02624                     for i in v[1]:
02625                         f.write("%r," % i)
02626 
02627                     f.write("]),")
02628                 f.write("}\n")
02629 
02630                 f.write("""
02631 _lr_goto = { }
02632 for _k, _v in _lr_goto_items.items():
02633    for _x,_y in zip(_v[0],_v[1]):
02634        if not _x in _lr_goto: _lr_goto[_x] = { }
02635        _lr_goto[_x][_k] = _y
02636 del _lr_goto_items
02637 """)
02638             else:
02639                 f.write("\n_lr_goto = { ");
02640                 for k,v in self.lr_goto.items():
02641                     f.write("(%r,%r):%r," % (k[0],k[1],v))
02642                 f.write("}\n");
02643 
02644             # Write production table
02645             f.write("_lr_productions = [\n")
02646             for p in self.lr_productions:
02647                 if p.func:
02648                     f.write("  (%r,%r,%d,%r,%r,%d),\n" % (p.str,p.name, p.len, p.func,p.file,p.line))
02649                 else:
02650                     f.write("  (%r,%r,%d,None,None,None),\n" % (str(p),p.name, p.len))
02651             f.write("]\n")
02652             f.close()
02653 
02654         except IOError:
02655             e = sys.exc_info()[1]
02656             sys.stderr.write("Unable to create '%s'\n" % filename)
02657             sys.stderr.write(str(e)+"\n")
02658             return
02659 


Member Data Documentation

Definition at line 1959 of file yacc.py.

Definition at line 1964 of file yacc.py.

Definition at line 1944 of file yacc.py.

Definition at line 1950 of file yacc.py.

Definition at line 1957 of file yacc.py.

Reimplemented from ply.yacc.LRTable.

Definition at line 1953 of file yacc.py.

Reimplemented from ply.yacc.LRTable.

Definition at line 1954 of file yacc.py.

Definition at line 1956 of file yacc.py.

Reimplemented from ply.yacc.LRTable.

Definition at line 1945 of file yacc.py.

Reimplemented from ply.yacc.LRTable.

Definition at line 1955 of file yacc.py.

Definition at line 1963 of file yacc.py.

Definition at line 1967 of file yacc.py.

Definition at line 1962 of file yacc.py.

Definition at line 1966 of file yacc.py.


The documentation for this class was generated from the following file: