How to implement the priority of expressions Bakus-Naur Form

134 Views Asked by At

There is a grammar of this kind described in the documentation:

grammar
    =
    | ['()'] ['$'] {'#' &'#'} '#'
    | ['()'] {'#' &'#'} '#%'
    | ['()'] ['$'] {'0' &'0'} '0'
    | ['()'] {'0' &'0%'} '0%'
    | ['()'] ['$'] {'#' &'0'} {'0' &'0'} '0'
    ;

How to correctly describe the grammar so that when you try to parse a string, you get the following result:

For string '######' we get the result (['#', '#', '#', '#', '#'], '#') it's True (worked first rule)

For string '#####%' we get the result (['#', '#', '#', '#'], '#') it's False it should be (['#', '#', '#', '#'], '#%') (worked first but should have been second rule)

For string '000000' we get the result (['0', '0', '0', '0', '0'], '0') it's True (worked third rule)

For string '###000' we get the result (['#', '#'], '#') it's False (worked first but should have been fifth rule)

Are the rules given in the documentation absurd or am I doing something wrong ?

1

There are 1 best solutions below

0
On

Tatsu try rules in the order they are declared.

So in your example:

| ['()'] ['$'] {'#' &'#'} '#'
| ['()'] {'#' &'#'} '#%'

The first rule will successfully match ##### before even reading the %

Reversing the two options will make Tatsu try to parse #% first, and only try # if it fails.

NB: the ~ symbol can also be used to avoid trying other options for a rule once a pattern has been successfully parsed.