如何去掉C ++风格的单行注释(`// ...`)

时间:2011-09-13 08:13:25

标签: regex parsing comments dsl

对于我写的小型DSL,我正在寻找一个正则表达式,以匹配C ++ //语法末尾的注释字符串。 简单的案例:

someVariable = 12345; // assignment

匹配很简单,但是当我在同一行中有一个字符串时问题就开始了:

someFunctionCall("Hello // world"); // call with a string

字符串中的//不应与评论匹配


编辑 - 编写DSL的东西不是我的。就我而言,这是一个黑盒子,我不想改变,也不支持评论。我只是想添加一个瘦包装器来支持注释。

2 个答案:

答案 0 :(得分:2)

修改

由于您有效地预处理源文件,为什么不使用现有的预处理器?如果该语言与C / C ++非常相似(特别是关于引用和字符串文字),您将能够使用cpp -P

 echo 'int main() { char* sz="Hello//world"; /*profit*/ } // comment' | cpp -P

输出:int main() { char* sz="Hello//world"; }


其他想法:

使用适当的词法分析器/解析器

看看

  • CoCo / R(适用于Java,C ++,C#等)
  • ANTLR(同上)
  • 提升精神(使用精灵Lex让你更容易删除评论)

所有套件都带有解析C,C ++或其子集的示例语法

答案 1 :(得分:2)

  

shoosh写道:

     

编辑 - 编写DSL的东西不是我的。就我而言,这是一个黑盒子,我不想改变,也不支持评论。我只是想添加一个瘦包装器来支持注释。

在这种情况下,创建一个匹配三个标记之一的非常简单的词法分析器:

  1. // ...评论
  2. 字符串文字:" ... "
  3. 或者,如果以上都不匹配,则匹配任何单个字符
  4. 现在,在迭代这3种不同类型的令牌时,只需将标记(2)和(3)打印到标准输出(或文件)即可获得源文件的未注释版本。

    使用GNU Flex的演示:

    示例输入文件 in.txt

    someVariable = 12345; // assignment
    // only a comment
    someFunctionCall("Hello // world"); // call with a string
    someOtherFunctionCall("Hello // \" world"); // call with a string and 
                                                // an escaped quote
    

    词法分析器语法文件 demo.l

    %%
    "//"[^\r\n]*             { /* skip comments */ }
    "\""([^"]|[\\].)*"\""    {printf("%s", yytext);}
    .                        {printf("%s", yytext);}
    %%
    int main(int argc, char **argv)
    {
        while(yylex() != 0);
        return 0;
    }
    

    要运行演示,请执行:

    flex demo.l 
    cc lex.yy.c -lfl
    ./a.out < in.txt
    

    将打印以下内容到控制台:

    someVariable = 12345; 
    
    someFunctionCall("Hello // world"); 
    someOtherFunctionCall("Hello // \" world"); 
    

    修改

    我对C / C ++并不熟悉,只是看到@ sehe建议使用预处理器。这似乎是一个比创建自己的(小)词法分析器更好的选择。但我想我会留下这个答案,因为它显示了如果没有可用的预处理器如何处理这种东西(无论出于何种原因:或许cpp无法识别DSL的某些部分?)。 / p>