Как сказать сканеру синтаксического анализатора языка, что строка является литералом, а не идентификатором, посмотрев на предыдущий токен - PullRequest
1 голос
/ 10 января 2020

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

У меня следующий запрос:

status=acknowledged

И я ожидаю, что status будет идентификатором переменной и acknowledged будет строковым литералом. Единственный способ определить это - посмотреть на оператор = между ними.

Теоретически сканер должен иметь возможность вернуть новый токен, не глядя на предыдущие, но если это так, как бы вы отличали guish идентификатор от строкового литерала? Помните, что я не могу просто добавить двойные кавычки вокруг строки acknowledged, так как мне нужно работать с языком запросов, который уже существует, и я не могу вносить в него какие-либо изменения.

Если я просто следите за предыдущими N токенами внутри сканера и действуйте соответственно?

Все становится еще более запутанным, если у меня что-то вроде этого:

status=acknowledged&visibility=all

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

1 Ответ

4 голосов
/ 10 января 2020

Вопрос, который вам нужно задать себе: «Нужно ли моему парсеру знать, является ли acknowledged идентификатором переменной или строковым литералом?»

И я рискну предположить, что ответ «Нет, это не так». Вы можете разобрать выражение типа status=acknowledged&visibility=all, не зная ничего о status и acknowledged (или visibility и all), кроме того, что они являются операндами. Возможной лексической категорией для таких операндов могут быть «голые слова» (термин происходит от Perl) или «атомы» (Лисп).

Конечно, в какой-то момент вы захотите выяснить, что эти токены означают (что по определению является вопросом семанти c), и в этот момент некоторые из них будут преобразованы в «имя переменной», а другие - в «строковый литерал» (без кавычек). Если, например, ваш оператор = настаивает на том, чтобы его левый операнд был именем переменной и чтобы его правый оператор был литералом, вы могли легко выполнить соответствующие преобразования во время обхода дерева синтаксического анализа сверху вниз. Я почти уверен, что такой подход используется большинством подобных анализаторов.

По принципу разделения интересов каждый компонент в языковом процессоре должен ограничивать себя, насколько это возможно, одной частью головоломка. Постарайтесь избежать соблазна преждевременно провести анализ, который может быть более удобно перенесен на соответствующую будущую фазу. Вы обнаружите, что все логи c проще, если вы работаете по этой схеме.

...