pythonbnfebnfgrakotatsu

How to implement this kind of EBNF grammar (lookahead)?


I am trying to parse the string "###" using an EBNF grammar in TatSu (grako) of this kind:

grammar = """mask =
                  | ['()'] ['$'] {'#'} '#'
                  | ['()'] {'#'} '#%'
                  | ['()'] ['$'] {'#'} {'0'} '0' '.#' {'#'}
"""

I get an error:

tatsu.exceptions.FailedToken: (1:1) expecting '#' :
#
^
mask
start

I suspect that the search {'#'} (match '#' zero or more times) is first performed and after that cannot find '#' (required character '#'). Is it possible to somehow implement it so that at first I see the required character '#' and only after that I look for {'#'} additional characters ?


Solution

  • You will need to provide a &('#'|'0') positive lookahead to all the instances of the optional '#' prefixes:

        mask = ['()'] ['$'] {'#' &('#'|'0')} '#'
             | # and so on...
    

    Notice that the repeating '0' prefix in the last line will have the same problem. You will need to add a &'0' lookahead check to it, too.