我面临的问题是ANSI编译器需要C样式注释。
所以我试图将我现有的注释转换为符合C标准ISO C89。
我正在寻找一个SED表达式来替换//注释/ *注释除了//注释出现在/ * * / comments中(这会破坏注释)。
我试过这个(范围表达式)无济于事:
sed -e '//*/,/*//! s_//(.*)_/*1 */_' > filename
有些东西可以忽略这样的评论中的1行注释,但改变其他一切吗?
/********************************** * Some comment * an example bit of code within the comment followed by a //comment * some more comment ***********************************/ y = x+7; //this comment must be changed
谢谢!
这是一个用C语言编写的经过轻度测试的filter,可以执行您想要的转换。 关于这个filter做什么的一些评论即使不是不可能用正则表达式处理也很困难:
当然,您需要执行自己的测试以确定它是否适合您的目的。
#include char* a = " this is /* a test of " junk // embedded in a '' string"; char* b = "it should be left alone//"; // comment /* that should ***//// be converted. /* leave this alone*/// but fix this one // and "leave these ' " quotes in a comment alone* /**** and these '' too // */ enum states { state_normal, state_double_quote, state_single_quote, state_c89_comment, state_c99_comment }; enum states current_state = state_normal; void handle_char( char ch) { static char last_ch = 0; switch (current_state) { case state_normal: if ((last_ch == '/') && (ch == '/')) { putchar( '*'); /* NOTE: changing to C89 style comment */ current_state = state_c99_comment; } else if ((last_ch == '/') && (ch == '*')) { putchar( ch); current_state = state_c89_comment; } else if (ch == '"') { putchar( ch); current_state = state_double_quote; } else if (ch == ''') { putchar( ch); current_state = state_single_quote; } else { putchar( ch); } break; case state_double_quote: if ((last_ch == '\') && (ch == '\')) { /* we want to output this \ escaped sequence, but we */ /* don't want to 'remember' the current backslash - */ /* otherwise we'll mistakenly treat the next character*/ /* as being escaped */ putchar( ch); ch = 0; } else if ((ch == '"') && (last_ch != '\')) { putchar( ch); current_state = state_normal; } else { putchar( ch); } break; case state_single_quote: if ((last_ch == '\') && (ch == '\')) { /* we want to output this \ escaped sequence, but we */ /* don't want to 'remember' the current backslash - */ /* otherwise we'll mistakenly treat the next character*/ /* as being escaped */ putchar( ch); ch = 0; } else if ((ch == ''') && (last_ch != '\')) { putchar( ch); current_state = state_normal; } else { putchar( ch); } break; case state_c89_comment: if ((last_ch == '*') && (ch == '/')) { putchar( ch); ch = 0; /* 'forget' the slash so it doesn't affect a possible slash that immediately follows */ current_state = state_normal; } else { putchar( ch); } break; case state_c99_comment: if ((last_ch == '/') && (ch == '*')) { /* we want to change any slash-star sequences inside */ /* what was a C99 comment to something else to avoid */ /* nested comments */ putchar( '+'); } else if ((last_ch == '*') && (ch == '/')) { /* similarly for star-slash sequences inside */ /* what was a C99 comment */ putchar( '|'); } else if (ch == 'n') { puts( "*/"); current_state = state_normal; } else { putchar( ch); } break; } last_ch = ch; } int main(void) { int c; while ((c = getchar()) != EOF) { handle_char( c); } return 0; }
一些放纵的评论:很多年前,我工作过的一家商店想强加一个禁止C99风格评论的编码标准,理由是即使我们当时使用的编译器没有问题,代码可能必须是移植到不支持它们的编译器。 我(和其他人)成功地认为这种可能性是如此遥远,以至于基本上不存在,并且即使它确实发生了,也可以很容易地编写使评论兼容的转换例程。 我们被允许使用C99 / C ++风格的评论。
我现在认为我的誓言已经实现了,而且可能已经解除了我的任何诅咒。
如果你不能使用@ephemient的建议,那么你需要跨多行应用你的正则表达式,这不是sed的默认行为。 sed有一个保持缓冲区,它允许你将多个字符串附加在一起并将正则表达式应用于连接字符串。
sed表达式如下所示:
sed '1h;1!H;${;g;s/your-matcher-regex/replacement-regex/g;}'
1h
– 如果是第一行,将该行放入保持缓冲区(首先将其清空)
1!H
– 如果不是第一行,则附加到保持缓冲区
$ {...}
– 如果是最后一行,执行此sed命令
现在,即使/ *和* /在不同的行上,您的matcher表达式也会起作用。
awk '{if($0~////){sub(////,"/*");$0=$0"*/"};print}' temp
使用任何可以为/*
和//
注释输出不同标记的转换器将代码转换为彩色HTML,使用perl / awk / sed / whatever处理输出,然后剥离标记。
您可以(几乎)完全在sed中执行此操作,您只需要调用tr
:
translate_comments_prepare.sed
s/\/\\/g # escape current escape characters s/$/\S/g # write all occurrences of $ as S s/(/\o/g # replace open braces with o s/)/\c/g # replace closing braces with c s/$/$/ # add a $ sign to the end of each line s_/*_(_g # replace the start of comments with ( s_*/_)_g # replace the end of comments with )
然后我们通过tr -d 'n'
管道“预处理”步骤的结果来连接所有行(我还没有找到一个从sed
执行此操作的好方法)。
然后我们做真正的工作:
translate_comments.sed
s_//([^$]*)$_(1)$_g # replace all C++ style comments (even nested ones) :b # while loop # remove nested comment blocks: # (foo(bar)baz) --> (foobarbaz) s/(([^()]*)(([^()]*))([^()]*))/(123)/ tb # EOF loop s_(_/*_g # reverse the steps done by the preparation phase s_)_*/_g # ... s/$/n/g # split lines that were previously joined s/\S/$/g # replace escaped special characters s/\o/(/g # ... s/\c/)/g # ... s/\(.)/1/g # ...
那我们基本上把所有东西放在一
sed -f translate_comments_prepare.sed | tr -d 'n' | sed translate_comments.sed
这可能适合你(GNU sed):
sed ':a;$!{N;ba};s/^/x00/;tb;:b;s/x00$//;t;s/x00(/*[^*]**+([^/*][^*]**+)*/)/1x00/;tb;s/x00//([^n]*)//*1*/x00/;tb;s/x00(.)/1x00/;tb' file
说明:
以上就是c/c++开发分享当//注释出现在/ * * /中时,sed用/ * * / comments替换//除外相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/549879.html