#-----------------------------------------------------------------------------
# ply: yacc.py
#
# Author(s): David M. Beazley (dave@dabeaz.com)
#
# Copyright (C) 2001-2006, David M. Beazley
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# 
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# 
# See the file COPYING for a complete copy of the LGPL.
#
#
# This implements an LR parser that is constructed from grammar rules defined
# as Python functions. The grammer is specified by supplying the BNF inside
# Python documentation strings.  The inspiration for this technique was borrowed
# from John Aycock's Spark parsing system.  PLY might be viewed as cross between
# Spark and the GNU bison utility.
#
# The current implementation is only somewhat object-oriented. The
# LR parser itself is defined in terms of an object (which allows multiple
# parsers to co-exist).  However, most of the variables used during table
# construction are defined in terms of global variables.  Users shouldn't
# notice unless they are trying to define multiple parsers at the same
# time using threads (in which case they should have their head examined).
#
# This implementation supports both SLR and LALR(1) parsing.  LALR(1)
# support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu),
# using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles,
# Techniques, and Tools" (The Dragon Book).  LALR(1) has since been replaced
# by the more efficient DeRemer and Pennello algorithm.
#
# :::::::: WARNING :::::::
#
# Construction of LR parsing tables is fairly complicated and expensive.
# To make this module run fast, a *LOT* of work has been put into
# optimization---often at the expensive of readability and what might
# consider to be good Python "coding style."   Modify the code at your
# own risk!
# ----------------------------------------------------------------------------

__version__ = "2.2"

#-----------------------------------------------------------------------------
#                     === User configurable parameters ===
#
# Change these to modify the default behavior of yacc (if you wish)
#-----------------------------------------------------------------------------

yaccdebug   = 1                # Debugging mode.  If set, yacc generates a
                               # a 'parser.out' file in the current directory

debug_file  = 'parser.out'     # Default name of the debugging file
tab_module  = 'parsetab'       # Default name of the table module
default_lr  = 'LALR'           # Default LR table generation method

error_count = 3                # Number of symbols that must be shifted to leave recovery mode

import re, types, sys, cStringIO, hashlib, os.path

# Exception raised for yacc-related errors
class YaccError(Exception):   pass

#-----------------------------------------------------------------------------
#                        ===  LR Parsing Engine ===
#
# The following classes are used for the LR parser itself.  These are not
# used during table construction and are independent of the actual LR
# table generation algorithm
#-----------------------------------------------------------------------------

# This class is used to hold non-terminal grammar symbols during parsing.
# It normally has the following attributes set:
#        .type       = Grammar symbol type
#        .value      = Symbol value
#        .lineno     = Starting line number
#        .endlineno  = Ending line number (optional, set automatically)
#        .lexpos     = Starting lex position
#        .endlexpos  = Ending lex position (optional, set automatically)

class YaccSymbol:
    def __str__(self):    return self.type
    def __repr__(self):   return str(self)

# This class is a wrapper around the objects actually passed to each
# grammar rule.   Index lookup and assignment actually assign the
# .value attribute of the underlying YaccSymbol object.
# The lineno() method returns the line number of a given
# item (or 0 if not defined).   The linespan() method returns
# a tuple of (startline,endline) representing the range of lines
# for a symbol.  The lexspan() method returns a tuple (lexpos,endlexpos)
# representing the range of positional information for a symbol.

class YaccProduction:
    def __init__(self,s,stack=None):
        self.slice = s
        self.pbstack = []
        self.stack = stack

    def __getitem__(self,n):
        if type(n) == types.IntType:
             if n >= 0: return self.slice[n].value
             else: return self.stack[n].value
        else:
             return [s.value for s in self.slice[n.start:n.stop:n.step]]

    def __setitem__(self,n,v):
        self.slice[n].value = v

    def __len__(self):
        return len(self.slice)
    
    def lineno(self,n):
        return getattr(self.slice[n],"lineno",0)

    def linespan(self,n):
        startline = getattr(self.slice[n],"lineno",0)
        endline = getattr(self.slice[n],"endlineno",startline)
        return startline,endline

    def lexpos(self,n):
        return getattr(self.slice[n],"lexpos",0)

    def lexspan(self,n):
        startpos = getattr(self.slice[n],"lexpos",0)
        endpos = getattr(self.slice[n],"endlexpos",startpos)
        return startpos,endpos

    def pushback(self,n):
        if n <= 0:
            raise ValueError, "Expected a positive value"
        if n > (len(self.slice)-1):
            raise ValueError, "Can't push %d tokens. Only %d are available." % (n,len(self.slice)-1)
        for i in range(0,n):
            self.pbstack.append(self.slice[-i-1])

# The LR Parsing engine.   This is defined as a class so that multiple parsers
# can exist in the same process.  A user never instantiates this directly.
# Instead, the global yacc() function should be used to create a suitable Parser
# object. 

class Parser:
    def __init__(self,magic=None):

        # This is a hack to keep users from trying to instantiate a Parser
        # object directly.

        if magic != "xyzzy":
            raise YaccError, "Can't instantiate Parser. Use yacc() instead."

        # Reset internal state
        self.productions = None          # List of productions
        self.errorfunc   = None          # Error handling function
        self.action      = { }           # LR Action table
        self.goto        = { }           # LR goto table
        self.require     = { }           # Attribute require table
        self.method      = "Unknown LR"  # Table construction method used

    def errok(self):
        self.errorcount = 0

    def restart(self):
        del self.statestack[:]
        del self.symstack[:]
        sym = YaccSymbol()
        sym.type = '$end'
        self.symstack.append(sym)
        self.statestack.append(0)
        
    def parse(self,input=None,lexer=None,debug=0):
        lookahead = None                 # Current lookahead symbol
        lookaheadstack = [ ]             # Stack of lookahead symbols
        actions = self.action            # Local reference to action table
        goto    = self.goto              # Local reference to goto table
        prod    = self.productions       # Local reference to production list
        pslice  = YaccProduction(None)   # Production object passed to grammar rules
        pslice.parser = self             # Parser object
        self.errorcount = 0              # Used during error recovery

        # If no lexer was given, we will try to use the lex module
        if not lexer:
            import lex
            lexer = lex.lexer

        pslice.lexer = lexer
        
        # If input was supplied, pass to lexer
        if input:
            lexer.input(input)

        # Tokenize function
        get_token = lexer.token

        statestack = [ ]                # Stack of parsing states
        self.statestack = statestack
        symstack   = [ ]                # Stack of grammar symbols
        self.symstack = symstack

        pslice.stack = symstack         # Put in the production
        errtoken   = None               # Err token

        # The start state is assumed to be (0,$end)
        statestack.append(0)
        sym = YaccSymbol()
        sym.type = '$end'
        symstack.append(sym)
        
        while 1:
            # Get the next symbol on the input.  If a lookahead symbol
            # is already set, we just use that. Otherwise, we'll pull
            # the next token off of the lookaheadstack or from the lexer
            if debug > 1:
                print 'state', statestack[-1]
            if not lookahead:
                if not lookaheadstack:
                    lookahead = get_token()     # Get the next token
                else:
                    lookahead = lookaheadstack.pop()
                if not lookahead:
                    lookahead = YaccSymbol()
                    lookahead.type = '$end'
            if debug:
                errorlead = ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()

            # Check the action table
            s = statestack[-1]
            ltype = lookahead.type
            t = actions.get((s,ltype),None)

            if debug > 1:
                print 'action', t
            if t is not None:
                if t > 0:
                    # shift a symbol on the stack
                    if ltype == '$end':
                        # Error, end of input
                        sys.stderr.write("yacc: Parse error. EOF\n")
                        return
                    statestack.append(t)
                    if debug > 1:
                        sys.stderr.write("%-60s shift state %s\n" % (errorlead, t))
                    symstack.append(lookahead)
                    lookahead = None

                    # Decrease error count on successful shift
                    if self.errorcount > 0:
                        self.errorcount -= 1
                        
                    continue
                
                if t < 0:
                    # reduce a symbol on the stack, emit a production
                    p = prod[-t]
                    pname = p.name
                    plen  = p.len

                    # Get production function
                    sym = YaccSymbol()
                    sym.type = pname       # Production name
                    sym.value = None
                    if debug > 1:
                        sys.stderr.write("%-60s reduce %d\n" % (errorlead, -t))

                    if plen:
                        targ = symstack[-plen-1:]
                        targ[0] = sym
                        try:
                            sym.lineno = targ[1].lineno
                            sym.endlineno = getattr(targ[-1],"endlineno",targ[-1].lineno)
                            sym.lexpos = targ[1].lexpos
                            sym.endlexpos = getattr(targ[-1],"endlexpos",targ[-1].lexpos)
                        except AttributeError:
                            sym.lineno = 0
                        del symstack[-plen:]
                        del statestack[-plen:]
                    else:
                        sym.lineno = 0
                        targ = [ sym ]
                    pslice.slice = targ
                    pslice.pbstack = []
                    # Call the grammar rule with our special slice object
                    p.func(pslice)

                    # If there was a pushback, put that on the stack
                    if pslice.pbstack:
                        lookaheadstack.append(lookahead)
                        for _t in pslice.pbstack:
                            lookaheadstack.append(_t)
                        lookahead = None

                    symstack.append(sym)
                    statestack.append(goto[statestack[-1],pname])
                    continue

                if t == 0:
                    n = symstack[-1]
                    return getattr(n,"value",None)
                    sys.stderr.write(errorlead, "\n")

            if t == None:
                if debug:
                    sys.stderr.write(errorlead + "\n")
                # We have some kind of parsing error here.  To handle
                # this, we are going to push the current token onto
                # the tokenstack and replace it with an 'error' token.
                # If there are any synchronization rules, they may
                # catch it.
                #
                # In addition to pushing the error token, we call call
                # the user defined p_error() function if this is the
                # first syntax error.  This function is only called if
                # errorcount == 0.
                if not self.errorcount:
                    self.errorcount = error_count
                    errtoken = lookahead
                    if errtoken.type == '$end':
                        errtoken = None               # End of file!
                    if self.errorfunc:
                        global errok,token,restart
                        errok = self.errok        # Set some special functions available in error recovery
                        token = get_token
                        restart = self.restart
                        tok = self.errorfunc(errtoken)
                        del errok, token, restart   # Delete special functions
                        
                        if not self.errorcount:
                            # User must have done some kind of panic
                            # mode recovery on their own.  The
                            # returned token is the next lookahead
                            lookahead = tok
                            errtoken = None
                            continue
                    else:
                        if errtoken:
                            if hasattr(errtoken,"lineno"): lineno = lookahead.lineno
                            else: lineno = 0
                            if lineno:
                                sys.stderr.write("yacc: Syntax error at line %d, token=%s\n" % (lineno, errtoken.type))
                            else:
                                sys.stderr.write("yacc: Syntax error, token=%s" % errtoken.type)
                        else:
                            sys.stderr.write("yacc: Parse error in input. EOF\n")
                            return

                else:
                    self.errorcount = error_count
                
                # case 1:  the statestack only has 1 entry on it.  If we're in this state, the
                # entire parse has been rolled back and we're completely hosed.   The token is
                # discarded and we just keep going.

                if len(statestack) <= 1 and lookahead.type != '$end':
                    lookahead = None
                    errtoken = None
                    # Nuke the pushback stack
                    del lookaheadstack[:]
                    continue

                # case 2: the statestack has a couple of entries on it, but we're
                # at the end of the file. nuke the top entry and generate an error token

                # Start nuking entries on the stack
                if lookahead.type == '$end':
                    # Whoa. We're really hosed here. Bail out
                    return 

                if lookahead.type != 'error':
                    sym = symstack[-1]
                    if sym.type == 'error':
                        # Hmmm. Error is on top of stack, we'll just nuke input
                        # symbol and continue
                        lookahead = None
                        continue
                    t = YaccSymbol()
                    t.type = 'error'
                    if hasattr(lookahead,"lineno"):
                        t.lineno = lookahead.lineno
                    t.value = lookahead
                    lookaheadstack.append(lookahead)
                    lookahead = t
                else:
                    symstack.pop()
                    statestack.pop()

                continue

            # Call an error function here
            raise RuntimeError, "yacc: internal parser error!!!\n"

# -----------------------------------------------------------------------------
#                          === Parser Construction ===
#
# The following functions and variables are used to implement the yacc() function
# itself.   This is pretty hairy stuff involving lots of error checking,
# construction of LR items, kernels, and so forth.   Although a lot of
# this work is done using global variables, the resulting Parser object
# is completely self contained--meaning that it is safe to repeatedly
# call yacc() with different grammars in the same application.
# -----------------------------------------------------------------------------
        
# -----------------------------------------------------------------------------
# validate_file()
#
# This function checks to see if there are duplicated p_rulename() functions
# in the parser module file.  Without this function, it is really easy for
# users to make mistakes by cutting and pasting code fragments (and it's a real
# bugger to try and figure out why the resulting parser doesn't work).  Therefore,
# we just do a little regular expression pattern matching of def statements
# to try and detect duplicates.
# -----------------------------------------------------------------------------

def validate_file(filename):
    base,ext = os.path.splitext(filename)
    if ext != '.py': return 1          # No idea. Assume it's okay.

    try:
        f = open(filename)
        lines = f.readlines()
        f.close()
    except IOError:
        return 1                       # Oh well

    # Match def p_funcname(
    fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
    counthash = { }
    linen = 1
    noerror = 1
    for l in lines:
        m = fre.match(l)
        if m:
            name = m.group(1)
            prev = counthash.get(name)
            if not prev:
                counthash[name] = linen
            else:
                sys.stderr.write("%s:%d: Function %s redefined. Previously defined on line %d\n" % (filename,linen,name,prev))
                noerror = 0
        linen += 1
    return noerror

# This function looks for functions that might be grammar rules, but which don't have the proper p_suffix.
def validate_dict(d):
    for n,v in d.items(): 
        if n[0:2] == 'p_' and type(v) in (types.FunctionType, types.MethodType): continue
        if n[0:2] == 't_': continue

        if n[0:2] == 'p_':
            sys.stderr.write("yacc: Warning. '%s' not defined as a function\n" % n)
        if 1 and isinstance(v,types.FunctionType) and v.func_code.co_argcount == 1:
            try:
                doc = v.__doc__.split(" ")
                if doc[1] == ':':
                    sys.stderr.write("%s:%d: Warning. Possible grammar rule '%s' defined without p_ prefix.\n" % (v.func_code.co_filename, v.func_code.co_firstlineno,n))
            except StandardError:
                pass

# -----------------------------------------------------------------------------
#                           === GRAMMAR FUNCTIONS ===
#
# The following global variables and functions are used to store, manipulate,
# and verify the grammar rules specified by the user.
# -----------------------------------------------------------------------------

# Initialize all of the global variables used during grammar construction
def initialize_vars():
    global Productions, Prodnames, Prodmap, Terminals 
    global Nonterminals, First, Follow, Precedence, LRitems
    global Errorfunc, Signature, Requires

    Productions  = [None]  # A list of all of the productions.  The first
                           # entry is always reserved for the purpose of
                           # building an augmented grammar
                        
    Prodnames    = { }     # A dictionary mapping the names of nonterminals to a list of all
                           # productions of that nonterminal.
                        
    Prodmap      = { }     # A dictionary that is only used to detect duplicate
                           # productions.

    Terminals    = { }     # A dictionary mapping the names of terminal symbols to a
                           # list of the rules where they are used.

    Nonterminals = { }     # A dictionary mapping names of nonterminals to a list
                           # of rule numbers where they are used.

    First        = { }     # A dictionary of precomputed FIRST(x) symbols
    
    Follow       = { }     # A dictionary of precomputed FOLLOW(x) symbols

    Precedence   = { }     # Precedence rules for each terminal. Contains tuples of the
                           # form ('right',level) or ('nonassoc', level) or ('left',level)

    LRitems      = [ ]     # A list of all LR items for the grammar.  These are the
                           # productions with the "dot" like E -> E . PLUS E

    Errorfunc    = None    # User defined error handler

    Signature    = hashlib.sha256()   # Digital signature of the grammar rules, precedence
                               # and other information.  Used to determined when a
                               # parsing table needs to be regenerated.

    Requires     = { }     # Requires list

    # File objects used when creating the parser.out debugging file
    global _vf, _vfc
    _vf           = cStringIO.StringIO()
    _vfc          = cStringIO.StringIO()

