2014-09-16 4 views
2

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

... 
%% 
COMMENT ("(^"|"/^")(.|\n)*("^)"|"^/") 
%% 
{COMMENT} printf("comment: %s\n", yytext); 
[.]*  printf("other: %s\n", yytext); 
%% 
... 

и в этом случае входной

(^^^^^^^^^ 
this is a comment 
^) 

function(arg); 
sometext 

выводит:

comment: (^^^^^^^^^ 
this is a comment 
^) 

function(arg) 
other: ; 
sometext 

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

+0

У меня была работа с тестовым сайтом http://regexr.com/39gl2 с шаблоном \ (\ * (. \\ n) *? \ * \), Однако, с lex, похоже, нет эффект. Я не вижу, как (. | \ N) * и (. | \ N) *? все равно. –

+0

В lex это не так.Я не знаю регекса «тестовый сайт», который понимает синтаксис lex, но вы можете подойти ближе, выбрав синтаксис Posix, если он доступен. В lex (и вообще) '. *' Соответствует максимально возможной последовательности, а не последовательности до «следующего совпадения». – rici

ответ

1

Возможно, вам следует ознакомиться с руководством по гибкому руководству или, по крайней мере, разделами на patterns и в следующем разделе "How the input is matched". Из последнего, я процитирую:

Если совпадение не найдено, то правилопо умолчанию выполняется: следующий символ на входе считается соответствием и копируются в стандартный вывод.

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

%option nodefault 

в первом разделе вашего ввода с гибким интерфейсом. Это заставит вас написать собственное резервное правило, потому что непревзойденные символы будут вызывать ошибку.

Большинство современных библиотек регулярных выражений допускают «не жадные» повторения. (Однако некоторые библиотеки не выполняют эту функцию очень эффективно.) Но Flex не делает этого. Таким образом, в Perl регулярное выражение \(.*?\) (- это не жадное совпадение) будет соответствовать первой открытой скобке и символам до следующей закрывающей круглой скобки, тогда как \(.*\) будет соответствовать первой открытой скобке до последней закрывающей скобкой. В Flex оба шаблона будут соответствовать последней скобке.

Обратите внимание, что \([^()]*\) является гораздо более полезным регулярное выражение: он будет соответствовать первому сокровенное скобки выражение: то есть, открытое и закрывающую скобку без промежуточных скобок. Поскольку мы явно указываем, что мы готовы сопоставить в середине, нет никакой разницы между жадным и не-жадным сопоставлением; шаблон точен. Когда это возможно, это почти всегда лучшее решение. Однако сложнее применить в случае, когда перевернутое совпадение длиннее одного символа.

Хотя всегда можно создавать регулярное выражение, которое является обратным к другому регулярному выражению, это не всегда легко. И правдоподобной альтернативой является использование flex "start conditions". В этом разделе вы найдете пример для lexing C comments, который несколько похож на то, что вы пытаетесь сделать.

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