这里使用的是wls,wls安装教程可以参考这一篇,亲测可用,安装后是自带gcc的,但是相关依赖没有,需要运行以下两个命令
sudo apt-get update
sudo apt-get install build-essential
可能会遇到一些问题,可以广泛参考网上的错误解决方案~
在Ubuntu系统系统下安装flex bison,输入以下命令
sudo apt-get install flex bison
一会就装好了,然后我们尝试我们的第一个flex程序(feb1-1.l
),该程序参考flex与bison中文版第二版(可以买来看看!)
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
%%
[a-zA-Z]+ {words++; chars+= strlen(yytext);}
\n {chars++; lines++;}
. {chars++;}
%%
main(int argc, char** argv){
yylex();
printf("%d,%d,%d\n", lines, words, chars);
}
这个程序就是C代码,flex程序包含三个部分,各个部分通过%%行进行分割
我们首先编译flex生成C程序(lex.yy.c
)
flex fb-1-1.l
然后将它与相应的flex库文件(-lfl)链接,生成a.out
cc lex.yy.c -lfl
最后运行程序
./a.out
尝试输入以下内容:
The boy stood on the burning deck
shelling peanuts by the peck
输出为(行数、单词数、字符数)
2,12,63
对于flex正则表达式匹配的一些说明:
我们现在需要完成一个简单的计算器
首先使用编写一个简单的flex词法分析器,不显示的定义记号值,而是直接包含头文件,因为我们希望在语法分析器中直接调用它
文件名:fb-1-5.l
%{
#include"fb-1-5.tab.h"
int yylval;
%}
%%
"+" {return ADD;}
"-" {return SUB;}
"*" {return MUL;}
"/" {return DIV;}
"|" {return ABS;}
[0-9]+ {yylval = atoi(yytext); return NUMBER;}
\n {return EOL;}
[ \t] {return EOL;}
. {printf("Mystery character %c\n", *yytext);}
%%
然后bison程序部分,bison的规则基本上就是BNF(可参考编译原理),bison程序和flex一样分成三部分:
文件名:fb-1-5.y
%{
#include
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
calclist:
| calclist exp EOL {printf("=%d\n", $2);}
;
exp: factor
| exp ADD factor {$$ = $1 + $3;}
| exp SUB factor {$$ = $1 - $3;}
;
factor: term
| factor MUL factor {$$ = $1 * $3;}
| factor DIV term {$$ = $1 / $3;}
;
term:NUMBER
| ABS term {$$ = $2 >= 0? $2 : -$2;}
;
%%
main(int argc, int **argv){
yyparse();
}
yyerror(char *s)
{
fprintf(stderr, "error:%s\n", s);
}
然后联合编译flex与bison程序,由于编译的步骤比较复杂,所以我们写一个Makefile,运行vim Makefile
, 写入如下内容
fb-1-5:fb-1-5.l fb-1-5.y
bison -d fb-1-5.y
flex fb-1-5.l
cc -o $@ fb-1-5.tab.c lex.yy.c -lfl
然后我们编译:
make
得到程序fb-1-5,直接运行就可以了,一个简易的计算器就完成了~