ANTLR解析器,我可以在第一次匹配时停止吗?

ANTLR解析器,我可以在第一次匹配时停止吗?,antlr,antlr3,Antlr,Antlr3,我正在使用ANTLR为PDF对象结构编写解析器,但在解析混合了PDF引用和整数的字符串流时遇到了一个问题 基本上,PDF引用是这样的字符串:“10 0 R”(整数空间整数空间'R') 这是我的语法文件(简化): 下面是测试代码(用C#): 我希望结果是规则r中匹配的第一条规则(无论是ref还是INTEGER) 例如: 如果输入=“97 98 10 0 R 100 101”:结果=“97” 如果输入=“10 0 R 100 101”:结果=“10 0 R” 不需要遍历整个字符串流。只要符合第一

我正在使用ANTLR为PDF对象结构编写解析器,但在解析混合了PDF引用和整数的字符串流时遇到了一个问题

基本上,PDF引用是这样的字符串:“10 0 R”(整数空间整数空间'R')

这是我的语法文件(简化):

下面是测试代码(用C#):

我希望结果是规则r中匹配的第一条规则(无论是ref还是INTEGER)

例如:

  • 如果输入=“97 98 10 0 R 100 101”:结果=“97”

  • 如果输入=“10 0 R 100 101”:结果=“10 0 R”

不需要遍历整个字符串流。只要符合第一条规则,然后停止

我是ANTLR的新手,不知道怎么做。 我使用的是ANTLRWorks 1.4.3和antlr-dotnet-csharpruntime-3.4.1.9004


感谢您的帮助

backtrack=true
仅适用于解析器规则:不适用于lexer规则。因此,当lexer偶然发现
整数空间
后接的不是
整数
,lexer将抛出一个错误/异常:它将
REF
规则中回溯,并创建一个
整数
空间
标记

但是
REF
一开始不应该是词法规则,而是解析器规则:

ref
 : INTEGER SPACE INTEGER SPACE 'R'
 ;
编辑 我在Linux上,因此无法测试C#目标(至少,我从未能够在MonoDevelop中运行
CSharp3
目标)。但这里有一个Java演示:

语法Pdf;
公共图书馆
:(ref{System.out.println(“ref=”+$ref.text+“””);)
|整数{System.out.println(“整数=”+$INTEGER.text+“””);}
|空格{System.out.println(“SPACE=”+$SPACE.text+“””);}
)*
EOF
;
裁判
:整数空间整数空间'R'
;
整数
:数字+;
空间
: ' '
;
碎片数字
: '0'..'9'
;
您可以使用类测试解析器:

import org.antlr.runtime.*;
公共班机{
公共静态void main(字符串[]args)引发异常{
PdfLexer lexer=新PdfLexer(新AntlStringStream(“97 98 10 0 R 100 101”));
PdfParser parser=newpdfparser(newcommontokenstream(lexer));
parser.r();
}
}
如果运行该类,将打印以下内容:

INTEGER='97'
空格=“”
整数='98'
空格=“”
ref='10 0 R'
空格=“”
整数='100'
空格=“”
整数='101'

这正是我所期望的。

我将REF改为REF,但它不起作用。虽然有些不同,但现在标记变成了:97,空格,98,空格,10,空格,0,空格,'R',空格,101,EOF。它只识别整数,不识别ref.@sun1991,当我测试它时,一切正常。请看我的编辑。@Kiers,我可以在我的机器上用C#output复制结果,这对我来说是一大步,谢谢!很抱歉,我在问题中没有说清楚,但我的初衷不是使用规则r:(…)*遍历所有字符串流。我希望r()只返回它匹配的第一个规则,可以是ref或INTEGER。如果输入为“10 0 R 100 101”,它应该返回“ref=10 0 R”并停止,如果输入为“97 98 10 0 R”,它只返回“INTEGER=97”并停止。我试图删除规则r周围的括号和*号,但同样,它没有返回任何内容。
byte[] bytes = Encoding.ASCII.GetBytes("97 98 10 0 R 100 101");
MemoryStream stream = new MemoryStream(bytes);

ANTLRInputStream inputStream = new ANTLRInputStream(stream);
PdfLexer lexer = new PdfLexer(inputStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);

PdfParser parser = new PdfParser(tokens);
string result = parser.r();
ref
 : INTEGER SPACE INTEGER SPACE 'R'
 ;