Re: [Pyparsing] [pyparsing] RecursiveGrammarException
Brought to you by:
ptmcg
From: Paul M. <pt...@au...> - 2011-08-23 05:58:35
|
Haifeng - You have 2 problems going on here: - you are matching 'a' before trying to match 'a->b'; the leading 'a' will match, and the trailing '->b' will then raise an error - you have defined a left-recursive expression (to match 'a->b', you will try to match 'a->b', but first you will match 'a->b', etc.); the left-recursion is what validate() is complaining about Pyparsing is not like lex/yacc or LR parsers - it works purely left-to-right through the input text, according to the definitions in the grammar. There is no lookahead to try to achieve longer matches, as is done in regular expressions. In pyparsing expressions, the '|' is a short-circuiting alternative operator, creating MatchFirst expressions: the first alternative expression to match will be the "winner", even if a later alternative might match a longer part of the input string. You can force all alternatives to be tested for matching (with the longest match chosen) using the '^' operator, which creates Or expressions. Pyparsing does not allow you to directly implement a BNF definition, since BNF follows different rules for matching, and has different constraints for notation. There is more description of the BNF->pyparsing process here (http://pyparsing.wikispaces.com/message/view/home/11262229 and http://pyparsing.wikispaces.com/message/view/home/41102255). You use some terms like "postfix" in your grammar, but I don't see a lot of postfixing going on. You do describe an infix '->' operator, but this too is somewhat confusing; in your example, you just show "a->b", but from your implementation, it looks like you want to support unbounded repetition, presumably something like "a->b->c->d". To implement your grammar to parse your two examples, you would write: ARROW = Literal('->') identifier = Word(alphas+"_", alphanums+"_") primary_expression = identifier compound_expression = identifier + ARROW + identifier # must test for compound_expression before primary_expression expression = compound_expression | primary_expression To add repetition to compound_expression, you could simply change it to: compound_expression = identifier + OneOrMore(ARROW + identifier) -- Paul -----Original Message----- From: Haifeng [mailto:min...@gm...] Sent: Sunday, August 21, 2011 2:43 AM To: pyp...@li... Subject: [Pyparsing] [pyparsing] RecursiveGrammarException Hi I am new to pyparsing. I am trying to parse just the following C expressions: a a->b My code looks like: from pyparsing import * ARROW = Literal('->') identifier = Word(alphas+"_", alphanums+"_") primary_expression = identifier postfix_expression = Forward() postfix_expression << ( primary_expression | (postfix_expression + ARROW + identifier)) But it failed on postfix_expression.validate(). What did I do wrongly here? Thanks ---------------------------------------------------------------------------- -- Get a FREE DOWNLOAD! and learn more about uberSVN rich system, user administration capabilities and model configuration. Take the hassle out of deploying and managing Subversion and the tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2 _______________________________________________ Pyparsing-users mailing list Pyp...@li... https://lists.sourceforge.net/lists/listinfo/pyparsing-users |