0

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.

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I've looked through your suggestion and found it's great!! But I wonder somethings, what we're gonna do after the expression done, The last digit is still in the stack and when it's printed out, it's an integer not the "true". Anyway, the "false" works flawlessly, I love it.
Ah yes, very good point; I didn't play it out until the end. But you should be able to detect that you are at the end and put a true on the stack. Just a little extra work is all. :) Glad it worked out.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.