Commit 36df2034 authored by Matthew Dawson's avatar Matthew Dawson
Browse files

Move the general expression parser over to a general interface.

To allow for any given expression parser to be used in jTET, have both
existing expression parsers implement an interface, instead of being a bunch
of static methods.  This also moves all code over to the new interface.

This simplifies ParserOperatorParseTest, as it no longer needs reflection
to call the parse functions.

This adds some extra special exceptions to report errors from the parsers.
The existing ones don't make use of them yet, but they can in the future
when error reporting gets better.
parent 8c3baa22
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 Matthew Dawson <matthew@mjdsystems.ca>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the distribution
 *     * Neither the name of the McMaster Centre for Software Certification nor the names
 *       of its contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package ca.mcscert.jtet.parsers;

import ca.mcscert.jtet.expression.Expression;
import ca.mcscert.jtet.expression.VariableCollection;

/**
 * Parses a given expression represented as a string into a jTET abstract syntax tree.
 * <p>
 * This interface is created specifically to allow the {@link ca.mcscert.jtet.tabularexpression.Table} class to use
 * an arbitrary syntax in each cell.  This would allow both MATLAB and PVS syntax to be used for expressions in a table.
 *
 * @author Matthew Dawson
 */
public interface ExpressionParser {
    /**
     * Parses the given expression into a jTET expression with the given variables.
     * <p>
     * Implementations should return a jTET expression that is equivalent to the given string expression.  The passed
     * in variable collection should be the only source of variables used, and the parser should only use input variables.
     * Output variables should not be used, as jTET does not support state currently.
     * @param variableCollection Collection of variables to be used.
     * @param expression String representation of the expression.
     * @return A jTET abstract syntax tree representing the given expression.
     */
    Expression parseExpressionString(VariableCollection variableCollection, String expression);
}
+3 −2
Original line number Diff line number Diff line
@@ -49,12 +49,13 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
 *
 * @author matthew
 */
final public class MatlabParser {
final public class MatlabParser implements ExpressionParser{
    final public static MatlabParser Parser = new MatlabParser();

    private MatlabParser() {
    }

    public static Expression parseMatlabCode(VariableCollection variableListing, String matlabCode) {
    public Expression parseExpressionString(VariableCollection variableListing, String matlabCode) {
        // create a CharStream that reads from standard input
        ANTLRInputStream input = new ANTLRInputStream(matlabCode + "\n");

+3 −2
Original line number Diff line number Diff line
@@ -51,12 +51,13 @@ import java.util.Map;
 *
 * @author matthew
 */
final public class PVSSimpleParser {
final public class PVSSimpleParser implements ExpressionParser {
    final public static PVSSimpleParser Parser = new PVSSimpleParser();

    private PVSSimpleParser() {
    }

    public static Expression parsePVSCode(VariableCollection variableListing, String pvsCode) {
    public Expression parseExpressionString(VariableCollection variableListing, String pvsCode) {
        // create a CharStream that reads from standard input
        ANTLRInputStream input = new ANTLRInputStream(pvsCode + "\n");

+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ final public class VariableParser {
                m_variables.put(subtypeVar, m_variables.get(limitingExpression.getKey()));

                VariableCollection variableCollection = new VariableCollection(new PartialVariableCollection(m_variables, m_usedEnumerationTypes));
                m_variables.get(limitingExpression.getKey()).setSubtypePredicate(PVSSimpleParser.parsePVSCode(variableCollection, subtypeExpression));
                m_variables.get(limitingExpression.getKey()).setSubtypePredicate(PVSSimpleParser.Parser.parseExpressionString(variableCollection, subtypeExpression));

                // Undo the variables hack, to avoid having unused variables bleed into the verification scripts!
                m_variables.remove(subtypeVar);
+1 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public class Table {
    }

    private Expression parseMatlabCode(Cell cell) {
        return MatlabParser.parseMatlabCode(m_variables, cell.contents());
        return MatlabParser.Parser.parseExpressionString(m_variables, cell.contents());
    }

    private int HandleLeftGrid(SubHierarchyFetcher grid, HierarchicalGridDepthFirstCheckerGenerator generator, int outputCellXIndex, int outputCellYIndex) {
Loading