Я пишу парсер, используя Python/lex, и пытаюсь создать запись для удаления комментариев в стиле C. Моя текущая (неисправная) попытка:Удаление комментариев с помощью lex: почему это не работает?
def t_comment_ignore(t):
r'(\/\*[^*]*\*\/)|(//[^\n]*)'
pass
Это произвело причуду, которая сбила меня с толку. Когда я разобрать строку ниже:
input = """
if // else mystery
=/*=*/=
true /* false
*/ return"""
Выходные лексемы:
['IF', 'EQUAL', 'TIMES', 'EQUAL', 'DIVIDE', 'EQUAL', 'TRUE', 'RETURN']
Видимо комментарий на линии 3 не была признана правильной и 3 символов в нем были возвращены в качестве маркеров.
Но если добавить пробел перед комментарием в строке 3, а именно:
input = """
if // else mystery
= /*=*/=
true /* false
*/ return"""
я получаю:
['IF', 'EQUAL', 'EQUAL', 'TRUE', 'RETURN']
Debugging показал, что все 3 комментариев были признаны правильно, когда дополнительное пространство было добавлено.
Ну, я совершенно не согласен с этим поведением. Любой вход оценивается.
Спасибо, Пауло
PS: Как некоторые, наверное, заметили, это энчилада от задачи Набор 2 в https://www.udacity.com/wiki/cs262. Они дают более сложное решение, используя другие функции lex, но мне интересно, мой подход звучит и мой код исправляется.
Ваша функция 't_comment_ignore' фактически ничего не делает. – user2357112
Как ваша реализация обрабатывает '*' в комментарии '/ * * /'? Также как он обрабатывает что-то вроде '/ * comment // comment */return'? –
1-й случай не был обработан правильно - средняя звездочка «сбивает» [^ *] в регулярном выражении, но вторая работала нормально - [^ *] «chomps» - двойная косая черта. Я изменил регулярное выражение на '(\/\ *. * \ * \ /) | (// [^ \ n] *)' и '/ * * * /' обрабатывается OK сейчас. –