实验四用语法分析器生成工具实现语法分析器文档格式.docx

上传人:b****5 文档编号:21344617 上传时间:2023-01-29 格式:DOCX 页数:8 大小:17.75KB
下载 相关 举报
实验四用语法分析器生成工具实现语法分析器文档格式.docx_第1页
第1页 / 共8页
实验四用语法分析器生成工具实现语法分析器文档格式.docx_第2页
第2页 / 共8页
实验四用语法分析器生成工具实现语法分析器文档格式.docx_第3页
第3页 / 共8页
实验四用语法分析器生成工具实现语法分析器文档格式.docx_第4页
第4页 / 共8页
实验四用语法分析器生成工具实现语法分析器文档格式.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

实验四用语法分析器生成工具实现语法分析器文档格式.docx

《实验四用语法分析器生成工具实现语法分析器文档格式.docx》由会员分享,可在线阅读,更多相关《实验四用语法分析器生成工具实现语法分析器文档格式.docx(8页珍藏版)》请在冰豆网上搜索。

实验四用语法分析器生成工具实现语法分析器文档格式.docx

delim[\t\n]

ws{delim}+

letter[A-Za-z]

digit[0-9]

%%

{ws}{}

"

if"

{printf("

IF"

);

return(IF);

}

else"

ELSE"

return(ELSE);

int"

INT"

return(BASIC);

float"

FLOAT"

break"

BREAK"

return(BREAK);

do"

DO"

return(DO);

while"

WHILE"

return(WHILE);

true"

TRUE"

return(TRUE);

index"

INDEX"

return(INDEX);

bool"

BOOL"

char"

CHAR"

real"

return(REAL);

false"

FLASE"

return(FALSE);

