Как реализовать приоритет выражений Бакус-Наур Форма

В документации есть такая грамматика:

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

Как правильно описать грамматику, чтобы при попытке разобрать строку вы получили следующий результат:

Для строки '######' получаем результат (['#', '#', '#', '#', '#'], '#') True (сработало первое правило)

Для строки '#####%' мы получаем результат (['#', '#', '#', '#'], '#') это False, должно быть (['#', '#', '#', '#'], '#%') (сначала работало, но должно было быть вторым правилом)

Для строки '000000' получаем результат (['0', '0', '0', '0', '0'], '0') True (сработало третье правило)

Для строки '###000' мы получаем результат (['#', '#'], '#'), это False (сначала работало, но должно было быть пятое правило)

Правила, приведенные в документации, абсурдны или я что-то делаю не так?


person MadInc    schedule 25.05.2020    source источник


Ответы (1)


Тацу пробует правила в том порядке, в котором они объявлены.

Итак, в вашем примере:

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

Первое правило будет успешно соответствовать ##### еще до чтения %

Если поменять местами эти два варианта, Татсу попытается сначала проанализировать #%, и только #, если это не удастся.

NB: символ ~ также можно использовать, чтобы не пытаться использовать другие параметры правила после успешного анализа шаблона.

person linkdd    schedule 17.10.2020