JavaCC中使用JJTree的并行关系表达式(即1<2<3)是否可能?
我浏览了 JavaCC 包附带的“解释器”示例。 它允许并行关系表达式的语法,但它没有给出正确的答案。
boolean a;
a = 1<2<3;
write a;
这将给出 ClassCastException,因为解释器处理“1<2”并将布尔值放入堆栈中,而第三个变量 3 是整数,因此它无法与布尔值进行比较。
我尝试更改 ASTLTNode.java,其中包含
public 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());
}
}
如果我在解释()末尾添加“top++”,堆栈将保留最后一个值,但当处理完成时,它将显示最后一个数字而不是布尔值。
你们有这样做的想法吗? 多谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是正确的,SPL(愚蠢的编程语言)语法确实允许诸如
1
1
1
1
1
1
1
1 2< 3
-- 您可以在规范中看到这一点:但是,仅仅因为表达式
1
2< 3
语法上允许,但不意味着它在语义上允许。正如您所发现的,您的表达式通过了语法检查,但它具有所谓的静态语义错误,特别是类型错误。
流行的编程语言中存在多种此类语义错误。例如,在 Java 中,您可以声明一个带有四个参数的方法,但如果您用两个参数调用它,会发生什么?您的调用在语法上是正确的(id 后跟左括号,后跟逗号分隔的表达式列表),但存在语义错误:调用中的参数数量与声明的参数。
如果你想要
1 < 2< 3
是一个返回 true 的有效布尔表达式,当且仅当1<2
和2<3
(如 Python),那么您需要更改 SPL 的语义。既然这是面向堆栈的,那你能做什么呢?让我们来看看。假设你有First,你会推 x,推 y,然后做小于。现在如果 x
y
您将需要用y
替换堆栈顶部(当前为true
),然后继续测试(即y < z< /代码>)。但如果你发现
x < y
产生 false,那么您需要将 false 留在堆栈顶部并跳过其余的小于。即使你有
等等,这也有效。诀窍是当您发现
<
返回 false 时尽早退出。这可能会提醒您实施短路与和或。希望有帮助。You are correct that the SPL (Stupid Programming Language) syntax does allow expressions like
1 < 2 < 3
-- you can see this in the spec:However, just because the expression
1 < 2 < 3
is syntactically allowed does not mean it is semantically allowed.Like you discovered, your expression passes its syntax check, but it has what is called a static semantic error, in particular a type error.
There are many kinds of these semantic errors in popular programming languages. For example in Java you can declare a method to take four parameters but if you call it with two, what happens? Your call is syntactically correct (id followed by a left paren followed by a comma-separated list of expressions), but there is a semantic error: the number of arguments in the call does not match the number of declared parameters.
If you want
1 < 2 < 3
to be a valid boolean expression that returns true iff1<2
and2<3
(like Python), then you need to change the semantics of SPL. Since this is stack-oriented, what can you do? Let's see. Suppose you hadFirst you would push x, push y, and do the less than. Now if
x < y
you will want to replace the top of stack (currentlytrue
) withy
and then continue with your test (namelyy < z
). But if you found thatx < y
produced false, then you need to leave the false on the top of the stack and skip the rest of the less thans.This works even if you have
and so on. The trick is to bail out early when you find a
<
returning false. This might remind you of implementing short-circuit ands and ors. Hope it helps.