在 ANTLR 中跳过输入文件的部分内容

发布于 2024-12-18 09:34:30 字数 352 浏览 1 评论 0原文

我想构建一个解析器来分析大型输入文件,但我不需要整个输入文件,只需要它的某些部分。

例如,输入文件可能如下所示:

bla bla bla bla bla ...

EVENT: e1
type: t1
version: 1
additional-info: abc

EVENT: e2
type: t2
version: 1
uninteresting-info: def

blu blu blu blu blu ...

从该文件中,我想要的只是输入一个事件映射(e1=>t1,e2=>t2)。所有其他信息我都不感兴趣。

我如何构建一个简单的 ANTLR 语法来执行此操作?

I want to build a parser for analyzing a large input file, but I don't need the entire input file, only some parts of it.

For exmaple, the input file may look like this:

bla bla bla bla bla ...

EVENT: e1
type: t1
version: 1
additional-info: abc

EVENT: e2
type: t2
version: 1
uninteresting-info: def

blu blu blu blu blu ...

From this file, all I want is to have a map of event to type (e1=>t1, e2=>t2). All other information is of no interest for me.

How can I build a simple ANTLR grammar that does this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

傲世九天 2024-12-25 09:34:30

您可以通过在词法分析器中引入一个布尔标志来跟踪是否遇到了 event- 或 type- 关键字来做到这一点。如果遇到,词法分析器不应跳过该单词,而应跳过所有其他单词。

一个小演示:

grammar T;

@lexer::members {
  private boolean ignoreWord = true;
}

parse
  :  event* EOF
  ;

event
  :  Event w1=Word Type w2=Word 
     {System.out.println("event=" + $w1.text + ", type=" + $w2.text);}
  ;  

Event 
  :  'EVENT:' {ignoreWord=false;}
  ;

Type
  :  'type:' {ignoreWord=false;}
  ;

Word
  :  ('a'..'z' | 'A'..'Z' | '0'..'9')+ {if(ignoreWord) skip();}
  ;

NewLine
  :  ('\r'? '\n' | '\r') {ignoreWord=true; skip();}
  ;

Other
  :  . {skip();}
  ;

您可以使用以下类测试解析器:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String src = 
        "bla bla bla bla bla ...  \n" +
        "                         \n" +
        "prEVENT: ...             \n" +
        "EVENTs: ...              \n" +
        "                         \n" +
        "EVENT: e1                \n" +
        "type: t1                 \n" +
        "version: 1               \n" +
        "additional-info: abc     \n" +
        "                         \n" +
        "EVENT: e2                \n" +
        "type: t2                 \n" +
        "version: 1               \n" +
        "uninteresting-info: def  \n" +
        "                         \n" +
        "blu blu blu blu blu ...  \n";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.parse();
  }
}

它将产生以下输出:

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main

event=e1, type=t1
event=e2, type=t2

You can do that by introducing a boolean flag inside your lexer that keeps track whether an event- or type-keyword has been encountered. If it has been encountered, the lexer should not skip the word, all other words should be skipped.

A small demo:

grammar T;

@lexer::members {
  private boolean ignoreWord = true;
}

parse
  :  event* EOF
  ;

event
  :  Event w1=Word Type w2=Word 
     {System.out.println("event=" + $w1.text + ", type=" + $w2.text);}
  ;  

Event 
  :  'EVENT:' {ignoreWord=false;}
  ;

Type
  :  'type:' {ignoreWord=false;}
  ;

Word
  :  ('a'..'z' | 'A'..'Z' | '0'..'9')+ {if(ignoreWord) skip();}
  ;

NewLine
  :  ('\r'? '\n' | '\r') {ignoreWord=true; skip();}
  ;

Other
  :  . {skip();}
  ;

You can test the parser with the following class:

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    String src = 
        "bla bla bla bla bla ...  \n" +
        "                         \n" +
        "prEVENT: ...             \n" +
        "EVENTs: ...              \n" +
        "                         \n" +
        "EVENT: e1                \n" +
        "type: t1                 \n" +
        "version: 1               \n" +
        "additional-info: abc     \n" +
        "                         \n" +
        "EVENT: e2                \n" +
        "type: t2                 \n" +
        "version: 1               \n" +
        "uninteresting-info: def  \n" +
        "                         \n" +
        "blu blu blu blu blu ...  \n";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.parse();
  }
}

which will produce the following output:

java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main

event=e1, type=t1
event=e2, type=t2
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文