用Flex构造简易C语言词法分析器
Flex构造C语言词法分析器 可以识别大部分的C语言关键字和标识符,可以去除注释(多行单行都可以),可以识别整数和浮点数,可以识别错误的浮点数。
lex文件结构:
[第一部分:定义段]
/*
*按照C语言语法,声明文件包含,宏定义,常数定义,全局变量及外部变量定义,函数声明等
*/
%%
第二部分:词法规则段
/*
*核心部分,正则定义和状态定义(解释见后)
*/
%%
第三部分:辅助函数段]
/*
* 辅助函数段用C语言语法来写,辅助函数一般是在词法规则段中用到的函数。这一部分一般会被直接拷贝到lex.yy.c中。
*/
状态定义:
"//".* {}
"/*" {BEGIN COMMENT;}
<COMMENT>"*/" {BEGIN INITIAL;}
<COMMENT>. {}
这一部分是根据不同的状态使用不同的规则,比如要识别多行注释,则添加BEGIN COMMENT即可转移到< COMMENT >状态。
代码如下:
在这里插入代码片/*
*t2.lex 词法分析器
*班级:计科1604
*学号:1030416414
*姓名:wyc(ORION233)
*时间:2018-11-4
*/
%option pointer
%option noyywrap
%x COMMENT
%{
#include <stdio.h>
#include <string.h>
#define MAXLEN 100
#define MAXTYPE 10
#define MAXSTR 15
char *a[MAXTYPE] = {"type","for","integer","decimal","identify","bracket","QUOTE","OPT","float"};
struct {
int line; //store line numbers
int id; // store tag
char text[MAXSTR]; //store yytext
}tag[MAXLEN]; //store tags
int flag = 0; //error flag
int cnt = 0; //array notation counter
int line=1; //line counter
%}
DIGIT [0-9]
OINTEGER [1-9]{DIGIT}*
INTEGER ("+"|"-")?{OINTEGER}
DECIMAL {INTEGER}(.{OINTEGER})?
LETTER [a-zA-Z]
ID ({LETTER}|_)({LETTER}|_|{DIGIT})*
OPT ("+="|"-="|"*="|"/="|"+"|"-"|"*"|"/"|"<="|">="|"=="|"=")
INDEX {DIGIT}+(\.{DIGIT}+)?e([+-])?{DIGIT}+
ERROR {DIGIT}+(\.{DIGIT}+)?e
%%
"//".* {}
"/*" {BEGIN COMMENT;}
<COMMENT>"*/" {BEGIN INITIAL;}
<COMMENT>. {}
\n {++line;}
(int|float|double|short) {
tag[cnt].line = line;
tag[cnt].id = 0;
strcpy(tag[cnt].text,yytext); //has bugs--use strcpy is ok,no pointer
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
for {
tag[cnt].line = line;
tag[cnt].id = 1;
strcpy(tag[cnt].text,"");
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
{INTEGER} {
tag[cnt].line = line;
tag[cnt].id = 2;
strcpy(tag[cnt].text,yytext);
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
{DECIMAL} {
tag[cnt].line = line;
tag[cnt].id = 3;
strcpy(tag[cnt].text,yytext);
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
{ID} {
tag[cnt].line = line;
tag[cnt].id = 4;
strcpy(tag[cnt].text,yytext);
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
("("|")"|"{"|"}"|"["|"]") {
tag[cnt].line = line;
tag[cnt].id = 5;
strcpy(tag[cnt].text,yytext);
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
"\"" {
tag[cnt].line = line;
tag[cnt].id = 6;
strcpy(tag[cnt].text,"");
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
{OPT} {
tag[cnt].line = line;
tag[cnt].id = 7;
strcpy(tag[cnt].text,yytext);
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
{INDEX} {
tag[cnt].line = line;
tag[cnt].id = 8;
strcpy(tag[cnt].text,yytext);
//printf("%s : %d--%d\n",tag[cnt].text,yyleng,cnt);
cnt++;
}
{ERROR} {
flag = 1;
tag[cnt].line = line;
tag[cnt].id = -1; //soso
strcpy(tag[cnt].text,yytext);
cnt++;
}
. {}
%%
int main()
{
/*
*begin lexical analysis
*present all the tags
*but ...
*/
yylex();
if(flag) {//print ERRORS
int i;
for(i=0;i<cnt;i++){
if(tag[i].id == -1){
printf("Error type A at Line %d: Illegal floating point number \"%s\".\n",tag[i].line,tag[i].text);
break;
}
}
} else {
int i;
for(i=0;i<cnt;i++){
if(tag[i].id == 5){//print "QUOTE"
printf("line%d:(%s, \"%s\")\n",tag[i].line,a[tag[i].id],tag[i].text);
} else {
printf("line%d:(%s, %s)\n",tag[i].line,a[tag[i].id],tag[i].text);
}
}
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!