4

I'm trying to parse a simple language. The trouble comes with parsing function calls. I'm trying to tell it that a function call is an expression followed by left parenthesis, argument list, and right parenthesis. I have something like this:

expr = Forward()
iden = Word(alphas+'_', alphanums+'_')
integer = Word(nums)
binop = operatorPrecedence(expr, ...) # irrevelant
call = expr + Literal('(') + delimitedList(expr) + Literal(')')
expr << call | integer | iden

The problem is obvious: expr is left-recursive. However, I can't figure what to do to solve this. I'm experienced with right-recursive-style grammars(a.k.a. PLY, Yacc, etc.) but am still trying to figure out left-recursive grammars.

4
  • To parse an immediately-left-recursive production in an LL parser, you need to either (a) convert it to a weakly-equivalent right-recursive production, or (b) write an explicit disambiguation or curtailment algorithm. (Or, of course, you can weaken the production so that a call can't start with any expr, only with a sub-production of expr.) I don't know pyparsing well enough to know if (b) is an option. Commented Jul 23, 2014 at 0:30
  • I think there are PyParsing examples for various versions of Python, which basically uses option (c). IIRC, in early 2.x (which is probably the simplest) a call was an atom (not an expr) followed by a parenthesized arglist, and produced a power (not an expr). Just figure out where in the precedence you want call expressions to go, split the operatorPrecedence group into the half about that and the half below that, and explicitly put the call in between. (But, you know, actually look at the pyparsing examples or Python grammar rather than trusting my memory.:)) Commented Jul 23, 2014 at 0:35
  • So in this language, "36(21)" is a valid function call? Commented Jul 23, 2014 at 6:26
  • 1
    @PaulMcGuire: Technically not, but that would be found out after parsing, when the code is checked. It is syntactically valid, however. Commented Jul 23, 2014 at 19:48

1 Answer 1

3
Functionname = Word(alphanums + '_')
functionbody = Forward()
functionbody <<=  Functionname + (Literal("(") +
Optional( delimitedList ( functionbody | Word(alphanums + '_') | "''"),'')
+ Literal(")"))
Sign up to request clarification or add additional context in comments.

1 Comment

Haha, I had forgotten all about this question!! Thanks for answering anyhow. ;D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.