Unix Flex Regex для многострочных комментариев

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

/* This is a comment \*/

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

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

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

4 ответа

Решение

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

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


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

  • 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?

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

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