Устранение неоднозначности в простой грамматике Instaparse
[Также опубликовано в списке рассылки Instaparse, но также и здесь, так как я предполагаю, что это довольно общая проблема]
Рассмотрим грамматику
D = (B|S)*
S = 'S' B*
B = 'B'
(Это версия Instaparse BNF...)
B может произойти сам по себе или после S; если последнее, то оно должно рассматриваться как часть выражения SER (без каламбура).
Пример:
(-> "D = (B|S)*
S = 'S' B*
B = 'B'"
parser
(parses "BSBB"))
;;=>
([:D [:B "B"] [:S "S"] [:B "B"] [:B "B"]]
[:D [:B "B"] [:S "S" [:B "B"] [:B "B"]]] ;; <------
[:D [:B "B"] [:S "S" [:B "B"]] [:B "B"]])
Я бы хотел, чтобы совпадал только второй результат - так, чтобы B был включен в S, когда это возможно, и удалил другие опции. Что нужно сделать с моим парсером, чтобы сделать это изменение?
Больше примеров выражений показано в этой сущности.
1 ответ
Решение
Вы можете использовать отрицательный прогноз, чтобы постулировать, что совпадения S
не должно сопровождаться действительным B
s:
(-> "
D = (B|S)*
S = 'S' B* !B
B = 'B'
"
insta/parser
(insta/parses "BSBB"))
;= ([:D [:B "B"] [:S "S" [:B "B"] [:B "B"]]])
Это работает для всех примеров (текущей версии) в вашей сути.