Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104674207
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: C/C++

2008-05-19 14:44:44

作者:绚丽也尘埃  出自:

最近看《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

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自动生成了。
阅读(1704) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~