2014-11-03 97 views
0

我有以下結構:Antlr4渠道行爲

mode PASS_THROUGH; 
    END_LITERAL: PASS_THROUGH_CHAR* '{/literal}'   -> popMode; 
    PASS_THROUGH_CHAR: .+         -> channel(TEXT); 

當這種模式被執行的END_LITERAL得到所有的PASS_THROUGH_CHARs預追加到它。 雖然所有的PASS_THROUGH_CHAR都會出現在TEXT頻道上,而END_LITERAL只會是'{/ literal}

此行爲是否正確?

回答

0

很難說爲什麼它表現得如你所說,但在PASS_THROUGH_CHAR上和在PASS_THROUGH_CHAR中使用*和+的複合/衝突是根本原因。以下是我認爲你正在努力完成的事情。

START_LITERAL: '{/literal}' -> pushMode(PASS_THROUGH); 

mode PASS_THROUGH; 
    END_LITERAL: '{/literal}' -> popMode; 
    PASS_THROUGH_CHAR: .  -> more, channel(TEXT); 

更新時間: 我沒有嘗試過這個確切,但使用的「更多」選項可能(應該)PASS_THROUGH_CHAR的每個字符串塌陷成一個單一的令牌。

+0

這就創造了我試圖避免的確切問題。如果我處理一個90K文本文件,它會將每個字符作爲單個標記放入通道中,而不是作爲90k文本字符串。在C#中執行此操作需要大約7Gb的內存來解決它,並需要大約15秒來處理它。如果按照我的方式進行操作,它只需要一兩秒鐘,只能使用大約3MB的內存,但不幸的是它會將所有PASS_THROUGH_CHARS都放入END_LITERAL標記中。 – Terry151151 2014-11-03 10:59:21

+0

我並不熟悉C#後端,但這種性能水平令人驚訝。你是否已經完成了對你的START_LITERAL規則和這種模式的Lexer單元測試? Lexer生產90k令牌並不是那麼不尋常。你的代幣「沉重」嗎?檢測TokenFactory以檢查令牌分配/ C#後端問題。後端是否可能在每個令牌中放入一個副本,而不是對輸入流的引用?數學幾乎奏效。另外,在解析器真正啓動之前,詞法分析器會運行完成,因此,在詞法分析器中花費15分鐘中的哪一部分? – GRosenberg 2014-11-04 05:27:50

+0

詞法分析器處理所有的處理時間和內存。我可以在解析器中設置一個斷點,它至少需要15秒鐘才能達到斷點。每個令牌的大小我不知道如何找到,因爲幾乎不可能找到參考項目的運行時間大小,更不用說連接到接口(IToken)的項目。嘗試實施一個TokenFactory,但沒有真正展現太多。我已將其記錄爲一個錯誤。走着瞧吧。 – Terry151151 2014-11-04 10:54:45