首页 > 学技术 > 技术网文 > C/C++ > 正文

[原创] CU论坛C语言代码语法高亮工具


来源 chinaunix.net kuqin整理

%{
[color=Brown]#include <ctype.h>[/color]
[color=Brown]#include <stdio.h>[/color]
[color=Brown]#include <string.h>[/color]

[color=LimeGreen]//格式串定义[/color]
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_number = [color=Orange]"["[/color][color=Orange]"color=Red]%s"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_keyword = [color=Orange]"["[/color][color=Orange]"color=Blue]%s"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_ctype = [color=Orange]"["[/color][color=Orange]"color=Purple]%s"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_lcomment = [color=Orange]"["[/color][color=Orange]"color=LimeGreen]%s"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_bcomment1 = [color=Orange]"["[/color][color=Orange]"color=LimeGreen]"[/color];         [color=LimeGreen]///!![/color]
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_bcomment2 = [color=Orange]"["[/color][color=Orange]"/color]"[/color];                  [color=LimeGreen]///!![/color]
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_string = [color=Orange]"["[/color][color=Orange]"color=Orange]%s%c"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];   [color=LimeGreen]///!![/color]
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_char = [color=Orange]"["[/color][color=Orange]"color=Navy]%s%c"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];       [color=LimeGreen]///!![/color]
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_normal = [color=Orange]"%s"[/color];          [color=LimeGreen]//default: black[/color]
[color=Purple]const[/color] [color=Purple]char[/color] *fmt_preproc = [color=Orange]"["[/color][color=Orange]"color=Brown]%s"[/color][color=Orange]"["[/color][color=Orange]"/color]"[/color];
%}

digit           [[color=Red]0[/color]-[color=Red]9[/color]]
xdigit          [[color=Red]0[/color]-[color=Red]9[/color]a-fA-F]
odigit          [[color=Red]0[/color]-[color=Red]7[/color]]

decnum          ([color=Red]0[/color](\.{digit}+)?)|([[color=Red]1[/color]-[color=Red]9[/color]]{digit}*(\.{digit}+)?)
octnum          [color=Red]0[/color]{odigit}+
hexnum          [color=Red]0[/color](x|X){xdigit}+
number          {decnum}|{octnum}|{hexnum}
lcomment        \/\/.*
string          \[color=Orange]"[^"[/color]]*
[color=Purple]char[/color]              \[color=Navy]'[^'[/color]]*
normal          [a-zA-Z_]+[a-z0-[color=Red]9[/color]A-Z_]*
preproc         [color=Brown]#.*[/color]

keyword1        [color=Blue]break[/color]|[color=Blue]case[/color]|[color=Blue]continue[/color]|[color=Blue]default[/color]|[color=Blue]do[/color]|[color=Blue]else[/color]|[color=Blue]enum[/color]
keyword2        [color=Blue]extern[/color]|[color=Blue]for[/color]|[color=Blue]goto[/color]|[color=Blue]if[/color]|[color=Blue]return[/color]|[color=Blue]sizeof[/color]|[color=Blue]struct[/color]
keyword3        [color=Blue]switch[/color]|[color=Blue]typedef[/color]|[color=Blue]union[/color]|[color=Blue]volatile[/color]|[color=Blue]while[/color]
keyword4        [color=Blue]catch[/color]|[color=Blue]class[/color]|[color=Blue]delete[/color]|[color=Blue]friend[/color]|[color=Blue]inline[/color]|[color=Blue]new[/color]|[color=Blue]operator[/color]
keyword5        [color=Blue]private[/color]|[color=Blue]protected[/color]|[color=Blue]public[/color]|[color=Blue]template[/color]|[color=Blue]this[/color]|[color=Blue]throw[/color]|[color=Blue]try[/color]|[color=Blue]virtual[/color]
ctype1          [color=Purple]auto[/color]|[color=Purple]char[/color]|[color=Purple]const[/color]|[color=Purple]double[/color]|[color=Purple]float[/color]|[color=Purple]int[/color]|[color=Purple]long[/color]|[color=Purple]register[/color]
ctype2          [color=Purple]short[/color]|[color=Purple]signed[/color]|[color=Purple]static[/color]|[color=Purple]unsigned[/color]|[color=Purple]void[/color]|[color=Purple]bool[/color]

