0

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

Входной

int i = 0 ; int j = i + 3; 

Выход

int KEYWORD 
i  IDENTIFIER 
=  OPERATOR 
;  PUNCTUATION 
int KEYWORD 
j  IDENTIFIER 
=  OPERATOR 
i  IDENTIFIER 
+  OPERATOR 
3  INTEGER_CONSTANT 
;  PUNCTUATION 

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

Входной

int i = "1.2.2222.+\<++++ 

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

Проблема возникает с неоднозначными ситуациями типа +, где + может быть либо оператором сложения, либо частью предстоящего целочисленного литерала или даже части оператора инкремента. Требования к учителю объясняются в следующем параграфе.

, если a + предшествует +, оно должно обрабатываться как оператор приращения. Простыми словами программа должна стараться искать все возможности и выбирать лучшее. Это означает, что если у программы есть допустимый ввод, тогда какой-то недопустимый ввод снова приведет к некоторому действительному вводу, который не должен останавливаться на этом недопустимом входе, а не будет искать правильные литералы. Для меня, хотя я против этого. Мой аргумент заключается в том, что если строка программы становится недействительной при определенном индексе, она должна прекратить обработку, потому что мы все-таки не записываем систему проверки ошибок.

Я попытался закодировать все возможности, используя сложную (для меня) вложенную структуру if else и получил частичный успех. Возможно, вы предложите мне более простое и элегантное решение. Я также думал о структурировании этой проблемы в машине состояния, но я не уверен, потому что я никогда не реализовал машину состояний, отличную от DFA, которая может просто сказать «да» или «нет» для сопоставления шаблонов.

Как вы можете видеть, это вопрос домашней работы, но я не прошу только код.

+0

Лучший способ, с помощью которого IMHO обрабатывать неправильные лексические элементы, - это вернуть их в парсер. Вы уже возвращаете «+», «;» и т. Д. (И лучше всего возвращать их как самих себя, а не сопоставлять их с постоянным именем): поэтому, если вы получаете незаконный символ, вы просто возвращаете его. Тогда синтаксический анализатор может справиться с этим с помощью любой схемы восстановления ошибок. Это лучше, чем иметь отдельную схему восстановления ошибок для лексического анализатора, которая на практике может состоять только в том, чтобы выбросить персонажа. Парсер также может это сделать, но он также может попытаться сократить, чтобы узнать, помогают ли они. – EJP

ответ

0

Обычный подход к лексическому анализу заключается в использовании алгоритма "maximal munch": входной поток делится на токены, повторяя самый длинный префикс, который может быть единственным токеном. См. this answer для одного алгоритма.

Это иногда необходимо делать исключение из этого правила (в C++, например, <:: обычно lexed в <, ::), но в целом, максимальное правило жует легко реализовать и, что более важно, чтобы прочитать ,

Смежные вопросы