我不是 100% 确定您为什么会收到该错误:我需要查看您的整个语法。无论如何,没有必要同时检查is_a
和 !is_a
。并且两者$is_a
都是is_a
有效的。
假设您正在解析一个数字列表,并且每第 4 个数字,您想通过不同的“分支”进行处理。一个语法看起来像:
grammar T;
parse
@init{int n = 1;}
: (number[n\%4 == 0] {n++;})+ EOF
;
number [boolean multipleOf4]
: {multipleOf4}?=> Int {System.out.println("branch A -> " + $Int.text);}
| Int {System.out.println("branch B :: " + $Int.text);}
;
Int
: '0'..'9'+
;
Space
: (' ' | '\t' | '\r' | '\n') {skip();}
;
(请注意,这%
是 ANTLR 语法中的保留字符(但不在字符串文字和注释中),因此需要使用反斜杠转义)
并且可以用类进行测试:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("11 22 33 44 55 66 77 88 99");
TLexer lexer = new TLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
TParser parser = new TParser(tokens);
parser.parse();
}
}
现在生成解析器/词法分析器(A),编译所有源文件(B)并运行主类(C):
java -cp antlr-3.2.jar org.antlr.Tool Tg // A
javac -cp antlr-3.2.jar *.java // B
java -cp .:antlr-3.2.jar Main // C
(在 Windows 上,通过 do 运行它java -cp .;antlr-3.2.jar Main
)
产生以下输出:
B分公司::11
B分公司::22
B分公司::33
分支 A -> 44
B分公司::55
B分公司::66
B分公司::77
分支 A -> 88
B分店::99
所以,是的,在这种情况下,您需要一个“门控语义谓词”({boolean}?=>
),而不是“验证语义谓词”({boolean}?
)。这两个谓词之间的区别在之前的 SO Q&A 中进行了解释:什么是 ANTLR 中的“语义谓词”?