Changeset 110:602b33270077

Show
Ignore:
Timestamp:
02/20/10 16:48:19 (7 months ago)
Author:
Roger Gammans <rgammans@…>
Branch:
default
Message:

More grammar improvements, allow arbitary defrefences , and remove old stuff.

  • Arbitray length field specifiers such as a:b:c:d now possible. = useful for dereference now across link objects. = dereferencing collection attributes (new feature due soon).
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • MysteryMachine/parsetools/grammar.py

    r109 r110  
    22 
    33###Grammar stuff 
    4 from pyparsing import Forward, Regex,Optional,ZeroOrMore, QuotedString , Literal, Word, alphas , nums , printables  , CharsNotIn , stringEnd 
    5 from functools import partial 
     4from pyparsing import Forward, OneOrMore, QuotedString , Literal, Word, alphas , nums , stringEnd 
    65 
    76import logging 
     
    1110 
    1211#Tokens 
    13 openExpr   =   Literal("${") 
    14 closeExpr  =   Literal("}") 
    1512seperator  =   Literal(":") 
    1613queryOp    =   Literal("?") 
     
    1916 
    2017#Characters to avoid ?,:,/,!,= (eg other literals) 
    21 identifier =   Word("_" + alphas + nums) 
    22 objectName =   identifier.copy() 
    23 fieldName  =   identifier.copy() 
    24 ObjectId   =   Word(nums) 
    25 NonExpr    =   CharsNotIn("$") 
    26  
    27 ExprLimit  =   Regex("[^ \n\t]*[ \n\t]") 
     18identifier =   Word("-" + "_" + alphas + nums) 
    2819LiteralVal =   QuotedString('"')  
    2920 
     
    3324    # Productions 
    3425    cfoperator  =   equalsOp ^ notequalsOp 
    35     ObjectUID   =   Optional(objectName + seperator + ObjectId) 
     26   
     27    pathElement=    seperator + identifier 
     28    RelSpec    =    OneOrMore(pathElement) 
     29    AbsSpec    =    identifier + RelSpec 
    3630 
    37     NamedField  =   ObjectUID + seperator +fieldName 
    38     ExprField   =   ObjectUID ^  \ 
    39                 NamedField 
     31    ExprField  =    AbsSpec ^ RelSpec 
    4032 
    4133    ExprText   =    Forward()    
     
    4739                      LiteralVal  ) 
    4840 
    49     #Error      =   openExpr + ExprLimit  
    50  
    51     #These production are about handling expressions 
    52     # in run of text. The use is mainly historical. 
    53     Expr       =   openExpr + ExprText + closeExpr 
    54      
    55     textEle    =   NonExpr  ^ \ 
    56                    Expr  
    57         
    58     text       =   ZeroOrMore(textEle) 
    59  
    60  
    6141    ## Functions for parsing. 
    62  
    63     def getField(s,loc,toks): 
    64         modlogger.debug( "getField(%s)\n" % toks) 
    65         field=toks[2] 
    66         obj=toks[0] 
    67         return obj[field] 
    68  
    69  
    7042    def doBool(s,loc,toks): 
    7143        modlogger.debug( "getbol\n") 
     
    8153                return toks[4] 
    8254 
    83     def initFromParse(s,loc,toks): 
    84         modlogger.debug( "Creating from :'%s'->%s (current=%s)\n" %(s,str(toks),repr(home))) 
    85         isSelf=len(toks)==0 
    86         if isSelf:         return home  
    87         elif home is None: return None 
    88         else:              return home.get_root().get_object(toks[0],toks[2]) 
     55    def ExprFieldAction(s,loc,toks): 
     56        #In this case our walk will fail so 
     57        # just return None as an invalid thang. 
     58        if home is None: return None 
     59 
     60        #Determine whether abs or rel and 
     61        # find our origin. 
     62        # We use the home  objct - or 
     63        # derefernce the object if it is an absolute reference. 
     64        # - we can't just get the category because there is (currently) 
     65        #   no object which represents those , but we can get an object 
     66        #   and the grammar is specified such that an object must be spcified 
     67        #   not just a category` 
     68        if toks[0] == ":": 
     69            origin  = home 
     70            path    = toks[1:] 
     71        else: 
     72            origin  = home.get_root().get_object(toks[0],toks[2]) 
     73            path    = toks[4:] 
     74        
     75        #Walk along the attributes 
     76        for ele in path: 
     77            if ele != ":": #Skip ':' as grammar noise. 
     78                origin = origin[ele] 
     79 
     80        return origin 
     81     
    8982 
    9083    #def gotError(s,loc,toks): 
     
    9386    ## Bind functions to parse actions 
    9487     
    95     NamedField.setParseAction(getField) 
    96  
     88    ExprField.setParseAction(ExprFieldAction) 
    9789    BoolExpr.setParseAction(doBool) 
    9890    QueryExpr.setParseAction(doQuery) 
    99     Expr.setParseAction(lambda s,loc,tok:tok[1]) 
    100     #Error.setParseAction(gotError) 
    10191 
    102     ObjectUID.setParseAction(initFromParse) 
    103      
     92    ExprText.enablePackrat() 
     93    ExprText.validate() 
    10494    return ExprText + stringEnd