备忘录1 - 阿林的词法分析器答辩内容
前言:
我们知道,通过一些词法分析生成器工具可以完成一个编译器的词法分析过程,比如说flex,我们可以通过它完成词法分析过程,但是它完成了这个过程并不会将整个词法分析的结果打印出来,因此我们需要使用正则表达式来匹配相应的字符串,并将匹配的结果输出,以便能够更加清晰地看到词法分析器的分析过程。
一、实现思路
一般情况下,Flex的输入可以由三段组成,分别是定义部分、规则部分、以及代码部分,三者分别使用%%隔开,如下:
//定义部分代码
%%
//规则部分代码(正则表达式)
%%
//用户代码部分(即用户输入的代码,供词法分析器识别)
案例如下:
//定义部分
%{
#include<stdio.h>
#include<stdlib.h>
int line=1;
%}
//正则表达式输出匹配字符串输出规则部分
DIGIT [0-9] //单位整数
OINTEGER [1-9]{DIGIT}* //整数
%%
\n {++line;}
{DIGIT} {printf("line%d:(integer, %s)\n",line,yytext);}
{OINTEGER} {printf("line%d:(integer, %s)\n",line,yytext);}
. {}
[ \t]+ {}
//用户输入代码部分,可通过读取代码文件,也可以从命令窗口中输入代码。
%%
int main(){
yyin=fopen("F:/data.txt","r");
yylex();
return 0;
}
int yywrap(){
return 1;
}
二、实验结果
- 创建lex.l文件,编辑输入处理词法单元的正则表达式文件。
- 输入 flex lex.l, 生成lex.yy.c文件、
- 输入 gcc lex.yy.c -o test ,执行代码
- ./test 输入用户测试代码,得到实验结果
//lex.l代码:
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int line=1;
%}
LETTER [a-zA-Z]
ID ({LETTER}|_)({LETTER}|_|{DIGIT})*
OPT ("+"|"-"|"*"|"/"|"+="|"-="|"*="|"/="|">="|"<="|"=="|">"|"<"|"="|"++"|"--")
BRACKET ("("|")"|"["|"]"|"{"|"}"|";"|","|"\'"|"\""|"#")
DIGIT [0-9]
OINTEGER [1-9]{DIGIT}*
INTEGER ("+"|"-")?{OINTEGER}
DECIMAL {INTEGER}(.{OINTEGER})
FLOAT ([0-9])*+[.]([0-9])*+[Ee]([+-]?[0-9]([0-9])*|[0])
ERROEFLOAT ([0-9])*+[.](0-9)*+("E"|"e")
TYPE void|int|double|char
KEYWORD if|else|do|while|for|scanf|printf|sqrt|abs|main|return|float
TYPEIDENTIFY %d|%c|%s|%f|&{ID}
SGPS \/\/.*
DBPS \/\*(.|\n)*\*\/
%%
\n {++line;}
{TYPE} {printf("line%d:(type, %s)\n",line,yytext);}
{KEYWORD} {printf("line%d:(keyword, %s)\n",line,yytext);}
{DIGIT} {printf("line%d:(integer, %s)\n",line,yytext);}
{OINTEGER} {printf("line%d:(integer, %s)\n",line,yytext);}
{ID} {printf("line%d:(identify, %s)\n",line,yytext);}
{BRACKET} {printf("line%d:(bracket, %s)\n",line,yytext);}
{OPT} {printf("line%d:(OPT, %s)\n",line,yytext);}
{INTEGER} {printf("line%d:(integer, %s)\n",line,yytext);}
{DECIMAL} {printf("line%d:(decimal, %s)\n",line,yytext);}
{FLOAT} {printf("line%d:(float, %s)\n",line,yytext);}
{TYPEIDENTIFY} {printf("line%d:(typeidentify, %s)\n",line,yytext);}
{ERROEFLOAT} {printf("ERROEFLOAT\n");}
({SGPS}|{DBPS}) {}
. {}
[ \t]+ {}
%%
int main(){
yyin=fopen("/home/ctguzyj/Desktop/wordtest/data.txt","r");
yylex();
return 0;
}
int yywrap(){
return 1;
}
//data.txt代码
int main(){
int a = 10;
double b = -20.9;
if(a<=b)
a+=b;
return a;
}
截图如下:
仅为编译原理课程所用,如若未提前安装好flex工具,传送门这里