Add syntax for converting local failure to global failure
See original GitHub issueIssue type
- Bug Report: no
- Feature Request: yes
- Question: no
- Not an issue: no
Prerequisites
- Can you reproduce the issue?: yes
- Did you search the repository issues?: yes
- Did you check the forums?: no
- Did you perform a web search (google, yahoo, etc)?: yes
Description
I think it would be a really powerful extension to the grammar if we were able to convert local failure (as in: failure that happens while parsing an optional (?) or a predicate (&, !)) to a global one. While it might not seem straightforward why this would be useful, in complex grammars (such as one I’m writing now) it becomes an invaluable tool.
I took the idea from the PEGTL parsing library. There is a rule called must<>, which, when present, will immediately throw an exception when the rule inside it didn’t match.
Technical details:
I propose a new operator (#), that, when present, compiles to a matcher with a throw-statement instead of one that just pushes FAILED onto the stack. I have already made a prototype that seems to work on most trivial use-cases, and will file a pull request right away.
Example code:
VariableDefninition = VarToken __ name:#Identifier __ #"=" __ #Expression
Expected behavior:
Whenever a VarToken (e.g. “var”) is encountered, it will try to parse the identifier, an equality sign, and an expression. Whenever any of these fail, the parser will throw an error (indicated by the #-symbol), even when VariableDefinition occurs in a predicate or an optional.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (1 by maintainers)

Top Related StackOverflow Question
PEG grammars are usually written without any lexer. In a case when lexeme couldn’t be parsed, it’s a global failure. PEG grammars would nevertheless try several other rules before failing to parse the string. The feature to make a non-backtrackable failure is thus useful. It’s also available in boost::spirit as
atom<>.The problem is that it’s a dirty hack. There’s a whole variety of dirty hacks (e.g. skipper grammars and
lexeme<>rule), and assigning one of the very limited one-symbol combinations to them is not a good idea.I’d rather recommend to figure out another long requested feature, rules parameterized with other rules, and just use something in lines of
atom(p) = p / &{ error('Forced failiure'); }here.Several years ago I tried to add it to PEG.js, but it turned out way harder than I thought and I abandoned idea. Probably I should try it once more too.