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