简体   繁体   English

ANTLR4解析器中的访客文件问题

[英]Visitor file issue in ANTLR4 parser

What to write within Visitor class? 在Visitor类中写什么?

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 ) 我们的语法(文件名:sys.g):(运行良好,我们使用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. 问题1:我们使用antlr4.5编译了语法文件,还使用了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? 问题2:是否需要制作另一个名为“值”的类,该类将值返回给访问者?

EvalVisitor.java file: EvalVisitor.java文件:

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. 我们的主要Java文件SysLogCheck.java,其中我们使用的是语法sys.g文件生成的Lexer(SysLexer.java)和Parser(SysParser.java)。

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 : 这是一个原始访客的示例,其输出Dec, 17, 14:00:00 : Dec, 17, 14:00:00 : Dec, 17, 14:00:00

In the line which reads /* do something with the results */ you can place some code which saves the results. 在读取/* do something with 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);
  }
  //
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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