Commit 6ed48eef authored by Matthew Dawson's avatar Matthew Dawson
Browse files

Fix up expressions to work with arbritrary expressions.

Fix up the expression parser to actually work with different expressions.  So now,
it handles both longer expressions (ex 4+5+6) and where order of operations takes
effect (ex 4+5*6 and 4*5+6).  Include tests.

git-svn-id: https://groke.mcmaster.ca/svn/grad/colin/branches/TableTool_javization@9844 57e6efec-57d4-0310-aeb1-a6c144bb1a8b
parent d07a3090
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ package ca.mcmaster.cas.matlab2smt;
 *
 * @author matthew
 */
final class MatlabExpressionOperation implements MatlabExpression {
final class MatlabExpressionOperation implements MatlabExpression, MatlabExpressionWithSubExpression {
    MatlabExpressionOperation(MatlabExpression lhs, MatlabOperation op, MatlabExpression rhs) {
        m_lhs = lhs;
        m_rhs = rhs;
@@ -53,6 +53,16 @@ final class MatlabExpressionOperation implements MatlabExpression {
        }
    }

    @Override
    public MatlabExpression getSubExpression() {
        return m_rhs;
    }

    @Override
    public void setSubExpression(MatlabExpression subExpression) {
        m_rhs = subExpression;
    }
    
    MatlabExpression m_lhs, m_rhs;
    MatlabOperation m_op;
}
+14 −0
Original line number Diff line number Diff line
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ca.mcmaster.cas.matlab2smt;

/**
 *
 * @author matthew
 */
public interface MatlabExpressionWithSubExpression {
    public MatlabExpression getSubExpression();
    public void setSubExpression(MatlabExpression subExpression);
}
+4 −1
Original line number Diff line number Diff line
@@ -10,12 +10,15 @@ package ca.mcmaster.cas.matlab2smt;
 */
enum MatlabOperation {
    Addition("+", "BVPLUS(", "BVPLUS("),
    Multiplication("*", "BVMULT(", "BVMULT("),
    GreaterThen(">", "BVSGT(", "BVGT("),
    Equals("=", "=", "=");

