2015-05-14 17 views
7

Ho problemi con la destinazione Python in ANTLR4. Sembra che ci siano pochissimi esempi disponibili e andare al corrispondente codice Java non sembra rilevante.ANTLR4 e il target Python

sto usando la grammatica standard di Hello.g4:

// Define a grammar called Hello 
grammar Hello; 
r : 'hello' ID ;   // match keyword hello followed by an identifier 
ID : [a-z]+ ;    // match lower-case identifiers 
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines 

L'esempio (costruito da l'esempio standard Hello.g4):

input_ = antlr4.FileStream(_FILENAME) 
lexer = HelloLexer.HelloLexer(input_) 
stream = antlr4.CommonTokenStream(lexer) 
parser = HelloParser.HelloParser(stream) 

rule_name = 'r' 
tree = getattr(parser, rule_name)() 

Ho anche scritto un ascoltatore. Per affermare/verificare che questo è corretto, lo ripeto qui:

class HelloListener(antlr4.ParseTreeListener): 
    def enterR(self, ctx): 
     print("enterR") 

    def exitR(self, ctx): 
     print("exitR") 

    def enterId(self, ctx): 
     print("enterId") 

    def exitId(self, ctx): 
     print("exitId") 

Quindi, in primo luogo, non posso garantire che la stringa sto dando è valida perché non sto ricevendo qualsiasi schermo produzione. Come faccio a sapere dall'oggetto albero se qualcosa è stato abbinato? Come estrarre le regole/i token corrispondenti?

Un esempio Python sarebbe fantastico, se possibile.

risposta

3

Ho sentito, avendo gli stessi problemi in questo momento. La documentazione di Python per v4 è inutile e la v3 è molto diversa per essere utilizzabile. Sto pensando di tornare a Java per implementare le mie cose.

Per quanto riguarda il codice: penso che il proprio listener personalizzato debba ereditare dal HelloListener generato. Puoi fare la stampa lì.

Prova anche ad analizzare l'input non valido per vedere se il parser inizia affatto. Non sono sicuro della linea con getattr (parser, rule_name)() però. Ho seguito i passaggi nella documentazione (purtroppo molto breve) per il target di Python Antlr4: https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Python+Target

Puoi anche trovare della documentazione sulle cose dell'ascoltatore lì. Spero che sia d'aiuto.

0

Ho creato an example for Python 2 utilizzando la grammatica Hello.

Ecco il codice rilevante:

from antlr4 import * 
from HelloLexer import HelloLexer 
from HelloListener import HelloListener 
from HelloParser import HelloParser 
import sys 

class HelloPrintListener(HelloListener): 
    def enterHi(self, ctx): 
     print("Hello: %s" % ctx.ID()) 

def main(): 
    lexer = HelloLexer(StdinStream()) 
    stream = CommonTokenStream(lexer) 
    parser = HelloParser(stream) 
    tree = parser.hi() 
    printer = HelloPrintListener() 
    walker = ParseTreeWalker() 
    walker.walk(printer, tree) 

if __name__ == '__main__': 
    main() 

Come FAB ha detto, la chiave è quello di ereditare dalla HelloListener generato. Sembra esserci un certo problema su questo problema, in quanto è possibile vedere se si modifica il mio HelloPrintListener per ereditare direttamente da ANTLR ParseTreeListener. Ho immaginato che avrebbe funzionato dato che lo HelloListener generato ha solo metodi vuoti, ma ho visto lo stesso comportamento che hai visto (i metodi listener non venivano mai chiamati).

Sebbene la documentazione per gli ascoltatori Python manchi, i metodi disponibili sono simili a Java.

0

La documentazione di antlr è stata aggiornata per documentare il supporto per le destinazioni Python 3 e Python 4. Gli esempi del libro antlr convertito in python3 possono essere trovati here, sono sufficienti per far avviare qualcuno.

Problemi correlati