flexbison使用教程Word文档下载推荐.docx

上传人:b****2 文档编号:1565048 上传时间:2023-05-01 格式:DOCX 页数:26 大小:22.88KB
下载 相关 举报
flexbison使用教程Word文档下载推荐.docx_第1页
第1页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第2页
第2页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第3页
第3页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第4页
第4页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第5页
第5页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第6页
第6页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第7页
第7页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第8页
第8页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第9页
第9页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第10页
第10页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第11页
第11页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第12页
第12页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第13页
第13页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第14页
第14页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第15页
第15页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第16页
第16页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第17页
第17页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第18页
第18页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第19页
第19页 / 共26页
flexbison使用教程Word文档下载推荐.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

flexbison使用教程Word文档下载推荐.docx

《flexbison使用教程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《flexbison使用教程Word文档下载推荐.docx(26页珍藏版)》请在冰点文库上搜索。

flexbison使用教程Word文档下载推荐.docx

b'

从'

j'

到'

o'

还有'

Z'

[^A-Z] 

一个取反的字符类,比如任何字母除了大写字母。

[^A-Z\n] 

任何字符除了大写字母和换行

r* 

零个或更多r,r可以是任意正则表达式

r+ 

一个或更多r

零个或最多一个r

r{2,5} 

任何2到5个r

r{2,} 

2个或更多r

r{4} 

正好4个r

{name} 

对name的扩展

"

[xyz]\"

foo"

 

符合正则表达式[xyz]"

foo的字符串

\X 

如果X是一个'

f'

n'

r'

t'

或者'

v'

则按照ASCII码\x转义符进行处理,否则,其他的'

X'

将用来做取消处理符处理

\0 

一个ASCII码空字符

\123 

内容为八进制123的char型

\x2a 

内容为十六进制0x2a的char型

(r) 

符合一个r,括号是用来越过优先级的

rs 

正则表达式r,紧跟着一个

r|s 

要么是r要么是s

^r 

一个r,但是必须是在一行的开始

r$ 

一个r,但是必须是在行末

<

s>

一个r,但是之前字符串必须符合条件s

s1,s2,s3>

r

同上,但是必须之前字符串符合s1或者s2或者s3

*>

不考虑开始字符串类型,只符合r

EOF>

>

文件末尾

s1,s2>

前面符合s1或者s2的文件末尾

.第一个Lex代码

按照上一节我们讲述的正则表达式例子,我们尝试第一次使用Lex来产生我们所需要的程序,实践一遍Lex的使用以及gcc编译器如何编译和生成所需的二进制。

Flex甚至Bison代码都有如下的编写格式:

/*定义段*/

%%

/*Flex、Bison代码段(规则)*/

/*辅助代码段,C语言*/

首先,使用vi编译器,输入以下代码():

文件

#include<

%}

test 

#运行刚刚生成的二进制

下面我们来对刚生成的二进制进行试验,以弄清楚flex到底是做什么的,在test程序中输入以下内容,按下Ctrl-D可以退出test程序:

3505

hello

whatis3505

通过这些试验,相信您已经明白了Flex的用途,每当一个正则表达式符合时,flex生成的代码就会自动调用对应的函数,或者运行对应的程序。

下面我们对这个例子进行一些深入研究,处理一个类似C语言的程序配置脚本代码。

首先,一个演示脚本如下:

