最近看《GCC-the-Complete-Reference-fly》才知道有lex和yacc这两个有趣的工具,并且fedora core 8也默认安装有这两个工具,所以趁此机会学习一下,以前学编译原理时,知道有yacc这个名词,但是从来没有考虑过它是个什么东东,要学习的东西实在是太多了,真是学海无涯。
先从lex讲起吧。Lex又称Lexical Analyzar是对源程序进行词法分析的。如果学过《编译原理》便会知道一份源代码从文本文件变成可执行的二进制文件的过程。最开始的两个步骤便是词法分析和语法分析。lex按照指定的模式来匹配输入,当匹配到一条规则时,便执行相应的动作。
一个 Lex 程序分为三个段:第一段是 C 和 Lex 的全局声明,第二段包括模式(C 代码),第三段是补充的 C 函数。 例如, 第三段中一般都有 main() 函数。这些段以%%来分界。
下面是一个统计字数的lex程序。
引用:%{
int wordCount = 0;
%}
chars [A-za-z\_\'\.\"] /*类似shell使用的正则表达式*/
numbers ([0-9])+
delim [" "\n\t]
whitespace {delim}+
words {chars}+
%%
{words} { wordCount++; /*increase the word count by one*/ }
{whitespace} { /* do nothing*/ }
{numbers} { /* one may want to add some processing here*/ }
%%
void main()
{
yylex(); /* start the analysis*/ /*此函数由lex自动生成*/
printf(" No of words: %d\n", wordCount);
}
int yywrap()
{
return 1;
}
将文件保存为wordCount.lex。接下来就是编译它生成可执行程序了,步骤如下:
引用:[ecy@localhost ~]$ flex wordCount.lex
[ecy@localhost ~]$ gcc lex.yy.c -lfl -o wordCount
[ecy@localhost ~]$ cat word
fuzhijie
dandan
1234567
ecy_fu@163.com
fuzhijie1985
annie
[ecy@localhost ~]$ cat word | ./wordCount
@ No of words: 6
生成的可执行程序为wordCount,它对输入的文件按照指定的模式进行匹配,当一个词语中出现了字母,这个词语便同words匹配,匹配促发的动作是将变量wordCount加1。这个lex文件是比较完备的,在《GCC-the-Complete-Reference-fly》有个例子,它的代码只有中间一段,起代码如下:
引用:%%
switch printf("SWITCH ");
case printf("CASE ");
[a-zA-Z][_a-zA-Z0-9]* printf("WORD(%s) ",yytext);
[0-9]+ printf("INTEGER(%s) ",yytext);
375
Chapter 19: Implementing a Language
\{ printf("LEFTBRACE ");
\} printf("RIGHTBRACE ");
%%
[ecy@localhost ~]$ flex kwords.lex
[ecy@localhost ~]$ gcc lex.yy.c -lfl -o kwords
[ecy@localhost ~]$ cat kwtry.text
blatz {
switch big_time_do
case HamFram
case 889
} dend
[ecy@localhost ~]$ cat kwtry.text | ./kwords
WORD(blatz) LEFTBRACE
SWITCH WORD(big_time_do)
CASE WORD(HamFram)
CASE INTEGER(889)
RIGHTBRACE WORD(dend)
这个程序编译后也能正常工作,这说明相关的函数都有lex自动生成了。
1025955575 于 2010-10-11 19:05:23发表:
看看中