keyword         {keyword1}|{keyword2}|{keyword3}|{keyword4}|{keyword5}
ctype           {ctype1}|{ctype2}

%x comment

%%

[color=Orange]"/*"[/color] {
        printf(fmt_bcomment1);
        ECHO;
        BEGIN(comment);
}
        <comment>[^*\n]* ECHO;
        <comment>[color=Orange]"*"[/color]+[^*/\n]* ECHO;
        <comment>\n ECHO;
        <comment>[color=Orange]"*"[/color]+[color=Orange]"/"[/color] {
                BEGIN(INITIAL);
                ECHO;
                printf(fmt_bcomment2);
        }

{number} {
        printf(fmt_number, yytext);
}
{keyword} {
        printf(fmt_keyword, yytext);
}
{ctype} {
        printf(fmt_ctype, yytext);
}
{lcomment} {
        printf(fmt_lcomment, yytext);
}
{string} {
        [color=Blue]if[/color] (yytext[yyleng - [color=Red]1[/color]] == [color=Navy]'\\'[/color]) {
                [color=Purple]int[/color] i;
                [color=Purple]int[/color] more = [color=Red]1[/color];
                [color=Blue]for[/color] (i = yyleng - [color=Red]2[/color]; i >= [color=Red]0[/color]; i--) {
                        [color=Blue]if[/color] (yytext[ i ] == [color=Navy]'\\'[/color]) more = !more;
                        [color=Blue]else[/color] [color=Blue]break[/color];
                }
                [color=Blue]if[/color] (more) yymore();
                [color=Blue]else[/color] printf(fmt_string, yytext, input());
        } [color=Blue]else[/color] {
                printf(fmt_string, yytext, input());
        }
}
{[color=Purple]char[/color]} {
        [color=Blue]if[/color] (yytext[yyleng - [color=Red]1[/color]] == [color=Navy]'\\'[/color]) {
                [color=Purple]int[/color] i;
                [color=Purple]int[/color] more = [color=Red]1[/color];
                [color=Blue]for[/color] (i = yyleng - [color=Red]2[/color]; i >= [color=Red]0[/color]; i--) {
                        [color=Blue]if[/color] (yytext[ i ] == [color=Navy]'\\'[/color]) more = !more;
                        [color=Blue]else[/color] [color=Blue]break[/color];
                }
                [color=Blue]if[/color] (more) yymore();
                [color=Blue]else[/color] printf(fmt_char, yytext, input());
        } [color=Blue]else[/color] {
                printf(fmt_char, yytext, input());
        }
}
{normal} {
        printf(fmt_normal, yytext);
}
{preproc} {
        printf(fmt_preproc, yytext);
}

%%

[color=Purple]void[/color] printhelp()
{
        [color=Purple]char[/color] *h =
        [color=Orange]"cucolor 0.2\n"[/color]
        [color=Orange]"a C/C++ code syntax highlighting utility for chinaunix forum\n"[/color]
        [color=Orange]"copyright (c) 2007 nully\n"[/color]
        [color=Orange]"this is GPLed freeware\n\n"[/color]
        [color=Orange]"Usage: cucolor [input file] [output file]\n\n"[/color];

        fprintf(stderr, [color=Orange]"%s\n"[/color], h);
}

[color=Purple]int[/color] main([color=Purple]int[/color] argc, [color=Purple]char[/color] **argv)
{
        [color=Blue]if[/color] (argv[[color=Red]1[/color]]) {
                [color=Blue]if[/color] (strcmp(argv[[color=Red]1[/color]], [color=Orange]"--help"[/color]) == [color=Red]0[/color] ||
                    strcmp(argv[[color=Red]1[/color]], [color=Orange]"-h"[/color]) == [color=Red]0[/color]) {
                        printhelp();
                        [color=Blue]return[/color] [color=Red]0[/color];
                }
                [color=Blue]if[/color] (freopen(argv[[color=Red]1[/color]], [color=Orange]"r"[/color], stdin) == NULL) {
                        fprintf(stderr, [color=Orange]"cannot open input file %s\n"[/color], argv[[color=Red]1[/color]]);
                        [color=Blue]return[/color] -[color=Red]1[/color];
                }
        }
        [color=Blue]if[/color] (argv[[color=Red]2[/color]]) {
                [color=Blue]if[/color] (freopen(argv[[color=Red]2[/color]], [color=Orange]"w"[/color], stdout) == NULL) {
                        fprintf(stderr, [color=Orange]"cannot open output file %s\n"[/color], argv[[color=Red]1[/color]]);
                        [color=Blue]return[/color] -[color=Red]1[/color];
                }
        }

        yylex();
        [color=Blue]return[/color] [color=Red]0[/color];
}

