基于Flex (词法分析生成器) 构造词法分析器

备忘录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;
}

二、实验结果

  1. 创建lex.l文件,编辑输入处理词法单元的正则表达式文件。
  2. 输入 flex lex.l, 生成lex.yy.c文件、
  3. 输入 gcc lex.yy.c -o test ,执行代码
  4. ./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工具,传送门这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村头卖假发的小郑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值