Ich versuche, ant ANTLR3 grammar in eine ANTLR4 grammar zu konvertieren, um es mit der Antlr4-Python2-Laufzeit zu verwenden. Diese Grammatik ist ein C/C++ - Fuzzy-Parser.Slow ANTLR4 generiert Parser in Python, aber schnell in Java
Nachdem Umwandlung (im Grunde das Entfernen Baum Operatoren und semantische/syntaktische Prädikate), erzeugt ich die Python2 Dateien mit:
java -jar antlr4.5-complete.jar -Dlanguage=Python2 CPPGrammar.g4
Und der Code ohne Fehler erzeugt wird, so dass ich importieren es in meinem Python-Projekt (ich benutze PyCharm), um einige Tests zu machen:
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)
Das Problem ist, dass das Parsing sehr langsam ist. Bei einer Datei mit ~ 200 Zeilen dauert es mehr als 5 Minuten, während die Analyse der gleichen Datei in antlrworks nur 1-2 Sekunden dauert. den ANTLRWorks Baum Analyse, bemerkte ich, dass die expr
Regel und alle seine Nachkommen sehr oft genannt werden, und ich denke, dass ich diese Regeln vereinfachen/ändern müssen schneller den Parser arbeiten zu machen:
meine Annahme richtig oder habe ich beim Konvertieren der Grammatik einen Fehler gemacht? Was kann getan werden, um das Parsen so schnell wie auf antlrworks zu machen?
UPDATE: Ich exportierte die gleiche Grammatik nach Java und es dauerte nur 795ms, um das Parsen abzuschließen. Das Problem scheint mehr mit der Python-Implementierung als mit der Grammatik selbst zu tun zu haben. Gibt es etwas, das getan werden kann, um Python-Parsing zu beschleunigen?Ich habe here gelesen, dass Python 20-30 mal langsamer als Java sein kann, aber in meinem Fall ist Python ~ 400 mal langsamer!
Müssen Profil Regel Ausführungszeiten, um irgendeine Gewissheit zu haben. Könnte die starke Verwendung von negierten Mengen, Literalen im Parser oder etwas anderes sein, das völlig gutartig erscheint. – GRosenberg
@GRosenberg danke für die kommentierung. Ich bin kein ANTLR-Experte, aber scheint mir nicht, dass meine Grammatik und das Original eine Menge negierter Sätze oder Literale im Parser haben. Ich denke, es ist ein Fehler im Zusammenhang mit 'antlr4-python2-runtime', da es nur 1 Sekunde dauert, um die gleiche Datei in Java zu parsen.Python kann langsamer sein, aber 400 mal langsamer ist zu viel um zu denken, dass es ein Problem auf meiner Seite ist. – Vektor88
Der beste Weg, um den Aspekt der Laufzeit zu identifizieren, der nicht performant ist, besteht darin, die einzelnen Regeln zu profilieren und bestimmte Regelaspekte zu identifizieren, die langsam verarbeitet werden müssen. Das Problem ist auf Ihrer Seite nur in dem Sinne, dass Ihre Grammatik etwas unternimmt, um die Verlangsamung auszulösen. Fast unzweifelhaft ist eine Änderung der Laufzeit erforderlich. Der schwierige Teil ist herauszufinden, was zu beheben ist. Der Schlüssel liegt glücklicherweise irgendwo in deiner Grammatik. Tun Sie, was Sie können, um die Ursache zu isolieren und ein Problem im Antlr Github Repo zu erzeugen. Das ist der schnellste Weg, um es zu reparieren. – GRosenberg