Разбор опций с PEG (Grako) не дотягивает?
Мой коллега PaulS спросил меня следующее:
Я пишу парсер для существующего языка (SystemVerilog - стандарт IEEE), и в спецификации есть правило, похожее по структуре на следующее:
cover_point
=
[[data_type] identifier ':' ] 'coverpoint' identifier ';'
;
data_type
=
'int' | 'float' | identifier
;
identifier
=
?/\w+/?
;
Проблема в том, что при разборе следующей допустимой строки:
anIdentifier: coverpoint another_identifier;
anIdentifier
соответствует data_type
(через опцию идентификатора) успешно, что означает, что Grako ищет другой идентификатор после него и затем терпит неудачу. Затем он не пытается проанализировать без части data_type.
Я могу переписать правило следующим образом:
cover_point_rewrite
=
[data_type identifier ':' | identifier ':' ] 'coverpoint' identifier ';'
;
но мне интересно, если:
- это намеренно и
- есть ли лучший синтаксис?
Это проблема PEG в целом или инструментальная (Grako)?
1 ответ
Здесь говорится, что в PEG оператору выбора приказано избегать двусмысленности CFG при использовании первого совпадения.
В вашем первом примере
[тип данных]успешно разбирает идентификатор, поэтому он не может найти его
:
вместо другого идентификатора. Это может быть потому, что [data_type]
ведет себя как (data_type | ε)
так будет всегда разбирать data_type
с первым идентификатором.В
[идентификатор типа данных ':' | идентификатор ':' ]первый выбор терпит неудачу, когда нет второго идентификатора, поэтому анализатор возвращается назад и пытается выполнить второй выбор.