<s> """<STR_LIT>""" <EOL> from google . appengine . _internal import antlr3 <EOL> from google . appengine . _internal . antlr3 import tree <EOL> from google . appengine . api . search import QueryLexer <EOL> from google . appengine . api . search import QueryParser <EOL> COMPARISON_TYPES = [ <EOL> QueryParser . EQ , <EOL> QueryParser . HAS , <EOL> QueryParser . NE , <EOL> QueryParser . GT , <EOL> QueryParser . GE , <EOL> QueryParser . LESSTHAN , <EOL> QueryParser . LE , <EOL> ] <EOL> class QueryException ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class QueryTreeException ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , msg , position ) : <EOL> Exception . __init__ ( self , msg ) <EOL> self . position = position <EOL> class QueryLexerWithErrors ( QueryLexer . QueryLexer ) : <EOL> """<STR_LIT>""" <EOL> def displayRecognitionError ( self , tokenNames , e ) : <EOL> msg = "<STR_LIT>" % ( e . line , e . charPositionInLine ) ; <EOL> self . emitErrorMessage ( msg ) <EOL> def emitErrorMessage ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> raise QueryException ( msg ) <EOL> class QueryParserWithErrors ( QueryParser . QueryParser ) : <EOL> """<STR_LIT>""" <EOL> def displayRecognitionError ( self , tokenNames , e ) : <EOL> msg = "<STR_LIT>" % ( e . line , e . charPositionInLine ) ; <EOL> self . emitErrorMessage ( msg ) <EOL> def emitErrorMessage ( self , msg ) : <EOL> """<STR_LIT>""" <EOL> raise QueryException ( msg ) <EOL> def CreateParser ( query ) : <EOL> """<STR_LIT>""" <EOL> input_string = antlr3 . ANTLRStringStream ( query ) <EOL> lexer = QueryLexerWithErrors ( input_string ) <EOL> tokens = antlr3 . CommonTokenStream ( lexer ) <EOL> parser = QueryParserWithErrors ( tokens ) <EOL> return parser <EOL> def ParseAndSimplify ( query ) : <EOL> """<STR_LIT>""" <EOL> node = Parse ( query ) . tree <EOL> try : <EOL> node = SimplifyNode ( node ) <EOL> ValidateNode ( node ) <EOL> except QueryTreeException , e : <EOL> msg = "<STR_LIT>" % ( e . message , query ) <EOL> raise QueryException ( msg ) <EOL> return node <EOL> def Parse ( query ) : <EOL> """<STR_LIT>""" <EOL> parser = CreateParser ( query ) <EOL> try : <EOL> return parser . query ( ) <EOL> except Exception , e : <EOL> msg = "<STR_LIT>" % ( e . message , query ) <EOL> raise QueryException ( msg ) <EOL> def ConvertNodes ( node , from_type , to_type , to_text ) : <EOL> """<STR_LIT>""" <EOL> if node . getType ( ) == from_type : <EOL> new_node = CreateQueryNode ( to_text , to_type ) <EOL> else : <EOL> new_node = node <EOL> convert_children = lambda c : ConvertNodes ( c , from_type , to_type , to_text ) <EOL> new_node . children = map ( convert_children , node . children ) <EOL> return new_node <EOL> def _ColonToEquals ( node ) : <EOL> """<STR_LIT>""" <EOL> return ConvertNodes ( node , QueryParser . HAS , QueryParser . EQ , '<STR_LIT:=>' ) <EOL> def SequenceToConjunction ( node ) : <EOL> """<STR_LIT>""" <EOL> return ConvertNodes ( <EOL> node , QueryParser . SEQUENCE , QueryParser . CONJUNCTION , '<STR_LIT>' ) <EOL> def Simplify ( parser_return ) : <EOL> """<STR_LIT>""" <EOL> if parser_return . tree : <EOL> node = SimplifyNode ( parser_return . tree ) <EOL> ValidateNode ( node ) <EOL> return node <EOL> return parser_return <EOL> QUERY_FUNCTION_NAMES = frozenset ( [ "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> def ValidateNode ( node ) : <EOL> for i in range ( node . getChildCount ( ) ) : <EOL> ValidateNode ( node . getChild ( i ) ) <EOL> if node . getType ( ) == QueryLexer . FUNCTION : <EOL> name = node . getChild ( <NUM_LIT:0> ) <EOL> if name . getText ( ) not in QUERY_FUNCTION_NAMES : <EOL> raise QueryTreeException ( "<STR_LIT>" % name . getText ( ) , <EOL> name . getCharPositionInLine ( ) ) <EOL> def SimplifyNode ( node , restriction = None ) : <EOL> if node . getType ( ) == QueryLexer . VALUE : <EOL> return node <EOL> elif node . getType ( ) == QueryParser . SEQUENCE and node . getChildCount ( ) == <NUM_LIT:1> : <EOL> return SimplifyNode ( node . children [ <NUM_LIT:0> ] , restriction ) <EOL> elif node . getType ( ) == QueryParser . CONJUNCTION and node . getChildCount ( ) == <NUM_LIT:1> : <EOL> return SimplifyNode ( node . children [ <NUM_LIT:0> ] , restriction ) <EOL> elif node . getType ( ) == QueryParser . DISJUNCTION and node . getChildCount ( ) == <NUM_LIT:1> : <EOL> return SimplifyNode ( node . children [ <NUM_LIT:0> ] , restriction ) <EOL> elif node . getType ( ) == QueryLexer . HAS or node . getType ( ) == QueryLexer . EQ : <EOL> lhs = node . getChild ( <NUM_LIT:0> ) ; <EOL> if lhs . getType ( ) == QueryLexer . VALUE : <EOL> myField = lhs . getChild ( <NUM_LIT:1> ) . getText ( ) <EOL> if restriction is None : <EOL> restriction = lhs <EOL> else : <EOL> otherField = restriction . getChild ( <NUM_LIT:1> ) . getText ( ) ; <EOL> if myField != otherField : <EOL> raise QueryTreeException ( <EOL> "<STR_LIT>" % ( otherField , myField ) , <EOL> lhs . getChild ( <NUM_LIT:1> ) . getCharPositionInLine ( ) ) ; <EOL> rhs = node . getChild ( <NUM_LIT:1> ) ; <EOL> flattened = SimplifyNode ( rhs , restriction ) ; <EOL> if ( flattened . getType ( ) == QueryLexer . HAS or <EOL> flattened . getType ( ) == QueryLexer . EQ or <EOL> flattened . getType ( ) == QueryLexer . CONJUNCTION or <EOL> flattened . getType ( ) == QueryLexer . DISJUNCTION or <EOL> flattened . getType ( ) == QueryLexer . SEQUENCE ) : <EOL> return flattened ; <EOL> if flattened != rhs : <EOL> node . setChild ( <NUM_LIT:1> , flattened ) ; <EOL> if restriction != lhs : <EOL> node . setChild ( <NUM_LIT:0> , restriction ) ; <EOL> return node ; <EOL> for i in range ( node . getChildCount ( ) ) : <EOL> original = node . getChild ( i ) ; <EOL> flattened = SimplifyNode ( node . getChild ( i ) , restriction ) ; <EOL> if original != flattened : <EOL> node . setChild ( i , flattened ) <EOL> return node ; <EOL> def CreateQueryNode ( text , type ) : <EOL> token = tree . CommonTreeAdaptor ( ) . createToken ( tokenType = type , text = text ) <EOL> return tree . CommonTree ( token ) <EOL> def GetQueryNodeText ( node ) : <EOL> """<STR_LIT>""" <EOL> return GetQueryNodeTextUnicode ( node ) . encode ( '<STR_LIT:utf-8>' ) <EOL> def GetQueryNodeTextUnicode ( node ) : <EOL> """<STR_LIT>""" <EOL> if node . getType ( ) == QueryParser . VALUE and len ( node . children ) >= <NUM_LIT:2> : <EOL> return u'<STR_LIT>' . join ( c . getText ( ) for c in node . children [ <NUM_LIT:1> : ] ) <EOL> elif node . getType ( ) == QueryParser . VALUE : <EOL> return None <EOL> return node . getText ( ) <EOL> def RemoveSurroundingQuotes ( text ) : <EOL> """<STR_LIT>""" <EOL> if text : <EOL> if text [ <NUM_LIT:0> ] == '<STR_LIT:">' and text [ - <NUM_LIT:1> ] == '<STR_LIT:">' : <EOL> text = text [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> return text <EOL> def GetPhraseQueryNodeText ( node ) : <EOL> """<STR_LIT>""" <EOL> text = GetQueryNodeText ( node ) <EOL> text = RemoveSurroundingQuotes ( text ) <EOL> return text <EOL> def IsPhrase ( node ) : <EOL> """<STR_LIT>""" <EOL> text = GetQueryNodeText ( node ) <EOL> return ( node . getType ( ) == QueryParser . VALUE and <EOL> text . startswith ( '<STR_LIT:">' ) and text . endswith ( '<STR_LIT:">' ) ) </s>