[a-zA-Z_][a-zA-Z0-9_]*{printf("

ID"

return(ID);

[+-]?

[0-9]+{printf("

NUM"

return(NUM);

[0-9]*[.][0-9]+{printf("

<

LT"

return('

'

="

LE"

return(LE);

="

='

=="

EQ"

return(EQ);

!

NE"

return(NE);

>

GT"

GE"

return(GE);

+"

+"

+'

-"

-"

-'

["

["

['

]"

]"

]'

{"

{'

}

}"

}'

("

('

)"

)'

;

"

'

&

return(AND);

||"

return(OR);

%tokenNUM

%tokenID

%tokenIFWHILEDOBREAKREALTRUEFALSEBASICELSEINDEXGELENEEQANDOR

program:

block{printf("

program-->

block\n"

}

;

block:

'

declsstmts'

{printf("

block-->

{declsstmts}\n"

decls:

|declsdecl{printf("

decls-->

declsdecl\n"

decl:

typeID'

decl-->

typeid;

\n"

type:

type'

NUM'

type-->

type[num]\n"

|BASIC{printf("

basic\n"

stmts:

|stmtsstmt{printf("

stmts-->

stmtsstmt\n"

stmt:

matched_stmt{printf("

stmt-->

matched_stmt\n"

|open_stmt{printf("

open_stmt\n"

open_stmt:

IF'

booL'

stmt{printf("

open_stmt-->

if(bool)stmt\n"

|IF'

matched_stmtELSEopen_stmt{printf("

if(bool)matched_stmtelseopen_stmt\n"

matched_stmt:

matched_stmtELSEmatched_stmt{printf("

matched_stmt-->

if(bool)matched_stmtelsematched_stmt\n"

|other{printf("

other\n"

other:

loc'

loc=bool;

|WHILE'

while(bool)stmt\n"

|DOstmtWHILE'

dostmtwhile(bool);

|BREAK'

break;

|block{printf("

loc:

loc-->

loc[bool]\n"

|ID{printf("

id\n"

booL:

booLORjoin{printf("

bool-->

bool||join\n"

|join{printf("

join\n"

join:

joinANDequality{printf("

join-->

join&

equality\n"

|equality{printf("

equality:

equalityEQrel{printf("

equality-->

equality==rel\n"

|equalityNErel{printf("

equality!

=rel\n"

|rel{printf("

rel\n"

rel:

expr'

expr{printf("

rel-->

expr<

expr\n"

|exprLEexpr{printf("

=expr\n"

}

|exprGEexpr{printf("

expr>

|expr'

|expr{printf("

expr:

term{printf("

expr-->

expr+term\n"

expr-term\n"

|term{printf("

term\n"

term:

term'

*'

unary{printf("

term-->

term*unary\n"

|term'

/'

term/unary\n"

|unary{printf("

unary\n"

unary:

unary-->

|'

-unary\n"

|factor{printf("

factor\n"

factor:

factor-->

(bool)\n"

|loc{printf("

loc\n"

|NUM{printf("

num\n"

|REAL{printf("

real\n"

|TRUE{printf("

true\n"

|FALSE{printf("

false\n"

#include"

lex.yy.c"

main(intargc,char**argv)

{

yyparse();

yyerror(char*s)

fprintf(stderr,"

error:

%s\n"

s);

六、实验结果

Lex.l词法分析结果:

Yacc.y语法分析结果:

…..

七、实验总结

遇到的问题1):

刚开始在window环境下使用lex和yacc工具,编写lex.l文件的时候,在识别到if时,return(IF),提示IF没有定义,定义#defineIF265后,在yacc.y文件中,再定义%tokenIF,发生重定义错误。

解决办法:

在lex.l文件中,无须定义#defineIF265,只在yacc.y文件中定义%tokenIF即可,不过在yacc.y中要加入#include””,使两个文件关联起来。

遇到的问题2):

在使用yacc工具编译yacc.y文件时,提示缺少bison.simple。

上网下载一个bison.simple,放到yacc工具主目录下。

遇到的问题3):

在lex.l和yacc.y文件的第三部分同时写了main函数,导致错误。

Lex.l文件中第三部分为空,不需要任何函数。

因为关联lex.l和yacc.y后,yyparse()会自动调用yylex()。

遇到的问题4):

生成yacc.tab.c文件后,放入VC++编译器中编译,提示错误如下:

errorLNK2001:

unresolvedexternalsymbol_yyerror

Debug/main.exe:

fatalerrorLNK1120:

1unresolvedexternals

未找到解决办法,无奈只能放弃window环境,改用linux环境编写。

遇到的问题5):

IF'

bool'

stmt--if(bool)stmt\n"

stmtELSEstmt{printf("

if(bool)stmtelsestmt\n"

存在冲突。

改为:

遇到的问题6):

这是一个致命性的问题,由于使用的linux下的lex版本太低,导致照抄课本上的ID和NUM正则表达式无法识别,困扰了我很久很久。

多亏了朋友的帮助,终于发现错误,把{letter}({letter}|{digit})*改为[a-zA-Z_][a-zA-Z0-9_]*;

把{digit}+(\.{digit}+)?

(E[+-]?

{digit}+)?

改为[+-]?

[0-9]+和[+-]?

[0-9]*[.][0-9]+,分别用于识别整数和浮点数。

遇到的问题7):

一些小错误,比如词法分析中,漏识别while等,还有把‘=’误当做了EQ。

仔细检查lex.l,对错漏的部分进行改补。

遇到的问题8):

对IF和IFELSE消除二义性后,依然存在冲突如下:

尚未找到解决办法。

本次实验主要是学习结合lex和yacc工具进行语法分析,通过工具文档,了解lex和yacc的编写规则,然后使用教程后的源语言定义规则,即语法分析的各个文法即可编写出正确的yacc.y。

在linux下使用lex和yacc比较容易,而在window下使用,就相对麻烦,会遇到的各种问题,所以该实验选用linux环境是不二选择。

其次,linux环境可能存在lex和yacc的版本比较低,导致一些教程上的一些正则表达式无法识别,这个错误比较难发现。

总之,通过本次实验,用了近一天的时间调试程序,对词法分析和语法分析有了进一步的认识,同时对程序纠错有了进一步的体会,再者更加熟悉了linux环境操作,更加体会到了linux功能的强大。

但本实验还有一些令人不太满意的地方,比如*.y文件中依然存在冲突没有解决彻底,而且*.l文件中对于浮点数的识别还是具有一定的局限性,不能识别所有可能出现的浮点数。

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

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1