tutorial tomassetti mega grun descargar python parsing antlr antlr4

python - tomassetti - descargar antlr4



Error de reconocimiento de token de gramática ANTLR4 después de la importación (1)

Estoy usando una gramática del analizador y una gramática del lexer para antlr4 de GitHub para analizar PHP en Python3.

Cuando uso estas gramáticas directamente funciona mi código PoC:

antlr-test.py

from antlr4 import * # from PHPParentLexer import PHPParentLexer # from PHPParentParser import PHPParentParser # from PHPParentParser import PHPParentListener from PHPLexer import PHPLexer as PHPParentLexer from PHPParser import PHPParser as PHPParentParser from PHPParser import PHPParserListener as PHPParentListener class PhpGrammarListener(PHPParentListener): def enterFunctionInvocation(self, ctx): print("enterFunctionInvocation " + ctx.getText()) if __name__ == "__main__": scanner_input = FileStream(''test.php'') lexer = PHPParentLexer(scanner_input) stream = CommonTokenStream(lexer) parser = PHPParentParser(stream) tree = parser.htmlDocument() walker = ParseTreeWalker() printer = PhpGrammarListener() walker.walk(printer, tree)

lo que da la salida

/opt/local/bin/python3.4 /Users/d/PycharmProjects/name/antlr-test.py enterFunctionInvocation echo("hi") enterFunctionInvocation another_method("String") enterFunctionInvocation print("print statement") Process finished with exit code 0

Cuando uso la siguiente gramática PHPParent.g4, recibo muchos errores:

grammar PHPParent; options { tokenVocab=PHPLexer; } import PHPParser;

Después de intercambiar comentarios sobre las importaciones de pitones, recibo este error

/opt/local/bin/python3.4 /Users/d/PycharmProjects/name/antlr-test.py line 1:1 token recognition error at: ''?'' line 1:2 token recognition error at: ''p'' line 1:3 token recognition error at: ''h'' line 1:4 token recognition error at: ''p'' line 1:5 token recognition error at: ''/n'' ... line 2:8 no viable alternative at input ''<('' line 2:14 mismatched input '';'' expecting {<EOF>, ''<'', ''{'', ''}'', '')'', ''?>'', ''list'', ''global'', ''continue'', ''return'', ''class'', ''do'', ''switch'', ''function'', ''break'', ''if'', ''for'', ''foreach'', ''while'', ''new'', ''clone'', ''&'', ''!'', ''-'', ''~'', ''@'', ''$'', <INVALID>, ''Interface'', ''abstract'', ''static'', Array, RequireOperator, DecimalNumber, HexNumber, OctalNumber, Float, Boolean, SingleQuotedString, DoubleQuotedString_Start, Identifier, IncrementOperator} line 3:28 mismatched input '';'' expecting {<EOF>, ''<'', ''{'', ''}'', '')'', ''?>'', ''list'', ''global'', ''continue'', ''return'', ''class'', ''do'', ''switch'', ''function'', ''break'', ''if'', ''for'', ''foreach'', ''while'', ''new'', ''clone'', ''&'', ''!'', ''-'', ''~'', ''@'', ''$'', <INVALID>, ''Interface'', ''abstract'', ''static'', Array, RequireOperator, DecimalNumber, HexNumber, OctalNumber, Float, Boolean, SingleQuotedString, DoubleQuotedString_Start, Identifier, IncrementOperator} line 4:28 mismatched input '';'' expecting {<EOF>, ''<'', ''{'', ''}'', '')'', ''?>'', ''list'', ''global'', ''continue'', ''return'', ''class'', ''do'', ''switch'', ''function'', ''break'', ''if'', ''for'', ''foreach'', ''while'', ''new'', ''clone'', ''&'', ''!'', ''-'', ''~'', ''@'', ''$'', <INVALID>, ''Interface'', ''abstract'', ''static'', Array, RequireOperator, DecimalNumber, HexNumber, OctalNumber, Float, Boolean, SingleQuotedString, DoubleQuotedString_Start, Identifier, IncrementOperator}

Sin embargo, no obtengo errores al ejecutar la herramienta antlr4 sobre las gramáticas. Estoy perplejo aquí, ¿qué podría estar causando este problema?

$ a4p PHPLexer.g4 warning(146): PHPLexer.g4:363:0: non-fragment lexer rule DoubleQuotedStringBody can match the empty string $ a4p PHPParser.g4 warning(154): PHPParser.g4:523:0: rule doubleQuotedString contains an optional block with at least one alternative that can match an empty string $ a4p PHPParent.g4 warning(154): PHPParent.g4:523:0: rule doubleQuotedString contains an optional block with at least one alternative that can match an empty string


Importar es ANTLR4 es un poco desordenado.

Primero, tokenVocab no puede generar el lexer que necesita. Solo significa que esta gramática está utilizando los tokens de PHPLexer . Si elimina PHPLexer.tokens , ¡ni siquiera se compilará!

Eche un vistazo a PHPParser.g4 donde también usamos las options { tokenVocab=PHPLexer; } options { tokenVocab=PHPLexer; } . Sin embargo, en el script de Python todavía necesitamos usar el PHPLexer de PHPLexer para que funcione. Bueno, este PHPParentLexer no es utilizable en absoluto. Es por eso que tienes todo el error.

Para generar un nuevo lexer a partir de la gramática combinada, necesita importarlo así:

grammar PHPParent; import PHPLexer;

Sin embargo, el mode no es compatible al importar. PHPLexer sí usa mucho el mode . Así que tampoco es una opción.

¿Podemos simplemente reemplazar PHPParentLexer con PHPLexer ? Tristemente no. Debido a que PHPParentParser se genera con PHPParentLexer , están estrechamente acoplados y no se pueden usar por separado. Si usa PHPLexer , PHPParentParser tampoco funcionará. En cuanto a esta gramática, gracias a la recuperación de errores, realmente funciona, pero da un error.

Parece que no hay mejor manera que reescribir algo de la gramática. Definitivamente hay algunos problemas de diseño en esta parte de import de ANTLR4.