【编译原理】 词法分析实验 基于Flex构造词法分析器
【问题描述】
设计c语言常见单词的正规式,编制lex源文件,利用flex编译得到词法分析的.c文件,继而对该文件编译得到词法分析器。
【输入形式】
输入一段c语言程序
【输出形式】
各类单词的token字,或者给出程序中的单词错误。
【样例输入】
int main(){
int a = 10;
double b = 20.9;
if(a <= b)
a+=b;
else a = 0;
return a;
}
【样例输出】
line1:(type, int)
line1:(keyword, main)
line1:(bracket, ()
line1:(bracket, ))
line1:(bracket, {)
line2:(type, int)
line2:(identify, a)
line2:(OPT, =)
line2:(integer, 10)
line2:(bracket, ;)
line3:(type, double)
line3:(identify, b)
line3:(OPT, =)
line3:(decimal, 20.9)
line3:(bracket, ;)
line4:(keyword, if)
line4:(bracket, ()
line4:(identify, a)
line4:(OPT, <=)
line4:(identify, b)
line4:(bracket, ))
line5:(identify, a)
line5:(OPT, +=)
line5:(identify, b)
line5:(bracket, ;)
line6:(keyword, else)
line6:(identify, a)
line6:(OPT, =)
line6:(integer, 0)
line6:(bracket, ;)
line7:(keyword, return)
line7:(identify, a)
line7:(bracket, ;)
line8:(bracket, })
【样例说明】
需要识别的关键字包括main, return, if, else, do, while, for, scanf, printf, sqrt, abs;type类型包括void, int, double, float, char;运算符(算术、关系、逻辑、位);需要识别的其他单词有标识符, 整数(十进制形式、指数形式),实数(十进制形式、指数形式),字符串(输出类型名为string);过滤注释及空格。
【评分标准】
根据设计文档的质量、lex文件的正确性,代码的正确性、代码的时间空间复杂度、识别单词的种类等综合评分
【Flex源文件代码】
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int line=1;
int count=0;
int atline[1005];
int type[1005];
char text[1005][30];
int errorflag=0;
int errorcount=0;
%}
DIGIT [0-9]
OINTEGER [0-9]{DIGIT}*
INTEGER ("+"|"-")?{OINTEGER}
DECIMAL {INTEGER}"."{OINTEGER}
LETTER [A-Za-z]
IDENTIFY ({LETTER}|_)({LETTER}|{DIGIT}|_)*
OPT "+"|"-"|"*"|"/"|"+="|"-="|"*="|"/="|">"|"<"|"="|">="|"<="|"=="|"++"|"--"
BRACKET "("|")"|"["|"]"|"{"|"}"|","|";"|"\""|"\'"
TYPE void|int|double|char|float
KEYWORD main|return|if|else|do|while|for|scanf|printf|sqrt|abs
TYPEIDENTIFY %{IDENTIFY}|&{IDENTIFY}
COMMENT \/\/(.)*|\/\*(.|\n)*\*\/
FLOAT ({INTEGER}|{DECIMAL})(e|E){INTEGER}
ERROR ({INTEGER}|{DECIMAL})(e|E)
%%
\n {line++;}
{COMMENT} {}
{BRACKET} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=0;}
{OPT} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=1;}
{KEYWORD} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=2;}
{TYPE} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=3;}
{TYPEIDENTIFY} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=4;}
{IDENTIFY} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=5;}
{INTEGER} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=6;}
{DECIMAL} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=7;}
{FLOAT} {count++;atline[count]=line;strcpy(text[count],yytext);type[count]=8;}
{ERROR} {count++;atline[count]=line;strcpy(text[count],yytext);errorcount=count;errorflag=1;}
. {}
%%
int main()
{
yyin=fopen("test.txt","r");
yylex();
fclose(yyin);
int n=1;
if(errorflag==1)
{
printf("Error at Line %d: Illegal floating point number \"%s\".",atline[errorcount],text[errorcount]);
return 0;
}
while(n<=count)
{
printf("line%d:(",atline[n]);
if(type[n]==0) printf("bracket, ");
else if(type[n]==1) printf("OPT, ");
else if(type[n]==2) printf("keyword, ");
else if(type[n]==3) printf("type, ");
else if(type[n]==4) printf("typeidentify, ");
else if(type[n]==5) printf("identify, ");
else if(type[n]==6) printf("integer, ");
else if(type[n]==7) printf("decimal, ");
else if(type[n]==8) printf("float, ");
printf("%s)\n",text[n]);
n++;
}
return 0;
}
int yywrap()
{
return 1;
}