编译器是如何识别C++注释的?

mimosazhao 2010-10-25 03:58:15
编译器对C++代码是如何解析的?又是如何识别是代码还是注释呢?

1 void function()
2 {
3 cstring temp = "/*";
4 }
5 /* comment 1
6 /* comment 2
7 */

比如对于以上代码,编译器在识别代码时是如何把第3行的/*给忽略掉,如何识别出注释是第5行和第7行匹配而不是第6行和第7行匹配的?

有没有开源的类库可以识别代码中的注释?
...全文
702 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
djwolfs 2011-09-19
  • 打赏
  • 举报
回复
我也在纠结这个问题,,做大作业。。
mimosazhao 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 zyyjaf 的回复:]
双引号里面的,当字符串处理;双引号外面的,/*与最近的一个*/匹配(就近原则,不能嵌套),中间的任何字符都被注释掉。
[/Quote]

关键如何判断是在引号里面还是在引号外面?
mimosazhao 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 delphigis 的回复:]
好像在哪听说过,,,,国内的编译原理课程都没有接触到实质,有精力学点别的吧
[/Quote]
项目要用到这一点,自己写的又判断不完全,想找下有没有开源的库可以用的,毕竟很多代码编辑器都可以识别出代码和注释的
luciferisnotsatan 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 zclmoon 的回复:]

预处理器直接干掉了
[/Quote]
+1
百事烟 2010-10-26
  • 打赏
  • 举报
回复
好像在哪听说过,,,,国内的编译原理课程都没有接触到实质,有精力学点别的吧
mimosazhao 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 zclmoon 的回复:]
预处理器直接干掉了
[/Quote]
在编译时确实是被预处理器给处理了,但在代码中能明显看出哪是注释哪是代码,我想获得注释的范围
mimosazhao 2010-10-26
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 stjay 的回复:]
UltraEdit里C/C++语法着色配置
[/Quote]

UltraEdit是怎么实现着色的呢?
ForestDB 2010-10-25
  • 打赏
  • 举报
回复
一个状态机。
AI应用技术 2010-10-25
  • 打赏
  • 举报
回复
预处理器直接干掉了
stjay 2010-10-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 mimosazhao 的回复:]
4楼的什么意思?
[/Quote]

UltraEdit里C/C++语法着色配置
yshuise 2010-10-25
  • 打赏
  • 举报
回复
这个很简单,本人研究过词法分析器.
难度是在语法分析+语义分析+语法树,这些单独来讲都会,但是实现代码是合在一起的.所以比较难.
可以说前端应该弄清语法树就好了.但是,是各种难度的集合在一起了.
zyyjaf 2010-10-25
  • 打赏
  • 举报
回复
双引号里面的,当字符串处理;双引号外面的,/*与最近的一个*/匹配(就近原则,不能嵌套),中间的任何字符都被注释掉。
zyrr159487 2010-10-25
  • 打赏
  • 举报
回复
这就要涉及到编译原理了,其实每个语句都要这样分析一遍的,分析到/* 的时候它就会做出判断
康斯坦汀 2010-10-25
  • 打赏
  • 举报
回复
如果要去掉所有c++语言中的注释,这几行perl代码就搞定。


#!/usr/bin/perl -w

foreach (@ARGV) {
@_ = <>;
$_ = "@_";
s#/\*.*?\*/|//[^\n]*|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined
$1 ? $1 : ""#gse;

print;

}


怎么样? perl超级简单吧?
康斯坦汀 2010-10-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 r3000 的回复:]

任何一种语言的编译器,做得第一件也是最基本的一件事都是“词法分析”,首先就是
去掉注释,这个不用你操心,如果你是想自己处理,最好用的工具是perl,基础是前面提到
的正则表达式。
[/Quote]

下面这段perl代码,即可以去掉任何c文件中的注释,可以忽略在字符串中的/*
使用方法:

test.pl test.c

test.pl

#!/usr/bin/perl -w


foreach (@ARGV) {
@_ = <>;
$_ = "@_";
s#/\*.*?\*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $1
? $1 : ""#gse;
print;

}

test.c
void function()
{
cstring temp = "/*";
}
/* comment 1
/* comment 2
*/


输出结果:
void function()
{
cstring temp = "/*";
}

具体怎么做到的,就需要你学点perl了,做这种事,perl要比任何语言都简单,因为它就是为这个诞生的。





mLee79 2010-10-25
  • 打赏
  • 举报
回复
最简单的例子:
$ ( function x() { echo ------------ $* -------------- ; $* ; } ; x cat 1.l ; x cat 1.i ;\
x flex -o 1.c 1.l ; gcc 1.c -o 1 -lfl ; x ./1 < 1.i ) > result

------------ cat 1.l --------------

%x MULTICOMM SINGLECOMM STRING

NEWLINE \r\n|\r|\n

%%

"/*" BEGIN( MULTICOMM );
<MULTICOMM>"*/" BEGIN( INITIAL );
<MULTICOMM>.|\n

"//" BEGIN( SINGLECOMM );
<SINGLECOMM>.
<SINGLECOMM>{NEWLINE} BEGIN( INITIAL );

\" ECHO; BEGIN( STRING );
<STRING>{
\" ECHO; BEGIN( INITIAL );
\\. ECHO;
\\{NEWLINE} ECHO;
. ECHO;
}

%%

------------ cat 1.i --------------

"asdfadf"

void function()
{
cstring temp = "/*";
}
/* comment 1
/* comment 2
*/

// asdfasdfadfasdf
/*

* *
**
------------ flex -o 1.c 1.l --------------
------------ ./1 --------------

"asdfadf"

void function()
{
cstring temp = "/*";
}


leiqiuchan 2010-10-25
  • 打赏
  • 举报
回复
LZ可以看下The C Program这本书,好像是这么写吧,里面有简单的注释程序的程序,可以参考下,也许就明白了
ddboy 2010-10-25
  • 打赏
  • 举报
回复
按行解析安全些,当然,如果你只是要简单的匹配,用正则,速度快些
mimosazhao 2010-10-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 r3000 的回复:]
任何一种语言的编译器,做得第一件也是最基本的一件事都是“词法分析”,首先就是
去掉注释,这个不用你操心,如果你是想自己处理,最好用的工具是perl,基础是前面提到
的正则表达式。
[/Quote]

嗯,我是想把函数体外注释的第一行和最后一行的行号给获取到,用perl给怎么做?
康斯坦汀 2010-10-25
  • 打赏
  • 举报
回复
任何一种语言的编译器,做得第一件也是最基本的一件事都是“词法分析”,首先就是
去掉注释,这个不用你操心,如果你是想自己处理,最好用的工具是perl,基础是前面提到
的正则表达式。
加载更多回复(10)

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