Грамматика BNF + синтаксический анализатор Gold LALR, не в состоянии отличить специальный случай NewLine от пробела

  • Я хочу рассматривать пробелы и символы новой строки как обычные пробелы.
  • Я хочу отличать новые строки от других пробелов, кроме того, чтобы разрешить особый случай.

Первая попытка написать совместимую грамматику не удалась.

Вот грамматика:

! ------------------------------------------------- Sets

{WS}           = {Whitespace} - {CR} - {LF}
{ID Head}      = {Letter} + [_]
{ID Tail}      = {Alphanumeric} + [_]
{String Chars} = {Printable} + {HT} - ["\]

! ------------------------------------------------- Terminals

! The following defines the Whitespace terminal using the {WS}
! set - which excludes the carriage return and line feed 
! characters

Whitespace    = {WS}+ | {CR}{LF} | {CR} | {LF}
!NewLine       = {CR}{LF} | {CR} | {LF}
MyNewLine      = {CR}{LF} | {CR} | {LF}

3 ответа

Решение

Они неоднозначны, потому что они оба содержат один и тот же набор {CR}{LF} | {CR} | {LF},

Учитывая вход {CR}{LF} парсер не может сказать, с каким терминалом он должен совпадать.

Парсер, управляемый таблицами, не предназначен для непосредственной обработки "особых случаев". Если вы хотите игнорировать новые строки в одних контекстах, но приписывать им значение в других контекстах, вам придется обрабатывать это в ваших сокращениях (то есть разбивать новые строки по отдельности и отбрасывать их в ваших сокращениях), но это будет ужасно,

(Потенциально) лучшее решение состоит в том, чтобы использовать состояния токенизатора (возможно, контролируемые парсером), чтобы изменить, как вводятся символы новой строки. Трудно сказать без полного понимания вашей грамматики. Плюс, прошло несколько лет с тех пор, как я с этим связался.

Я думаю, что грамматика неоднозначна в том смысле, что и Whitespace, и MyNewLine соответствуют символам новой строки. Поскольку это приводит к шаткой работе по-своему, я предлагаю обнаруживать пробелы и новые строки по отдельности и решать, что делать с новой строкой в ​​каждом конкретном случае.

Я не слишком опытен в этой области, но это то, что я помню из своего класса Theory Of Computation и класса Compiler Design.

Надеюсь, это поможет.

Поздний ответ.

К моему ужасу, я только недавно умер в последнее время;-).

Продолжайте использовать обычные линейные объявления грамматики

! ====================================================================
{Whitespace Ch} = {Whitespace} - {CR} - {LF}

Whitespace = {Whitespace Ch}+
Newline    = {CR}{LF} | {CR} | {LF}
! ====================================================================

Различие между пробелами и символами новой строки уже учтено!

Рассмотрите возможность рассмотрения вашего особого случая при написании правил производства.

Для сложных случаев вам может даже потребоваться определить какой-нибудь виртуальный терминал (продвинутый метод).

Вы можете разработать свою грамматику и спросить, разместив ее снова.

Последнее редактирование: поделитесь, если вы уже обратились к проблеме. Благодарю.

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