【问题标题】:Use flex to uppercase C comments使用 flex 将 C 注释大写
【发布时间】:2016-09-02 08:39:38
【问题描述】:

我想使用 flex 将文本中的 C cmets 大写。

这是我的弹性代码:

%{
#include <ctype.h>
%}

%%

\/\/.* {
    for(int i = 0; i < strlen(yytext); i++)
        printf("%c", toupper(yytext[i]));   
}

\/\*[^\*]*\*(\*|[^\*\/][^\*]*)*\/ {
    for(int i = 0; i < strlen(yytext); i++)
        printf("%c", toupper(yytext[i]));
}

%%

int main(int argc ,char* argv[]) {
    yylex();
    return 0;
}

int yywrap() {
    return 1;
}

这是测试文本:

/*aBc*aBc/aBc*/
/** /aBc*/
/*aBc*/aBc*/
aBc
aBc/*aBC
aBc/aBc*aBc
aBc**/
/*aBc/*aBc
//aBc
//aBc
aBc

结果:

/*ABC*ABC/ABC*/
/** /ABC*/
/*ABC*/aBc*/
aBc
aBc/*ABC
ABC/ABC*ABC
ABC**/
/*ABC/*ABC
//ABC
//aBc
aBc

结果中倒数第二行和第四行很奇怪。

我的程序有什么问题?

【问题讨论】:

    标签: compiler-construction flex-lexer lex


    【解决方案1】:

    问题只是你使用的正则表达式不正确。

    这是 C 风格 cmets 的正确 flex 正则表达式:

    "/*"[^*]*"*"+([^*/][^*]*"*"+)*"/"
    

    使用双引号(一种弹性功能)来引用正则表达式元字符。请注意,不必在字符类中转义正则表达式运算符。

    替代品也不是很漂亮:

    1. 靠木林:

      \/\*[^*]*\*+([^*/][^*]*\*+)*\/
      
    2. 字符类的混乱:

      [/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]
      

    【讨论】:

    • 感谢您的回答!我从 DFA 重写了正则表达式,发现遗漏了一个“*”。糟糕...现在是\/\*[^\*]*\*(\*|[^\*\/][^\*]*\*)*\/,它可能与您编写的正则表达式具有相同的效果。
    • 元字符(如“*”)的转义在字符类中是可选的。
    • @chaosink;是的,这就是“不必要”的意思。在 Posix 正则表达式中,这是不允许的,但 flex 更慷慨。不过,我总是建议不要这样做,因为它不会提高可读性恕我直言,你可能有一天想在不允许转义的方言中使用正则表达式。
    • 您的(新)正则表达式包括 γ(γ |ωγ)*(其中 γ 是星号,ω 是斜线或星号以外的任何内容,后跟任意数量的非星号)。 (γ |ωγ)* 等价于 (ω?γ)*,后者又等价于 γ*(ωγ+)*。所以 γ(γ |ωγ)* 可以重写为 γ+(ωγ+)*。这和我的正则表达式一样。 FWIW。
    • 我怀疑 (ω?γ)* 是否等同于 γ*(ωγ+)*。我怎样才能从后者中得到 γωγγ?顺便问一下,有没有关于正则表达式的简化或等效的引导?
    猜你喜欢
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    相关资源
    最近更新 更多