В этой грамматике нет ничего плохого, кроме:
- она представляет собой очень старую версию C
- , для нее требуется лексический анализатор, который может каким-то образом различать guish между
IDENTIFIER
и TYPE_NAME
- он даже не пытается обработать фазы препроцессора
Кроме того, он имеет один конфликт сдвига / уменьшения в результате "болтаться" двусмысленность. Однако этот конфликт может быть проигнорирован, потому что алгоритм разрешения конфликтов Bison дает правильный результат в этом случае. (Вы можете подавить предупреждение либо с помощью директивы %expect
, либо с помощью объявления приоритета, которое способствует смещению else
по сравнению с уменьшением if
. Или вы можете устранить неоднозначность в грамматике, используя описанную технику . на странице Википедии, ссылки на которую приведены выше. (Примечание: я не говорю о коде копирования и вставки со страницы Википедии. В случае C вам необходимо рассмотреть все случаи составных операторов, которые заканчиваются на if
Statement.)
Более того, синтаксический анализатор LR не является рекурсивным, и у него нет проблем, которые можно было бы описать как сбой в «обработке рекурсивных множественных выражений». (У вас может быть такая проблема с анализатором рекурсивного спуска , хотя обойти эту проблему довольно легко.)
Таким образом, любые проблемы, с которыми вы могли столкнуться (если ваш вопрос относится к конкретной проблеме), не имеют ничего общего с тем, что описано в вашем вопросе.
Из перечисленных выше проблем больше всего беспокоит syntacti c Неоднозначность приведенного оператора. Оператор приведения не является на самом деле неоднозначным; ясно, что C компиляторам удается корректно компилировать такие выражения. Но для различения двух возможных синтаксических разборов, например, (x)-y*z
, необходимо знать, называет ли x
тип или переменную.
В C все имена имеют лексическую область, поэтому, безусловно, это возможно разрешить x
во время компиляции. Но резолюция не является контекстно-свободной. Поскольку GLR также является техникой парсинга контекстно-свободных грамматик, использование синтаксического анализатора GLR не поможет вам напрямую. Это может быть полезно в том смысле, что синтаксические анализаторы GLR могут теоретически создавать «леса разбора», а не деревья разбора; то есть выходные данные синтаксического анализатора GLR могут эффективно содержать все возможные правильные синтаксические разборы, оставляя возможность устранить неоднозначность путем создания таблиц символов для каждой области, а затем выбирать между альтернативными синтаксическими анализами, исследуя действующую привязку имени на каждом сайте. (Это работает, потому что объявления псевдонимов типов - "typedefs" - не являются неоднозначными, поэтому все потенциальные синтаксические разборы будут иметь одинаковые объявления псевдонимов.)
Обычное решение, однако, состоит в том, чтобы проанализировать текст программы, используя детерминированный синтаксический анализатор c, поддерживающий таблицу символов во время синтаксического анализа и предоставляющий лексическому анализатору доступ к этой таблице символов, чтобы она могла различать guish между IDENTIFIER
и TYPE_NAME
, как того требует грамматика Вы ссылку. Эту технику вежливо называют «лексической обратной связью», хотя ее также часто называют «хакером лексера».