linux bison的作用是什么

2023年 8月 2日 19.5k 0

这篇文章主要讲解了“linux bison的作用是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“linux bison的作用是什么”吧!

在linux中,bison是用来生成语法分析器程序的工具,它可以将用户提供的语法规则转化成一个语法分析器;bison需要和flex(词法分析器)配合使用来处理复杂的文件解析工作。通过给定语法的产生式开始,bison会通过算法,最终构造得到动作表,然后利用这个动作表去解析句子。

Unix Lex/YACC 发展为 Linux FLex/Bison

Lex是1975年由Mike Lesk和当时尚在AT&T实习的Eric Schmidt共同完成的(Schmidt做的更多),是一个词法分析器的生成程序,可以单独使用也可以与Johnson的yacc协同工作。lex很有名气,但是无奈效率太低加上有bug。大概在1987年,Lawrence Berkeley实验室的Vern Paxson用C重新写了Lex,并命名为FLex(the Fast Lexical Analyzer Generator),基于伯克利许可证。flex现在是SourceForge的一个项目,依然基于伯克利许可,
[Flex](https://github.com/westes/flex "Flex") 是起初unix版lex的free (but non-GNU) implementation,用于c/c ++ 的词法扫描生成器。

(注意:Schmidt曾是google的CEO)

bison的前身是yacc。yacc是由贝尔实验室的S.C.Johnson基于Knuth大神的LR语法分析理论,于1975~1978年写成。大约1985年,UC Berkeley 的研究生Bob Corbett使用改进的内部算法实现了伯克利yacc,来自FSF的Richard Stallman改写了伯克利yacc并将其用于GNU项目,添加了很多特性,形成了今天的GNU Bison。bison现在作为FSF的项目被维护,基于GNU公共许可证发布,[Bison](http://www.gnu.org/software/bison/manual/)是兼容yacc的free的语法生成器。

早期Unix的Lex/YACC,发展为FLex/Bison,新版本的程序是向上兼容的(即兼容老版本),现chang用Flex和Bison。

flex/bison工作原理

使用的角度,Flex和Bison是Linux下用来生成词法分析器和语法分析器两个程序的工具,可以处理结构化输入,一般结合使用来处理复杂的文件解析工作。

linux bison的作用是什么

bison可以将用户提供的语法规则转化成一个语法分析器。简单来说,通过给定语法的产生式开始,bison会通过算法,最终构造得到动作表,然后利用这个动作表去解析句子。具体来说,bison 读取用户提供的语法的产生式,生成一个 C 语言格式的 LALR(1) 动作表,并将其包含进一个名为yyparse的 C 函数,这个函数的作用就是利用这个动作表来解析 token 流 ,而这个 token 流 是由 flex 生成的词法分析器扫描源程序得到的。

flex文件是定义pattern(哪是黄豆,哪是绿豆...),通过flex处理(词法分析)将输出切分成一段一段的token(将输入的豆子一个个摘出来),从而执行不同的action(黄豆就磨豆浆(action),绿豆去做绿豆糕(action))...
flex 生成的tokens可以喂给Bison处理(更简便易调试),当然也可以不喂给bison而直接自己处理就得了(如喜下例)。但是使用bison可以更方便的处理复杂的逻辑,编写简单,调试方便。

编码实战:字符统计器

//本例中仅仅使用flex以及少量手写代码(main中),来完成字符串统计功能。
Yolandas-MacBook-Pro:flex-bison liuyuanyuan$ cat fb1-1.l
/* 统计输入字符串*/
%{
  int chars = 0;
  int words = 0;
  int lines =0;

%}

%%
[a-zA-Z]+ {
		words++;
		chars += strlen(yytext);
          }

n        {     chars++; lines++;}

.         {     chars++;     }

%%


int main(int args, char **argv)
{
	yylex();
	printf("lines=%6d words=%6d chars=%6dn", lines, words, chars);
	return 0;
}

//Linux 系统上用 -lfl 选项编译, Mac 的编译选项是 -ll
Yolandas-MacBook-Pro:flex-bison liuyuanyuan$ gcc -ll lex.yy.c  -o fb1-1
Yolandas-MacBook-Pro:flex-bison liuyuanyuan$ ./fb1-1
hello 
this is yolanda
bye.
lines=     3 words=     5 chars=    28

1 flex(fast lex, scanner)文件内容结构(*.l, 分3部分)

/* P1: declarations(定义段) */
%{
  
%}

%%
  /* P2: translation rules(规则段) */
%%

/* P3: auxiliary functions(用户辅助程序段,c函数)*/

定义段 包括文字块、定义、内部声明等。
C语言的头文件、函数和变量的声明等一般就放在%{…%}之间,这一部分的内容会被直接复制到生成.c文件的开头部分。

包含%option选项

%option noyywrap /* 定义段中包含了option选项*/

%{
#include "cal.tab.h"
extern int yylval;
%}

规则段 %%...%%之间部分,为一系列匹配模式(正则表达式)和动作(C代码)。

当flex扫描程序运行时,它把输入与规则段的模式进行匹配,每次发现一个匹配(被匹配的输入称为标记(token))时就执行与那种模式相关的C代码。

pattern(正则表达式) { action(c代码) }

example:
[0-9]+ {yylval = atoi(yytest); return NUMBER;}

用户辅助程序段 为C代码,会被原样复制到c文件中,一般这里定义一些辅助函数等。

int terror(chr *s)
{
    printf("%sn", s);
    return 0;
}

2 bison(yacc, parser)文件内容结构(*.y , 分3部分,%%分隔)

/*P1: declarations 定义段*/
%{

%}
 
%%
/*P2: grammar rules 规则段(rule-action)*/
    
     A: a1  {  语义动作1 }
	  | a2  {  语义动作2 }
	  | …
	  | an  {  语义动作n }
	  | b  //没有{…},则使用缺省的语义动作       
	; //产生式结束标记
    //语义动作一般是在产生式右部分析完,归约动作进行前执行。
    A→ a1 | a2 |  … | an | b 
%%

/* P3: supporting C routines 用户辅助程序段(C函数) */

定义段 可以分为两部分:

1. %{ 和%}之间的部分,C语言编写的,包括头文件include、宏定义、全局变量定义、函数声明等;

2. 对文法的终结符和非终结符做一些相关声明。

常用的Bison标记声明有:%token %union %start %type %left %right %nonassoc等。

%token 定义文法中使用了哪些终结符。定义形式: %token TOKEN1 TOKEN2  
终结符一般全大写;(如 TOKEN1 TOKEN2)  
一行可定义多个终结符,空格分隔;  

%left、%right、%nonassoc 也是定义文法中使用了哪些终结符。定义形式与%token类似。  
先定义的优先级低,最后定义的优先级最高,同时定义的优先级想通过。  
%left表示左结合,%right表示右结合;  
%nonassoc 表示不可结合(即它定义的终结符不能连续出现。例如

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论