Search code examples
grammarraku

How to commit to an alternation branch in a Raku grammar token?


Suppose I have a grammar with the following tokens

token paragraph {
    (
        || <header>
        || <regular>
    )

    \n
}

token header { ^^ '---' '+'**1..5 ' ' \N+ }
token regular { \N+ }

The problem is that a line starting with ---++Foo will be parsed as a regular paragraph because there is no space before "Foo". I'd like to fail the parse in this case, i.e. somehow "commit" to this branch of the alternation, e.g. after seeing --- I want to either parse the header successfully or fail the match completely.

How can I do this? The only way I see is to use a negative lookahead assertion before <regular> to check that it does not start with ---, but this looks rather ugly and impractical, considering that my actual grammar has many more than just these 2 branches. Is there some better way? Thanks in advance!


Solution

  • If I understood your question correctly, you could do something like this:

    token header {
        ^^ '---' [
                     || '+'**1..5 ' ' \N+
                     || { die "match failed near position $/.pos()" }
                 ]
    }