2016-05-05 8 views
1

Derzeit bin ich mit dieser ANTLR4 Grammatik (Teil), um strings und numbers zu erhalten:ANTLR4 -> prüfen eine wörtliche ist string_literal oder ein NUMBER_LITERAL

Go figure diese zusammengefasst Grammatik:

gramm 
: expr SCOL 
; 

expr 
: literal   #LiteralExpression 
; 

literal 
: NUMERIC_LITERAL 
| STRING_LITERAL 
; 

NUMERIC_LITERAL 
: DIGIT+ ('.' DIGIT*)? (E [-+]? DIGIT+)? 
| '.' DIGIT+ (E [-+]? DIGIT+)? 
; 

STRING_LITERAL 
: '\'' (~'\'' | '\'\'')* '\'' 
; 

SPACES 
: [ \u000B\t\r\n] -> channel(HIDDEN) 
; 

fragment DIGIT : [0-9]; 

Also implementiere ich eine GrammBaseVisitor<Void>.

Ich bin nicht ganz herauszufinden, wie Sie überprüfen, ob ein Literal ist NUMERIC_LITERAL oder STRING_LITERAL.

Was ich in der Lage gewesen zu bekommen, habe ich außer Kraft setzen visitLiteral() und visitLiteralExpression():

@Override 
public Void visitLiteral(LiteralContext ctx) { 
    // TODO What should I do here in order to check whether 
    // ctx contains an STRING_LITERAL or a NUMBER_LITERAL? 
    return super.visitLiteral(ctx); 
} 

@Override 
public Void visitLiteralExpression(LiteralExpressionContext ctx) { 
    return super.visitLiteralExpression(ctx); 
} 

Was ist der Unterschied zwischen visitLiteral und visitLiteralExpression() ist?

Antwort

1

Ihre literal Produktion besteht aus zwei möglichen Terminals, dem numerischen und dem String-Literal. Ob die geparste Eingabe das eine oder das andere enthält, können Sie mit null Checks innerhalb visitLiteral feststellen.

@Override 
public Object visitLiteral(LiteralContext ctx) {    
    TerminalNode numeric = ctx.NUMERIC_LITERAL(); 
    TerminalNode string = ctx.STRING_LITERAL(); 
    if (numeric != null) { 
     System.out.println(numeric.getSymbol().getType()); 
    } else if (string != null) { 
     System.out.println(string.getSymbol().getType()); 
    } 
    return super.visitLiteral(ctx); 
} 

können Sie alle Terminals besuchen durch visitTerminal überschrieben.

@Override 
public Object visitTerminal(TerminalNode node) { 
    int type = node.getSymbol().getType(); // matches a constant in your parser 

    switch (type) { 
     case GrammParser.NUMERIC_LITERAL: 
      System.out.println("numeric literal"); 
      break; 
     case GrammParser.STRING_LITERAL: 
      System.out.println("string literal"); 
      break; 
    } 

    System.out.println(node.getSymbol().getText()); 
    return super.visitTerminal(node); 
} 

Was ist der Unterschied zwischen visitLiteral und visitLiteralExpression()?

Der ehemalige stellt Ihre literal Produktion und die letztere stellt Ihre expr Produktion. Beachten Sie, dass das Symbol # in der ANTLR 4-Syntax eine besondere Bedeutung hat und eine Bezeichnung darstellt - ein Name für Alternativen innerhalb von Produktionen. Es ist kein Kommentar. Da Ihre expr nur eine Alternative hat, wird sie visitLiteralExpression. Versuchen Sie es auskommentieren (//) und sehen Sie Ihre generierten Code ändern.