[TransWarp] fmtparse - named rules
Phillip J. Eby
pje at telecommunity.com
Mon Jun 16 11:37:56 EDT 2003
At 01:15 PM 6/16/03 +0400, Oleg Broytmann wrote:
>Hello.
>
> How should I use Named rules?
>
>from peak.util.fmtparse import *
>
>cmp_func = Named("cmp_func",
> Alternatives("eq", "neq", "lt", "le", "gt", "ge", "like"))
>
>test1 = "eq"
>print parse(test1, cmp_func)
>
> Prints {}. Oops, where is my name?
fmtparse rules are sort of like generators, except they call a passed-in
visitor function rather than yielding. 'Named' "yields" a (name,value)
tuple for each value yielded by its contained rule. Alternatives never
yields anything, so Named(Alternatives) yields nothing either. You need an
ExtractString around the Alternatives.
> The following is better:
>
>between_expr = Sequence("between", '(', Named("name"), ',',
>Named("value1"), ',', Named("value2"), ')')
This is because the default subrule for Named is an
ExtractString(). ExtractString has a default subrule of
MatchString(). The default MatchString behavior is to match until it hits
a terminator. In your sequence above, each MatchString will be told that
',' (and maybe ')') are terminators. The default ExtractStrings then take
the value matched by the MatchString, and yield it to the Named, which then
turns it into a (name,value) tuple and yields it to the Sequence. The
sequence yields a sequence to the parse operation, which turns it into a
dictionary.
>test2 = "between(month,1,12)"
>print parse(test2, between_expr)
>
> It prints {'name': 'month', 'value1': '1', 'value2': '12'}. Ok. But
>this:
>
>between_expr = Named("between", Sequence("between", '(', Named("name"),
>',', Named("value1"), ',', Named("value2"), ')'))
>
>test3 = "between(month,1,12)"
>print parse(test3, between_expr)
>
> Prints {'between': ('value2', '12')}. Ouch, where is name and value1? It
>seems I am doing it wrong way, but what is the right way?
I'm not clear on what you're trying to accomplish..
> Returning to the very first exampl... I can use ExtractString:
>
>cmp_func = Named("cmp_func",
> ExtractString(Alternatives("eq", "neq", "lt", "le", "gt", "ge", "like")))
ExtractString yields the string that is matched by its subrule, so
'cmp_func' will yield a pair like ('cmp_func', 'eq') or ('cmp_func','like').
>test4 = "eq"
>print parse(test4, cmp_func) # => {} Oops, where is my name?
>
> {'cmp_func': 'eq'} - ok, exactly what I wanted... but this:
>between_expr = Named("between", ExtractString(Sequence("between", '(',
>Named("name"), ',', Named("value1"), ',', Named("value2"), ')')))
>
>test5 = "between(month,1,12)"
>print parse(test5, between_expr)
>
> {'between': 'between(month,1,12)'}. ExtractString extracted too much...
What did you want it to extract? You told it to extract
Sequence("between", '(', ... ')'), so that's what you got. I'm having
trouble understanding what you *want* to do here.
More information about the PEAK
mailing list