BNF грамматика + анализатор Gold LALR, не различая особый случай NewLine от пробела - PullRequest
2 голосов
/ 01 марта 2009
  • Я хочу рассматривать пробелы и символы новой строки как обычные пробелы.
  • Я хочу отличать новые строки от других пробелов, кроме того, чтобы разрешить особый случай.

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

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

! ------------------------------------------------- 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 ]

5 голосов
/ 01 марта 2009

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

С учетом ввода {CR}{LF} парсер не может определить, к какому терминалу он должен соответствовать.

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

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

4 голосов
/ 01 марта 2009

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

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

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

0 голосов
/ 07 декабря 2011

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

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

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

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

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

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

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

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

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

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

...