我查看了随JavaCC包一起提供的“Interpreter”示例。 它允许并行关系表达式的语法,但它没有给出正确的答案。
boolean a;
a = 1<2<3;
write a;
这将给出ClassCastException,因为解释器处理“1&lt; 2”并将布尔值放入堆栈中,而第三个变量3是一个整数,因此它不能与布尔值相比较。
我尝试更改包含
的ASTLTNode.javapublic class ASTLTNode extends SimpleNode {
public ASTLTNode(int id) {
super(id);
}
public ASTLTNode(ShawaParser p, int id) {
super(p, id);
}
public void interpret()
{
jjtGetChild(0).interpret();
jjtGetChild(1).interpret();
stack[--top] = new Boolean(((Integer)stack[top]).intValue() <
((Integer)stack[top + 1]).intValue());
}
}
如果我在interpret()的末尾添加“top ++”,堆栈将保留最后一个值,但是当进程完成时,它将显示最后一个数字而不是布尔值。
你们有什么想法吗? 非常感谢。
答案 0 :(得分:1)
你是正确的,SPL(愚蠢的编程语言)语法允许像1 < 2 < 3
这样的表达式 - 你可以在规范中看到这一点:
void RelationalExpression() #void :
{}
{
AdditiveExpression()
(
"<" AdditiveExpression() #LTNode(2)
|
">" AdditiveExpression() #GTNode(2)
|
"<=" AdditiveExpression() #LENode(2)
|
">=" AdditiveExpression() #GENode(2)
)*
}
但是,仅仅因为表达式1 < 2 < 3
允许 ,
就像你发现的那样,你的表达式通过了它的语法检查,但它有一个所谓的静态语义错误,特别是一个类型错误。
流行的编程语言中存在多种这样的语义错误。例如,在Java中,您可以声明一个方法来获取四个参数,但如果用两个参数调用它,会发生什么?你的调用语法正确(id后面跟着一个逗号分隔的表达式列表),但是有一个语义错误:调用中的参数数量与声明的参数。
如果希望1 < 2 < 3
是一个有效的布尔表达式,返回true iff 1<2
和2<3
(如Python),则需要更改SPL的语义。由于这是面向堆栈的,你能做什么?让我们来看看。假设你有
x < y < z
首先你要推x,推y,做少于。现在,如果x < y
您想要用true
替换堆栈顶部(当前y
),然后继续测试(即y < z
)。但是如果你发现x < y
产生了错误,那么你需要将错误放在堆栈的顶部,然后跳过剩下的少数。
即使你有
,这也有效e1 < e2 < e3 < e4 < e5 < e6
等等。诀窍是当你发现<
返回false时提前纾困。这可能会提醒您实施短路和ors。希望它有所帮助。