Antlr的优势(比如说,lex / yacc / bison)

过去,我曾在各种项目中使用lex和yacc(通常是野牛),通常是翻译人员(例如EDIF的子集流入EDA应用程序)。 另外,我必须支持基于lex / yacc语法的代码,这些代码可以追溯到几十年前。 所以我知道我的工具,虽然我不是专家。

我在过去的各种论坛上看到过关于Antlr的积极评论,我很好奇我可能会错过什么。 所以,如果你已经使用了两者,请告诉我Antlr更好或更先进。 我目前的限制是我在C ++商店工作,我们发布的任何产品都不包含Java,因此得到的解析器必须遵循该规则。


一个主要区别是ANTLR生成LL(*)解析器,而YACC和Bison都生成LALR解析器。 这是许多应用程序的重要区别,最明显的是操作员:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLR完全不能按原样处理这个语法。 要使用ANTLR(或任何其他LL解析器生成器),您需要将此语法转换为不是左递归的。 但是,Bison在这种形式的语法上没有问题。 您需要将'+'和' - '声明为左关联运算符,但这不是左递归所必需的。 一个更好的例子可能是调度:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

请注意, expractuals规则都是左递归的。 由于它避免了多个寄存器和不必要的溢出(左倾斜树可以折叠,而右倾斜树不能),所以这会在代码生成时产生更高效的AST。

就个人品味而言,我认为LALR语法的构建和调试要容易得多。 缺点是你必须处理一些模糊的错误,如移位减少和(可怕的)减少 - 减少。 这些是Bison在生成解析器时捕获的错误,因此它不会影响最终用户的体验,但它可以使开发过程更有趣。 正因为如此,ANTLR通常被认为比YACC / Bison更易于使用。


YACC / Bison和ANTLR最显着的区别在于这些工具可以处理的语法类型。 YACC / Bison处理LALR语法,ANTLR处理LL语法。

通常,长期与LALR语法工作的人会发现LL语法的工作更加困难,反之亦然。 这并不意味着语法或工具本质上更难以使用。 您发现哪个工具更容易使用,主要归结为熟悉语法类型。

就优点而言,LALR语法与LL语法相比具有优势,还有其他方面,LL语法比LALR语法具有优势。

YACC / Bison生成表驱动解析器,这意味着“处理逻辑”包含在解析器程序的数据中,而不是解析器的代码中。 付出的代价是,即使是针对非常复杂的语言的解析器也有相对较小的代码占用空间。 这在20世纪60年代和70年代当硬件非常有限时更为重要。 Table驱动的解析器生成器可以回溯到这个时代,而当时的小代码占用是主要需求。

ANTLR生成递归下降解析器,这意味着“处理逻辑”包含在解析器的代码中,因为语法的每个生成规则都由解析器代码中的函数表示。 回报是通过阅读代码来理解解析器在做什么更容易。 此外,递归下降解析器通常比表驱动解析器更快。 但是,对于非常复杂的语言,代码占用空间会更大。 这在二十世纪六七十年代是一个问题。 那时候,由于硬件限制,只有像Pascal这样的相对较小的语言才以这种方式实现。

ANTLR生成的解析器通常在10.000行代码附近。 手写递归下降解析器通常在同一个球场内。 Wirth的Oberon编译器可能是最紧凑的编译器,包含大约4000行代码,包括代码生成,但Oberon是一种非常紧凑的语言,只有大约40条生产规则。

正如有人已经指出的那样,ANTLR的一大优势是图形化的IDE工具,称为ANTLRworks。 它是一个完整的语法和语言设计实验室。 它会在你键入它们时显示你的语法规则,如果它发现任何冲突,它将以图形方式向你显示冲突是什么以及是什么造成的。 它甚至可以自动重构和解决诸如左递归之类的冲突。 一旦你有了无冲突语法,你可以让ANTLRworks解析你的语言的输入文件,并为你构建一个分析树和AST,并在IDE中以图形方式显示树。 这是一个非常大的优势,因为它可以为您节省许多工作时间:在开始编码之前,您会在语言设计中发现概念错误! 我还没有找到任何这样的LALR语法工具,似乎没有任何这样的工具。

即使对于不希望生成解析器而是手动编码的用户,ANTLRworks也是语言设计/原型设计的绝佳工具。 很可能是最好的这种工具。 不幸的是,如果你想构建LALR解析器,那不会对你有所帮助。 从LALR转换到LL只是为了利用ANTLRworks可能是值得的,但对于一些人来说,切换语法类型可能是一个非常痛苦的经历。 换句话说:YMMV。


ANTLR的几个优点:

  • 可以输出各种语言的解析器 - 运行生成的解析器不需要Java。
  • 令人敬畏的GUI使得语法调试变得简单(例如,您可以在GUI中看到生成的AST的权限,无需额外的工具)
  • 生成的代码实际上是人类可读的(这是ANTLR的目标之一),并且它生成LL解析器的事实在这方面肯定会有帮助。
  • 终端的定义也是上下文无关的(与(f)lex中的正则表达式相反) - 因此允许例如包含正确关闭圆括号的终端的定义
  • 我的.02 $

    链接地址: http://www.djcxy.com/p/41733.html

    上一篇: Advantages of Antlr (versus say, lex/yacc/bison)

    下一篇: Git Merge Branches Conflict