2017-04-13 30 views
0

爲什麼JavaCC總是在前瞻中給出終端錯誤?就像在這個例子中,JavaCC遇到詞法錯誤,當lookahead遇到文件結尾

options{ 
    LOOKAHEAD = 2; 
} 

PARSER_BEGIN(GS) 
    public class GS{ 
     public static void main(String args[]) throws ParseException { 
      GS parser = new GS(System.in); 
      parser.q0(); 
     } 
    } 
PARSER_END(GS) 

void q0(): 
{} 
{ 
    "a" q1() | 
    "c" 
} 

void q1(): 
{} 
{ 
    "b" q0() 
    | "b" 
} 

在Q1()是有2個選擇,一個是讀「B」,並移動到Q0,或閱讀「b」和最終讀數。但是,如果我給出一個輸入「ab」,它將會給出一個錯誤,即使它具有lookahead選項。但是如果我給「(ab)* c」,JavaCC就接受它。

Exception in thread "main" TokenMgrError: Lexical error at line 1, column 3. Encountered: "\r" (13), after : "" 

當生產規則

{ 
    "terminal_x" non-terminal() 
    | "terminal_x" 
} 

此相同的錯誤總是發生有什麼辦法使這種生產規則的不給錯誤?

我正在使用JavaCC版本。 6.0_1。

謝謝。

編輯:

顯然,如果生產規則的形式

{ 
    "terminal_x" 
    | "terminal_x" non-terminal() 
} 

錯誤不會發生。但是,是什麼導致了這個錯誤呢?

回答

0

問題是您的輸入字符串包含詞法分析器不期望的返回字符。它與lookhahead無關;前瞻與解析有關,而不是輕視。我建議把這樣的規則。

SKIP : { " " | "\t" | "\r" | "\n" } 
+0

我明白了,我的不好。感謝這對我有用。 雖然如果我直接從命令提示符輸入,它仍然在等待輸入。有沒有什麼方法可以說明閱讀完成? – tettra

+0

在UNIX或Mac上,使用cntl-d。在DOS或Windows上使用cntl-z。這將作爲一個EOF令牌而變得鬆散。 –

0

你所建議的示例規則:

{ 
     "terminal_x" 
     | "terminal_x" non-terminal() 
    } 

有效地說:「一定有"terminal_x"後跟零個或一個non-terminal()」。

{ 
     "terminal_x" (non-terminal())? 
    } 

這種方式,因爲它總是會"terminal_x",然後允許零個或一個"non-terminal()",消除不需要前瞻:這將通過使用?運營商(零或一個),如下來容易做來難完全的問題。

+0

是的,這種形式更簡單,但錯誤仍然出現。 – tettra