Разбор опций с 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 ';' 
    ;

но мне интересно, если:

  1. это намеренно и
  2. есть ли лучший синтаксис?

Это проблема PEG в целом или инструментальная (Grako)?

1 ответ

Здесь говорится, что в PEG оператору выбора приказано избегать двусмысленности CFG при использовании первого совпадения.

В вашем первом примере

 [тип данных] 
успешно разбирает идентификатор, поэтому он не может найти его : вместо другого идентификатора. Это может быть потому, что [data_type] ведет себя как (data_type | ε) так будет всегда разбирать data_type с первым идентификатором.

В

 [идентификатор типа данных ':' | идентификатор ':' ] 
первый выбор терпит неудачу, когда нет второго идентификатора, поэтому анализатор возвращается назад и пытается выполнить второй выбор.

Другие вопросы по тегам