<s> """<STR_LIT>""" <EOL> from inspect import getargspec <EOL> import re <EOL> from parsimonious . exceptions import ParseError , IncompleteParseError <EOL> from parsimonious . nodes import Node , RegexNode <EOL> from parsimonious . utils import StrAndRepr <EOL> MARKER = object ( ) <EOL> def expression ( callable , rule_name , grammar ) : <EOL> """<STR_LIT>""" <EOL> num_args = len ( getargspec ( callable ) . args ) <EOL> if num_args == <NUM_LIT:2> : <EOL> is_simple = True <EOL> elif num_args == <NUM_LIT:5> : <EOL> is_simple = False <EOL> else : <EOL> raise RuntimeError ( "<STR_LIT>" <EOL> "<STR_LIT>" % num_args ) <EOL> class AdHocExpression ( Expression ) : <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> result = ( callable ( text , pos ) if is_simple else <EOL> callable ( text , pos , cache , error , grammar ) ) <EOL> if isinstance ( result , ( long , int ) ) : <EOL> end , children = result , None <EOL> elif isinstance ( result , tuple ) : <EOL> end , children = result <EOL> else : <EOL> return result <EOL> return Node ( self . name , text , pos , end , children = children ) <EOL> def _as_rhs ( self ) : <EOL> return '<STR_LIT>' % callable . __name__ <EOL> return AdHocExpression ( name = rule_name ) <EOL> class Expression ( StrAndRepr ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ '<STR_LIT:name>' ] <EOL> def __init__ ( self , name = '<STR_LIT>' ) : <EOL> self . name = name <EOL> def parse ( self , text , pos = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> node = self . match ( text , pos = pos ) <EOL> if node . end < len ( text ) : <EOL> raise IncompleteParseError ( text , node . end , self ) <EOL> return node <EOL> def match ( self , text , pos = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> error = ParseError ( text ) <EOL> node = self . match_core ( text , pos , { } , error ) <EOL> if node is None : <EOL> raise error <EOL> return node <EOL> def match_core ( self , text , pos , cache , error ) : <EOL> """<STR_LIT>""" <EOL> expr_id = id ( self ) <EOL> node = cache . get ( ( expr_id , pos ) , MARKER ) <EOL> if node is MARKER : <EOL> node = cache [ ( expr_id , pos ) ] = self . _uncached_match ( text , <EOL> pos , <EOL> cache , <EOL> error ) <EOL> if node is None and pos >= error . pos and ( <EOL> self . name or getattr ( error . expr , '<STR_LIT:name>' , None ) is None ) : <EOL> error . expr = self <EOL> error . pos = pos <EOL> return node <EOL> def __unicode__ ( self ) : <EOL> return u'<STR_LIT>' % ( <EOL> self . __class__ . __name__ , <EOL> self . as_rule ( ) , <EOL> id ( self ) ) <EOL> def as_rule ( self ) : <EOL> """<STR_LIT>""" <EOL> rhs = self . _as_rhs ( ) . strip ( ) <EOL> if rhs . startswith ( '<STR_LIT:(>' ) and rhs . endswith ( '<STR_LIT:)>' ) : <EOL> rhs = rhs [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> return ( u'<STR_LIT>' % ( self . name , rhs ) ) if self . name else rhs <EOL> def _unicode_members ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ ( m . name or m . _as_rhs ( ) ) for m in self . members ] <EOL> def _as_rhs ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> class Literal ( Expression ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ '<STR_LIT>' ] <EOL> def __init__ ( self , literal , name = '<STR_LIT>' ) : <EOL> super ( Literal , self ) . __init__ ( name ) <EOL> self . literal = literal <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> if text . startswith ( self . literal , pos ) : <EOL> return Node ( self . name , text , pos , pos + len ( self . literal ) ) <EOL> def _as_rhs ( self ) : <EOL> return '<STR_LIT>' % self . literal <EOL> class TokenMatcher ( Literal ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , token_list , pos , cache , error ) : <EOL> if token_list [ pos ] . type == self . literal : <EOL> return Node ( self . name , token_list , pos , pos + <NUM_LIT:1> ) <EOL> class Regex ( Expression ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ '<STR_LIT>' ] <EOL> def __init__ ( self , pattern , name = '<STR_LIT>' , ignore_case = False , locale = False , <EOL> multiline = False , dot_all = False , unicode = False , verbose = False ) : <EOL> super ( Regex , self ) . __init__ ( name ) <EOL> self . re = re . compile ( pattern , ( ignore_case and re . I ) | <EOL> ( locale and re . L ) | <EOL> ( multiline and re . M ) | <EOL> ( dot_all and re . S ) | <EOL> ( unicode and re . U ) | <EOL> ( verbose and re . X ) ) <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> """<STR_LIT>""" <EOL> m = self . re . match ( text , pos ) <EOL> if m is not None : <EOL> span = m . span ( ) <EOL> node = RegexNode ( self . name , text , pos , pos + span [ <NUM_LIT:1> ] - span [ <NUM_LIT:0> ] ) <EOL> node . match = m <EOL> return node <EOL> def _regex_flags_from_bits ( self , bits ) : <EOL> """<STR_LIT>""" <EOL> flags = '<STR_LIT>' <EOL> return '<STR_LIT>' . join ( flags [ i ] if ( <NUM_LIT:1> << i ) & bits else '<STR_LIT>' for i in xrange ( <NUM_LIT:6> ) ) <EOL> def _as_rhs ( self ) : <EOL> return '<STR_LIT>' % ( self . re . pattern , <EOL> self . _regex_flags_from_bits ( self . re . flags ) ) <EOL> class Compound ( Expression ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ '<STR_LIT>' ] <EOL> def __init__ ( self , * members , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> super ( Compound , self ) . __init__ ( kwargs . get ( '<STR_LIT:name>' , '<STR_LIT>' ) ) <EOL> self . members = members <EOL> class Sequence ( Compound ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> new_pos = pos <EOL> length_of_sequence = <NUM_LIT:0> <EOL> children = [ ] <EOL> for m in self . members : <EOL> node = m . match_core ( text , new_pos , cache , error ) <EOL> if node is None : <EOL> return None <EOL> children . append ( node ) <EOL> length = node . end - node . start <EOL> new_pos += length <EOL> length_of_sequence += length <EOL> return Node ( self . name , text , pos , pos + length_of_sequence , children ) <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' . format ( u'<STR_LIT:U+0020>' . join ( self . _unicode_members ( ) ) ) <EOL> class OneOf ( Compound ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> for m in self . members : <EOL> node = m . match_core ( text , pos , cache , error ) <EOL> if node is not None : <EOL> return Node ( self . name , text , pos , node . end , children = [ node ] ) <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' . format ( u'<STR_LIT>' . join ( self . _unicode_members ( ) ) ) <EOL> class Lookahead ( Compound ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> node = self . members [ <NUM_LIT:0> ] . match_core ( text , pos , cache , error ) <EOL> if node is not None : <EOL> return Node ( self . name , text , pos , pos ) <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' % self . _unicode_members ( ) [ <NUM_LIT:0> ] <EOL> class Not ( Compound ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> node = self . members [ <NUM_LIT:0> ] . match_core ( text , pos , cache , error ) <EOL> if node is None : <EOL> return Node ( self . name , text , pos , pos ) <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' % self . _unicode_members ( ) [ <NUM_LIT:0> ] <EOL> class Optional ( Compound ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> node = self . members [ <NUM_LIT:0> ] . match_core ( text , pos , cache , error ) <EOL> return ( Node ( self . name , text , pos , pos ) if node is None else <EOL> Node ( self . name , text , pos , node . end , children = [ node ] ) ) <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' % self . _unicode_members ( ) [ <NUM_LIT:0> ] <EOL> class ZeroOrMore ( Compound ) : <EOL> """<STR_LIT>""" <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> new_pos = pos <EOL> children = [ ] <EOL> while True : <EOL> node = self . members [ <NUM_LIT:0> ] . match_core ( text , new_pos , cache , error ) <EOL> if node is None or not ( node . end - node . start ) : <EOL> return Node ( self . name , text , pos , new_pos , children ) <EOL> children . append ( node ) <EOL> new_pos += node . end - node . start <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' % self . _unicode_members ( ) [ <NUM_LIT:0> ] <EOL> class OneOrMore ( Compound ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ '<STR_LIT>' ] <EOL> def __init__ ( self , member , name = '<STR_LIT>' , min = <NUM_LIT:1> ) : <EOL> super ( OneOrMore , self ) . __init__ ( member , name = name ) <EOL> self . min = min <EOL> def _uncached_match ( self , text , pos , cache , error ) : <EOL> new_pos = pos <EOL> children = [ ] <EOL> while True : <EOL> node = self . members [ <NUM_LIT:0> ] . match_core ( text , new_pos , cache , error ) <EOL> if node is None : <EOL> break <EOL> children . append ( node ) <EOL> length = node . end - node . start <EOL> if length == <NUM_LIT:0> : <EOL> break <EOL> new_pos += length <EOL> if len ( children ) >= self . min : <EOL> return Node ( self . name , text , pos , new_pos , children ) <EOL> def _as_rhs ( self ) : <EOL> return u'<STR_LIT>' % self . _unicode_members ( ) [ <NUM_LIT:0> ] </s>