logging{

categorylame-servers{null;

};

categorycname{null;

};

zone"

."

{

typehint;

file"

/etc/bind/"

;

}

在这个脚本中,我们可以看到一系列的词汇类型:

单词(WORD),比如'

zone'

type'

文件名(FILENAME),比如'

/etc/bind/'

引号(QUOTE),比如文件名两边的

左花括号(OBRACE),'

{'

右花括号(EBRACE),'

}'

分号(SEMICOLON),'

'

我们修改后的Lex代码如下:

%{

[a-zA-Z][a-zA-Z0-9]* 

printf("

WORD"

);

/*字符串*/

[a-zA-Z0-9\/.-]+ 

FILENAME"

/*文件名*/

\"

QUOTE"

/*引号"

*/

\{ 

OBRACE"

/*左花括号*/

\} 

EBRACE"

/*右花括号*/

printf("

SEMICOLON"

/*分号*/

\n 

\n"

/*换行*/

[\t]+ 

/*忽略空白字符*/

intyywrap(void) 

/*当词法分析器到了文件末尾做什么*/

{

return1;

/*返回1,说明停止前进,0则继续*/

voidyyerror(char*s)/*错误信息打印函数*/

fprintf(stderr,"

%s\n"

s);

return0;

intmain(intargc,char*argv[])

FILE*fp;

fp=fopen(argv[1],"

r"

/*首先打开要被处理的文件(参数1)*/

yyin=fp;

/*yyin是lex默认的文件输入指针,则不处理控制台输入*/

yylex();

/*调用lex的工作函数,从这里开始,lex的词法分析器开始工作*/

fclose(fp);

到这里,我们已经完全可以对一个包含各种类型词组的源代码文件进行分析,得出其中各类型词组的排列顺序。

在一个规范的基于语法的源代码中,词组的顺序从一定意义上来说,就是语法。

对于源代码,lex的处理能力也就到这里为止,但是我们并没有完全展示lex的所有功能,读者如果有兴趣,可以继续深入阅读本文提供的参考文献。

如何进行语法分析我们在下面的章节中讲开始讲述Bison的基本使用方法,以及如何使用Bison进行语法分析。

.基础理论

Bison采用与YACC相同的描述语言,这种语言是BNF语法(BackusNaurForm)的一种,最早被JohnBackus和PeterNaur用于ALGOL60语言的开发工作。

BNF语法可以用来表达与内容无关的,基于语法的语言,几乎所有的现代编程语言都可以用BNF进行描述。

作为一个例子,一个进行加法和乘法的数学表达式语法可以如下表达:

E:

E'

+'

E

*'

id

在这三句中,E在Bison语言中代表表达式,一个表达式可以是一个数字,也可以是一个变量名称,也可以是几个变量名称的组合,比如:

1

1+2

a

a+b*c

而以上三句Bison语言就能够表达这些语法结构。

初探

我们在下面作一个计算器,通过这个实例让大家明白Flex和Bison的相互关系和如何共同工作。

首先,建立文件,并输入以下内容:

/*计算器的词法分析器描述,Flex语言*/

%{ 

/*直接翻译为C语言*/

/*包含标准库文件*/

voidyyerror(char*);

/*这是我们上面用到的错误报告函数*/

#include"

/*这个头文件由Bison自动生成*/

[0-9]+ 

yylval=atoi(yytext);

/*yytext是flex内部用于指向当前词汇的字符串指针*/

returnINTEGER;

/*INTEGER是从中包含过来的,在Bison中定义*/

}

[-+\n] 

return*yytext;

[\t] 

;

/*跳过空白字符*/

yyerror("

invalidcharacter"

/*产生一个错误,说明是无效字符*/

intyywrap(void)

/*文件结束时退出*/

以上就是计算器使用的Flex语言,描述了我们将会遇到的各种词汇的格式,比如[0-9]+说明了,只有连续的从'

0'

9'

的字符串,才被分析为INTEGER类型,如果遇到制表符、空格等,直接忽略,遇到加减符号则返回字符指针,其它的则报告语法错误。

下面是我们的Bison语法文件:

/*注:

您先抄写,注解见下文*/

intyylex(void);

%tokenINTEGER 

/*Flex语言中INTEGER定义在此*/

program:

programexpr'

\n'

{printf("

%d\n"

$2);

|

expr:

INTEGER 

{$$=$1;

|expr'

expr 

{$$=$1+$3;

/*

(1)*/

-'

{$$=$1-$3;

/*

(2)*/

voidyyerror(char*s)

intmain(void)

yyparse();

编译过程:

flex

bison-d 

#注意-d,用于产生对应的头文件

gcc-otest2

在这个例子中,我们遇到了许多没有见过的用法,Bison的书写格式基本与Flex的相同,只是规则的定义语法不同。

其中,$N(N为数字)代表语法描述中,第N个词汇的内容,比如

(1)中的$1代表'

左边的expr,$3代表右边expr的内容,其中的N是指当前语法的词汇顺序,从1开始计数。

而$$则代表这一段语法处理完后的结果,每一个语法对应的处理都有输入$N和输出$$。

该例子中还有一个特殊的地方,就是第归调用,在Bison中,语法规则可以是第归的,这也是Bison之处(或者说是YACC的强大之处)。

举个例子:

这里,program的定义就是任何符合program的表达式后面紧接着expr和'

,扫描到该表达式后,将expr处理的结果打印到屏幕。

最后的|是“或者”的意思,也就是说program也可以是空的,什么都不写,分号代表该语义定义结束。

有了第归之后,Bison才可以说是一个能够应对任何状况的语法分析器,当然,这里还需要读者对以上所提供代码进行深入的研究和分析,考虑清楚后,会发现无论是C语言,还是Bison,第归永远是一个神奇的解决方案。

.计算器程序的深入研究

以上我们设计的计算器只能进行加减计算,并且里面还有一些软件缺陷,对于一个实用的计算器来说,我们必须能够支持:

1.变量定义

2.变量赋值

3.变量与数字立即处理

于是我们假想设计出来的计算器能有如下的操作过程(输入和输出):

输入:

3*(4+5)

结果:

27

x=3*(4+5)

y=5

x

y

5

x+2*y

37

这样看,这个计算器的功能已经相当强大了,下面我们着手实现,首先修改上面例子的Flex文件为如下:

#include<

voidyyerror(char*);

#include"

[a-z] 

/*变量类型词汇,限制:

变量只能用一个字符*/

yylval=*yytext-'

returnVARIABLE;

/*整数*/

yylval=atoi(yytext);

returnINTEGER;

[+-()=/*\n] 

{return*yytext;

/*数学计算符号*/

/*跳过空白符号*/

下面是我们新的Bison文件:

%tokenINTEGERVARIABLE

%left'

'

/'

intyylex(void);

intsym[26];

programstatement'

statement:

{printf("

$1);

|VARIABLE'

='

{sym[$1]=$3;

INTEGER

|VARIABLE 

{$$=sym[$1];

{$$=$1*$3;

{$$=$1/$3;

|'

('

expr'

)'

{$$=$2;

现在我们对该例子中引入的新功能介绍,%left,%right,%token都是用来声明词汇的,区别在于,%token声明的词汇与左右优先级无关,而%left的处理时,先处理左边的,%right先处理右边的,例如遇到字符串"

1-2-5"

,到底是处理为"

(1-2)-5"

,还是处理为"

1-(2-5)"

%left处理为前者,而%right处理为后者(注:

第一个计算器代码中就有这个缺陷,比如执行1-2+3,得到的结果就是-4,作为一个练习,读者可以使用这里讲解的%left自行更正)。

和Bison高级应用

在下面的例子中,我们便写了一个更高级的计算器程序,其操作实例如下:

x=0;

while(x<

3){

print(x);

x=x+1;

例子中得到的输出结果如下:

2

首先是我们的全局头文件:

typedefenum{

typeCon,

typeId,

typeOpr

}nodeEnum;

/*constants*/

typedefstruct{

intvalue;

/*valueofconstant*/

}conNodeType;

/*identifiers*/

inti;

/*subscripttosymarray*/

}idNodeType;

/*operators*/

intoper;

/*operator*/

intnops;

/*numberofoperands*/

structnodeTypeTag*op[1];

/*operands(expandable)*/

}oprNodeType;

typedefstructnodeTypeTag{

nodeEnumtype;

/*typeofnode*/

/*unionmustbelastentryinnodeType*/

/*becauseoperNodeTypemaydynamicallyincrease*/

union{

conNodeTypecon;

idNodeTypeid;

oprNodeTypeopr;

}nodeType;

externintsym[26];

下面是Flex语言文件:

=*yytext-'

returnVARIABLE;

=atoi(yytext);

[-()<

=+*/;

{}.]{

return*yytext;

="

returnGE;

returnLE;

=="

returnEQ;

!

returnNE;

while"

returnWHILE;

if"

returnIF;

else"

returnELSE;

print"

returnPRINT;

[\t\n]+ 

/*ignorewhitespace*/

Unknowncharacter"

然后是我们的Bison文件:

/*prototypes*/

nodeType*opr(intoper,intnops,...);

nodeType*id(inti);

nodeType*con(intvalue);

voidfreeNode(nodeType*p);

voidyyerror(char*s);

intsym[26];

%union{

intiValue;

/*integervalu

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 起诉状

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2