Changeset 110:602b33270077
- 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:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r109
|
r110
|
|
| 2 | 2 | |
| 3 | 3 | ###Grammar stuff |
| 4 | | from pyparsing import Forward, Regex,Optional,ZeroOrMore, QuotedString , Literal, Word, alphas , nums , printables , CharsNotIn , stringEnd |
| 5 | | from functools import partial |
| | 4 | from pyparsing import Forward, OneOrMore, QuotedString , Literal, Word, alphas , nums , stringEnd |
| 6 | 5 | |
| 7 | 6 | import logging |
| … |
… |
|
| 11 | 10 | |
| 12 | 11 | #Tokens |
| 13 | | openExpr = Literal("${") |
| 14 | | closeExpr = Literal("}") |
| 15 | 12 | seperator = Literal(":") |
| 16 | 13 | queryOp = Literal("?") |
| … |
… |
|
| 19 | 16 | |
| 20 | 17 | #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]") |
| | 18 | identifier = Word("-" + "_" + alphas + nums) |
| 28 | 19 | LiteralVal = QuotedString('"') |
| 29 | 20 | |
| … |
… |
|
| 33 | 24 | # Productions |
| 34 | 25 | cfoperator = equalsOp ^ notequalsOp |
| 35 | | ObjectUID = Optional(objectName + seperator + ObjectId) |
| | 26 | |
| | 27 | pathElement= seperator + identifier |
| | 28 | RelSpec = OneOrMore(pathElement) |
| | 29 | AbsSpec = identifier + RelSpec |
| 36 | 30 | |
| 37 | | NamedField = ObjectUID + seperator +fieldName |
| 38 | | ExprField = ObjectUID ^ \ |
| 39 | | NamedField |
| | 31 | ExprField = AbsSpec ^ RelSpec |
| 40 | 32 | |
| 41 | 33 | ExprText = Forward() |
| … |
… |
|
| 47 | 39 | LiteralVal ) |
| 48 | 40 | |
| 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 | | |
| 61 | 41 | ## 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 | | |
| 70 | 42 | def doBool(s,loc,toks): |
| 71 | 43 | modlogger.debug( "getbol\n") |
| … |
… |
|
| 81 | 53 | return toks[4] |
| 82 | 54 | |
| 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 | |
| 89 | 82 | |
| 90 | 83 | #def gotError(s,loc,toks): |
| … |
… |
|
| 93 | 86 | ## Bind functions to parse actions |
| 94 | 87 | |
| 95 | | NamedField.setParseAction(getField) |
| 96 | | |
| | 88 | ExprField.setParseAction(ExprFieldAction) |
| 97 | 89 | BoolExpr.setParseAction(doBool) |
| 98 | 90 | QueryExpr.setParseAction(doQuery) |
| 99 | | Expr.setParseAction(lambda s,loc,tok:tok[1]) |
| 100 | | #Error.setParseAction(gotError) |
| 101 | 91 | |
| 102 | | ObjectUID.setParseAction(initFromParse) |
| 103 | | |
| | 92 | ExprText.enablePackrat() |
| | 93 | ExprText.validate() |
| 104 | 94 | return ExprText + stringEnd |