[color=Purple]int[/color] yywrap()
{
        [color=Blue]return[/color] [color=Red]1[/color];
}


====================================
保存为 cucolor.lex
编译:
$ lex cucolor.lex
$ gcc lex.yy.c -o cucolor

已确认论坛代码完整,原附件被删。

[ 本帖最后由 nully 于 2007-1-3 15:56 编辑 ]



 nully 回复于:2007-01-02 03:53:45

编译:
$ lex cucolor.lex
$ gcc -o cucolor lex.yy.c


 langue 回复于:2007-01-02 07:50:41

好。

原创?辛苦了。下一步可以尝试把 RTF 转换为 Discuz! 代码。

P.S.

给条建议,把 formater 改成 syntax highlighting utility 吧。formater 也有词法错误,应作 formatter,双写 t

[ 本帖最后由 langue 于 2007-1-2 08:00 编辑 ]


 bleem1998 回复于:2007-01-02 08:44:00

是不是以后的代码支持语法高亮了?
厉害啊
造福全人类了


 nully 回复于:2007-01-02 10:56:01

引用:原帖由 langue 于 2007-1-2 07:50 发表
好。

原创?辛苦了。下一步可以尝试把 RTF 转换为 Discuz! 代码。

P.S.

给条建议,把 formater 改成 syntax highlighting utility 吧。formater 也有词法错误,应作 formatter,双写 t 



哈哈,本人英语不好。。。
已更改好。。。


这是刚学lex后写的,用于匹配的正则表达式还写得不是很好。。。。


 nully 回复于:2007-01-02 11:13:30

discuz!代码没有“转义的么”?
想把[ .color = XXX] 加入代码不容易啊。。。
搞得格式化串里要这么写。。。。


 heroooooo 回复于:2007-01-02 11:47:55

我有自己用ASP写的一个,感觉还可以,不过就是有点小毛病。什么时候高兴了就发出来,可惜是ASP的.


 kuaizaifeng 回复于:2007-01-02 23:28:56

厉害啊
造福大家阿


 lj_860603 回复于:2007-01-03 11:08:14

顶文师兄一个再说。


 nully 回复于:2007-01-03 16:03:01

看了bison手册。。。
原来的块注释有问题,这里替换了手册里的例子,呵呵
加入了CPLUSSULP的几个关键字

PS: 谁知道
keyword   auto|break|continue...这个要怎么换行?

PPS:
Discuz!代码要怎么转义?如 [ i ] (不含空格)这些东西都被吃掉了。。。


 newzy 回复于:2007-01-03 23:03:30

不错的创意, 

补充些 C 的关键字:
keyword0        #|if|ifdef|ifndef|elif|else|endif|define|defined|undef|include|error
keyword         {keyword0}|{keyword1}|{keyword2}|{keyword3}|{keyword4}|{keyword5}


 nully 回复于:2007-01-04 00:11:52

引用:原帖由 newzy 于 2007-1-3 23:03 发表
不错的创意, 

