简体   繁体   中英

Visitor file issue in ANTLR4 parser

What to write within Visitor class?

We already made a grammar for our language. We don't need to perform any operations on it. If language is passed through written grammar, then we just want to take some of the objects from them.

given language as input:

Dec 17 14:00:00 103.56.229.11 firewall,info FFFW forward: in:<pppoe-mm.demo.649> out:sfp-sfpplus1.vlan113, proto TCP (ACK,PSH), 10.0.15.245:49831->103.235.46.39:443, NAT (10.0.15.245:49831->202.173.127.253:49831)->103.235.46.39:443, len 250

desired output:

Dec, 17, 14:00:00, 103.56.229.11, pppoe-mm.demo.649, TCP, 10.0.15.245:49831, 103.235.46.39:443, 202.173.127.253:49831

Our grammar (File name: sys.g): ( which is working well, We attested it using ANTLRWorks2 )

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

grammar sys;

r: IDENT NUM time ip x+ user xout proto xuser ipfull xtra ipfull xtra1 ipfull xtra ipfull xtra2 ipfull xtra3; 
time: NUM SEP NUM SEP NUM;
ip: NUM USER NUM USER NUM USER NUM ;
ipfull: NUM USER NUM USER NUM USER NUM SEP NUM ;
x: (IDENT | SEP | NUM)+ LTHAN;
user: (IDENT | USER | NUM)+ ;
xuser: (IDENT | SEP | NUM)+ ;
xout: GTHAN IDENT+ SEP IDENT+ USER IDENT+ USER IDENT SEP IDENT;
proto: IDENT ;
xtra: USER GTHAN ;
xtra1: SEP IDENT SEP;
xtra2: SEP xtra;
xtra3: SEP IDENT NUM;

IDENT: ('a'..'z' | 'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'9')* ;
NUM: ('0'..'9')+ ;
LTHAN: '<' ;
GTHAN: '>' ;
SEP: ':' | ',' | '(' | ')' ;
USER: '-' | '.' ;
WS : (' ' | '\t' | '\r' | '\n')+ -> skip ;

Generated tree for the given language:

Generated tree for the language

Question 1: We compiled our grammar file using antlr4.5 and we also used visitor. So our problem is how to print specific objects in another file?

Question 2: Is it required to make another class named "value" which returns the value to the visitor?

EvalVisitor.java file:

public class EvalVisitor extends sysBaseVisitor{

//
}

Our main java file ie SysLogCheck.java, in which we are using Lexer (SysLexer.java) and Parser(SysParser.java) generated by our grammar sys.g file.

import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import java.io.*;
import org.antlr.v4.runtime.*;

public class SysLogCheck {
    public static void main(String[] args) throws Exception {
        ANTLRInputStream input = new ANTLRInputStream(new FileInputStream(new File("input.txt")));
        sysLexer lexer = new sysLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        sysParser parser = new sysParser(tokens);
        ParseTree tree = parser.r();
        EvalVisitor visitor = new EvalVisitor();
        visitor.visit(tree);        
    }
}

As for your first question:

Here is an example of a crude visitor, which outputs Dec, 17, 14:00:00 :

In the line which reads /* do something with the results */ you can place some code which saves the results.

import org.antlr.v4.runtime.tree.ParseTree;

public class EvalVisitor extends sysBaseVisitor{

  class LogEntry {
    String ident1;
    String dayNum;
    String ip;

    /*
    ...
     */
  }

  static LogEntry logEntry;

  @Override
  public Object visit(ParseTree tree) {
    /* Setup logentry used by all visitors (this case, there is only a single visitor...)*/
    logEntry = new LogEntry();

    /* visit */
    final Object o = super.visit(tree);

    /* do something with the results */
    System.out.println(logEntry.ident1 + ", " + logEntry.dayNum + ", " + logEntry.ip);

    return o;
  }

  StringBuilder stringBuilder;
  @Override
  public Object visitR(sysParser.RContext ctx) {
    logEntry.ident1 = ctx.IDENT().getText();
    logEntry.dayNum = ctx.NUM().getText();
    return super.visitR(ctx);
  }

  @Override
  public Object visitTime(sysParser.TimeContext ctx) {
    logEntry.ip = ctx.getText();
    return super.visitTime(ctx);
  }

  @Override
  public Object visitIp(sysParser.IpContext ctx) {
    return super.visitIp(ctx);
  }

  @Override
  public Object visitIpfull(sysParser.IpfullContext ctx) {
    return super.visitIpfull(ctx);
  }

  @Override
  public Object visitX(sysParser.XContext ctx) {
    return super.visitX(ctx);
  }

  @Override
  public Object visitUser(sysParser.UserContext ctx) {
    return super.visitUser(ctx);
  }

  @Override
  public Object visitXuser(sysParser.XuserContext ctx) {
    return super.visitXuser(ctx);
  }

  @Override
  public Object visitXout(sysParser.XoutContext ctx) {
    return super.visitXout(ctx);
  }

  @Override
  public Object visitProto(sysParser.ProtoContext ctx) {
    return super.visitProto(ctx);
  }

  @Override
  public Object visitXtra(sysParser.XtraContext ctx) {
    return super.visitXtra(ctx);
  }

  @Override
  public Object visitXtra1(sysParser.Xtra1Context ctx) {
    return super.visitXtra1(ctx);
  }

  @Override
  public Object visitXtra2(sysParser.Xtra2Context ctx) {
    return super.visitXtra2(ctx);
  }

  @Override
  public Object visitXtra3(sysParser.Xtra3Context ctx) {
    return super.visitXtra3(ctx);
  }
  //
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM