我为类似 Scheme 的语言解释器创建了一个语法。最初,我有一个用于 if-then-else 语句的语义谓词来控制评估,即当条件为真时,仅评估“then”;当它为假时,仅评估“其他”。为了添加类型检查功能,我添加了第二个包含第一个语义谓词的语义谓词。不过,这是一个 hack,因为要进行类型检查或评估,我必须手动将全局布尔值更改typeCheck
为 true 或 false。
IF 语句的 AST 现在有两个分支。第一个(IFT)用于对 IF 语句的参数进行类型检查。[这就是为什么有两个谓词;要进行类型检查,必须评估所有参数] 第二个分支 (IFE) 用于评估短路 if-then-else。当我添加包含第一个语义谓词的第二个语义谓词时,问题就开始了,得到了臭名昭著的“输入时没有可行的替代方案”错误。在慢慢无处可去之后,我只用基本要素创建了新语法。同样的问题。这是精简的 AST:
虽然我从未经历过,但我已经看到在 Eclipse 中使用 ANTLR IDE 报告的 SO 问题。所以我启动了 ANTLRWorks,调试了解析器语法,然后尝试调试树语法。版本 1.4.3 和 1.4.2 都弹出这个框,“警告:远程解析器使用的语法不一样”。我单击 OK,然后在调试器中单击 Step Forward 一次,java.exe*32 进程终止。作为最后的测试,我用 antlr-3.3 和 antlr-3.4 完整的 jar 从命令行手动编译,没有变化。
解析器:
grammar NestedSemPreds;
options {
output = AST;
ASTLabelType = CommonTree;
}
tokens {
IF;
IFT;
IFE;
}
/** parser rules **/
ifstmt : '(' 'if' COND THEN ELSE ')' NEWLN
-> ^(IF ^(IFT COND THEN ELSE)
^(IFE COND THEN ELSE)
)
;
/** lexer rules **/
COND : 'true' ;
THEN : 'then' ;
ELSE : 'else' ;
COMMENT : ('//' .* NEWLN) { skip(); } ; //for lines in datafile I don't want processed
NEWLN : '\r'? '\n' ;
WS : (' '|'\t')+ { skip(); } ;
树语法:
tree grammar treeEval;
options {
tokenVocab = NestedSemPreds;
ASTLabelType = CommonTree;
}
@members {
boolean typeCheck = false;
}
ifstmt
@init {
boolean condition = true;
}
: ^(IF (
{typeCheck}? => //{System.out.println("typeCheck is true");}
^(IFT COND THEN ELSE) {System.out.println("IFT COND THEN ELSE");}
^(IFE . . .) {System.out.println(" SKIP IFE WITH . WILDCARD");}
| {!typeCheck}? => //{System.out.println("typeCheck is false");}
^(IFT . . .) {System.out.println("skip ift with . wildcard");}
^(IFE COND
( {condition}? => ({System.out.println(" condition is true");}
THEN . {System.out.println(" evaluate THEN");})
| {!condition}? => ({System.out.println(" condition is false");}
. ELSE {System.out.println(" evaluate else");})
)//close inner predicate
)//close ^IFE
)//close outer predicate
)//close ^IF
;
我找不到关于嵌套语义谓词的任何特定问题,但我也没有找到任何示例。为什么这段代码失败了?关于 ANTLRWorks 调试器问题的任何想法?