How to fail and throw exceptions when a rule can't be fully matched , in PetitParserDart?

StackOverflow https://stackoverflow.com/questions/17584318

  •  02-06-2022
  •  | 
  •  

Question

I have defined some rules with PetitParserDart:

def("start", ref("rule").separatedBy(char('\n'), includeSeparators: false);
def("rule", char('(').seq(word().plus()).seq(char(')')));

So the following text will be matched:

(aaa)
(bbbbbb)

But if there are some lines can't match:

(aaaa)
bbbbb
(cccccccc

How to define the grammars to let it fail and throw exceptions on line (ccccccccc, but not on line bbbbb?

I mean it only throw exceptions when a rule is not fully matched. If nothing matchs, it won't throw exception.

Was it helpful?

Solution

At any point in the grammar you can introduce a failing parser:

failure('This parser always fails at this point');

Normally PetitParser does not use exceptions during parsing, success and failure are indicated with the respective Success and Failure response contexts.

That said, it is possible to throw exceptions, but normally not advised unless the user of your grammar can deal with it. For example, you could define a throwing parser factory like this:

Parser thrower(String message) {
  return epsilon().map((value) => throw new IllegalStateException(message));
}

Using the normal compositors you can then generate very precise error messages:

char('(')
  .seq(word().plus())
  .seq(char(')')
    // causes the parser to continue trying to parse the input
    .or(failure('something bad happened')))

Or with the helper above:

char('(')
  .seq(word().plus())
  .seq(char(')')
     // stops parsing altogether and throws an exception
    .or(thrower('something bad happened')))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top