Как мне написать не жадное совпадение в LEX / FLEX?

Я пытаюсь проанализировать устаревший язык (который похож на 'C'), используя FLEX и BISON. Все работает хорошо, за исключением соответствия строк.

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

"hello"
""
"\"

Я использую следующее правило для соответствия строковых литералов:

\".*\"            { yylval.strval = _strdup( yytext ); return LIT_STRING; }

К сожалению, это жадное совпадение, поэтому оно соответствует коду:

"hello", "world"

Как одна строка (hello", "world).

Обычный не жадный квантификатор .*? похоже, не работает в FLEX. Есть идеи?

2 ответа

Решение

Просто запретите иметь кавычки между кавычками.

\ "[^"] * \"

Обратная косая черта избежала кавычек

Следующее также позволяет это:

\"(\\.|[^\n"\\])*\" {
        fprintf( yyout, "STRING: %s\n", yytext );
    }

и запрещает переводы строк внутри строковых констант.

Например:

>>> "a\"b""c\d"""
STRING: "a\"b"
STRING: "c\d"
STRING: ""

и терпит неудачу на:

>>> "\"

При реализации таких C-подобных функций обязательно посмотрите на существующие реализации Lex, например: http://www.lysator.liu.se/c/ANSI-C-grammar-l.html

Другие вопросы по тегам