簡體   English   中英

ANTLR4 在 Python 中生成解析器很慢,但在 Java 中很快

[英]Slow ANTLR4 generated Parser in Python, but fast in Java

我正在嘗試將 ant ANTLR3 語法轉換為ANTLR4 語法,以便將它與 antlr4-python2-runtime 一起使用。 這個語法是一個 C/C++ 模糊解析器。

轉換后(基本上刪除樹運算符和語義/句法謂詞),我使用以下方法生成了 Python2 文件:

java -jar antlr4.5-complete.jar -Dlanguage=Python2 CPPGrammar.g4

並且生成的代碼沒有任何錯誤,所以我將它導入到我的 python 項目中(我使用的是 PyCharm)進行一些測試:

import sys, time
from antlr4 import *
from parser.CPPGrammarLexer import CPPGrammarLexer
from parser.CPPGrammarParser import CPPGrammarParser

currenttimemillis = lambda: int(round(time.time() * 1000))

def is_string(object):
    return isinstance(object,str)

def parsecommandstringline(argv):
    if(2!=len(argv)):
        raise IndexError("Invalid args size.")
    if(is_string(argv[1])):
        return True
    else:
        raise TypeError("Argument must be str type.")

def doparsing(argv):
    if parsecommandstringline(argv):
        print("Arguments: OK - {0}".format(argv[1]))
        input = FileStream(argv[1])
        lexer = CPPGrammarLexer(input)
        stream = CommonTokenStream(lexer)
        parser = CPPGrammarParser(stream)
        print("*** Parser: START ***")
        start = currenttimemillis()
        tree = parser.code()
        print("*** Parser: END *** - {0} ms.".format(currenttimemillis()-start))
        pass

def main(argv):
    tree = doparsing(argv)
    pass

if __name__ == '__main__':
    main(sys.argv)

問題是解析速度很慢。 一個包含約 200 行的文件需要 5 多分鍾才能完成,而在 antlrworks 中解析同一個文件只需要 1-2 秒。 分析 antlrworks 樹,我注意到expr規則及其所有后代經常被調用,我認為我需要簡化/更改這些規則以使解析器運行得更快:表達式樹

我的假設是正確的還是我在轉換語法時犯了一些錯誤? 可以做些什么來使解析像在 antlrworks 上一樣快?

更新:我將相同的語法導出到 Java,完成解析只用了 795 毫秒。 問題似乎與 python 實現有關,而不是與語法本身有關。 有什么可以加快 Python 解析的方法嗎?
我在這里讀到 python 可能比 java 慢 20-30 倍,但就我而言,python 慢了大約 400 倍!

我確認 Python 2 和 Python 3 運行時存在性能問題。 通過幾個補丁,我在 python3 運行時獲得了 10 倍的加速(約 5 秒到約 400 毫秒)。 https://github.com/antlr/antlr4/pull/1010

我遇到了類似的問題,所以我決定用一個可能的解決方案來撞這個舊帖子。 我的語法在 TestRig 上立即運行,但在 Python 3 上非常慢。

在我的情況下,錯誤是我用來生成一行注釋的非貪婪標記(C/C++ 中的雙斜線,在我的情況下為 '%'):

TKCOMM : '%' ~[\r\n]* -> skip ;

在此討論中,sharwell 的這篇文章對此有所支持: https : //github.com/antlr/antlr4/issues/658

當性能是一個問題時,避免使用非貪婪運算符,尤其是在解析器規則中。

要測試此場景,您可能希望從語法中刪除非貪婪規則/標記。

在這里發布,因為它可能對找到此線程的人有用。

自發布以來,Antlr 的 Python 目標已經有了一些性能改進。 也就是說,Python 解釋器本質上比 Java 或其他編譯語言慢。

我已經為 Antlr 的 Python3 目標組合了一個 Python 加速器代碼生成器。 它使用 Antlr C++ 目標作為 Python 擴展。 詞法分析和解析完全在 C++ 中完成,然后使用自動生成的訪問者在 Python 中重新構建生成的解析樹。 根據語法和輸入,初始測試顯示5 到 25 倍的加速,我有一些關於如何進一步改進它的想法。

這是代碼生成器工具: https : //github.com/amykyta3/speedy-antlr-tool

這是一個功能齊全的示例: https : //github.com/amykyta3/speedy-antlr-example

希望這對那些喜歡在 Python 中使用 Antlr 的人有用!

這些天我在 python3 目標中使用 ANTLR。 一個有 500~ 行的文件只需要不到 20 秒的時間來解析。 所以轉向 Python3 目標可能會有所幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM