有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Javacc解析器选项前瞻,Java

我最近开始使用javacc处理语法分析器,其中一个字段是options one。。。我有如下代码:

options
{
  LOOKAHEAD=1;
}
PARSER_BEGIN(Calculator)

public class Calculator
{
 ...
}
PARSER_END(Calculator)

“前瞻”选项到底意味着什么? 谢谢


共 (3) 个答案

  1. # 1 楼答案

    LOOKAHEAD值告诉生成的解析器要使用多少未处理(即未来)令牌来决定转换到哪个状态。在严格约束的语言中,只需要一个先行标记。语言越是模棱两可,就越需要更多的先行标记来确定要进行的状态转换

    我认为这在javacc(1)教程中有介绍

  2. # 2 楼答案

    JavaCC创建递归下降解析器。这种类型的解析器通过查看下一个符号来决定选择哪个规则。默认情况下,它只查看下一个符号(lookahead=1)。但是您可以将解析器配置为不仅查看下一个符号,还查看下一个N符号。如果将lookahead设置为2,则生成的解析器将查看接下来的两个符号,以决定选择哪个规则。这样,您可以更自然地定义语法,但要以性能为代价。前瞻性越大,解析器需要做的事情就越多

    如果将常规前瞻设置为更大的数字,那么对于所有输入(对于非平凡语法),解析器的速度都会变慢。如果希望让解析器在默认情况下使用lookahead=1,并且仅在特定情况下使用更大的lookahead,那么可以在本地使用lookahead

    http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm#tth_sEc4.5

    例如,lookahead=1的解析器无法决定采用哪种规则(1或2),但lookahead=2的解析器可以:

    void rule0() : {} { 
      <ID> rule1() 
    | <ID> rule2()
    }
    

    您可以更改语法的定义以获得相同的结果,但使用lookahead=1:

    void rule0() : {} { 
      <ID> ( rule1() | rule2() )
    }
    
  3. # 3 楼答案

    http://en.wikipedia.org/wiki/Lookahead#Lookahead_in_parsing

    通常,解析器只查看下一个标记以确定要应用的生产规则。然而,在某些情况下,这还不足以做出选择。例如,给定两条生产规则:

    p0: foo -> identifier "=" expr
    p1: bar -> identifier "(" arglist ")"
    

    如果下一个标记的类型为identifier,那么解析器无法确定它应该使用foo还是bar产品。JavaCC会给出一个错误,说它需要使用更多的前瞻性。将look-ahead更改为2意味着允许解析器查看下两个标记,在本例中,这足以在产品之间进行选择

    正如Steve指出的,这在javacc文档中:https://javacc.org/tutorials/lookahead