Unix Flex Regex для многострочных комментариев - PullRequest
9 голосов
/ 21 января 2011

Я делаю Lexical Analyzer, используя Flex в Unix.Если вы когда-либо использовали его раньше, вы знаете, что в основном просто определяете регулярное выражение для токенов любого языка, для которого вы пишете Lexical Analyzer.Я застрял на заключительной части.Мне нужен правильный Regex для многострочных комментариев, который допускает что-то вроде

/* This is a comment \*/

, но также позволяет

/* This **** //// is another type of comment */

Может кто-нибудь помочь с этим?

Ответы [ 4 ]

15 голосов
/ 21 января 2011

Вы не сопоставляете комментарии в стиле C с простым регулярным выражением во Flex;они требуют более сложного метода сопоставления, основанного на начальных состояниях. Flex FAQ говорит, как (ну, они делают для формы /*...*/; обработка другой формы только в состоянии <INITIAL> должна быть простой).

8 голосов
/ 01 сентября 2015

Однако, если вам нужно обойтись только с помощью регулярных выражений, существует действительно не слишком сложное решение:


"/ *" ([^ *] | (\ * + [^ * /])) * \ * + \ /
Полное объяснение и вывод этого регулярного выражения превосходно разработаны на здесь .
Короче: "/ *" отмечает начало комментария ([^ *] | (\ * + [^ * /])) * говорит, что принимает все символы, которые не являются * ([^ *]), или принимает последовательность из одного или нескольких *, пока последовательность после него нет ни «*», ни «/» ((* + [^ * /])). Это означает, что будут приняты все последовательности ****** ... за исключением ***** /, поскольку вы не можете найти там последовательность *, за которой не следует * или / /. Случай ******* / обрабатывается последним битом RegEx, который соответствует любому числу *, за которым следует /, чтобы обозначить конец комментария, т. Е. \ * + \ /
0 голосов

http://www.lysator.liu.se/c/ANSI-C-grammar-l.html делает:

"/*"            { comment(); }

comment() {
    char c, c1;

loop:
    while ((c = input()) != '*' && c != 0)
        putchar(c);

    if ((c1 = input()) != '/' && c != 0) {
        unput(c1);
        goto loop;
    }

    if (c != 0)
        putchar(c1);
}

Вопрос, который также решил бы это: Как мне написать не жадное совпадение в LEX / FLEX?

0 голосов
/ 21 января 2011

я не знаю flex, но я знаю регулярные выражения./\/\*.*?\*\//s должен совпадать с обоими типами (в PCRE), но если вам нужно дифференцировать их в вашем анализаторе, вы можете затем повторить список совпадений, чтобы увидеть, являются ли они вторым типом с /\*\*\s+\/{4}/

...