〇、所需安装包
flex-2.5.4a-1.exe + bison-2.4.1-setup.exe + mingw-get-setup.exe
一、安装配置与测试
%{
int yywrap(void);
%}
%%
%%
int yywrap(void)
{
return 1;
}
%{
void yyerror(const char *s);
%}
%%
program:
;
%%
void yyerror(const char *s)
{
}
int main()
{
yyparse();
return 0;
}
我们暂且不讨论上面代码的意思。 打开控制台,进入到刚才所建立文件【 lex.l】【 yacc.y 】所在的文件夹。
1.输入 【flex lex.l】
2.输入 【bison yacc.y】
3.如果我们看到当前文件夹上多了两个文件【yacc.tab.c】【lex.yy.c 】,那么说明 lex&&yacc 已 经安装配置成功,接下来就好好享受这两个小工具的魅力吧。
二、案例(粗糙)
case I:
1、新建文本文件,更改名称为 interpreter.lex,敲入下面代码 ------- 词法分析器的源代码
%{
int wordCount = 0;
int numcount = 0;
%}
chars [A-Za-z\_\'\.\"]
numbers ([0-9])+
delim [" "\n\t]
whitespace {delim}+
words {chars}+
%%
while {ECHO; printf("%s\n",yytext);}
{words} { wordCount++;
/* increase the word count by one*/ }
{whitespace} { /* do nothing*/ }
([0-9])+ { numcount++; /* one may want to add some processing here*/ }
%%
void main()
{
printf("ok1\n");
yylex(); /* start the analysis*/
printf("ok2\n");
printf(" No of words: %d\n number: %d\n", wordCount, numcount);
}
int yywrap()
{
return 1;
}
2、新建文本文件,更名为 sourcecode.c,敲入下面代码 -------- 此为输入源代码
asd asdf 23 q
a1
b2
!#@
while
3、打开菜单,运行,输入 cmd。
输入: cd 文件夹路径
输入: flex interpreter.lex 回车后生成一个 lex.yy.c 文件
输入: gcc -o interpreter lex.yy.c 回车后生成一个 interpreter.exe文件,现在我们已得到了一个简易的词法分析器【interpreter.exe】,下面就是运用次词法分析器,分析下 【sourcecode.c】 文件
输入: interpreter.exe <sourcecode.c> output.txt 回车后生成一个 output.txt 文件
case II: (输出token表)
1、sample2目录下新建 interpreter.lex
%{
#include <stdio.h>
/*
struct{
int linenum;
char name[255];
int typenum;
} tokenItem;
//mine
{Real} { printf("%15s %6d\n", yytext, NUMSYM);}
*/
#define PROGRAM 1
#define IDNAME 58
#define VARSYM 2
#define SEMICOLONSYM 47
#define COLONSYM 41
#define INTEGER 3
#define BEGINSYM 8
#define ASSIGNSYM 39
#define NUMSYM 53
#define PLUSSYM 30
#define ENDSYM 26
#define DOTSYM 50
#define CHARSYM 6
int linenum = 1;
int errornum = 0;
%}
blank [ \t]
Digit0 [1-9]
Digit [0-9]
Letter [a-zA-Z]
Integer {Digit}+
Id {Letter}({Letter}|{Digit}|_)*
delim [" "\t]
newline [\n]
whitespace {delim}+
Real ({Integer}[.]{Integer})([Ee][+-]?{Integer})?
invalId {Digit}({Letter}|{Digit}|_)*
invalLetter [^(Letter)(Digit)-*/\+|_'"!]
%%
[pP][rR][oO][gG][rR][aA][mM] { printf("%-5d %10s %6d\n",linenum, yytext, PROGRAM);}
[Bb][Ee][Gg][Ii][Nn] { printf("%-5d %10s %6d\n",linenum, yytext, BEGINSYM);}
[eE][nN][dD] { printf("%-5d %10s %6d\n",linenum, yytext, ENDSYM);}
[iI][nN][tT][eE][gG][eE][rR] { printf("%-5d %10s %6d\n",linenum, yytext, INTEGER);}
[vV][aA][rR] { printf("%-5d %10s %6d\n",linenum, yytext, VARSYM);}
[cC][hH][aA][rR] { printf("%-5d %10s %6d\n",linenum, yytext, CHARSYM);}
{newline} { linenum++;}
{whitespace} { /* do nothing*/ }
"." { printf("%-5d %10s %6d\n",linenum, yytext, DOTSYM);}
";" { printf("%-5d %10s %6d\n",linenum, yytext, SEMICOLONSYM);}
":" { printf("%-5d %10s %6d\n",linenum, yytext, COLONSYM);}
":=" { printf("%-5d %10s %6d\n",linenum, yytext, ASSIGNSYM);}
"+" { printf("%-5d %10s %6d\n",linenum, yytext, PLUSSYM);}
{Id} { printf("%-5d %10s %6d\n",linenum, yytext, IDNAME);}
{Integer}|{Real} { printf("%-5d %10s %6d\n",linenum, yytext, NUMSYM);}
{invalLetter} { errornum++; printf("[ERROR]:line %d: 无法识别的字符:%s\n", linenum, yytext);}
{invalId} { errornum++; printf("[ERROR]:line %d: 无法识别的标识符: %s\n", linenum, yytext);}
%%
void main()
{
//print("[START]start the analysis...");
//yylex(); /* start the analysis*/
printf("token表信息:\n");
printf("%-10s %10s %10s\n","行号","名称","种别码");
while(yylex()){
}
printf("\n词法分析错误信息:\n");
printf("%d error(s)\n", errornum);
}
int yywrap()
{
return 1;
}
2、新建sourcecode.c
program example;
var
a:integer;
begin
x:=3+3.5+3.5e4;
end.
3、新建soucecode2.c
program example;
var
3a:char;
α:integer;
4、输出sourcecode.c和sourcecode2.c的token表
(1)、cd [sample2的PATH]
(2)、flex interpreter.lex
(3)、gcc -o interpreter lex.yy.c
(4)、interpreter.exe <sourcecode.c> output.txt
(5)、interpreter.exe <sourcecode2.c> output2.txt
运行截图如下:
更多用法参考:
https://blog.csdn.net/wp1603710463/article/details/50365495
https://www.cnblogs.com/wp5719/p/5528896.html
https://wenku.baidu.com/view/715f1ce8b90d6c85ed3ac62d.html