2013-06-12 77 views
1

我試圖重複使用詞法分析器/解析器來順序解析短文本塊。爲了確保沒有殘留之前的運行將保持我總是做ANTLRv4錯誤後重置詞法分析器和解析器

mLexer.reset(); 
    mLexer.setInputStream(new ANTLRInputStream(data)); 

    mParser.reset(); 
    mParser.setTokenStream(new CommonTokenStream(mLexer)); 

認爲這將完全復位兩個詞法和語法分析器不管之前發生了什麼。不幸的是有些事情在解析無效模式時仍然存在

我的詞法不恢復:

 @Override 
     public void recover(final LexerNoViableAltException e) { 
      throw new RuntimeException(e); 
     } 

我的解析器也不:

private class HexParserErrorStrategy extends org.antlr.v4.runtime.DefaultErrorStrategy { 
    @Override 
    public void recover(final Parser recognizer, final RecognitionException e) { 
     throw new RuntimeException(e); 
    } 

    @Override 
    public Token recoverInline(final Parser recognizer) throws RecognitionException { 
     throw new RuntimeException(); 
    } 

    @Override 
    public void reportUnwantedToken(final Parser recognizer) { 
     throw new RuntimeException(); 
    } 
} 

當我解析,如 「123456」 的字符串這很好地工作。之後我解析了一個無效模式,這給了我一個RE。如果我嘗試再次解析「123456」,結果與第一次運行的結果不同。

那麼我該如何重新設置我的解析器/詞法分析器?

回答

1

似乎setXXStream和reset的順序很重要。當逆轉訂單時,它按預期工作:

mLexer.setInputStream(new ANTLRInputStream(data)); 
mLexer.reset(); 

mParser.setTokenStream(new CommonTokenStream(mLexer)); 
mParser.reset(); 

可能是某些文檔。最初我會希望在設置新流時重新設置詞法分析器/解析器。

1

如何是不同於第一次運行的結果?

下面是一些一般提示:

  1. 使用BailErrorStrategy而不是創建自己的。它已經包含在ANTLR運行時中,並且會拋出ParseCancelledException而不是僅僅RuntimeException。它還將所有相關分析樹節點的exception字段設置爲適當的值。

  2. 您可以創建一個新的詞法分析器/分析器實例,而不是重複使用前一個。

+0

在無效運行期間,我的流中有未知字符。這被正確地檢測到。在第三次運行中,我仍然收到錯誤,指出某些字符無法正確識別。 – Christian

+0

關於使用新的解析器。那是我迄今爲止的解決方法。我只是認爲隨着時間的推移,解析器學習和獲得更快速度;我想重複使用它。 – Christian

+1

DFA是一個共享結構,因此新的解析器實例會自動重用先前的結果。 –