# -----------------------------------------------------------------------------
# class Production:
#
# This class stores the raw information about a single production or grammar rule.
# It has a few required attributes:
#
#       name     - Name of the production (nonterminal)
#       prod     - A list of symbols making up its production
#       number   - Production number.
#
# In addition, a few additional attributes are used to help with debugging or
# optimization of table generation.
#
#       file     - File where production action is defined.
#       lineno   - Line number where action is defined
#       func     - Action function
#       prec     - Precedence level
#       lr_next  - Next LR item. Example, if we are ' E -> E . PLUS E'
#                  then lr_next refers to 'E -> E PLUS . E'   
#       lr_index - LR item index (location of the ".") in the prod list.
#       lookaheads - LALR lookahead symbols for this item
#       len      - Length of the production (number of symbols on right hand side)
# -----------------------------------------------------------------------------

class Production:
    def __init__(self,**kw):
        for k,v in kw.items():
            setattr(self,k,v)
        self.lr_index = -1
        self.lr0_added = 0    # Flag indicating whether or not added to LR0 closure
        self.lr1_added = 0    # Flag indicating whether or not added to LR1
        self.usyms = [ ]
        self.lookaheads = { }
        self.lk_added = { }
        self.setnumbers = [ ]
        
    def __str__(self):
        if self.prod:
            s = "%s -> %s" % (self.name," ".join(self.prod))
        else:
            s = "%s -> <empty>" % self.name
        return s

    def __repr__(self):
        return str(self)

    # Compute lr_items from the production
    def lr_item(self,n):
        if n > len(self.prod): return None
        p = Production()
        p.name = self.name
        p.prod = list(self.prod)
        p.number = self.number
        p.lr_index = n
        p.lookaheads = { }
        p.setnumbers = self.setnumbers
        p.prod.insert(n,".")
        p.prod = tuple(p.prod)
        p.len = len(p.prod)
        p.usyms = self.usyms

        # Precompute list of productions immediately following
        try:
            p.lrafter = Prodnames[p.prod[n+1]]
        except (IndexError,KeyError),e:
            p.lrafter = []
        try:
            p.lrbefore = p.prod[n-1]
        except IndexError:
            p.lrbefore = None

        return p

class MiniProduction:
    pass

# regex matching identifiers
_is_identifier = re.compile(r'^[a-zA-Z0-9_-~]+$')

# -----------------------------------------------------------------------------
# add_production()
#
# Given an action function, this function assembles a production rule.
# The production rule is assumed to be found in the function's docstring.
# This rule has the general syntax:
#
#              name1 ::= production1
#                     |  production2
#                     |  production3
#                    ...
#                     |  productionn
#              name2 ::= production1
#                     |  production2
#                    ... 
# -----------------------------------------------------------------------------

def add_production(f,file,line,prodname,syms):
    
    if Terminals.has_key(prodname):
        sys.stderr.write("%s:%d: Illegal rule name '%s'. Already defined as a token.\n" % (file,line,prodname))
        return -1
    if prodname == 'error':
        sys.stderr.write("%s:%d: Illegal rule name '%s'. error is a reserved word.\n" % (file,line,prodname))
        return -1
                
    if not _is_identifier.match(prodname):
        sys.stderr.write("%s:%d: Illegal rule name '%s'\n" % (file,line,prodname))
        return -1

    for x in range(len(syms)):
        s = syms[x]
        if s[0] in "'\"":
             try:
                 c = eval(s)
                 if (len(c) > 1):
                      sys.stderr.write("%s:%d: Literal token %s in rule '%s' may only be a single character\n" % (file,line,s, prodname)) 
                      return -1
                 if not Terminals.has_key(c):
                      Terminals[c] = []
                 syms[x] = c
                 continue
             except SyntaxError:
                 pass
        if not _is_identifier.match(s) and s != '%prec':
            sys.stderr.write("%s:%d: Illegal name '%s' in rule '%s'\n" % (file,line,s, prodname))
            return -1

    # See if the rule is already in the rulemap
    map = "%s -> %s" % (prodname,syms)
    if Prodmap.has_key(map):
        m = Prodmap[map]
        sys.stderr.write("%s:%d: Duplicate rule %s.\n" % (file,line, m))
        sys.stderr.write("%s:%d: Previous definition at %s:%d\n" % (file,line, m.file, m.line))
        return -1

    p = Production()
    p.name = prodname
    p.prod = syms
    p.file = file
    p.line = line
    p.func = f
    p.number = len(Productions)

            
    Productions.append(p)
    Prodmap[map] = p
    if not Nonterminals.has_key(prodname):
        Nonterminals[prodname] = [ ]
    
    # Add all terminals to Terminals
    i = 0
    while i < len(p.prod):
        t = p.prod[i]
        if t == '%prec':
            try:
                precname = p.prod[i+1]
            except IndexError:
                sys.stderr.write("%s:%d: Syntax error. Nothing follows %%prec.\n" % (p.file,p.line))
                return -1

            prec = Precedence.get(precname,None)
            if not prec:
                sys.stderr.write("%s:%d: Nothing known about the precedence of '%s'\n" % (p.file,p.line,precname))
                return -1
            else:
                p.prec = prec
            del p.prod[i]
            del p.prod[i]
            continue

        if Terminals.has_key(t):
            Terminals[t].append(p.number)
            # Is a terminal.  We'll assign a precedence to p based on this
            if not hasattr(p,"prec"):
                p.prec = Precedence.get(t,('right',0))
        else:
            if not Nonterminals.has_key(t):
                Nonterminals[t] = [ ]
            Nonterminals[t].append(p.number)
        i += 1

    if not hasattr(p,"prec"):
        p.prec = ('right',0)
        
    # Set final length of productions
    p.len  = len(p.prod)
    p.prod = tuple(p.prod)

    # Calculate unique syms in the production
    p.usyms = [ ]
    for s in p.prod:
        if s not in p.usyms:
            p.usyms.append(s)
    
    # Add to the global productions list
    try:
        Prodnames[p.name].append(p)
    except KeyError:
        Prodnames[p.name] = [ p ]
    return 0

# Given a raw rule function, this function rips out its doc string
# and adds rules to the grammar

def add_function(f):
    line = f.func_code.co_firstlineno
    file = f.func_code.co_filename
    error = 0

    if isinstance(f,types.MethodType):
        reqdargs = 2
    else:
        reqdargs = 1
        
    if f.func_code.co_argcount > reqdargs:
        sys.stderr.write("%s:%d: Rule '%s' has too many arguments.\n" % (file,line,f.__name__))
        return -1

    if f.func_code.co_argcount < reqdargs:
        sys.stderr.write("%s:%d: Rule '%s' requires an argument.\n" % (file,line,f.__name__))
        return -1
          
    if f.__doc__:
        # Split the doc string into lines
        pstrings = f.__doc__.splitlines()
        lastp = None
        dline = line
        for ps in pstrings:
            dline += 1
            p = ps.split()
            if not p: continue
            try:
                if p[0] == '|':
                    # This is a continuation of a previous rule
                    if not lastp:
                        sys.stderr.write("%s:%d: Misplaced '|'.\n" % (file,dline))
                        return -1
                    prodname = lastp
                    if len(p) > 1:
                        syms = p[1:]
                    else:
                        syms = [ ]
                else:
                    prodname = p[0]
                    lastp = prodname
                    assign = p[1]
                    if len(p) > 2:
                        syms = p[2:]
                    else:
                        syms = [ ]
                    if assign != ':' and assign != '::=':
                        sys.stderr.write("%s:%d: Syntax error. Expected ':'\n" % (file,dline))
                        return -1
                         
 
                e = add_production(f,file,dline,prodname,syms)
                error += e

                
            except StandardError:
                sys.stderr.write("%s:%d: Syntax error in rule '%s'\n" % (file,dline,ps))
                error -= 1
    else:
        sys.stderr.write("%s:%d: No documentation string specified in function '%s'\n" % (file,line,f.__name__))
    return error


# Cycle checking code (Michael Dyck)

def compute_reachable():
    '''
    Find each symbol that can be reached from the start symbol.
    Print a warning for any nonterminals that can't be reached.
    (Unused terminals have already had their warning.)
    '''
    Reachable = { }
    for s in Terminals.keys() + Nonterminals.keys():
        Reachable[s] = 0

    mark_reachable_from( Productions[0].prod[0], Reachable )

    for s in Nonterminals.keys():
        if not Reachable[s]:
            sys.stderr.write("yacc: Symbol '%s' is unreachable.\n" % s)

def mark_reachable_from(s, Reachable):
    '''
    Mark all symbols that are reachable from symbol s.
    '''
    if Reachable[s]:
        # We've already reached symbol s.
        return
    Reachable[s] = 1
    for p in Prodnames.get(s,[]):
        for r in p.prod:
            mark_reachable_from(r, Reachable)

# -----------------------------------------------------------------------------
# compute_terminates()
#
# This function looks at the various parsing rules and tries to detect
# infinite recursion cycles (grammar rules where there is no possible way
# to derive a string of only terminals).
# -----------------------------------------------------------------------------
def compute_terminates():
    '''
    Raise an error for any symbols that don't terminate.
    '''
    Terminates = {}

    # Terminals:
    for t in Terminals.keys():
        Terminates[t] = 1

    Terminates['$end'] = 1

    # Nonterminals:

    # Initialize to false:
    for n in Nonterminals.keys():
        Terminates[n] = 0

    # Then propagate termination until no change:
    while 1:
        some_change = 0
        for (n,pl) in Prodnames.items():
            # Nonterminal n terminates iff any of its productions terminates.
            for p in pl:
                # Production p terminates iff all of its rhs symbols terminate.
                for s in p.prod:
                    if not Terminates[s]:
                        # The symbol s does not terminate,
                        # so production p does not terminate.
                        p_terminates = 0
                        break
                else:
                    # didn't break from the loop,
                    # so every symbol s terminates
                    # so production p terminates.
                    p_terminates = 1

                if p_terminates:
                    # symbol n terminates!
                    if not Terminates[n]:
                        Terminates[n] = 1
                        some_change = 1
                    # Don't need to consider any more productions for this n.
                    break

        if not some_change:
            break

    some_error = 0
    for (s,terminates) in Terminates.items():
        if not terminates:
            if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
                # s is used-but-not-defined, and we've already warned of that,
                # so it would be overkill to say that it's also non-terminating.
                pass
            else:
                sys.stderr.write("yacc: Infinite recursion detected for symbol '%s'.\n" % s)
                some_error = 1

    return some_error

# -----------------------------------------------------------------------------
# verify_productions()
#
# This function examines all of the supplied rules to see if they seem valid.
# -----------------------------------------------------------------------------
def verify_productions(cycle_check=1):
    error = 0
    for p in Productions:
        if not p: continue

        for s in p.prod:
            if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
                sys.stderr.write("%s:%d: Symbol '%s' used, but not defined as a token or a rule.\n" % (p.file,p.line,s))
                error = 1
                continue

    unused_tok = 0 
    # Now verify all of the tokens
    if yaccdebug:
        _vf.write("Unused terminals:\n\n")
    for s,v in Terminals.items():
        if s != 'error' and not v:
            sys.stderr.write("yacc: Warning. Token '%s' defined, but not used.\n" % s)
            if yaccdebug: _vf.write("   %s\n"% s)
            unused_tok += 1

    # Print out all of the productions
    if yaccdebug:
        _vf.write("\nGrammar\n\n")
        for i in range(1,len(Productions)):
            _vf.write("Rule %-5d %s\n" % (i, Productions[i]))
        
    unused_prod = 0
    # Verify the use of all productions
    for s,v in Nonterminals.items():
        if not v:
            p = Prodnames[s][0]
            sys.stderr.write("%s:%d: Warning. Rule '%s' defined, but not used.\n" % (p.file,p.line, s))
            unused_prod += 1

    
    if unused_tok == 1:
        sys.stderr.write("yacc: Warning. There is 1 unused token.\n")
    if unused_tok > 1:
        sys.stderr.write("yacc: Warning. There are %d unused tokens.\n" % unused_tok)

    if unused_prod == 1:
        sys.stderr.write("yacc: Warning. There is 1 unused rule.\n")
    if unused_prod > 1:
        sys.stderr.write("yacc: Warning. There are %d unused rules.\n" % unused_prod)

    if yaccdebug:
        _vf.write("\nTerminals, with rules where they appear\n\n")
        ks = Terminals.keys()
        ks.sort()
        for k in ks:
            _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Terminals[k]])))
        _vf.write("\nNonterminals, with rules where they appear\n\n")
        ks = Nonterminals.keys()
        ks.sort()
        for k in ks:
            _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Nonterminals[k]])))

    if (cycle_check):
        compute_reachable()
        error += compute_terminates()
#        error += check_cycles()
    return error

# -----------------------------------------------------------------------------
# build_lritems()
#
# This function walks the list of productions and builds a complete set of the
# LR items.  The LR items are stored in two ways:  First, they are uniquely
# numbered and placed in the list _lritems.  Second, a linked list of LR items
# is built for each production.  For example:
#
#   E -> E PLUS E
#
# Creates the list
#
#  [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ] 
# -----------------------------------------------------------------------------

def build_lritems():
    for p in Productions:
        lastlri = p
        lri = p.lr_item(0)
        i = 0
        while 1:
            lri = p.lr_item(i)
            lastlri.lr_next = lri
            if not lri: break
            lri.lr_num = len(LRitems)
            LRitems.append(lri)
            lastlri = lri
            i += 1

    # In order for the rest of the parser generator to work, we need to
    # guarantee that no more lritems are generated.  Therefore, we nuke
    # the p.lr_item method.  (Only used in debugging)
    # Production.lr_item = None

# -----------------------------------------------------------------------------
# add_precedence()
#
# Given a list of precedence rules, add to the precedence table.
# -----------------------------------------------------------------------------

def add_precedence(plist):
    plevel = 0
    error = 0
    for p in plist:
        plevel += 1
        try:
            prec = p[0]
            terms = p[1:]
            if prec != 'left' and prec != 'right' and prec != 'nonassoc':
                sys.stderr.write("yacc: Invalid precedence '%s'\n" % prec)
                return -1
            for t in terms:
                if Precedence.has_key(t):
                    sys.stderr.write("yacc: Precedence already specified for terminal '%s'\n" % t)
                    error += 1
                    continue
                Precedence[t] = (prec,plevel)
        except:
            sys.stderr.write("yacc: Invalid precedence table.\n")
            error += 1

    return error

# -----------------------------------------------------------------------------
# augment_grammar()
#
# Compute the augmented grammar.  This is just a rule S' -> start where start
# is the starting symbol.
# -----------------------------------------------------------------------------

def augment_grammar(start=None):
    if not start:
        start = Productions[1].name
    Productions[0] = Production(name="S'",prod=[start],number=0,len=1,prec=('right',0),func=None)
    Productions[0].usyms = [ start ]
    Nonterminals[start].append(0)


# -------------------------------------------------------------------------
# first()
#
# Compute the value of FIRST1(beta) where beta is a tuple of symbols.
#
# During execution of compute_first1, the result may be incomplete.
# Afterward (e.g., when called from compute_follow()), it will be complete.
# -------------------------------------------------------------------------
def first(beta):

    # We are computing First(x1,x2,x3,...,xn)
    result = [ ]
    for x in beta:
        x_produces_empty = 0

        # Add all the non-<empty> symbols of First[x] to the result.
        for f in First[x]:
            if f == '<empty>':
                x_produces_empty = 1
            else:
                if f not in result: result.append(f)

        if x_produces_empty:
            # We have to consider the next x in beta,
            # i.e. stay in the loop.
            pass
        else:
            # We don't have to consider any further symbols in beta.
            break
    else:
        # There was no 'break' from the loop,
        # so x_produces_empty was true for all x in beta,
        # so beta produces empty as well.
        result.append('<empty>')

    return result


# FOLLOW(x)
# Given a non-terminal.  This function computes the set of all symbols
# that might follow it.  Dragon book, p. 189.

def compute_follow(start=None):
    # Add '$end' to the follow list of the start symbol
    for k in Nonterminals.keys():
        Follow[k] = [ ]

    if not start:
        start = Productions[1].name
        
    Follow[start] = [ '$end' ]
        
    while 1:
        didadd = 0
        for p in Productions[1:]:
            # Here is the production set
            for i in range(len(p.prod)):
                B = p.prod[i]
                if Nonterminals.has_key(B):
                    # Okay. We got a non-terminal in a production
                    fst = first(p.prod[i+1:])
                    hasempty = 0
                    for f in fst:
                        if f != '<empty>' and f not in Follow[B]:
                            Follow[B].append(f)
                            didadd = 1
                        if f == '<empty>':
                            hasempty = 1
                    if hasempty or i == (len(p.prod)-1):
                        # Add elements of follow(a) to follow(b)
                        for f in Follow[p.name]:
                            if f not in Follow[B]:
                                Follow[B].append(f)
                                didadd = 1
        if not didadd: break

    if 0 and yaccdebug:
        _vf.write('\nFollow:\n')
        for k in Nonterminals.keys():
            _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Follow[k]])))

# -------------------------------------------------------------------------
# compute_first1()
#
# Compute the value of FIRST1(X) for all symbols
# -------------------------------------------------------------------------
def compute_first1():

    # Terminals:
    for t in Terminals.keys():
        First[t] = [t]

    First['$end'] = ['$end']
    First['#'] = ['#'] # what's this for?

    # Nonterminals:

    # Initialize to the empty set:
    for n in Nonterminals.keys():
        First[n] = []

    # Then propagate symbols until no change:
    while 1:
        some_change = 0
        for n in Nonterminals.keys():
            for p in Prodnames[n]:
                for f in first(p.prod):
                    if f not in First[n]:
                        First[n].append( f )
                        some_change = 1
        if not some_change:
            break

    if 0 and yaccdebug:
        _vf.write('\nFirst:\n')
        for k in Nonterminals.keys():
            _vf.write("%-20s : %s\n" %
                (k, " ".join([str(s) for s in First[k]])))

# -----------------------------------------------------------------------------
#                           === SLR Generation ===
#
# The following functions are used to construct SLR (Simple LR) parsing tables
# as described on p.221-229 of the dragon book.
# -----------------------------------------------------------------------------

# Global variables for the LR parsing engine
def lr_init_vars():
    global _lr_action, _lr_goto, _lr_method
    global _lr_goto_cache, _lr0_cidhash
    
    _lr_action       = { }        # Action table
    _lr_goto         = { }        # Goto table
    _lr_method       = "Unknown"  # LR method used
    _lr_goto_cache   = { }
    _lr0_cidhash     = { }


# Compute the LR(0) closure operation on I, where I is a set of LR(0) items.
# prodlist is a list of productions.

_add_count = 0       # Counter used to detect cycles

def lr0_closure(I):
    global _add_count
    
    _add_count += 1
    prodlist = Productions
    
    # Add everything in I to J        
    J = I[:]
    didadd = 1
    while didadd:
        didadd = 0
        for j in J:
            for x in j.lrafter:
                if x.lr0_added == _add_count: continue
                # Add B --> .G to J
                J.append(x.lr_next)
                x.lr0_added = _add_count
                didadd = 1
               
    return J

# Compute the LR(0) goto function goto(I,X) where I is a set
# of LR(0) items and X is a grammar symbol.   This function is written
# in a way that guarantees uniqueness of the generated goto sets
# (i.e. the same goto set will never be returned as two different Python
# objects).  With uniqueness, we can later do fast set comparisons using
# id(obj) instead of element-wise comparison.

def lr0_goto(I,x):
    # First we look for a previously cached entry
    g = _lr_goto_cache.get((id(I),x),None)
    if g: return g

    # Now we generate the goto set in a way that guarantees uniqueness
    # of the result
    
    s = _lr_goto_cache.get(x,None)
    if not s:
        s = { }
        _lr_goto_cache[x] = s

    gs = [ ]
    for p in I:
        n = p.lr_next
        if n and n.lrbefore == x:
            s1 = s.get(id(n),None)
            if not s1:
                s1 = { }
                s[id(n)] = s1
            gs.append(n)
            s = s1
    g = s.get('$end',None)
    if not g:
        if gs:
            g = lr0_closure(gs)
            s['$end'] = g
        else:
            s['$end'] = gs
    _lr_goto_cache[(id(I),x)] = g
    return g

_lr0_cidhash = { }

# Compute the LR(0) sets of item function
def lr0_items():
    
    C = [ lr0_closure([Productions[0].lr_next]) ]
    i = 0
    for I in C:
        _lr0_cidhash[id(I)] = i
        i += 1

    # Loop over the items in C and each grammar symbols
    i = 0
    while i < len(C):
        I = C[i]
        i += 1

        # Collect all of the symbols that could possibly be in the goto(I,X) sets
        asyms = { }
        for ii in I:
            for s in ii.usyms:
                asyms[s] = None

        for x in asyms.keys():
            g = lr0_goto(I,x)
            if not g:  continue
            if _lr0_cidhash.has_key(id(g)): continue
            _lr0_cidhash[id(g)] = len(C)            
            C.append(g)
            
    return C

# -----------------------------------------------------------------------------
#                       ==== LALR(1) Parsing ====
#
# LALR(1) parsing is almost exactly the same as SLR except that instead of
# relying upon Follow() sets when performing reductions, a more selective
# lookahead set that incorporates the state of the LR(0) machine is utilized.
# Thus, we mainly just have to focus on calculating the lookahead sets.
#
# The method used here is due to DeRemer and Pennelo (1982).
#
# DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1)
#     Lookahead Sets", ACM Transactions on Programming Languages and Systems,
#     Vol. 4, No. 4, Oct. 1982, pp. 615-649
#
# Further details can also be found in:
#
#  J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing",
#      McGraw-Hill Book Company, (1985).
#
# Note:  This implementation is a complete replacement of the LALR(1) 
#        implementation in PLY-1.x releases.   That version was based on
#        a less efficient algorithm and it had bugs in its implementation.
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# compute_nullable_nonterminals()
#
# Creates a dictionary containing all of the non-terminals that might produce
# an empty production.   
# -----------------------------------------------------------------------------

def compute_nullable_nonterminals():
    nullable = {}
    num_nullable = 0
    while 1:
       for p in Productions[1:]:
           if p.len == 0:
                nullable[p.name] = 1
                continue
           for t in p.prod:
                if not nullable.has_key(t): break
           else:
                nullable[p.name] = 1
       if len(nullable) == num_nullable: break
       num_nullable = len(nullable)
    return nullable

# -----------------------------------------------------------------------------
# find_nonterminal_trans(C)
#
# Given a set of LR(0) items, this functions finds all of the non-terminal
# transitions.    These are transitions in which a dot appears immediately before
# a non-terminal.   Returns a list of tuples of the form (state,N) where state
# is the state number and N is the nonterminal symbol.
#
# The input C is the set of LR(0) items.
# -----------------------------------------------------------------------------

def find_nonterminal_transitions(C):
     trans = []
     for state in range(len(C)):
         for p in C[state]:
             if p.lr_index < p.len - 1:
                  t = (state,p.prod[p.lr_index+1])
                  if Nonterminals.has_key(t[1]):
                        if t not in trans: trans.append(t)
         state = state + 1
     return trans

# -----------------------------------------------------------------------------
# dr_relation()
#
# Computes the DR(p,A) relationships for non-terminal transitions.  The input
# is a tuple (state,N) where state is a number and N is a nonterminal symbol.
#
# Returns a list of terminals.
# -----------------------------------------------------------------------------

def dr_relation(C,trans,nullable):
    dr_set = { }
    state,N = trans
    terms = []

    g = lr0_goto(C[state],N)
    for p in g:
       if p.lr_index < p.len - 1:
           a = p.prod[p.lr_index+1]
           if Terminals.has_key(a):
               if a not in terms: terms.append(a)

    # This extra bit is to handle the start state
    if state == 0 and N == Productions[0].prod[0]:
       terms.append('$end')
 
    return terms

# -----------------------------------------------------------------------------
# reads_relation()
#
# Computes the READS() relation (p,A) READS (t,C).
# -----------------------------------------------------------------------------

def reads_relation(C, trans, empty):
    # Look for empty transitions
    rel = []
    state, N = trans

    g = lr0_goto(C[state],N)
    j = _lr0_cidhash.get(id(g),-1)
    for p in g:
        if p.lr_index < p.len - 1:
             a = p.prod[p.lr_index + 1]
             if empty.has_key(a):
                  rel.append((j,a))

    return rel

# -----------------------------------------------------------------------------
# compute_lookback_includes()
#
# Determines the lookback and includes relations
#
# LOOKBACK:
# 
# This relation is determined by running the LR(0) state machine forward.
# For example, starting with a production "N : . A B C", we run it forward
# to obtain "N : A B C ."   We then build a relationship between this final
# state and the starting state.   These relationships are stored in a dictionary
# lookdict.   
#
# INCLUDES:
#
# Computes the INCLUDE() relation (p,A) INCLUDES (p',B).   
#
# This relation is used to determine non-terminal transitions that occur
# inside of other non-terminal transition states.   (p,A) INCLUDES (p', B)
# if the following holds:
#
#       B -> LAT, where T -> epsilon and p' -L-> p 
#
# L is essentially a prefix (which may be empty), T is a suffix that must be
# able to derive an empty string.  State p' must lead to state p with the string L.
# 
# -----------------------------------------------------------------------------

def compute_lookback_includes(C,trans,nullable):
    
    lookdict = {}          # Dictionary of lookback relations
    includedict = {}       # Dictionary of include relations

    # Make a dictionary of non-terminal transitions
    dtrans = {}
    for t in trans:
        dtrans[t] = 1
    
    # Loop over all transitions and compute lookbacks and includes
    for state,N in trans:
        lookb = []
        includes = []
        for p in C[state]:
            if p.name != N: continue
        
            # Okay, we have a name match.  We now follow the production all the way
            # through the state machine until we get the . on the right hand side

            lr_index = p.lr_index
            j = state
            while lr_index < p.len - 1:
                 lr_index = lr_index + 1
                 t = p.prod[lr_index]

                 # Check to see if this symbol and state are a non-terminal transition
                 if dtrans.has_key((j,t)):
                       # Yes.  Okay, there is some chance that this is an includes relation
                       # the only way to know for certain is whether the rest of the 
                       # production derives empty

                       li = lr_index + 1
                       while li < p.len:
                            if Terminals.has_key(p.prod[li]): break      # No forget it
                            if not nullable.has_key(p.prod[li]): break
                            li = li + 1
                       else:
                            # Appears to be a relation between (j,t) and (state,N)
                            includes.append((j,t))

                 g = lr0_goto(C[j],t)               # Go to next set             
                 j = _lr0_cidhash.get(id(g),-1)     # Go to next state
             
            # When we get here, j is the final state, now we have to locate the production
            for r in C[j]:
                 if r.name != p.name: continue
                 if r.len != p.len:   continue
                 i = 0
                 # This look is comparing a production ". A B C" with "A B C ."
                 while i < r.lr_index:
                      if r.prod[i] != p.prod[i+1]: break
                      i = i + 1
                 else:
                      lookb.append((j,r))
        for i in includes:
             if not includedict.has_key(i): includedict[i] = []
             includedict[i].append((state,N))
        lookdict[(state,N)] = lookb

    return lookdict,includedict

# -----------------------------------------------------------------------------
# digraph()
# traverse()
#
# The following two functions are used to compute set valued functions
# of the form:
#
#     F(x) = F'(x) U U{F(y) | x R y}
#
# This is used to compute the values of Read() sets as well as FOLLOW sets
# in LALR(1) generation.
#
# Inputs:  X    - An input set
#          R    - A relation
#          FP   - Set-valued function
# ------------------------------------------------------------------------------

def digraph(X,R,FP):
    N = { }
    for x in X:
       N[x] = 0
    stack = []
    F = { }
    for x in X:
        if N[x] == 0: traverse(x,N,stack,F,X,R,FP)
    return F

def traverse(x,N,stack,F,X,R,FP):
    stack.append(x)
    d = len(stack)
    N[x] = d
    F[x] = FP(x)             # F(X) <- F'(x)
    
    rel = R(x)               # Get y's related to x
    for y in rel:
        if N[y] == 0:
             traverse(y,N,stack,F,X,R,FP)
        N[x] = min(N[x],N[y])
        for a in F.get(y,[]):
            if a not in F[x]: F[x].append(a)
    if N[x] == d:
       N[stack[-1]] = sys.maxint
       F[stack[-1]] = F[x]
       element = stack.pop()
       while element != x:
           N[stack[-1]] = sys.maxint
           F[stack[-1]] = F[x]
           element = stack.pop()

# -----------------------------------------------------------------------------
# compute_read_sets()
#
# Given a set of LR(0) items, this function computes the read sets.
#
# Inputs:  C        =  Set of LR(0) items
#          ntrans   = Set of nonterminal transitions
#          nullable = Set of empty transitions
#
# Returns a set containing the read sets
# -----------------------------------------------------------------------------

def compute_read_sets(C, ntrans, nullable):
    FP = lambda x: dr_relation(C,x,nullable)
    R =  lambda x: reads_relation(C,x,nullable)
    F = digraph(ntrans,R,FP)
    return F

# -----------------------------------------------------------------------------
# compute_follow_sets()
#
# Given a set of LR(0) items, a set of non-terminal transitions, a readset, 
# and an include set, this function computes the follow sets
#
# Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)}
#
# Inputs:    
#            ntrans     = Set of nonterminal transitions
#            readsets   = Readset (previously computed)
#            inclsets   = Include sets (previously computed)
#
# Returns a set containing the follow sets      
# -----------------------------------------------------------------------------

def compute_follow_sets(ntrans,readsets,inclsets):
     FP = lambda x: readsets[x]
     R  = lambda x: inclsets.get(x,[])
     F = digraph(ntrans,R,FP)
     return F

# -----------------------------------------------------------------------------
# add_lookaheads()
#
# Attaches the lookahead symbols to grammar rules. 
#
# Inputs:    lookbacks         -  Set of lookback relations
#            followset         -  Computed follow set
#
# This function directly attaches the lookaheads to productions contained
# in the lookbacks set
# -----------------------------------------------------------------------------

def add_lookaheads(lookbacks,followset):
    for trans,lb in lookbacks.items():
        # Loop over productions in lookback
        for state,p in lb:
             if not p.lookaheads.has_key(state):
                  p.lookaheads[state] = []
             f = followset.get(trans,[])
             for a in f:
                  if a not in p.lookaheads[state]: p.lookaheads[state].append(a)

# -----------------------------------------------------------------------------
# add_lalr_lookaheads()
#
# This function does all of the work of adding lookahead information for use
# with LALR parsing
# -----------------------------------------------------------------------------

def add_lalr_lookaheads(C):
    # Determine all of the nullable nonterminals
    nullable = compute_nullable_nonterminals()

    # Find all non-terminal transitions
    trans = find_nonterminal_transitions(C)

    # Compute read sets
    readsets = compute_read_sets(C,trans,nullable)

    # Compute lookback/includes relations
    lookd, included = compute_lookback_includes(C,trans,nullable)

    # Compute LALR FOLLOW sets
    followsets = compute_follow_sets(trans,readsets,included)
    
    # Add all of the lookaheads
    add_lookaheads(lookd,followsets)