    static MatlabOperation getOpForSymbol(String text) {
        if(text.equals("+")) {
                return Addition;
        } else if(text.equals("*")) {
                return Multiplication;
        } else if(text.equals(">")) {
                return GreaterThen;
        } else if(text.equals("==")) {
@@ -38,7 +41,7 @@ enum MatlabOperation {
                if(!((FixedPointVariableType)type).isSigned()){
                    func = m_CVC3VersionFunctionUnsigned;
                }
                if(this == Addition && type instanceof FixedPointVariableType) {
                if((this == Addition || this == Multiplication) && type instanceof FixedPointVariableType) {
                    FixedPointVariableType typeF = (FixedPointVariableType)type;
                    return func + typeF.digits() + ",";
                } else {
+45 −23
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import ca.mcmaster.cas.matlab2smt.MatlabParserParser.E10Context;
import ca.mcmaster.cas.matlab2smt.MatlabParserParser.E11Context;
import ca.mcmaster.cas.matlab2smt.MatlabParserParser.Literal_numberContext;
import ca.mcmaster.cas.matlab2smt.MatlabParserParser.Id_plus_indexersContext;
import java.util.ArrayDeque;
import java.util.Deque;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
@@ -31,9 +33,10 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
 *
 * @author matthew
 */
final public class MatlabParser {
final public class MatlabParser implements MatlabExpressionWithSubExpression {
    public MatlabParser(VariableParser variableListing, String matlabCode) {
        m_variableParser = variableListing;
        m_opStack.addFirst(new ExpressionStackContainer(0, this));
        parseMatlabCode(matlabCode);
    }
    
@@ -66,37 +69,41 @@ final public class MatlabParser {
    
    private void decrementLevel() {
        this.m_level--;
        if(!m_opStack.isEmpty() && m_opStack.peekFirst().level > m_level) {
            m_opStack.removeFirst();
        }
    }
    
    private void addExpressionValue(MatlabExpressionValue expressionValue) {
        System.out.println("" + m_level + " " + m_exprLevel);
        if(m_rootExpression == null) {
            m_rootExpression = expressionValue;
        } else {
            MatlabExpressionOperation rootOp = (MatlabExpressionOperation)m_rootExpression;
            if(rootOp != null) {
                rootOp.setRHS(expressionValue);
            } else {
                throw new UnsupportedOperationException("Expressions not linkable yet.");
            }
        }
        m_exprLevel = m_level;
        System.out.println("" + m_level + " " + m_opStack.peekFirst().level);
        m_opStack.peekFirst().op.setSubExpression(expressionValue);
    }
    
    private void addExpressionOperation(MatlabExpressionOperation op) {
        System.out.println("" + m_level + " " + m_exprLevel);
        System.out.println("" + m_level + " " + m_opStack.peekFirst().level);
        if(m_rootExpression == null) {
            throw new IllegalStateException("It should not be possible to have"
                    + "an op where the left hand side is a null expression!");
        } else {
            if(m_exprLevel > m_level) { //This current op happens after the root expression op.  Pull it up.
                op.setLHS(m_rootExpression);
                m_rootExpression = op;
            if(m_opStack.peekFirst().level >= m_level) { //This current op happens after the root expression op.  Pull it up.
                op.setLHS((MatlabExpression)m_opStack.removeFirst().op);
                m_opStack.peekFirst().op.setSubExpression(op);
            } else { //This op happens before.  Push it down the tree.
                throw new UnsupportedOperationException();
                op.setLHS(m_opStack.peekFirst().op.getSubExpression());
                m_opStack.peekFirst().op.setSubExpression(op);
            }
            m_opStack.addFirst(new ExpressionStackContainer(m_level, op));
        }
    }
        m_exprLevel = m_level;

    @Override
    public MatlabExpression getSubExpression() {
        return m_rootExpression;
    }

    @Override
    public void setSubExpression(MatlabExpression subExpression) {
        m_rootExpression = subExpression;
    }

    private class MatlabParserToMatlabExpressions extends MatlabParserBaseListener {
@@ -247,8 +254,7 @@ final public class MatlabParser {

        @Override
        public void enterG1(G1Context ctx) {
            System.out.print("op e ");
            System.out.println(ctx.getText());
            addExpressionOperation(new MatlabExpressionOperation(null, MatlabOperation.getOpForSymbol(ctx.getText()), null));
        }

        @Override
@@ -268,22 +274,26 @@ final public class MatlabParser {

        @Override
        public void exitG1(G1Context ctx) {
            addExpressionOperation(new MatlabExpressionOperation(null, MatlabOperation.getOpForSymbol(ctx.getText()), null));
            System.out.print("op e ");
            System.out.println(ctx.getText());
        }

        @Override
        public void exitG2(G2Context ctx) {
            System.out.println("op ex");
            System.out.println(ctx.getText());
        }

        @Override
        public void exitG3(G3Context ctx) {
            System.out.println("op ex");
            System.out.println(ctx.getText());
        }

        @Override
        public void exitG4(G4Context ctx) {
            System.out.println("op ex");
            System.out.println(ctx.getText());
        }

        @Override
@@ -299,6 +309,18 @@ final public class MatlabParser {
    }
    
    private MatlabExpression m_rootExpression;
    private int m_level = 0, m_exprLevel = 0;
    private int m_level = 0;
    private VariableParser m_variableParser;
    
    private static class ExpressionStackContainer {
        public int level;
        public MatlabExpressionWithSubExpression op;

        public ExpressionStackContainer(int level, MatlabExpressionWithSubExpression op) {
            this.level = level;
            this.op = op;
        }
    }
    
    Deque<ExpressionStackContainer> m_opStack = new ArrayDeque<MatlabParser.ExpressionStackContainer>();
}
+54 −2
Original line number Diff line number Diff line
@@ -43,11 +43,63 @@ public class MatlabParserTest {
    
    @Test
    public void testSimpleAdditionWithLiterals() {
        MatlabParser parser = new MatlabParser(null, "5+5\n");
        MatlabParser parser = new MatlabParser(null, "4+5\n");
        MatlabExpression expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("(5 + 5)", expr.getCVC3Output(expr.type()));
        assertEquals("(4 + 5)", expr.getCVC3Output(expr.type()));
    }
    
    @Test
    public void testSimpleMultiplicationWithLiterals() {
        MatlabParser parser = new MatlabParser(null, "4*5\n");
        MatlabExpression expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("(4 * 5)", expr.getCVC3Output(expr.type()));
    }
    
    @Test
    public void testDoubleAdditionWithLiterals() {
        System.out.println("$");
        MatlabParser parser = new MatlabParser(null, "4+5+6\n");
        MatlabExpression expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("((4 + 5) + 6)", expr.getCVC3Output(expr.type()));
    }
    
    @Test
    public void testMultiplyThenAddWithLiterals() {
        MatlabParser parser = new MatlabParser(null, "4*5+6\n");
        MatlabExpression expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("((4 * 5) + 6)", expr.getCVC3Output(expr.type()));
    }
    
    @Test
    public void testAddThenMultiplyWithLiterals() {
        MatlabParser parser = new MatlabParser(null, "4+5*6\n");
        MatlabExpression expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("(4 + (5 * 6))", expr.getCVC3Output(expr.type()));
    }
    
    @Test
    public void testInsanseExpressionsWithLiterals() {
        MatlabParser parser = new MatlabParser(null, "4*5+6*7\n");
        MatlabExpression expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("((4 * 5) + (6 * 7))", expr.getCVC3Output(expr.type()));
        
        parser = new MatlabParser(null, "4+5+6*7*8\n");
        expr = parser.getRootExpression();
        
        assertEquals(new MatlabLiteral(null).type(), expr.type());
        assertEquals("((4 + 5) + ((6 * 7) * 8))", expr.getCVC3Output(expr.type()));
    }
    
    @Test