Lex 和 Yacc 是 UNIX 两个非常重要的、功能强大的工具。如果能够熟练的熟练掌握 Lex 和 Yacc ,可以轻易的写出c编译器。本文将详细的讨论了这两种工具,包括常规表达式、声明、匹配模式、变量、Yacc 语法和解析器代码。最后,他把 Lex 和 Yacc 结合起来,完成一个示例。
1.lex
lex是一种词法分析器,可以识别文本中的词汇模式,模式可以用正则表达式表示。通过lex编译l文件(词法文件)就可以生产对应的c代码,然后编译连接c代码就可以生成词法分析器了。
一个l文件分为三个部分,每部分通过双百分号(%%)分割。如下所示:
... definitions ...
%%
... rules ...
%%
... subroutines ...
definitions 部分用于定义模式、C语言变量、以及包含c头文件等。 rules 部分用户定义模式对应的动作。 subroutines 部分用于定义c函数等。
一个简单的l文件例子,test.l。
%{
int yylineno;
%}
%%
^(.*)\n printf("%4d\t%s", ++yylineno, yytext);
%%
int main(int argc, char *argv[]) {
yyin = fopen(argv[1], "r");
yylex();
fclose(yyin);
}
int yywrap(void) {
return 1;
}
%{
#include <stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ return NUMBER;
heat return TOKHEAT;
on|off return STATE;
target return TOKTARGET;
temperature return TOKTEMPERATURE;
\n /* ignore end of line */;
[ \t]+ /* ignore whitespace */;
%%
%{
#include <stdio.h>
#include <string.h>
void yyerror(const char *str);
%}
%token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE
%%
commands: /* empty */
| commands command
;
command:
heat_switch
|
target_set
;
heat_switch:
TOKHEAT STATE
{
printf("\tHeat turned on or off\n");
}
;
target_set:
TOKTARGET TOKTEMPERATURE NUMBER
{
printf("\tTemperature set\n");
}
;
%%
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}

更多lex和yacc的资料如下:
http://epaperpress.com/lexandyacc/index.html
http://tldp.org/HOWTO/Lex-YACC-HOWTO-1.html