# -----------------------------------------------------------------------------
# lr_parse_table()
#
# This function constructs the parse tables for SLR or LALR
# -----------------------------------------------------------------------------
def lr_parse_table(method):
    global _lr_method
    goto = _lr_goto           # Goto array
    action = _lr_action       # Action array
    actionp = { }             # Action production array (temporary)

    _lr_method = method
    
    n_srconflict = 0
    n_rrconflict = 0

    if yaccdebug:
        sys.stderr.write("yacc: Generating %s parsing table...\n" % method)        
        _vf.write("\n\nParsing method: %s\n\n" % method)
        
    # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
    # This determines the number of states
    
    C = lr0_items()

    if method == 'LALR':
        add_lalr_lookaheads(C)

    # Build the parser table, state by state
    st = 0
    for I in C:
        # Loop over each production in I
        actlist = [ ]              # List of actions
        
        if yaccdebug:
            _vf.write("\nstate %d\n\n" % st)
            for p in I:
                _vf.write("    (%d) %s\n" % (p.number, str(p)))
            _vf.write("\n")

        for p in I:
            try:
                if p.prod[-1] == ".":
                    if p.name == "S'":
                        # Start symbol. Accept!
                        action[st,"$end"] = 0
                        actionp[st,"$end"] = p
                    else:
                        # We are at the end of a production.  Reduce!
                        if method == 'LALR':
                            laheads = p.lookaheads[st]
                        else:
                            laheads = Follow[p.name]
                        for a in laheads:
                            actlist.append((a,p,"reduce using rule %d (%s)" % (p.number,p)))
                            r = action.get((st,a),None)
                            if r is not None:
                                # Whoa. Have a shift/reduce or reduce/reduce conflict
                                if r > 0:
                                    # Need to decide on shift or reduce here
                                    # By default we favor shifting. Need to add
                                    # some precedence rules here.
                                    sprec,slevel = Productions[actionp[st,a].number].prec                                    
                                    rprec,rlevel = Precedence.get(a,('right',0))
                                    if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
                                        # We really need to reduce here.  
                                        action[st,a] = -p.number
                                        actionp[st,a] = p
                                        if not slevel and not rlevel:
                                            _vfc.write("shift/reduce conflict in state %d resolved as reduce.\n" % st)
                                            _vf.write("  ! shift/reduce conflict for %s resolved as reduce.\n" % a)
                                            n_srconflict += 1
                                    elif (slevel == rlevel) and (rprec == 'nonassoc'):
                                        action[st,a] = None
                                    else:
                                        # Hmmm. Guess we'll keep the shift
                                        if not rlevel:
                                            _vfc.write("shift/reduce conflict in state %d resolved as shift.\n" % st)
                                            _vf.write("  ! shift/reduce conflict for %s resolved as shift.\n" % a)
                                            n_srconflict +=1                                    
                                elif r < 0:
                                    # Reduce/reduce conflict.   In this case, we favor the rule
                                    # that was defined first in the grammar file
                                    oldp = Productions[-r]
                                    pp = Productions[p.number]
                                    if oldp.line > pp.line:
                                        action[st,a] = -p.number
                                        actionp[st,a] = p
                                    # sys.stderr.write("Reduce/reduce conflict in state %d\n" % st)
                                    n_rrconflict += 1
                                    _vfc.write("reduce/reduce conflict in state %d resolved using rule %d (%s).\n" % (st, actionp[st,a].number, actionp[st,a]))
                                    _vf.write("  ! reduce/reduce conflict for %s resolved using rule %d (%s).\n" % (a,actionp[st,a].number, actionp[st,a]))
                                else:
                                    sys.stderr.write("Unknown conflict in state %d\n" % st)
                            else:
                                action[st,a] = -p.number
                                actionp[st,a] = p
                else:
                    i = p.lr_index
                    a = p.prod[i+1]       # Get symbol right after the "."
                    if Terminals.has_key(a):
                        g = lr0_goto(I,a)
                        j = _lr0_cidhash.get(id(g),-1)
                        if j >= 0:
                            # We are in a shift state
                            actlist.append((a,p,"shift and go to state %d" % j))
                            r = action.get((st,a),None)
                            if r is not None:
                                # Whoa have a shift/reduce or shift/shift conflict
                                if r > 0:
                                    if r != j:
                                        sys.stderr.write("Shift/shift conflict in state %d\n" % st)
                                elif r < 0:
                                    # Do a precedence check.
                                    #   -  if precedence of reduce rule is higher, we reduce.
                                    #   -  if precedence of reduce is same and left assoc, we reduce.
                                    #   -  otherwise we shift
                                    rprec,rlevel = Productions[actionp[st,a].number].prec
                                    sprec,slevel = Precedence.get(a,('right',0))
                                    if (slevel > rlevel) or ((slevel == rlevel) and (rprec != 'left')):
                                        # We decide to shift here... highest precedence to shift
                                        action[st,a] = j
                                        actionp[st,a] = p
                                        if not rlevel:
                                            n_srconflict += 1
                                            _vfc.write("shift/reduce conflict in state %d resolved as shift.\n" % st)
                                            _vf.write("  ! shift/reduce conflict for %s resolved as shift.\n" % a)
                                    elif (slevel == rlevel) and (rprec == 'nonassoc'):
                                        action[st,a] = None
                                    else:                                            
                                        # Hmmm. Guess we'll keep the reduce
                                        if not slevel and not rlevel:
                                            n_srconflict +=1
                                            _vfc.write("shift/reduce conflict in state %d resolved as reduce.\n" % st)
                                            _vf.write("  ! shift/reduce conflict for %s resolved as reduce.\n" % a)
                                            
                                else:
                                    sys.stderr.write("Unknown conflict in state %d\n" % st)
                            else:
                                action[st,a] = j
                                actionp[st,a] = p
                                
            except StandardError,e:
                raise YaccError, "Hosed in lr_parse_table", e

        # Print the actions associated with each terminal
        if yaccdebug:
          _actprint = { }
          for a,p,m in actlist:
            if action.has_key((st,a)):
                if p is actionp[st,a]:
                    _vf.write("    %-15s %s\n" % (a,m))
                    _actprint[(a,m)] = 1
          _vf.write("\n")
          for a,p,m in actlist:
            if action.has_key((st,a)):
                if p is not actionp[st,a]:
                    if not _actprint.has_key((a,m)):
                        _vf.write("  ! %-15s [ %s ]\n" % (a,m))
                        _actprint[(a,m)] = 1
            
        # Construct the goto table for this state
        if yaccdebug:
            _vf.write("\n")
        nkeys = { }
        for ii in I:
            for s in ii.usyms:
                if Nonterminals.has_key(s):
                    nkeys[s] = None
        for n in nkeys.keys():
            g = lr0_goto(I,n)
            j = _lr0_cidhash.get(id(g),-1)            
            if j >= 0:
                goto[st,n] = j
                if yaccdebug:
                    _vf.write("    %-30s shift and go to state %d\n" % (n,j))

        st += 1

    if yaccdebug:
        if n_srconflict == 1:
            sys.stderr.write("yacc: %d shift/reduce conflict\n" % n_srconflict)
        if n_srconflict > 1:
            sys.stderr.write("yacc: %d shift/reduce conflicts\n" % n_srconflict)
        if n_rrconflict == 1:
            sys.stderr.write("yacc: %d reduce/reduce conflict\n" % n_rrconflict)
        if n_rrconflict > 1:
            sys.stderr.write("yacc: %d reduce/reduce conflicts\n" % n_rrconflict)

# -----------------------------------------------------------------------------
#                          ==== LR Utility functions ====
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# _lr_write_tables()
#
# This function writes the LR parsing tables to a file
# -----------------------------------------------------------------------------

def lr_write_tables(modulename=tab_module,outputdir=''):
    filename = os.path.join(outputdir,modulename) + ".py"
    try:
        f = open(filename,"w")

        f.write("""
# %s
# This file is automatically generated. Do not edit.

_lr_method = %s

_lr_signature = %s
""" % (filename, repr(_lr_method), repr(Signature.digest())))

        # Change smaller to 0 to go back to original tables
        smaller = 1
                
        # Factor out names to try and make smaller
        if smaller:
            items = { }
        
            for k,v in _lr_action.items():
                i = items.get(k[1])
                if not i:
                    i = ([],[])
                    items[k[1]] = i
                i[0].append(k[0])
                i[1].append(v)

            f.write("\n_lr_action_items = {")
            for k,v in items.items():
                f.write("%r:([" % k)
                for i in v[0]:
                    f.write("%r," % i)
                f.write("],[")
                for i in v[1]:
                    f.write("%r," % i)
                           
                f.write("]),")
            f.write("}\n")

            f.write("""
_lr_action = { }
for _k, _v in _lr_action_items.items():
   for _x,_y in zip(_v[0],_v[1]):
       _lr_action[(_x,_k)] = _y
del _lr_action_items
""")
            
        else:
            f.write("\n_lr_action = { ");
            for k,v in _lr_action.items():
                f.write("(%r,%r):%r," % (k[0],k[1],v))
            f.write("}\n");

        if smaller:
            # Factor out names to try and make smaller
            items = { }
        
            for k,v in _lr_goto.items():
                i = items.get(k[1])
                if not i:
                    i = ([],[])
                    items[k[1]] = i
                i[0].append(k[0])
                i[1].append(v)

            f.write("\n_lr_goto_items = {")
            for k,v in items.items():
                f.write("%r:([" % k)
                for i in v[0]:
                    f.write("%r," % i)
                f.write("],[")
                for i in v[1]:
                    f.write("%r," % i)
                           
                f.write("]),")
            f.write("}\n")

            f.write("""
_lr_goto = { }
for _k, _v in _lr_goto_items.items():
   for _x,_y in zip(_v[0],_v[1]):
       _lr_goto[(_x,_k)] = _y
del _lr_goto_items
""")
        else:
            f.write("\n_lr_goto = { ");
            for k,v in _lr_goto.items():
                f.write("(%r,%r):%r," % (k[0],k[1],v))                    
            f.write("}\n");

        # Write production table
        f.write("_lr_productions = [\n")
        for p in Productions:
            if p:
                if (p.func):
                    f.write("  (%r,%d,%r,%r,%d),\n" % (p.name, p.len, p.func.__name__,p.file,p.line))
                else:
                    f.write("  (%r,%d,None,None,None),\n" % (p.name, p.len))
            else:
                f.write("  None,\n")
        f.write("]\n")
        
        f.close()

    except IOError,e:
        print "Unable to create '%s'" % filename
        print e
        return

