bison使用浅析

Bison是GNU项目中的一个语法分析器,起源于StephenC.Johnson的Yacc。它用于解析输入文件,根据语法规则生成解析树。文章通过一个简单的计算器示例展示了Bison的语法规则,包括记号声明、BNF规则和C代码部分,其中$$和$1等符号用于表示语法符号的语义值。
摘要由CSDN通过智能技术生成

Bison背景介绍

Bison来源于Yacc(yet another compiler compiler), Yacc是Stephen C.Johnson在1975年到1978年期间在贝尔实验室完成的语法分析器。大约在1985年,一个名叫Bob Corbett的加州伯克利大学研究生改进了内部算法再次实现了Yacc(伯克利Yacc),由于这个版本比贝尔实验室的Yacc更快,并且许可证也更加灵活,很快成为主流的Yacc,来自自由软件基金会的Richard Stallman改写了Corbett的版本并集成到GNU的项目中,然后又被添加了大量新的特性,逐渐演化为当前的Bison.

Bison语法规则

先从一个简单的计算器示例来说明Bison的语法规则

%{
#include <stdio.h>
int yylex();
void yyerror(char *s);
%}

/*declare tokens */

%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL


/**
每个bison规则中的语法符号都有一个语义值,目标符号(冒号左边的语法符号)的值在动作中代码用$$代替,
右边语法符号的语义值依次为$1, $2,直到这条规则的结束。
当词法分析器返回记号时,记号值总是储存在yyval里。其他语法符号的语义值则在语法分析器的规则里进行设置。
*/
%%

calclist:/*空规则*/
    | calclist exp EOL { printf("=%d\n", $2); }
    ;

exp: factor {$$ = $1}
   | exp ADD factor { $$ = $1 + $3; }
   | exp SUB factor { $$ = $1 - $3; }
   ;
factor: term  {$$ = $1}
   | factor MUL term { $$ = $1 * $3; }
   | factor DIV term { $$ = $1 / $3; }
   ;
term: NUMBER {$$ = $1}
    | ABS term {$$ = $1 >= 0 ? $2 : -$2}
    ;

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

Bison的程序结构包含三个部分,以%%分割。

第一部分为声明部分,声明部分为
%{和%}之间的内容,会被直接拷贝到生成的C代码中,%token为记号声明,告诉Bison在语法分析程序中记号的名称,通常来说使用大写字母来表示(Bison并没有强制规定必须要大写)。如果一个语法符号既不是记号也没有出现在任何规则的左边,它就会像程序中未定义的变量,最好避免出现这种问题。

第二部分包含了BNF定义的规则,Bison使用的是单一冒号来表示赋值操作,分号表示规则的结束,类似于Flex,匹配之后需要执行的操作代码用花括号括起。每条规则中的语法符合都有一个语义值,目标符号(冒号左边的非终结符)的值在动作代码中用$$代替,右边的语法符号语意值依此为$1,$2…,直到这条规则的结束,当词法分析器返回记号时,记号值存储在yyval里,在上述示例中,头两条规则定义来calclist语法符号,第一条规则为空所以不进行任何匹配,第二条规则主要匹配我们需要计算的表达式,并通过$2打印出表达式的值,其余的规则实现了计算器的相关操作逻辑。

第三部分为C代码部分,会直接拷贝到生成的C文件中,在本例中主要包含一个主函数入口和错误打印函数,在主函数中会调用yyparse函数开始语法分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值