a) | ({!$is_a}? => b); 可以解决这个-6ren">
gpt4 book ai didi

ANTLR3: 参数和语义谓词 ("cannot find symbol", "illegal start of type")

转载 作者:行者123 更新时间:2023-12-01 13:02:50 24 4
gpt4 key购买 nike

我想在 ANTLR3 中实现一个“分支”。

我想用

branch[boolean is_a]
: ({ $is_a}? => a)
| ({!$is_a}? => b);

可以解决这个问题,但是我得到编译错误“找不到符号”和“类型的非法开始”,因为在生成的源中,即 DFA45.specialStateTransition(...)没有参数 is_a

我尝试省略 =>¹,和/或省略 $is_a$

第一组 ab 不相交。

事实上 b 是类型 ((C) => c) |一个

¹) 因为我不明白 {...} 之间的区别? => ...{...}? ...

最佳答案

我不是 100% 确定您为什么会收到该错误:为此我需要查看您的整个语法。无论如何,没有必要同时检查 is_a !is_a$is_ais_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 T.g // Ajavac -cp antlr-3.2.jar *.java            // Bjava -cp .:antlr-3.2.jar Main             // C

(在 Windows 上,通过执行 java -cp .;antlr-3.2.jar Main 运行它)

产生以下输出:

branch B :: 11branch B :: 22branch B :: 33branch A -> 44branch B :: 55branch B :: 66branch B :: 77branch A -> 88branch B :: 99

所以,是的,在这种情况下,您需要一个“门控语义谓词” ({boolean}?=>),而不是一个“验证语义谓词” “({boolean}?)。之前的 SO 问答中解释了这两个谓词之间的区别:What is a 'semantic predicate' in ANTLR?

关于ANTLR3: 参数和语义谓词 ("cannot find symbol", "illegal start of type"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4965200/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com