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

StackOverflow https://stackoverflow.com/questions/599409

  •  11-09-2019
  •  | 
  •  

Вопрос

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

Первая попытка написать соответствующую требованиям грамматику завершается неудачей.

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

! ------------------------------------------------- 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}
Это было полезно?

Решение

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

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

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

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

Другие советы

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

Я не слишком опытен в этой области, но это то, что я помню из моего класса Теории вычислений и класса проектирования компилятора.

Я надеюсь, что это поможет.

Запоздалый ответ.

К моему ужасу, я всего лишь недавний участник late bloomer ;-).

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

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

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

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

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

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

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

Последнее редактирование:Пожалуйста, поделитесь, если вы уже обращались к этой проблеме.Спасибо.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top