yacc(Yet Another
编译器 Compiler),是一个经典的生成语法分析器的工具。yacc生成的编译器主要是用
c语言写成的语法解析器(Parser),需要与词法解析器Lex一起使用,再把两部分产生出来的C程序一并编译。yacc本来只在Unix系统上才有,但现时已普遍移植往Windows及其他平台。
Yacc由Stephen C. Johnson在20世纪70年代初于贝尔实验室/AT\u0026T开发,最初是用B
编程语言编写,后由Alan Snyder改写为C语言。它作为
unix第3版的一部分出现,并于1975年发表了Yacc的详细描述。Yacc的设计受到了Donald Knuth关于LR分析的工作和TMG编译器-编译器的影响。
分析程序生成器(parser generator)是一个指定某个格式中的一种语言的语法作为它的输入,并为该种语言产生分析过程以作为它的输出的程序。在历史上,分析程序生成器被称作编译-编译程序(
编译器-compiler),这是由于按照规律可将所有的编译步骤作为包含在分析程序中的动作来执行。现在的观点是将分析程序仅考虑为编译处理的一个部分,所以这个术语也就有些过时了。合并LALR(1)分析算法是一种常用的分析生成器,它被称作Yacc(yet another compiler-compiler)。给出Yacc的概貌来,将使用Yacc为TINY语言开发一个分析程序。作为Yacc对说明文件中的%token NUMBER声明的对应。Yacc坚持定义所有的符号记号本身,而不是从别的地方引入一个定义。但是却有可能通过在记号声明中的记号名之后书写一个值来指定将赋给记号的数字值。yacc的输入是巴科斯范式(BNF)表达的语法规则以及语法规约的处理代码,Yacc输出的是基于表驱动的编译器,包含输入的语法规约的处理代码部分。yacc是开发编译器的一个有用的工具,采用LALR(1)语法分析方法。Yacc最初由AT\u0026T的Steven C. Johnson为Unix操作系统开发,后来一些兼容的程序如Berkeley Yacc,GNU bison,MKS yacc和Abraxas yacc陆续出现。它们都在原先基础上做了少许改进或者增加,但是基本概念是相同的。由于所产生的解析器需要词法分析器配合,因此Yacc经常和词法分析器的产生器——一般就是Lex——联合使用。IEEE POSIX P1003.2标准定义了Lex和Yacc的功能和需求。
Yacc的输入是带有C代码片段(称为“动作”)附加到其规则的语法。它的输出是一个在C中执行与每个规则关联的C代码片段的移位-归约解析器。典型的动作涉及构造解析树。例如,一个规则可能会识别求和表达式并为其构造节点。Yacc只生成解析器,可以在无
扫描仪解析的情况下单独使用,但完整的句法分析通常需要外部词法分析器首先执行标记化阶段。
首次使用Yacc实现的语言包括AWK、
C++、eqn和Pic。Yacc还在Unix上用于实现便携式C编译器,以及用于
Fortran 77、Ratfor、APL、bc、m4等
编程语言的解析器。此外,Yacc也被重写以支持其他语言,如OCaml、Ratfor、ML、Ada、Pascal、Java、
Python、
Ruby、Go、Common Lisp和
Erlang。