补充些 C 的关键字:
keyword0        #|if|ifdef|ifndef|elif|else|endif|define|defined|undef|include|error
keyword         {keyword0}|{keyword1}|{keyword2}|{keyword3}|{keyword4}|{key ... 



preproc         #.*

懒人主义。。。所有井号开始的都会使用“fmt_preproc”高亮。。。
与kate一样,呵呵。


 geel 回复于:2007-01-04 00:12:23

引用:原帖由 nully 于 2007-1-3 16:03 发表
看了bison手册。。。
原来的块注释有问题,这里替换了手册里的例子,呵呵
加入了CPLUSSULP的几个关键字

PS: 谁知道
keyword   auto|break|continue...这个要怎么换行?

PPS:
Discuz!代码要怎么转义?如  ... 



附件为啥要删呢。。。。
用[ code ] [ /code ](不含空格)括起来,只分析code标签里的代码,或者自定义个类似[code language=c]的东东。。。

[ 本帖最后由 geel 于 2007-1-4 00:15 编辑 ]


 nully 回复于:2007-01-04 00:30:21

引用:原帖由 geel 于 2007-1-4 00:12 发表


附件为啥要删呢。。。。
用[ code ] [ /code ](不含空格)括起来,只分析code标签里的代码,或者自定义个类似[code language=c]的东东。。。 



附件本意是怕页面上复制下去的代码不全,现在证明是全的,所以就不需要附件了。
如果没有转义的话,根本没法把诸如下面的C代码完整贴上来。。。

/*
 [ color = xxx ]  [ /color]

 */

for(i = 0; i < 10; ++i) {
  a = test[ i ];
}

汗。。。不知转成html能不能行: &nbsp; &amp; &nbsp; ...看来是不行的。


 geel 回复于:2007-01-04 00:32:51

联系f老大,直接写discuz插件


 nully 回复于:2007-01-04 00:40:12

引用:原帖由 geel 于 2007-1-4 00:32 发表
联系f老大,直接写discuz插件 



哦,你的意思是,直接整合到discuz里边?呵呵,有意思,那需要更强的功能,如代码折叠。。。hehehe...


 unixsc 回复于:2007-02-23 17:06:49

不错.


 zhw19810520 回复于:2007-04-03 20:27:30

高手如云啊!


 飞灰橙 回复于:2007-04-04 09:02:06

楼主啊楼主,lex用的很不错呢,赞!
小弟请教一个问题,语法分析的时候,有没办法支持不按顺序输入字符流。
具体意思就是,
这些库都有能力按某种语法解析字符串 abcdefg,
现在要在中间插入或删除一个字符,如 abcd=efg,
对于前后的已经解析过的字串,可以不需要再次全部解析吗?
因为abcd和efg已经解析过了。


 Namelessxp 回复于:2007-04-04 09:25:15

发贴时禁用掉 URL 识别,Smilies,Discuz!代码

[color=blue]y[/color]
b

[color=red]x[/color]



 nully 回复于:2007-04-04 14:02:27

引用:原帖由 飞灰橙 于 2007-4-4 09:02 发表
楼主啊楼主,lex用的很不错呢,赞!
小弟请教一个问题,语法分析的时候,有没办法支持不按顺序输入字符流。
具体意思就是,
这些库都有能力按某种语法解析字符串 abcdefg,
现在要在中间插入或删除一个字符,如 ... 



我知道你要做什么,写编辑器语法高亮对吧?
lex的词法分析程序只能从头进行,如果有需要,可以以行为单位进行加亮,但在处理夸行符,如/*时要进行特别的处理


 飞灰橙 回复于:2007-04-04 14:11:11

引用:原帖由 nully 于 2007-4-4 14:02 发表


我知道你要做什么,写编辑器语法高亮对吧?
lex的词法分析程序只能从头进行,如果有需要,可以以行为单位进行加亮,但在处理夸行符,如/*时要进行特别的处理 



:mrgreen::oops:给你猜中了!!
我想做到任意位置,随输随解析。
事实上vim/ultraedit做的都远非完美。


 assiss 回复于:2007-04-04 15:01:34

引用:原帖由 飞灰橙 于 2007-4-4 14:11 发表


:mrgreen::oops:给你猜中了!!
我想做到任意位置,随输随解析。
事实上vim/ultraedit做的都远非完美。 


这样的需求用LEX恐怕难以实现吧,得自己手工写代码了。


 飞灰橙 回复于:2007-04-04 15:09:34

谢楼上各位,貌似的确没有太好的办法


 nully 回复于:2007-04-04 15:13:29

要配合widget手写词法分析器代码...
词法加亮做得较好的,觉得win32下一个notepad++的编辑器不错,自定义功能强大。


 assiss 回复于:2007-04-04 15:31:08

这方面我觉得scite做得最好。可以参考一下。它的代码恰好又不是很大。


 rossalee 回复于:2007-04-25 23:50:11

对各位强人祟拜得不得了。




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=879964
转载请注明作者名及原文出处



收藏本页到:      

收藏本页到: