Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input matches rule A, but A|B fails to match #78

Open
rhoark opened this issue Apr 8, 2019 · 3 comments
Open

Input matches rule A, but A|B fails to match #78

rhoark opened this issue Apr 8, 2019 · 3 comments

Comments

@rhoark
Copy link

rhoark commented Apr 8, 2019

I'm trying to parse mathematical expressions with operator precedence, but I'm running into an odd problem where a rule of the form "A | B" fails to match, despite the fact that rule A matches the input string.
A stripped-down version of the grammar that exhibits this behavior:

spec = """
integer_literal = < digit+ >:x -> ("integer_literal",x)

oplevel_unary_left = ('+'|'-'):op unit:X -> ("op",1,op,X)
oplevel_unary_and_higher = oplevel_unary_left | integer_literal
oplevel_exponent = oplevel_exponent_and_higher:L ws ('^'):op ws oplevel_unary_and_higher:R -> ("op",2,op,L,R)
oplevel_exponent_and_higher = oplevel_exponent | oplevel_unary_and_higher
oplevel_mult = oplevel_mult_and_higher:L ws ('*'|'/'|'%'):op ws oplevel_exponent_and_higher:R -> ("op",2,op,L,R)
oplevel_mult_and_higher = oplevel_mult | oplevel_exponent_and_higher
"""

parser = parsley.makeGrammar(spec, {})

Then I get

>>> parser("2*3").oplevel_mult()
('op', 2, '*', ('integer_literal', '2'), ('integer_literal', '3'))
but
>>> parser("2*3").oplevel_mult_and_higher()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Anaconda3\lib\site-packages\parsley.py", line 98, in invokeRule
    raise err
ometa.runtime.ParseError:
2*3
  ^
Parse error at line 1, column 2: expected EOF. trail: [digit]
(or similarly with exponent_and_higher vs. just exponent)

I don't see how it's even possible for oplevel_mult_and_higher to fail when the first arm is oplevel_mult, which passes.

@wmstack
Copy link

wmstack commented Dec 24, 2019

is unit supposed to be integer_literal?

@rhoark
Copy link
Author

rhoark commented Dec 24, 2019

In the larger original code, unit was a literal or a variable name. For the purpose of this example it should have been changed to just a literal. Regardless, the expected behavior should be to never evaluate the right side of the pipe in oplevel_mult_and_higher.

@wmstack
Copy link

wmstack commented Dec 31, 2019

Yeah, you are right. I arrived here because I had a similar problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants