JavaCC中使用JJTree的并行关系表达式(即1<2<3)是否可能?

发布于 2024-11-28 04:44:17 字数 783 浏览 3 评论 0 原文

我浏览了 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++”,堆栈将保留最后一个值,但当处理完成时,它将显示最后一个数字而不是布尔值。

你们有这样做的想法吗? 多谢。

I've looked through the example of "Interpreter" coming with the JavaCC package.
It allows the syntax of parallel relational expression but it didn't give the correct answer.

boolean a;
a = 1<2<3;
write a;

This will give the ClassCastException because the interpreter process "1<2" and put the boolean into the stack while the third variable, 3, is an integer so it is not comparable with a boolean.

I try changing the ASTLTNode.java which contains

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());
    }
}

If I add the "top++" at the end of interpret(), the stack will keep the last value but when process done, it will show the last digit not a boolean.

Do you guys have any ideas of doing this?
Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

命硬 2024-12-05 04:44:17

您是正确的,SPL(愚蠢的编程语言)语法确实允许诸如 1 1 1 1 1 1 1 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 的有效布尔表达式,当且仅当 1<22<3 (如 Python),那么您需要更改 SPL 的语义。既然这是面向堆栈的,那你能做什么呢?让我们来看看。假设你有

x < y < z

First,你会推 x,推 y,然后做小于。现在如果 x y 您将需要用 y 替换堆栈顶部(当前为 true),然后继续测试(即 y < z< /代码>)。但如果你发现x < y 产生 false,那么您需要将 false 留在堆栈顶部并跳过其余的小于

即使你有

e1 < e2 < e3 < e4 < e5 < e6

等等,这也有效。诀窍是当您发现 < 返回 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:

void RelationalExpression() #void :
{}
{
  AdditiveExpression()
  (
    "<" AdditiveExpression() #LTNode(2)
   |
    ">" AdditiveExpression() #GTNode(2)
   |
    "<=" AdditiveExpression() #LENode(2)
   |
    ">=" AdditiveExpression() #GENode(2)
  )*
}

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 iff 1<2 and 2<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 had

x < y < z

First you would push x, push y, and do the less than. Now if x < y you will want to replace the top of stack (currently true) with y and then continue with your test (namely y < z). But if you found that x < 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

e1 < e2 < e3 < e4 < e5 < e6

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文