0

我查看了 JavaCC 包附带的“解释器”示例。它允许并行关系表达式的语法,但它没有给出正确的答案。

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

这将给出 ClassCastException,因为解释器处理“1<2”并将布尔值放入堆栈,而第三个变量 3 是一个整数,因此它不能与布尔值进行比较。

我尝试更改包含

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

你们有做这件事的想法吗?非常感谢。

4

1 回答 1

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成为一个有效的布尔表达式,返回真 iff1<22<3(如 Python),那么你需要改变 SPL 的语义。既然这是面向堆栈的,你能做什么?让我们来看看。假设你有

x < y < z

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

即使你有这也有效

e1 < e2 < e3 < e4 < e5 < e6

等等。<诀窍是当您发现返回错误时尽早退出。这可能会提醒您实现短路 ands 和 ors。希望能帮助到你。

于 2011-08-07T06:38:44.090 回答