Bison生成文件分析

Bison功能很强大,可以加参数-v可以生成可阅读的.output文件,还可以生成dot转换图

本文以lex yacc 创建一个桌面计算器为例子研究bison生成代码

所有介绍都以bison生成为准,通过-v生成*.output文件,通过设置#define YYDEBUG 1以及yydebug=1进行调制

文法

0 ACCEPT : OVER

1 OVER : E '\n'

2 E : E + T

3 E : T

4 T : T * F

5 T : F

6 F : ( E )

7 F : NUM

状态图

NUM+*()$\nEFTOUTdef
0ACC->.OVERs1s24653
1F->NUM.r7
2F->(.E)s1s2765
3ACC->OVER.acc
4OUT->e.'\n'
E->E.+T
s10s9
5E->T.
T->T.*F
s11r3
6T->F.r5
7E->E.+T
F->(E.)
s10s12
8ACC->OVER end.acc
9OVER->E'\n'.r1
10E->E+.Ts1s2613
11T->T*.Fs1s214
12F->(E).r6
13E->E+T.
T->T.*F
s11r2
14T->T*F.r4

3+2*5规约过程

符号输入动作
00$3+2*5\n$shift1
10 1$3+2*5\n$r7
20 6$F+2*5\n$r5
30 5$T+2*5\n$read->r3
40 4$E+2*5\n$shift10
50 4 10$E+2*5\n$shift1
60 4 10 1$E+2*5\n$r7
70 4 10 6$E+F*5\n$r5
80 4 10 13$E+T*5\n$shift11
90 4 10 13 11$E+T*5\n$shift1
100 4 10 13 11 1$E+T*5 \n$r7
110 4 10 13 11 14$E+T*F \n$r4
120 4 10 13$E+T \n$r2
130 4$E \n$shift9
140 4 9$E\n$r1
150 3$OVER$over

源代码分析

yyprhs[] { } 产生式右端文法串在yyrhs中的开始位置

yyrhs[] { } 以-1隔开的产生式右端串

yyrline[] { 0, 8, 8, 9 } .y文件中产生式定义所在的行号,调试信息用

yyname[] {{0:$end}, {1:error}, {2:$undefined}, {3:NUM}, {4:'\n'}, {5:+}, {6:*}, {7:(}, {8:)}, {9:acc}, {10:OUT}, {11:E}, {12:T}, {13:F}, '\0' }

yytoknum[] { 0, 256, 257, 258, 10, 43, 42, 40, 41 }功能与yytranslate相同,token转化为标示符

yy1[] {}产生式左端符号的编号,阅读Bison生成的.output文件开头即可明白

yyr2[] { } 产生式右端长度,阅读Bison生成的.output文件开头即可明白,规约的时候从栈中弹出多少个状态用到

yydefact[] { } 对于每个状态的缺省规约表达式,对应于状态图中def这一列+1

yydefgoto[] { } 对于每个非终结符号,状态0情况下GOTO状态

yypact[] { } 如果某个状态只有默认动作,则为设置默认操作值,这儿是-6, 没有向前看token的情况下执行判断

yypgoto[] { }

yytable[] { }

yycheck[] { }

yystos[] { }

如果yypact值不为默认值,则yypact、yytoken、yytable、yycheck来确定状态转移,应该是用了某种压缩算法

规约以后状态转移根据yypgoto,判断采用yytable还是yydefgoto计算新的state



参考资源

以下是网上找到的资源,太不容易了

bison的实现中用到的表格:

yyrhs 和yyprhs一起表示产生式右端文法串,是一个用-1隔开的索引串大数组,串的内容是文法符号的编号 yyr1 产生式左端文法符号的编号 yyr2 产生式右端长度 yyrline 产生式的定义行 yyprhs 和yyrhs一起表示产生式右端文法串,内容为右端在yyrhs中的起始位置 yytname 文法符号的名称,必须用YYDEBUG条件编译 yytranslate 把flex返回的token编号翻译成bison的文法编号 yytoknum flex返回的token编号翻译成bison的token编号 yytable DFA状态转移表 yycheck 和yycheck等长的数组 yypgoto 非终结符号上的goto下个状态 yypact Index in YYTABLE of the portion describing STATE-NUM. yydefact 缺省动作,长度为DFA的状态个数 yydefgoto 缺省goto,长度为非终结符号

