TinyPG неправильно анализирует эту грамматику, ошибку или плохую грамматику?
Мне нужно разобрать простой язык, который я не проектировал, поэтому я не могу изменить язык. Мне нужны результаты в C#, поэтому я использую TinyPG, потому что он очень прост в использовании и не требует внешних библиотек для запуска парсера.
Все шло довольно хорошо, пока я не столкнулся с этой конструкцией на языке. (Это упрощенная версия, но она показывает проблему):
EOF -> @"^\s*$";
[Skip] WHITESPACE -> @"\s+";
LIST -> "LIST";
END -> "END";
IDENTIFIER -> @"[a-zA-Z_][a-zA-Z0-9_]*";
Expr -> LIST IDENTIFIER+ END;
Start -> (Expr)+ EOF;
Результирующий синтаксический анализатор не может проанализировать это:
LIST foo BAR Baz END
потому что это жадно лекс IDENTIFIER
вместо того, чтобы правильно как END
ключевое слово.
Итак, вот мои вопросы:
Является ли эта грамматика неоднозначной или неправильной для анализа LL(1)? Или это ошибка в TinyPG?
Есть ли способ изменить грамматику так, чтобы
TinyPG
правильно проанализирует пример строки?Есть ли другие предложения для простого парсера, который выводит код в
C#
и не требует дополнительных библиотек? Я смотрел наLLLPG
а такжеANTLR4
, но нашел их гораздо более хлопотным, чемTinyPG
,
1 ответ
Вы можете быть тем же парнем, поскольку проблема выглядит идентично той, что я ответил на GitHub, но здесь она снова для людей, которые гуглили эту проблему.
Вот пример из проекта Simple-CIL-compiler. Идентификатор должен перехватывать отдельные слова, кроме перечисленных, что означает, что вы должны включить токен исключения в идентификатор
IDENTIFIER-> @"[a-zA-Z_][a-zA-Z0-9_]*(?<!(^)(end|else|do|while|for|true|false|return|to|incby|global|or|and|not|write|readnum|readstr|call))(?!\w)";
Надеюсь, это поможет.