Bison 基础

Bison 基础

简单介绍

bison 是一个语法分析器,把用户输入的内容,根据在.y文件中事先定义好的规则,构建一棵语法分析树。(所谓的规则就是,匹配上对应字符之后,执行相应的动作.)

一个简单的语法例子和分析:

statement :NAME '=' expression
expression : NUMBER '+' NUMBER 
           | NUMBER '-' NUMBER

冒号(:) 用来间隔一条规则的左边和右边。statement等价于NAME ‘=’ expression。

在语法中规定大写字母和引号的内容为终结符,比如NAME '='两个字符不再有含义,已经终结。

expression是非终结符,根据第二行的规定,expression 等价为
两个数的加法或者两个数的减法。其中**竖线(|)**表示一个语法符号有两种等价方式。
NUMBER ‘+’ NUMBER NUMBER ‘-’ NUMBER均是终结符,语法解析结束。

移进规约分析

当bison处理一个语法分析树时,会创建一组状态,每个状态对应一个或者多个分析过的规则中的可能的位置。

当读到的记号不足以结束一条规则的时候,就会把这个记号压入一个内部堆栈,然后切换到新状态,这个过程叫做移进

当压入栈内的所有的语法符号已经等价于一个规则的右部时,就把这些符号全部弹出,把规则的左部压入栈。这个过程叫做规约

Bison组成部分

定义部分
%%
规则部分
%%
用户附加的C语言部分

第一部分为定义部分,此部分主要包括选项文字块注释声明符号语义值数据类型的集合指定开始符号其它声明等等。
文字块存在与%{和%}之间,它们将被原样拷贝到生成文件中。

/* 指定起始符号(start symbol)有时也称为目标符号(goal symbol) */
%start calclist
/* 声明tokens记号,以便于告诉bison在语法分析程序中记号的名称。通常这些记号总是使用大写字母,虽然bison本身并没有这个要求。 */
%token NUMBER 
    
%{
  /* 文字块,该部分的内容将直接复制到生成的代码文件的开头,
  以便它们在使用yyparse定义之前使用。 */
  #define _GNU_SOURCE
  #include <stdio.h>
  #include "ptypes.h"
%}

第二部分,主要是语法规则

%%
 /* 空规则 -- 起始符号(start symbol)有时也称为目标符号(goal symbol) */
calclist:
  /* 如果没有指定语义动作,bison将使用默认的动作: { $$ = $1; }*/
  | calclist exp EOL { printf("- %d\n", $2); } 
  //EOL代表一个表达式的结束。像flex一样,大括号中的表示规则的动作
  ;

exp: factor // default $$ = $1
  | exp ADD factor { $$ = $1 + $3; }
  | exp SUB factor { $$ = $1 - $3; }
  ; // represent the termination of this rule.

factor: term // default $$ = $1
  | factor MUL term { $$ = $1 * $3; }
  | factor DIV term { $$ = $1 / $3; }
  ;

term: NUMBER // default $$ = $1
  | ABS term { $$ = $2 >= 0? $2 : - $2; }
  ;
%%

第三部分,此部分的内容将直接逐字复制到生成的代码文件末尾。该部分主要用于对之前一些声明了的函数进行实现。

int main(int argc, char ** argv)
{
    printf(">");
    yyparse();
    return 0;
}
 
yyerror(char *s)
{
    fprintf(stderr,"error:%s\n",s);
}

左递归和右递归
当你编写一个递归规则时,你可以把递归的引用放在规则右部的左端或者右端,例如:

exprlist: exprlist ',' expr; /* 左递归 */
exprlist: expr ',' exprlist; /* 右递归 */

大多数情况下,你可以选择任意一种方式来编写语法。bison处理左递归要比处理右递归更有效率 。这是因为它的内部堆栈需要追踪到目前位置所有还处在分析中规则的全部符号。

YYINITDEPTH来控制语法分析器堆栈的长度,表明堆栈的初始大小,通常为200,也可以定义YYMAXDEPTH来设置堆栈长度的最大值,通常为1000

%{
#define YYMAXDEPTH 50000
%}
Flex和Bison是一对工具,用于帮助开发者构建编译器和解析器。Flex是一个词法分析器生成器,它将用户定义的正则表达式转化为C/C++代码,用于对输入文本进行词法分析。而Bison是一个语法分析器生成器,它将用户定义的语法规则转化为C/C++代码,用于对词法分析器生成的词法单元序列进行语法分析。 Flex和Bison在编译器开发中的工作流程是相互协作的。首先,Flex生成词法分析器,它根据用户定义的正则表达式规则,将输入文本分解为一系列的词法单元。然后,Bison读取词法分析器生成的词法单元序列,并根据用户定义的语法规则进行语法分析,生成抽象语法树或执行相应的语义动作。 在使用Flex和Bison时,通常需要定义词法规则和语法规则。词法规则描述了词法单元的正则表达式模式,而语法规则描述了语法结构的产生式规则。在Bison生成的代码中,通过调用yylex()函数来获得下一个词法单元,并根据词法单元的类型进行相应的处理。 总之,Flex和Bison是用于构建编译器和解析器的工具,它们相互协作,通过词法分析和语法分析来解析输入文本,并生成相应的处理代码或数据结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [flex & bison 基础概述](https://blog.csdn.net/JiMoKuangXiangQu/article/details/128200598)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值