0

Example:

start = name / invocation;

name = [a-zA-Z]+ { return text() };

invocation = a:name "()" { return {type: 'inv', value: a } };

If input is abc() I am getting error:

Expected [a-zA-Z] or end of input but "(" found

However, if start was defined as follows no issues arise:

start = invocation / name;

For the earlier case, shouldn't the name rule not match and consequently enter the invocation rule? Else how to manage such a thing?

For working example, see playground

deostroll
  • 11,661
  • 21
  • 90
  • 161

1 Answers1

0

This is a property of Parser Expression Grammar. Changing the order of expressions in a choice-operator can change the result.

From wikipedia:

The fundamental difference between context-free grammars and parsing expression grammars is that the PEG's choice operator is ordered. If the first alternative succeeds, the second alternative is ignored. Thus ordered choice is not commutative, unlike unordered choice as in context-free grammars.

fafl
  • 7,222
  • 3
  • 27
  • 50
  • Shouldn't `name` rule gracefully fail and attempt to match the next rule (considering the first example)? Instead I get an exception. Is this the way it is supposed to work? To rephrase, in that choice-order itself why did I get an exception while processing `name` rule. I mean, I know the reason "why", however, I can't explain why it fatally stopped; the parser execution should have continued... – deostroll Jun 12 '19 at 11:23
  • It successfully matches `name` but then finds `(` for which there is no rule. It then does not backtrack, but just throws the exception. You always have to put the most specific rules first. – fafl Jun 12 '19 at 11:36
  • There is more I'd like to discuss: if you can join the following room it would be awesome... https://chat.stackoverflow.com/rooms/194824/temporary-pegjs-discussion-room – deostroll Jun 12 '19 at 11:55