编译原理-实验二-FLEX词法分析器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编译原理-实验⼆-FLEX词法分析器
FLEX词法分析器
⼀、Lex和Yacc介绍
Lex 是⼀种⽣成扫描器的⼯具。

扫描器是⼀种识别⽂本中的词汇模式的程序。

⼀种匹配的常规表达式可能会包含相关的动作。

这⼀动作可能还包括返回⼀个标记。

当 Lex 接收到⽂件或⽂本形式的输⼊时,它试图将⽂本与常规表达式进⾏匹配。

它⼀次读⼊⼀个输⼊字符,直到找到⼀个匹配的模式。

如果能够找到⼀个匹配的模式,Lex 就执⾏相关的动作(可能包括返回⼀个标记)。

另⼀⽅⾯,如果没有可以匹配的常规表达式,将会停⽌进⼀步的处理,Lex 将显⽰⼀个错误消息。

Yacc代表 Yet Another Compiler Compiler 。

Yacc 的 GNU 版叫做 Bison。

它是⼀种⼯具,将任何⼀种编程语⾔的所有语法翻译成针对此种语⾔的 Yacc 语法解析器。

(下载下载flex和bison。

⽹址分别是/packages/flex.htm和
/packages/bison.htm。


⼆、配置环境(win7)
①下载flex和bison并安装到D:\GnuWin32(尽量是根⽬录)
②由于我们使⽤的flex和bison都是GNU的⼯具,所以为了⽅便,采⽤的C/C++
编译器也采⽤GNU的编译器GCC,当然我们需要的也是Windows版本的GCC了。

所以提前准备好VC 6.0
③检验是否可以进⾏lex⽂件编译
1.新建⽂本⽂件,更改名称为lex.l,敲⼊下⾯代码
%{
int yywrap(void);
%}
%%
%%
int yywrap(void)
{
return 1;
}
2.新建⽂本⽂件,更改名称为yacc.y,敲⼊下⾯代码
%{
void yyerror(const char *s);
%}
%%
program:
;
%%
void yyerror(const char *s)
{
}
int main()
{
yyparse();
}
我们暂且不讨论上⾯代码的意思。

打开控制台,进⼊到刚才所建⽴⽂件(lex.l,yacc.y)所在的⽂件夹。

1.输⼊ flex lex.l
2.输⼊ bison yacc.y
如果我们看到当前⽂件夹上多了两个⽂件(yacc.tab.c,lex.yy.c),那么说明lex&&yacc已经安装配置成功,接下来就可以进⾏实验了。

三、课本实例
1. 按课本p58 3.7.3代码,保存testscan.lex⽂件,然后放到与flex相同的⽂件夹下,然后进⼊DOS下,输⼊flex testscan.lex 并回车,即可⽣成lex.yy.c⽂件
2. ⽤C编译器(VC 6.0)编译并产⽣lexyy.exe
3. 建好aaa.txt输⼊⽂件,进⼊DOS下,进⼊到lexyy.exe所在⽬录,输⼊lexyy.exe aaa.txt bbb.txt即可。

{
int a;
a=10;
}
通过分析后:
{, {
int, int
NUM, a
;, ;
NUM, a
=, =
ID, 10
;, ;
}, }
4. 课本p61 7
按题⽬要求适当修改代码,然后在进⼊DOS下,进⼊到lexyy.exe所在⽬录,输⼊lexyy.exe abc.txt abcdef.txt,再打开abcdef.txt即可看到结果
int i=10;
do{
printf(i);
i++;
}while(i!>10)
if(1<2&&2<4)
else(1||2)
分析后:
int, int
NUM, i
=, =
ID, 10
;, ;
NUM, do
{, {
NUM, printf
(, (
NUM, i
), )
;, ;
+, +
+, +
;, ;
}, }
while, while
(, (
NUM, i
!, !
>, >
ID, 10
), )
if, if
(, (
ID, 1
<, <
ID, 2
&&ID, 2
<, <
ID, 4
), )
else, else
(, (
ID, 1
||ID, 2
), )
五、代码
%{
#include<stdio.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
%}
digit [0-9]
number {digit}+
letter [a-zA-Z]
identifier {letter}({letter}|{digit})*
newline [\n]
whitespace [\t]+
%%
"if" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "else" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "for" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "while" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "int" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "=" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "+" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "-" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "*" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "/" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "<" {fprintf(yyout,"%s, %s\n", yytext,yytext);} ">" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "(" {fprintf(yyout,"%s, %s\n", yytext,yytext);} ")" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "{" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "}" {fprintf(yyout,"%s, %s\n", yytext,yytext);} ";" {fprintf(yyout,"%s, %s\n", yytext,yytext);} ":" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "'" {fprintf(yyout,"%s, %s\n", yytext,yytext);} "," {fprintf(yyout,"%s, %s\n", yytext,yytext);}
"!" {fprintf(yyout,"%s, %s\n", yytext,yytext);}
"==" {fprintf(yyout,"%s, %s\n", yytext,yytext);}
">=" {fprintf(yyout,"%s, %s\n", yytext,yytext);}
"<=" {fprintf(yyout,"%s, %s\n", yytext,yytext);}
"!=" {fprintf(yyout,"%s, %s\n", yytext,yytext);} {number} {fprintf(yyout,"%s, %s\n", "ID",yytext);} {identifier} {fprintf(yyout,"%s, %s\n", "NUM",yytext);} {whitespace} {/*跳过空⽩*/}
"/*" {char c ;
int done=FALSE;
do{
while((c=input())!='*');
while((c=input())=='*');
if(c=='/') done=TRUE;
}while(!done);
}
{fprintf(yyout,"%d, %s\n", 0,yytext);}
%%
main(argc,argv)
int argc;
char **argv;
{
++argv,--argc;
if(argc>0)
yyin=fopen(argv[0],"r");
else
yyin=stdin;
++argv,--argc;
if(argc>0)
yyout=fopen(argv[0],"w");
else
yyout=stdout;
yylex();
}
int yywrap()
{
return 1;
}。

相关文档
最新文档