dartpetitparser

How would I create a parser which consumes a character that is also at the beginning and end


How would I create a parser that allows a character which also happens to be the same as the begin/end character. Using the following example:

'Isn't it hot'

The second single-quote should be accepted as part of the content that is between the beginning and ending single-quote. I created a parser like this:

char("'").seq((word()|char("'")|whitespace()).plus()).seq(char("'"))

but it fails as:

Failure[1:15]: "'" expected

If I use "any()|char("'") then it greedily consumes the ending single-quote causing an error as well.

Would I need to create an actual Grammar class? I have attempted to create one but can't figure out how to make a Parser that doesn't try to consume the end marker greedily.


Solution

  • The problem is that plus() is greedy and blind. This means the repetition consumes as much input as possible, but does not consider what comes afterwards. In your example, everything up to the end of the input is consumed, but then the last quote in the sequence cannot be matched anymore.

    You can solve the problem by using the non-blind variation plusGreedy(Parser) instead:

    char("'")
      .seq((word() | char("'") | whitespace()).plusGreedy(char("'")))
      .seq(char("'"));
    

    This consumes the input as long as there is still a char("'") left that can be consumed afterwards.