2010-02-20 63 views
8

我最近開始使用的JavaCC玩弄語法分析器和領域之一是選項之一......我有一個像如下因素代碼:的JavaCC解析器選項LOOKAHEAD,爪哇

options 
{ 
    LOOKAHEAD=1; 
} 
PARSER_BEGIN(Calculator) 

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

什麼這是否意味着LOOKAHEAD選項? 感謝

回答

7

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

通常情況下,解析器僅着眼於下一個標記,以確定哪些生產規則來應用。但是,在某些情況下,這還不足以做出選擇。例如,給定兩個生產規則:

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

如果下一個標記的類型爲identifier,解析器不能確定它是否應該使用foobar生產。然後JavaCC會發出一個錯誤,說它需要使用更多的預見。將前瞻更改爲2意味着解析器可以查看接下來的兩個令牌,在這種情況下,這足以在產品之間進行選擇。

正如史蒂夫指出,這是在JavaCC的文檔:https://javacc.org/tutorials/lookahead

2

超前值告訴生成的解析器多少未處理(即未來)令牌使用來決定轉換到什麼狀態。在嚴格限制的語言中,只需要一個預讀標記。語言越模糊,需要更多的前瞻令牌來確定要進行哪種狀態轉換。

我認爲這包括在javacc(1)教程中。

8

JavaCC創建遞歸下降解析器。這種類型的解析器通過查看下一個符號來決定選擇哪個規則。默認情況下,它只查看下一個符號(lookahead = 1)。但是,您可以將解析器配置爲不僅看下一個,而且還看下N個符號。如果將lookahead設置爲2,則生成的解析器將查看接下來的兩個符號,以決定選擇哪個規則。這樣,您可以更自然地定義您的語法,但需要犧牲性能。 lookahead越大,解析器就越需要做。

如果將常規前瞻設置爲更大的數字,則對於所有輸入(對於非平凡語法),解析器將會變慢。如果您希望默認情況下讓解析器的lookahead = 1,並且只在特定情況下使用更大的lookahead,則可以在本地使用lookahead。

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

例如,對於先行解析器= 1不能決定(2 1或)取,但與先行= 2它能其中規則:

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

您可以更改語法的定義以獲得相同的結果,但使用lookahead = 1:

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