2017-05-12 2 views
1

Dans Antlr4, comment puis-je intercepter tout l'analyse de jetons INT/NEWLINE? Je veux somenting comme un auditeur.ANTLR4 Lexer listener

Compte tenu de la langue:

grammar Expr;  
    prog: (expr NEWLINE)* ; 
    expr: expr ('*'|'/') expr 
     | expr ('+'|'-') expr 
     | INT 
     | '(' expr ')' 
     ; 
    NEWLINE : [\r\n]+ ; 
    INT  : [0-9]+ ; 


Css3Lexer lexer = new Css3Lexer(this.file.getStreamAntlr()); 
Css3Parser parser = new Css3Parser(new CommonTokenStream(lexer)); 
parser.addParseListener(..)// doesnt resolve. 

Répondre

1

D'abord, je voudrais annoter votre grammaire pour rendre les événements d'écouteur plus précis:

grammar Expr; 
prog: stmt+ EOF; 
stmt: expr NEWLINE+; 
expr: 
    expr ('*'|'/') expr  # Mult 
| expr ('+'|'-') expr  # Add 
| INT      # Int 
| '(' expr ')'   # Paren 
; 

NEWLINE : '\r\n'; 
INT  : [0-9]+ ; 

Cela vous permettra de faire des auditeurs spécifiques tels que:

public class ExprListener : ExprBaseListener 
{ 
    private Stack <int> stack = new Stack <int>(); 

    public override void ExitInt(ExprParser.IntContext context) 
    { 
     int i = Convert.ToInt32(context.INT().GetText()); 
     stack.Push(i); 
    } 

    public override void ExitStmt(ExprParser.StmtContext context) 
    { 
     int result = stack.Pop(); 
     Console.WriteLine("result " + result); 
    } 

    public override void ExitMult(ExprParser.MultContext context) 
    { 
     int r = stack.Pop(); 
     int l = stack.Pop(); 
     string op = context.GetChild(1).GetText(); 
     int result; 
     if (op == "*") 
      result = l * r; 
     else 
      result = l/r; 
     stack.Push(result); 
    } 

    public override void ExitAdd(ExprParser.AddContext context) 
    { 
     int r = stack.Pop(); 
     int l = stack.Pop(); 
     string op = context.GetChild(1).GetText(); 
     int result; 
     if (op == "+") 
      result = l + r; 
     else 
      result = l - r; 
     stack.Push(result); 
    } 
}