`
chinamming
  • 浏览: 140706 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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 + * ( ) $ \n E F T OUT def
0 ACC->.OVER s1 s2 4 6 5 3
1 F->NUM. r7
2 F->(.E) s1 s2 7 6 5
3 ACC->OVER. acc
4 OUT->e.'\n'
E->E.+T
s10 s9
5 E->T.
T->T.*F
s11 r3
6 T->F. r5
7 E->E.+T
F->(E.)
s10 s12
8 ACC->OVER end. acc
9 OVER->E'\n'. r1
10 E->E+.T s1 s2 6 13
11 T->T*.F s1 s2 14
12 F->(E). r6
13 E->E+T.
T->T.*F
s11 r2
14 T->T*F. r4

3+2*5规约过程

符号 输入 动作
0 0 $ 3+2*5\n$ shift1
1 0 1 $3 +2*5\n$ r7
2 0 6 $F +2*5\n$ r5
3 0 5 $T +2*5\n$ read->r3
4 0 4 $E +2*5\n$ shift10
5 0 4 10 $E+ 2*5\n$ shift1
6 0 4 10 1 $E+2 *5\n$ r7
7 0 4 10 6 $E+F *5\n$ r5
8 0 4 10 13 $E+T *5\n$ shift11
9 0 4 10 13 11 $E+T* 5\n$ shift1
10 0 4 10 13 11 1 $E+T*5 \n$ r7
11 0 4 10 13 11 14 $E+T*F \n$ r4
12 0 4 10 13 $E+T \n$ r2
13 0 4 $E \n$ shift9
14 0 4 9 $E\n $ r1
15 0 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的实现中用到的表格:

  1. yyrhs 和yyprhs一起表示产生式右端文法串,是一个用-1隔开的索引串大数组,串的内容是文法符号的编号
  2. yyr1 产生式左端文法符号的编号
  3. yyr2 产生式右端长度
  4. yyrline 产生式的定义行
  5. yyprhs 和yyrhs一起表示产生式右端文法串,内容为右端在yyrhs中的起始位置
  6. yytname 文法符号的名称,必须用YYDEBUG条件编译
  7. yytranslate 把flex返回的token编号翻译成bison的文法编号
  8. yytoknum flex返回的token编号翻译成bison的token编号
  9. yytable DFA状态转移表
  10. yycheck 和yycheck等长的数组
  11. yypgoto 非终结符号上的goto下个状态
  12. yypact Index in YYTABLE of the portion describing STATE-NUM.
  13. yydefact 缺省动作,长度为DFA的状态个数
  14. 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 + * ( ) $ \n E F T OUT def
0 ACC->.OVER s1 s2 4 6 5 3
1 F->NUM. r7
2 F->(.E) s1 s2 7 6 5
3 ACC->OVER. acc
4 OUT->e.'\n'
E->E.+T
s10 s9
5 E->T.
T->T.*F
s11 r3
6 T->F. r5
7 E->E.+T
F->(E.)
s10 s12
8 ACC->OVER end. acc
9 OVER->E'\n'. r1
10 E->E+.T s1 s2 6 13
11 T->T*.F s1 s2 14
12 F->(E). r6
13 E->E+T.
T->T.*F
s11 r2
14 T->T*F. r4

3+2*5规约过程

符号 输入 动作
0 0 $ 3+2*5\n$ shift1
1 0 1 $3 +2*5\n$ r7
2 0 6 $F +2*5\n$ r5
3 0 5 $T +2*5\n$ read->r3
4 0 4 $E +2*5\n$ shift10
5 0 4 10 $E+ 2*5\n$ shift1
6 0 4 10 1 $E+2 *5\n$ r7
7 0 4 10 6 $E+F *5\n$ r5
8 0 4 10 13 $E+T *5\n$ shift11
9 0 4 10 13 11 $E+T* 5\n$ shift1
10 0 4 10 13 11 1 $E+T*5 \n$ r7
11 0 4 10 13 11 14 $E+T*F \n$ r4
12 0 4 10 13 $E+T \n$ r2
13 0 4 $E \n$ shift9
14 0 4 9 $E\n $ r1
15 0 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的实现中用到的表格:

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

分享到:
评论

相关推荐

    Writing MATLAB to C:使用 Bison/Flex 创建的解析器和代码生成器

    该文件包含tmcpar_lex()由 Bison 生成的解析器在内部调用的词法分析器函数的实现。词法分析器定义文件使用解析器定义文件提供的标记定义。由于词法分析器应该返回标记定义,因此应该先运行 Bison。

    Linux环境中使用Flex_Bison进行SQL语法分析

    Linux环境中使用Flex_Bison进行SQL语法分析

    c语法分析器--采用bison(yacc)

    c语法分析器,采用bison2.1(yacc), flex(lex), 生成程序的语法树 分析单个文件,不支持预处理, 不解析预处理符号# bison,flex工具在上传包内,语法见cgrammar-new.y,词法见input.lex 另附相关说明,本代码采用vs...

    Bison and Flex for windows source

    bison 语法分析程序生成器 flex 记法分析程序生成器 文件内含windows可执行程序和源代码。

    windows下的bison.exe和flex.exe

    windows下的用来生成程序的工具,flex是一个词法分析器,用来将一个.l文件生成一个.c程序文件。bison是词法分析器,根据文法把一系列的记号转换成一个语法分析树。

    PL/0语言编译程序改写 利用 Flex 及 Bison 工具重写 C 语言编写的 PL/0 编译器 编译原理技术课程设计作业

    程序包括.l .y .cpp .h 4个部分,根据原先的 pl0.c 进行改写,功能是读入一段给定的程序并进行自动分析,生成代码序列。 1.程序会要求用户输入文件的名称,然后确定输出文件的名称。 2.自动逐个单词读取文件中信息。...

    基于flexbison的语法分析C语言实现源码+项目说明.zip

    │ ├── cgen.sh # 由flex/bison生成lexer.c,parser.c,parser.h │ ├── display.c # ast输出主函数display(ASTNode* T) │ ├── lexer.l # 词法规则文件 │ └── parser.y # 语法规则文件 └── test_...

    cCompiler:c语言编译器,用lex和yacc工具完成词法分析与语法分析并生成语法树,C ++实现了语法树的解析并生成中间代码,生成中间代码的过程中实现了错误检测。之后利用python对中间代码进行处理并生成mips汇流编码并且可以成功在PCSpim(mips模拟器)上运行

    词法分析与语法分析的原始文件扩展: ://www.quut.com/c/ANSI-C-grammar-l-1998.html和 实现了C语言除了struct和指针几乎所有的语法。 运行 环境要求:flex bison g ++ 11 python3 中间代码生成 Windows命令行输入:...

    bison-example:一个简单的示例,如何启动和运行flexbison项目

    像bison这样的解析器生成器对于语法原型非常有用,不幸的是,它需要大量代码才能启动和运行。 这只是一个非常小的示例,显示了构建基于野牛的解析器所需的样板代码。 我喜欢bison的地方是,您可以编译和部署bison-...

    基于lex和yacc的词法分析器+语法分析器,可以在控制台生成语法分析树.zip

    要使用lex和yacc(或其GNU版本flex和bison)来创建一个可以在控制台生成语法分析树的词法分析器和语法分析器,你需要遵循以下步骤: 定义词法规则 (lex文件): 使用正则表达式来定义你的语言中的记号(tokens)。 ...

    bison-3.4.tar.xz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.3.1.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.5.4.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.2.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.4.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.2.4.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.2.3.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.4.1.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.4.2.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

    bison-3.1.tar.gz

    Bison 是一个由 GNU 项目开发的解析器生成器,通常用于将语法描述转换成一个 C 程序。它是 Yacc(Yet Another Compiler Compiler)的一个自由软件替代品,广泛用于编译器和解释器的开发中,尤其是在处理复杂的语法和...

Global site tag (gtag.js) - Google Analytics