2017-04-02 6 views
0
BLOCK_COMMENT : '/*' .*? '*/' -> skip; 
EOL_COMMENT : '//' ~[\r\n]* -> skip; 
WS: [ \n\t\r]+ -> skip; 

program: usingDirectives? EOF; 

usingDirectives: usingDirective+; 

usingDirective: USING 
     fullyQualifiedType 
     (usingAlias | USING_ALL)? 
     END; 

USING: 'using'; 

fullyQualifiedType: identifier (DOT identifier)*; 

identifier: (LETTER | UNDERSCORE) 
     (LETTER | DIGIT | UNDERSCORE)*; 

DOT: '.'; 

usingAlias: AS identifier; 

USING_ALL: '.*'; 

AS: 'as'; 

END: ';'; 

LETTER: [a-zA-Z]; 

DIGIT: [0-9]; 

UNDERSCORE: '_'; 

Das ist meine Grammatik.Antlr4 - eine Kennung als ein einzelnes Token

using IO.Console.Print as Print; 
using IO.Console; // same as using IO.Console as Console; 
using IO.Console.*; 

Dies sind meine Testdaten.

Die Grammatik funktioniert wie vorgesehen, aber jeder Buchstabe in einem Bezeichner wird zu einem einzelnen Token, was ein wenig nutzlos ist.

Wenn ich versuche, eine Kennung Lexer Regel (IDENTIFIER) zu machen, dann bekomme ich den folgenden Fehler, wenn die Durchführung des Tests:

line 1:23 extraneous input 'as' expecting {'.', '.*', 'as', ';'} 

Auch wenn ich versuche nur haben IDENTIFIER sein [a-Za Z], ohne Unterregeln, das gleiche passiert.

Wenn es wichtig ist, verwende ich Python3 als Zielsprache. Bitte weisen Sie auch auf andere Anfängerfehler hin, da dies mein erstes Projekt ist, das Antlr verwendet. Vielen Dank!

Antwort

0

Im Moment sagen Sie Ihrem Lexer, dass er eine Sammlung von Zeichen für einen Bezeichner anstelle eines Bezeichners als Ganzes erhalten soll. Nach vereinfachten Grammatik (Lexer und Parser) sollte für Sie arbeiten:

grammar test; 

root 
    : identifier*; 

identifier 
    : IdentifierChars; 

IdentifierChars 
    : [a-zA-Z0-9_]+; 

WhiteSpace 
    : [ \r\n\t]+ -> skip; 

hier ist ein Beispiel für Java-Code i verwendet zu überprüfen:

InputStream input = IntegrationMain.class.getResourceAsStream("test.txt"); 
    ANTLRInputStream inputStream = new ANTLRInputStream(input); 
    TokenSource tokenSource = new testLexer(inputStream); 
    CommonTokenStream tokenStream = new CommonTokenStream(tokenSource); 
    testParser parser = new testParser(tokenStream); 
    testParser.RootContext root = parser.root(); 

    root.identifier().forEach(identifier -> System.out.println(identifier.getText())); 

und hier ist das Ergebnis von stdout:

abc 
a0bc 
a_bc 
+0

Danke. Ich nahm deinen Rat und vereinfachte die Grammatik. Außerdem stellt sich heraus, dass mein grundlegendes Verständnis dafür, wie Antlr funktioniert, fehlte. Sobald ich herausgefunden hatte, dass die Reihenfolge der Regeln wichtig war und dass die Lexer-Regeln alle vor den Parser-Regeln ausgewertet wurden, begann alles sehr sinnvoll. – MackThax

+0

froh, dass es geholfen hat, Ihr Problem zu lösen, sind Sie willkommen. – Yevgeniy

Verwandte Themen