Regex 如何删除C++风格的单行注释(…//…)

Regex 如何删除C++风格的单行注释(…//…),regex,parsing,comments,dsl,Regex,Parsing,Comments,Dsl,我写的是一个小的DSL,我正在寻找一个正则表达式,以匹配C++的//语法结尾处的注释字符串。 简单的情况是: someVariable = 12345; // assignment 匹配起来很简单,但当我在同一行中有一个字符串时,问题就开始了: someFunctionCall("Hello // world"); // call with a string 字符串中的//不应作为注释匹配 编辑-编译DSL的东西不是我的。就我而言,这是一个黑匣子,我不想改变,也不支持评论。我只想添加一个薄包

我写的是一个小的DSL,我正在寻找一个正则表达式,以匹配C++的//语法结尾处的注释字符串。 简单的情况是:

someVariable = 12345; // assignment
匹配起来很简单,但当我在同一行中有一个字符串时,问题就开始了:

someFunctionCall("Hello // world"); // call with a string
字符串中的//不应作为注释匹配

编辑-编译DSL的东西不是我的。就我而言,这是一个黑匣子,我不想改变,也不支持评论。我只想添加一个薄包装,使其支持注释。

编辑

既然您正在有效地预处理源文件,为什么不使用现有的预处理器呢?如果该语言与C/C++非常相似,特别是在引用和字符串文本方面,那么您将能够只使用cpp-P:

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

其他想法:

使用合适的lexer/解析器

看看

可用于java、C++、C等。 ANTLR idem 使用Spirit Lex提升Spirit,使评论更容易剥离

所有的套件都带有解析C、C++的子集或其子集

< P >编辑< /P>的语法。 既然您正在有效地预处理源文件,为什么不使用现有的预处理器呢?如果该语言与C/C++非常相似,特别是在引用和字符串文本方面,那么您将能够只使用cpp-P:

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

其他想法:

使用合适的lexer/解析器

看看

可用于java、C++、C等。 ANTLR idem 使用Spirit Lex提升Spirit,使评论更容易剥离

所有的套件都带有解析C、C++的子集或其子集

的语法。 肖什写道:

编辑-编译DSL的东西不是我的。就我而言,这是一个黑匣子,我不想改变,也不支持评论。我只想添加一个薄包装,使其支持注释

在这种情况下,创建一个非常简单的lexer,该lexer匹配以下三个标记之一:

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

GNU Flex的演示:

示例输入文件,in.txt:

someVariable=12345;//分配 //只是一句评论 someFunctionCallHello//world;//用字符串调用 someOtherFunctionCallHello/\world;//用字符串和 //转述 lexer语法文件demo.l:

%% //[^\r\n]*{/*跳过注释*/} \[^]|[\\].\{printf%s,yytext;} . {printf%s,yytext;} %% int main argc,字符**argv { whileylex!=0; 返回0; } 要运行演示,请执行以下操作:

flex demo.l 抄送法yy.c-lfl ./a.out someVariable=12345; 有些功能叫做hello//world; someOtherFunctionCallHello//\world; 编辑 我对C/C++不是很熟悉,只是看到@sehe建议使用前置处理器。这看起来比创建自己的小型lexer要好得多。但我想我会留下这个答案,因为它展示了在没有前置处理器的情况下,如何处理这类问题,不管是什么原因:也许cpp不能识别DSL的某些部分

肖什写道:

编辑-编译DSL的东西不是我的。就我而言,这是一个黑匣子,我不想改变,也不支持评论。我只想添加一个薄包装,使其支持注释

在这种情况下,创建一个非常简单的lexer,该lexer匹配以下三个标记之一:

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

GNU Flex的演示:

示例输入文件,in.txt:

someVariable=12345;//分配 //只是一句评论 someFunctionCallHello//world;//用字符串调用 someOtherFunctionCallHello/\world;//用字符串和 //转述 lexer语法文件demo.l:

%% //[^\r\n]*{/*跳过注释*/} \[^]|[\\].\{printf%s,yytext;} . {printf%s,yytext;} %% int main argc,字符**argv { whileylex!=0; 返回0; } 要运行演示,请执行以下操作:

flex demo.l 抄送法yy.c-lfl ./a.out someVariable=12345; 有些功能叫做hello//world; someOtherFunctionCallHello//\world; 编辑 我对C/C++不是很熟悉,只是看到@sehe建议使用前置处理器。看起来是这样
这是一个比创建自己的小型lexer更好的选择。但是我想我会留下这个答案,因为它显示了如果没有前置处理器,无论出于什么原因,如何处理这类事情:也许cpp不能识别DSL的某些部分?

另一个有用的测试用例:someFunctionCallHello World;//评论//恶作剧!如果您正在为您的DSL创建标记器,那么很容易过滤掉该阶段的评论。试图用正则表达式这样做会导致一个错误的解决方案,特别是如果引号可以在字符串文本中转义的话。请参阅另一个有用的测试用例:someFunctionCallHello World;//评论//恶作剧!如果您正在为您的DSL创建标记器,那么很容易过滤掉该阶段的评论。试图用正则表达式这样做会导致一个错误的解决方案,特别是如果引号可以在字符串文本中转义的话。看,编译器实际上不是我的。这是一个黑盒子,我不想改变,它不支持评论。我只想添加一个薄包装,使其支持评论。甚至更好。你不需要完整的语法。编辑使用预处理器。有几种独立的预处理器实现可供选择,例如Boost Wave编译器实际上不是我的。这是一个黑盒子,我不想改变,它不支持评论。我只想添加一个薄包装,使其支持评论。甚至更好。你不需要完整的语法。编辑使用预处理器。有几种独立的预处理器实现,如Boost Wave
 echo 'int main() { char* sz="Hello//world"; /*profit*/ } // comment' | cpp -P