实 际上BISON就是给我们造表,至于怎么用这个表是我们的事,这些好比是个瓤子,在这个瓤子外头套个毛衣,一个翻译程序就出来了。当然一般来说都是直接用 嵌在BISON里头的毛衣,这样就得到一个LALR(1)分析程序,BISON程序多半支持一个``-S''参数可以用来切换毛衣。

想 了想,明白为什么昨天搞的那个parse tree那么庞大了,因为那个语法是从c99手册扒出来的一点都没有改造过。c99为了严谨用的是优先级级联的无二义性的文法(所以c99里头用不着说明 什么优先级了),这个文法的毛病就是实现太不方便,太多的单一产生式(右端只有一个文法符号的产生式),所以parse tree打印出来就成了一个个很大的锯齿。反观gcc的语法文件就很不一样,引入优先级说明之后,文法变的很简单,所以分析树也得到了简化。

http://www.docin.com/p-483435351.html

介绍了gcc语法分析

yyprhs[] { 0, 0, 3, 7 } 产生式右端文法串在yyrhs中的开始位置,表示从第3、7项开始

yyrhs[] { 6, 0, -1, 6, 4, 3, -1, 3, -1 } 以-1隔开的产生式右端串

yydefact[] { 0, 3, 0, 1, 0, 2 } 对于每个状态的缺省规约表达式,0表示默认出错

yydefgoto[] { -1, 2 } 对于每个非终结符号的缺省GOTO

yypact[] { -2, -3, 0, -3, -1, -3 } -3:默认 没有向前看token的情况下执行判断

yypgoto[] { -3, -3 }

yytable[] { 3, 1, 5, 0, 4 }

yycheck[] { 0, 3, 3, -1, 4 }

yystos[] { 0, 3, 6, 0, 4, 3 }

Bison功能很强大,可以加参数-v可以生成可阅读的.output文件,还可以生成dot转换图

本文以lex yacc 创建一个桌面计算器为例子研究bison生成代码

所有介绍都以bison生成为准,通过-v生成*.output文件,通过设置#define YYDEBUG 1以及yydebug=1进行调制

文法

0 ACCEPT : OVER

1 OVER : E '\n'

2 E : E + T

3 E : T

4 T : T * F

5 T : F

6 F : ( E )

7 F : NUM

状态图

NUM+*()$\nEFTOUTdef
0ACC->.OVERs1s24653
1F->NUM.r7
2F->(.E)s1s2765
3ACC->OVER.acc
4OUT->e.'\n'
E->E.+T
s10s9
5E->T.
T->T.*F
s11r3
6T->F.r5
7E->E.+T
F->(E.)
s10s12
8ACC->OVER end.acc
9OVER->E'\n'.r1
10E->E+.Ts1s2613
11T->T*.Fs1s214
12F->(E).r6
13E->E+T.
T->T.*F
s11r2
14T->T*F.r4

3+2*5规约过程

符号输入动作
00$3+2*5\n$shift1
10 1$3+2*5\n$r7
20 6$F+2*5\n$r5
30 5$T+2*5\n$read->r3
40 4$E+2*5\n$shift10
50 4 10$E+2*5\n$shift1
60 4 10 1$E+2*5\n$r7
70 4 10 6$E+F*5\n$r5
80 4 10 13$E+T*5\n$shift11
90 4 10 13 11$E+T*5\n$shift1
100 4 10 13 11 1$E+T*5 \n$r7
110 4 10 13 11 14$E+T*F \n$r4
120 4 10 13$E+T \n$r2
130 4$E \n$shift9
140 4 9$E\n$r1
150 3$OVER$over

源代码分析

yyprhs[] { } 产生式右端文法串在yyrhs中的开始位置

yyrhs[] { } 以-1隔开的产生式右端串

