Parsing ANTLR 2.7从解析器获取对象流

Parsing ANTLR 2.7从解析器获取对象流,parsing,antlr,inputstream,Parsing,Antlr,Inputstream,我正在使用Antlr2.7.6解析另一个应用程序的混乱输出。遗憾的是,我没有能力升级到ANTLR3,尽管它已经推出了很长一段时间。与对象树相比,我将要解析的那种日志文件更好地概念化为对象列表,并且可能非常大(>100MB),因此将其全部读取到一个AST中是不切实际的。(我的应用程序是多线程的,一次可以处理半打到十几个这样的文件,所以内存会很快填满。)我希望能够从流中读取每个对象,这样我就可以逐个处理它们。注意,对象本身可以被概念化为小树。有没有办法让我的ANTLR解析器像对象流、迭代器或类似的东

我正在使用Antlr2.7.6解析另一个应用程序的混乱输出。遗憾的是,我没有能力升级到ANTLR3,尽管它已经推出了很长一段时间。与对象树相比,我将要解析的那种日志文件更好地概念化为对象列表,并且可能非常大(>100MB),因此将其全部读取到一个AST中是不切实际的。(我的应用程序是多线程的,一次可以处理半打到十几个这样的文件,所以内存会很快填满。)我希望能够从流中读取每个对象,这样我就可以逐个处理它们。注意,对象本身可以被概念化为小树。有没有办法让我的ANTLR解析器像对象流、迭代器或类似的东西一样工作

[见]

编辑:下面是一个概念性的例子,说明我想用解析器做什么

import java.io.FileReader;
import antlr.TokenStream;
import antlr.CharBuffer;
//...
FileReader fileReader = new FileReader(filepath);
TokenStream lexer = new MyExampleLexer(new CharBuffer(fileReader));
MyExampleParser parser = new MyExampleParser(lexer);
for (Object obj : parser)
{
    processObject(obj);
}

在如何使用Antlr解析器方面,我是否使用了错误的范例?(我意识到解析器没有实现
迭代器
;但从概念上讲,这就是我要寻找的那种行为。)

AFAIK,ANTLR v2.x缓冲令牌的创建。在。当解析器需要更多令牌时,通过its轮询该
TokenStream

换句话说,如果您以文件的形式提供输入源,ANTLR不会读取整个文件并创建其标记,但只有在需要时才会创建(并丢弃)标记

请注意,我从未使用过Antlr2.x,因此我可能是错的。你观察到了不同的东西吗?如果是这样,您如何将源代码作为文件或大字符串提供给ANTLR?如果是后者,我建议提供一个文件

编辑 假设您要解析一个文件,该文件由带数字的行组成,由空格分隔(您希望忽略空格)。您还希望解析器逐行处理文件,因为一次收集所有数字会导致内存问题

您可以通过让主解析器规则
parse
为每行返回一个数字列表来实现这一点。如果达到
EOF
(文件末尾),只需返回
null
,而不是列表

使用ANTLR 2.7.6的演示: 文件:My.g
classmyparser扩展了Parser;
解析返回[java.util.List number]
{
numbers=new java.util.ArrayList();
}
:(n:Number{numbers.add(Integer.valueOf(n.getText());})+换行符
|EOF{numbers=null;}
;
类MyLexer扩展了Lexer;
数
:  ('0'..'9')+
;
断线
:('\r')?'\不
;
空间
:(''|'\t'){$setType(Token.SKIP);}
;
文件:Main.java
导入antlr.*;
公共班机{
公共静态void main(字符串[]args)引发异常{
MyLexer lexer=newmylexer(newjava.io.StringReader(“1234\n4568\n910”);
MyParser=newmyparser(newtokenbuffer(lexer));
内线=0;
java.util.List number=null;
而((numbers=parser.parse())!=null){
line++;
System.out.println(“行”+行+“=”+数字);
}
}
}
要在上运行演示,请执行以下操作:

*尼克斯
java-cp antlr-2.7.6.jar antlr.Tool My.g
javac-cp antlr-2.7.6.jar*.java
java-cp.:antlr-2.7.6.jar Main
或在:

窗户
java-cp antlr-2.7.6.jar antlr.Tool My.g
javac-cp antlr-2.7.6.jar*.java
java-cp。;antlr-2.7.6.jar Main
将产生以下输出:

第1行=[1,2,3]
第2行=[4,5,6,7,8]
第3行=[9,10]

警告
任何尝试此代码的人,请注意此代码使用ANTLR 2.7.6。除非您有非常令人信服的理由使用此版本,否则强烈建议您使用最新的ANTLR稳定版本(撰写本文时为v3.3)。

感谢您的回复。我看到你在Antlr上回答了很多问题,所以我很高兴听到你的意见。也许这表明了一种更根本的无知。恐怕你所说的是对的;但是如何利用解析器的结果呢?我是否在解析器本身中定义该代码?我宁愿让另一个类以类似于解析器使用令牌流的方式使用解析器。@Kazark,对不起,我不确定我是否理解您的意思。你能编辑你的原始问题,并提供一个(小的)你想如何解析某些输入的用例吗?哇,你太棒了。谢谢