9

我最近开始使用 javacc 使用语法分析器,其中一个字段是选项之一...我有如下代码:

options
{
  LOOKAHEAD=1;
}
PARSER_BEGIN(Calculator)

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

LOOKAHEAD 选项到底是什么意思?谢谢

4

3 回答 3

8

JavaCC 创建递归下降解析器。这种类型的解析器通过查看下一个符号来决定选择哪个规则。默认情况下,它只查看下一个符号(lookahead=1)。但是您可以将解析器配置为不仅查看下一个符号,还查看接下来的 N 个符号。如果将前瞻设置为 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() )
}
于 2010-02-20T16:59:32.213 回答
7

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

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

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

如果下一个标记是类型,identifier那么解析器无法确定它是否应该使用fooorbar产生式。JavaCC 然后会给出一个错误,说它需要使用更多的前瞻。将前瞻更改为 2 意味着允许解析器查看接下来的两个标记,在这种情况下,这足以在产生式之间进行选择。

正如史蒂夫指出的那样,这是在 javacc 文档中:https ://javacc.org/tutorials/lookahead

于 2010-02-20T16:57:06.023 回答
2

LOOKAHEAD 值告诉生成的解析器有多少未处理的(即未来的)令牌用于决定要转换到什么状态。在严格约束的语言中,只需要一个前瞻标记。语言越模糊,需要越多的前瞻标记来确定要进行哪种状态转换。

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

于 2010-02-20T16:59:13.493 回答