yyrline[] { 0, 8, 8, 9 } .y文件中产生式定义所在的行号,调试信息用

yyname[] {{0:$end}, {1:error}, {2:$undefined}, {3:NUM}, {4:'\n'}, {5:+}, {6:*}, {7:(}, {8:)}, {9:acc}, {10:OUT}, {11:E}, {12:T}, {13:F}, '\0' }

yytoknum[] { 0, 256, 257, 258, 10, 43, 42, 40, 41 }功能与yytranslate相同,token转化为标示符

yy1[] {}产生式左端符号的编号,阅读Bison生成的.output文件开头即可明白

yyr2[] { } 产生式右端长度,阅读Bison生成的.output文件开头即可明白,规约的时候从栈中弹出多少个状态用到

yydefact[] { } 对于每个状态的缺省规约表达式,对应于状态图中def这一列+1

yydefgoto[] { } 对于每个非终结符号,状态0情况下GOTO状态

yypact[] { } 如果某个状态只有默认动作,则为设置默认操作值,这儿是-6, 没有向前看token的情况下执行判断

yypgoto[] { }

yytable[] { }

yycheck[] { }

yystos[] { }

如果yypact值不为默认值,则yypact、yytoken、yytable、yycheck来确定状态转移,应该是用了某种压缩算法

规约以后状态转移根据yypgoto,判断采用yytable还是yydefgoto计算新的state



参考资源

以下是网上找到的资源,太不容易了

bison的实现中用到的表格:

yyrhs 和yyprhs一起表示产生式右端文法串,是一个用-1隔开的索引串大数组,串的内容是文法符号的编号 yyr1 产生式左端文法符号的编号 yyr2 产生式右端长度 yyrline 产生式的定义行 yyprhs 和yyrhs一起表示产生式右端文法串,内容为右端在yyrhs中的起始位置 yytname 文法符号的名称,必须用YYDEBUG条件编译 yytranslate 把flex返回的token编号翻译成bison的文法编号 yytoknum flex返回的token编号翻译成bison的token编号 yytable DFA状态转移表 yycheck 和yycheck等长的数组 yypgoto 非终结符号上的goto下个状态 yypact Index in YYTABLE of the portion describing STATE-NUM. yydefact 缺省动作,长度为DFA的状态个数 yydefgoto 缺省goto,长度为非终结符号

实 际上BISON就是给我们造表,至于怎么用这个表是我们的事,这些好比是个瓤子,在这个瓤子外头套个毛衣,一个翻译程序就出来了。当然一般来说都是直接用 嵌在BISON里头的毛衣,这样就得到一个LALR(1)分析程序,BISON程序多半支持一个``-S''参数可以用来切换毛衣。

想 了想,明白为什么昨天搞的那个parse tree那么庞大了,因为那个语法是从c99手册扒出来的一点都没有改造过。c99为了严谨用的是优先级级联的无二义性的文法(所以c99里头用不着说明 什么优先级了),这个文法的毛病就是实现太不方便,太多的单一产生式(右端只有一个文法符号的产生式),所以parse tree打印出来就成了一个个很大的锯齿。反观gcc的语法文件就很不一样,引入优先级说明之后,文法变的很简单,所以分析树也得到了简化。

http://www.docin.com/p-483435351.html

介绍了gcc语法分析

yyprhs[] { 0, 0, 3, 7 } 产生式右端文法串在yyrhs中的开始位置,表示从第3、7项开始

yyrhs[] { 6, 0, -1, 6, 4, 3, -1, 3, -1 } 以-1隔开的产生式右端串

yydefact[] { 0, 3, 0, 1, 0, 2 } 对于每个状态的缺省规约表达式,0表示默认出错

yydefgoto[] { -1, 2 } 对于每个非终结符号的缺省GOTO

yypact[] { -2, -3, 0, -3, -1, -3 } -3:默认 没有向前看token的情况下执行判断

yypgoto[] { -3, -3 }

yytable[] { 3, 1, 5, 0, 4 }

yycheck[] { 0, 3, 3, -1, 4 }

yystos[] { 0, 3, 6, 0, 4, 3 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值