124
|
Don Wakefield · 技术社区 · 16 年前 |
1
134
一个主要的区别是antlr生成一个ll(*)解析器,而yacc和bison都生成一个lalr解析器。这是许多应用程序的一个重要区别,最明显的是运算符:
Antlr完全无法处理这种语法。要使用antlr(或任何其他ll解析器生成器),您需要将此语法转换为非递归的语法。然而,野牛对这种形式的语法没有问题。您需要将“+”和“-”声明为左关联运算符,但这不是左递归的严格要求。一个更好的例子是分派:
注意这两个
就个人品味而言,我认为LALR语法更容易构造和调试。缺点是你必须处理一些神秘的错误,比如移位减少和(可怕的)减少减少。这些都是Bison在生成解析器时捕捉到的错误,因此它不会影响最终用户体验,但它可以使开发过程更有趣。由于这个原因,一般认为Antlr比Yacc/Bison更容易使用。 |
2
102
yacc/bison和antlr之间最显著的区别是这些工具可以处理的语法类型。yacc/bison处理lalr语法,antlr处理ll语法。 通常,与Lalr语法一起工作很长时间的人会发现与所有语法一起工作更困难,反之亦然。这并不意味着语法或工具本身就更难使用。你觉得哪个工具更容易使用,主要是为了熟悉语法类型。 就优势而言,有一些方面,拉尔语法比所有语法都有优势,还有一些方面,所有语法都比拉尔语法有优势。 yacc/bison生成表驱动的解析器,这意味着“处理逻辑”包含在解析器程序的数据中,而不是解析器代码中。回报是,即使是非常复杂语言的解析器,其代码占用空间也相对较小。在20世纪60年代和70年代,硬件非常有限,这一点更为重要。表驱动的解析器生成器可以追溯到这个时代,小代码占用是当时的主要需求。 ANTLR生成递归下降解析器,这意味着“处理逻辑”包含在解析器代码中,因为语法的每个生成规则都由解析器代码中的函数表示。结果是,通过读取解析器的代码更容易理解解析器正在做什么。此外,递归下降解析器通常比表驱动解析器更快。但是,对于非常复杂的语言,代码占用空间将更大。在20世纪60年代和70年代,这是一个问题。当时,由于硬件的限制,只有像Pascal这样的相对较小的语言可以通过这种方式实现。 ANTLR生成的解析器通常在10000行代码及更多代码附近。手写递归下降解析器通常位于同一个大致位置。Wirth的Oberon编译器可能是最紧凑的编译器,它有大约4000行代码,包括代码生成,但是Oberon是一种非常紧凑的语言,只有大约40条生产规则。 正如有人已经指出的,Antlr的一个大优点是图形化的IDE工具,称为AntlWorks。它是一个完整的语法和语言设计实验室。它在您键入语法规则时将其可视化,如果发现任何冲突,它将以图形方式向您显示冲突是什么以及导致冲突的原因。它甚至可以自动重构和解决冲突,如左递归。一旦您有了一个无冲突的语法,您就可以让AntlWorks解析您的语言的输入文件,并为您构建一个解析树和AST,并在IDE中以图形方式显示该树。这是一个非常大的优势,因为它可以节省您许多小时的工作:在开始编码之前,您将在语言设计中发现概念错误!我还没有为Lalr语法找到任何这样的工具,似乎没有这样的工具。 即使对于那些不希望生成解析器但手工编写代码的人来说,AntlWorks也是一个很好的语言设计/原型设计工具。很可能是最好的工具。不幸的是,如果您想要构建LALR解析器,这对您没有帮助。从LALR转换到LL只是为了利用AntlWorks可能是值得的,但是对于某些人来说,转换语法类型可能是一个非常痛苦的经历。换句话说:YMMV。 |
3
30
Antlr的几个优点:
我的02美元 |
4
8
Antrl的另一个优点是可以使用 ANTLRWORKS 虽然我不能说这是一个严格的优势,因为其他发电机也可能有类似的工具。 |
5
7
bison/flex内存的使用量通常是兆字节左右。与Antlr相比——假设它为您想要解析的文件中的每个令牌使用512字节的内存。400万个令牌,32位系统上的虚拟内存不足。 如果您希望解析的文件很大,那么antlr可能会耗尽内存,因此如果您只想解析一个配置文件,那么它将是一个可行的解决方案。否则,如果您想解析一个包含大量数据的文件,请尝试bison。 |
lluisrojass · 为什么Yacc/野牛规则没有用? 7 年前 |
neomang · 解决yacc冲突-由于冲突,解析器中的规则无效 8 年前 |
Zhang Kai Yu · yacc:%{}在yacc中是什么意思? 9 年前 |
gornvix · 分析多个文件时出现错误的lex状态 9 年前 |
Shehzaad · 为什么它显示我的函数在返回char*时返回int? 11 年前 |
Nikon the Third · 如何解析连续的文本流 11 年前 |
TreeTree · lex和yacc的运行时“语法错误” 11 年前 |