flex&bison安装与简单使用

flex&bison安装与简单使用

1.wls安装

这里使用的是wls,wls安装教程可以参考这一篇,亲测可用,安装后是自带gcc的,但是相关依赖没有,需要运行以下两个命令

sudo apt-get update
sudo apt-get  install  build-essential

可能会遇到一些问题,可以广泛参考网上的错误解决方案~

2.安装flex bison并尝试第一个flex程序

在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程序包含三个部分,各个部分通过%%行进行分割

  • 第一部分是声明部分,%{和}%之间的代码会原样照抄到生成的C文件的开头部分,在上面的栗子中,我们使用其设定了行数、单词书与字符数的变量
  • 第二部分是模式匹配部分,学习过正则表达式的同学对着肯定不会陌生(这里就不对正则表达式做详细介绍了~),每一行的开始处对应一个模式(用一个正则表达式表示),后面是当模式匹配时会执行的C语言代码(变量yytext总是被设定为指向本次匹配输入的文本)
  • 第三部分是我们的主程序,它负责调用flex体用的词法分析例程yylex(),并输出结果。在没有其他改变的情况下,词法分析器将读取标准输入。

我们首先编译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&bison安装与简单使用_第1张图片

对于flex正则表达式匹配的一些说明:

  • 默认贪婪匹配(匹配更长的字符串)
  • 优先匹配程序里先出现的模式

3.让Flex和Bison协同工作

我们现在需要完成一个简单的计算器

首先使用编写一个简单的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一样分成三部分:

  • 第一部分首先也是声明,会拷贝到目标程序开头,随后事%token标记声明,以便告诉bison在语法分析中的记号名称
  • 第二部分就是BNF定义的规则,使用单一的冒号:表示,和flex一样,匹配每一条规则后,就会执行后面用花括号括起来的动作代码,我们一般使用动作代码维护每个语法对应的符号关联语义值,目标符号的值在动作代码中用$$表示,右边语法符号的语义值依次为$1, $2…,直到这条规则结束。记号值总是存储在yyval中,这就对应我们上面的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,直接运行就可以了,一个简易的计算器就完成了~

flex&bison安装与简单使用_第2张图片

你可能感兴趣的:(编译原理,正则表达式,编译原理,flex,bison)