2016-12-04 13 views
0

Я начал писать свой собственный лексер и столкнулся с проблемой с токенизирующими строками, поскольку у них есть символ начала (") и связанный с ним символ конца (").Лексер: обработка неиспользуемых строк, в то время как токенизация

Кто-нибудь знает об общем методе, в котором лексер может справиться с лексикой и продолжить лексирование с неисчерпаемой строкой? Я думаю, что ANTLR может это сделать, обрабатывается ли ATN в ANTLR?

я вижу там быть два вопроса здесь в предположении, что строки должны оканчиваются на одной строке:

  1. окончание строки происходит на отдельной строке - следовательно, предупреждая пользователя, что строки можно поместить только один линия.
  2. Окончание строки не происходит, тогда, когда вы знаете, что действительная точка для продолжения находится? Используйте эвристику следующего действительного токена после новой строки.

т.е.

char *mystring = "my string which is unterminated.... 
int id = 20; 

ответ

1

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

Вы можете пропустить полезную закрытую скобку :

printf("%s\n, line); 

, но у вас, вероятно, есть правила восстановления, которые могут справиться с этим.

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

+0

Я читал в другом ответе, что обработка ошибок намного лучше отбрасывается на парсер, а не на lexer. Каково ваше мнение об этом и как вы его передадите, поскольку здесь нет токена ... – Har

+1

@har: Конечно, есть аргумент в пользу централизации обработки ошибок, но в сканере всегда будут обнаружены лексические ошибки. Обычно я просто вызываю 'yyerror', чтобы сообщить об ошибке; в случае плохого токена (в равной степени относится к плохим числам), как правило, ничего больше не нужно делать. Вы могли бы, конечно, вернуть токен «плохой литерал», а затем создать сообщение об ошибке в синтаксическом анализаторе с производством единицы, которое превращает «BAD_LITERAL» в значение «value» (или независимо от вашего базового нетерминала) и сигнализирует ошибка. – rici