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

时间:2011-08-07 05:59:27

标签: javacc

我查看了随JavaCC包一起提供的“Interpreter”示例。 它允许并行关系表达式的语法,但它没有给出正确的答案。

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

这将给出ClassCastException,因为解释器处理“1&lt; 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());
    }
}

如果我在interpret()的末尾添加“top ++”,堆栈将保留最后一个值,但是当进程完成时,它将显示最后一个数字而不是布尔值。

你们有什么想法吗? 非常感谢。

1 个答案:

答案 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<22<3(如Python),则需要更改SPL的语义。由于这是面向堆栈的,你能做什么?让我们来看看。假设你有

x < y < z

首先你要推x,推y,做少于。现在,如果x < y您想要用true替换堆栈顶部(当前y),然后继续测试(即y < z)。但是如果你发现x < y产生了错误,那么你需要将错误放在堆栈的顶部,然后跳过剩下的少数

即使你有

,这也有效
e1 < e2 < e3 < e4 < e5 < e6

等等。诀窍是当你发现<返回false时提前纾困。这可能会提醒您实施短路和ors。希望它有所帮助。