def lr_read_tables(module=tab_module,optimize=0):
    global _lr_action, _lr_goto, _lr_productions, _lr_method
    try:
        exec "import %s as parsetab" % module
        
        if (optimize) or (Signature.digest() == parsetab._lr_signature):
            _lr_action = parsetab._lr_action
            _lr_goto   = parsetab._lr_goto
            _lr_productions = parsetab._lr_productions
            _lr_method = parsetab._lr_method
            return 1
        else:
            return 0
        
    except (ImportError,AttributeError):
        return 0


# Available instance types.  This is used when parsers are defined by a class.
# it's a little funky because I want to preserve backwards compatibility
# with Python 2.0 where types.ObjectType is undefined.

try:
   _INSTANCETYPE = (types.InstanceType, types.ObjectType)
except AttributeError:
   _INSTANCETYPE = types.InstanceType

# -----------------------------------------------------------------------------
# yacc(module)
#
# Build the parser module
# -----------------------------------------------------------------------------

def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module, start=None, check_recursion=1, optimize=0,write_tables=1,debugfile=debug_file,outputdir=''):
    global yaccdebug
    yaccdebug = debug
    
    initialize_vars()
    files = { }
    error = 0


    # Add parsing method to signature
    Signature.update(method)
    
    # If a "module" parameter was supplied, extract its dictionary.
    # Note: a module may in fact be an instance as well.
    
    if module:
        # User supplied a module object.
        if isinstance(module, types.ModuleType):
            ldict = module.__dict__
        elif isinstance(module, _INSTANCETYPE):
            _items = [(k,getattr(module,k)) for k in dir(module)]
            ldict = { }
            for i in _items:
                ldict[i[0]] = i[1]
        else:
            raise ValueError,"Expected a module"
        
    else:
        # No module given.  We might be able to get information from the caller.
        # Throw an exception and unwind the traceback to get the globals
        
        try:
            raise RuntimeError
        except RuntimeError:
            e,b,t = sys.exc_info()
            f = t.tb_frame
            f = f.f_back           # Walk out to our calling function
            ldict = f.f_globals    # Grab its globals dictionary

    # Add starting symbol to signature
    if not start:
        start = ldict.get("start",None)
    if start:
        Signature.update(start)

    # If running in optimized mode.  We're going to

    if (optimize and lr_read_tables(tabmodule,1)):
        # Read parse table
        del Productions[:]
        for p in _lr_productions:
            if not p:
                Productions.append(None)
            else:
                m = MiniProduction()
                m.name = p[0]
                m.len  = p[1]
                m.file = p[3]
                m.line = p[4]
                if p[2]:
                    m.func = ldict[p[2]]
                Productions.append(m)
        
    else:
        # Get the tokens map
        if (module and isinstance(module,_INSTANCETYPE)):
            tokens = getattr(module,"tokens",None)
        else:
            tokens = ldict.get("tokens",None)
    
        if not tokens:
            raise YaccError,"module does not define a list 'tokens'"
        if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
            raise YaccError,"tokens must be a list or tuple."

        # Check to see if a requires dictionary is defined.
        requires = ldict.get("require",None)
        if requires:
            if not (isinstance(requires,types.DictType)):
                raise YaccError,"require must be a dictionary."

            for r,v in requires.items():
                try:
                    if not (isinstance(v,types.ListType)):
                        raise TypeError
                    v1 = [x.split(".") for x in v]
                    Requires[r] = v1
                except StandardError:
                    print "Invalid specification for rule '%s' in require. Expected a list of strings" % r            

        
        # Build the dictionary of terminals.  We a record a 0 in the
        # dictionary to track whether or not a terminal is actually
        # used in the grammar

        if 'error' in tokens:
            print "yacc: Illegal token 'error'.  Is a reserved word."
            raise YaccError,"Illegal token name"

        for n in tokens:
            if Terminals.has_key(n):
                print "yacc: Warning. Token '%s' multiply defined." % n
            Terminals[n] = [ ]

        Terminals['error'] = [ ]

        # Get the precedence map (if any)
        prec = ldict.get("precedence",None)
        if prec:
            if not (isinstance(prec,types.ListType) or isinstance(prec,types.TupleType)):
                raise YaccError,"precedence must be a list or tuple."
            add_precedence(prec)
            Signature.update(repr(prec))

        for n in tokens:
            if not Precedence.has_key(n):
                Precedence[n] = ('right',0)         # Default, right associative, 0 precedence

        # Look for error handler
        ef = ldict.get('p_error',None)
        if ef:
            if isinstance(ef,types.FunctionType):
                ismethod = 0
            elif isinstance(ef, types.MethodType):
                ismethod = 1
            else:
                raise YaccError,"'p_error' defined, but is not a function or method."                
            eline = ef.func_code.co_firstlineno
            efile = ef.func_code.co_filename
            files[efile] = None

            if (ef.func_code.co_argcount != 1+ismethod):
                raise YaccError,"%s:%d: p_error() requires 1 argument." % (efile,eline)
            global Errorfunc
            Errorfunc = ef
        else:
            print "yacc: Warning. no p_error() function is defined."
            
        # Get the list of built-in functions with p_ prefix
        symbols = [ldict[f] for f in ldict.keys()
               if (type(ldict[f]) in (types.FunctionType, types.MethodType) and ldict[f].__name__[:2] == 'p_'
                   and ldict[f].__name__ != 'p_error')]

        # Check for non-empty symbols
        if len(symbols) == 0:
            raise YaccError,"no rules of the form p_rulename are defined."
    
        # Sort the symbols by line number
        symbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))

        # Add all of the symbols to the grammar
        for f in symbols:
            if (add_function(f)) < 0:
                error += 1
            else:
                files[f.func_code.co_filename] = None

        # Make a signature of the docstrings
        for f in symbols:
            if f.__doc__:
                Signature.update(f.__doc__)
    
        lr_init_vars()

        if error:
            raise YaccError,"Unable to construct parser."

        if not lr_read_tables(tabmodule):

            # Validate files
            for filename in files.keys():
                if not validate_file(filename):
                    error = 1

            # Validate dictionary
            validate_dict(ldict)

            if start and not Prodnames.has_key(start):
                raise YaccError,"Bad starting symbol '%s'" % start
        
            augment_grammar(start)    
            error = verify_productions(cycle_check=check_recursion)
            otherfunc = [ldict[f] for f in ldict.keys()
               if (type(f) in (types.FunctionType,types.MethodType) and ldict[f].__name__[:2] != 'p_')]

            if error:
                raise YaccError,"Unable to construct parser."
            
            build_lritems()
            compute_first1()
            compute_follow(start)
        
            if method in ['SLR','LALR']:
                lr_parse_table(method)
            else:
                raise YaccError, "Unknown parsing method '%s'" % method

            if write_tables:
                lr_write_tables(tabmodule,outputdir)        
    
            if yaccdebug:
                try:
                    f = open(os.path.join(outputdir,debugfile),"w")
                    f.write(_vfc.getvalue())
                    f.write("\n\n")
                    f.write(_vf.getvalue())
                    f.close()
                except IOError,e:
                    print "yacc: can't create '%s'" % debugfile,e
        
    # Made it here.   Create a parser object and set up its internal state.
    # Set global parse() method to bound method of parser object.

    p = Parser("xyzzy")
    p.productions = Productions
    p.errorfunc = Errorfunc
    p.action = _lr_action
    p.goto   = _lr_goto
    p.method = _lr_method
    p.require = Requires

    global parse
    parse = p.parse

    global parser
    parser = p

    # Clean up all of the globals we created
    if (not optimize):
        yacc_cleanup()
    return p

# yacc_cleanup function.  Delete all of the global variables
# used during table construction

def yacc_cleanup():
    global _lr_action, _lr_goto, _lr_method, _lr_goto_cache
    del _lr_action, _lr_goto, _lr_method, _lr_goto_cache

    global Productions, Prodnames, Prodmap, Terminals 
    global Nonterminals, First, Follow, Precedence, LRitems
    global Errorfunc, Signature, Requires
    
    del Productions, Prodnames, Prodmap, Terminals
    del Nonterminals, First, Follow, Precedence, LRitems
    del Errorfunc, Signature, Requires
    
    global _vf, _vfc
    del _vf, _vfc
    
    
# Stub that raises an error if parsing is attempted without first calling yacc()
def parse(*args,**kwargs):
    raise YaccError, "yacc: No parser built with yacc()"

