编译原理实验——flex语法实现简单词法分析器
作者:互联网
一、实验目的
设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求
2.1 待分析的简单的词法
(1)关键字:
begin if then while do end
所有的关键字都是小写。
(2)运算符和界符
:= + - * /
< <= <> > >= =
; ( ) #
(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
ID = letter (letter | digit)*
NUM = digit digit*
(4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:
表2.1 各种单词符号对应的种别码
2.3 词法分析程序的功能:
输入:所给文法的源程序字符串。
输出:二元组(syn,token或num)构成的序列。
其中:syn为单词种别码;
token为存放的单词自身字符串;
num为整型常数。
例如:对源程序begin x:=9; if x>9 then x:=2*x+1/3; end #
的源文件,经过词法分析后输出如下序列:
(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…
三、实验过程
首先需要了解flex语法格式
%{
C语言声明,一般声明全局变量和函数,会复制进lex.yy.c中
%}
定义正则表达式的名字,可以在规则段中使用
%%
规则段,每一行都是一条规则,每一条规则由匹配模式和事件组成。每当一个模式被匹配到,后面的事件被执行!
%%
用户自定义过程,直接复制到lex.yy.c末尾
flex提供的2个全局变量:
yytext:刚刚匹配到的字符串 yyleng:刚刚匹配到的字符串的长度
代码段如下:
%{
#include <stdio.h>
#include <string.h>
%}
ALPHA [a-zA-Z]
ID {ALPHA}+[a-zA-Z0-9_]*
KEY begin|if|then|while|do|end
NUM [\-]?[1-9][0-9]*|0
%%
{KEY} {
if(yytext[0]=='b')
printf("(1,%s)",yytext);
else if(yytext[0]=='i')
printf("(2,%s)",yytext);
else if(yytext[0]=='t')
printf("(3,%s)",yytext);
else if(yytext[0]=='w')
printf("(4,%s)",yytext);
else if(yytext[0]=='d')
printf("(5,%s)",yytext);
else if(yytext[0]=='e')
printf("(6,%s)",yytext);
}
{ID} printf("(10,%s)",yytext);
{NUM} printf("(11,%s)",yytext);
\+ printf("(13,%s)",yytext);
\- printf("(14,%s)",yytext);
\* printf("(15,%s)",yytext);
\/ printf("(16,%s)",yytext);
\: printf("(17,%s)",yytext);
\:= printf("(18,%s)",yytext);
\< printf("(20,%s)",yytext);
\<> printf("(21,%s)",yytext);
\<= printf("(22,%s)",yytext);
\> printf("(23,%s)",yytext);
\>= printf("(24,%s)",yytext);
\= printf("(25,%s)",yytext);
; printf("(26,%s)",yytext);
\( printf("(27,%s)",yytext);
\) printf("(28,%s)",yytext);
\# printf("(0,%s)",yytext);
\n printf("\n");
.
%%
int main(int argc, char **argv)
{
yylex();
yywrap();
}
int yywrap()
{
return 1;
}
解释:
- ALPHA是字母,ID是标识符,KEY是关键字,NUM整型常数
- 关键字比标识符优先,所以要放它前面,不然识别会有错误
- 符号'.'表示除\n外的所有字符
- 整型常数可以是负数也可以是0
- 匹配的那些符号,最好在前面都加上\(转义字符)
四、实验结果
- 用管理员身份打开cmd窗口
- 进入到该代码文本文件所在的文件夹内
- 然后输入下面两行命令,完成对代码的编译生成。
flex test.l //此后会生成C文件lex.yy.c
gcc lex.yy.c //使用gcc编译成可执行文件
- 我这里生成的是a.exe文件,在窗口中输入a.exe或a回车,运行该文件
即可输入字符串来验证结果。
可以看到结果是正确的。
标签:flex,yytext,分析器,else,词法,NUM,printf,ID 来源: https://www.cnblogs.com/aliali/p/14822335.html