<s> """<STR_LIT>""" <EOL> from . import token <EOL> class ParseError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , msg , type , value , context ) : <EOL> Exception . __init__ ( self , "<STR_LIT>" % <EOL> ( msg , type , value , context ) ) <EOL> self . msg = msg <EOL> self . type = type <EOL> self . value = value <EOL> self . context = context <EOL> class Parser ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , grammar , convert = None ) : <EOL> """<STR_LIT>""" <EOL> self . grammar = grammar <EOL> self . convert = convert or ( lambda grammar , node : node ) <EOL> def setup ( self , start = None ) : <EOL> """<STR_LIT>""" <EOL> if start is None : <EOL> start = self . grammar . start <EOL> newnode = ( start , None , None , [ ] ) <EOL> stackentry = ( self . grammar . dfas [ start ] , <NUM_LIT:0> , newnode ) <EOL> self . stack = [ stackentry ] <EOL> self . rootnode = None <EOL> self . used_names = set ( ) <EOL> def addtoken ( self , type , value , context ) : <EOL> """<STR_LIT>""" <EOL> ilabel = self . classify ( type , value , context ) <EOL> while True : <EOL> dfa , state , node = self . stack [ - <NUM_LIT:1> ] <EOL> states , first = dfa <EOL> arcs = states [ state ] <EOL> for i , newstate in arcs : <EOL> t , v = self . grammar . labels [ i ] <EOL> if ilabel == i : <EOL> assert t < <NUM_LIT> <EOL> self . shift ( type , value , newstate , context ) <EOL> state = newstate <EOL> while states [ state ] == [ ( <NUM_LIT:0> , state ) ] : <EOL> self . pop ( ) <EOL> if not self . stack : <EOL> return True <EOL> dfa , state , node = self . stack [ - <NUM_LIT:1> ] <EOL> states , first = dfa <EOL> return False <EOL> elif t >= <NUM_LIT> : <EOL> itsdfa = self . grammar . dfas [ t ] <EOL> itsstates , itsfirst = itsdfa <EOL> if ilabel in itsfirst : <EOL> self . push ( t , self . grammar . dfas [ t ] , newstate , context ) <EOL> break <EOL> else : <EOL> if ( <NUM_LIT:0> , state ) in arcs : <EOL> self . pop ( ) <EOL> if not self . stack : <EOL> raise ParseError ( "<STR_LIT>" , <EOL> type , value , context ) <EOL> else : <EOL> raise ParseError ( "<STR_LIT>" , type , value , context ) <EOL> def classify ( self , type , value , context ) : <EOL> """<STR_LIT>""" <EOL> if type == token . NAME : <EOL> self . used_names . add ( value ) <EOL> ilabel = self . grammar . keywords . get ( value ) <EOL> if ilabel is not None : <EOL> return ilabel <EOL> ilabel = self . grammar . tokens . get ( type ) <EOL> if ilabel is None : <EOL> raise ParseError ( "<STR_LIT>" , type , value , context ) <EOL> return ilabel <EOL> def shift ( self , type , value , newstate , context ) : <EOL> """<STR_LIT>""" <EOL> dfa , state , node = self . stack [ - <NUM_LIT:1> ] <EOL> newnode = ( type , value , context , None ) <EOL> newnode = self . convert ( self . grammar , newnode ) <EOL> if newnode is not None : <EOL> node [ - <NUM_LIT:1> ] . append ( newnode ) <EOL> self . stack [ - <NUM_LIT:1> ] = ( dfa , newstate , node ) <EOL> def push ( self , type , newdfa , newstate , context ) : <EOL> """<STR_LIT>""" <EOL> dfa , state , node = self . stack [ - <NUM_LIT:1> ] <EOL> newnode = ( type , None , context , [ ] ) <EOL> self . stack [ - <NUM_LIT:1> ] = ( dfa , newstate , node ) <EOL> self . stack . append ( ( newdfa , <NUM_LIT:0> , newnode ) ) <EOL> def pop ( self ) : <EOL> """<STR_LIT>""" <EOL> popdfa , popstate , popnode = self . stack . pop ( ) <EOL> newnode = self . convert ( self . grammar , popnode ) <EOL> if newnode is not None : <EOL> if self . stack : <EOL> dfa , state , node = self . stack [ - <NUM_LIT:1> ] <EOL> node [ - <NUM_LIT:1> ] . append ( newnode ) <EOL> else : <EOL> self . rootnode = newnode <EOL> self . rootnode . used_names = self . used_names </s>
