All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ExprParser.ExprParser Maven / Gradle / Ivy

Go to download

This project implements Affine Arithmetic Decision Diagrams (AADD) in Java. AADD permit in particular the symbolic execution of Java codes.

The newest version!
package ExprParser;

import jAADD.*;

import java.util.ArrayList;

/**
 * This class provides a parser for simple expressions
 * that are equivalent to operations on AADD/BDD.
 * They are used to model dependencies between a part's
 * property and his part's properties.
 *
 * It returns an AADD with the value for expressions that can be evaluated,
 * and otherwise an attributes syntax tree.
 *
 * Lexical elements:
* * - Keywords "if" "then" "else" "ite"
* - ID: ( a-zA-Z ("." a-zA-Z)* )
* (Keywords and ID are case insensitive, converted to lower case)
* - DOUBLE: as in Java StreamTokenizer, but without sign.
* - Operators {@code + - * / & | > < = LE GE}
* * The parser uses the recursive descent method. * It recognizes the following language: *
 *{@code
 *
 * Stmt    :-  "var"  NAME ":=" CExpr
 *           | "func" NAME Params ":=" CExpr
 *           | "eqn"  NAME "==" CExpr
 *           | CExpr
 *
 * CExpr   :- Expr  [ (">", "<", "=", LE, GE) Expr ]
 *
 * Sum     :- Product (("+"|"-"|"|") Product)*
 *
 * Product :- Value (("*"|"/"|"&") Value)*
 *
 * Value   :- ["-"]
 *              (   FLOAT
 *                | "(" CExpr ")"
 *                | NAME [Params]
 *              )
 *
 * Params  :- "(" CExpr ("," CExpr)* ")"
 *
 * }
 * 
* Examples are in the unit test. */ public class ExprParser extends ExprScanner { public ExprTree AST; public ExprParser() throws ExprError { } public ExprTree setExpr(String expr) throws ParseError, ExprError { super.setup(expr); parse(); return AST; } // Starts parsing and returns the root of the AST. private void parse() throws ParseError, ExprError { nextToken(); AST = Stmt(); if (token != EOL) throw new ParseError("expected Statement"); } // Evaluates a given String with the defined variables. // It returns an expression tree. public ExprTree evalExpr(String expr_str) throws ParseError, ExprError { super.setup(expr_str); parse(); AST.evalExpr(); return AST; } // Evaluates a given String with the defined variables. // It returns the AADD result from the expression tree. public AADD evalAADD(String expr_str) throws ParseError, ExprError { evalExpr(expr_str); return AST.getAADD(); } // Evaluates a given String with the defined variables. // It returns the BDD result from the expression tree. public BDD evalBDD(String expr_str) throws ParseError, ExprError { evalExpr(expr_str); return AST.getBDD(); } // Re-evaluates the expression with the defined variables. // It returns the AADD result from the expression tree. public AADD evalAADD() throws ExprError { AST.evalExpr(); return AST.getAADD(); } // Re-evaluates the expression with the defined variables. // It returns the BDD result from the expression tree. public BDD evalBDD() throws ParseError, ExprError { if (AST==null) throw new ExprError("Expr not evaluated"); AST.evalExpr(); return AST.getBDD(); } // Re-evaluates the expression with the defined variables. // It returns the BDD result from the expression tree. public DD evalDD() throws ParseError, ExprError { if (AST==null) throw new ExprError("Expr not evaluated"); AST.evalExpr(); return AST.getResult(); } // stmt :- LET NAME "=" CExpr // | FUNC NAME Params "=" CExpr private ExprTree Stmt() throws ParseError, ExprError { if (nextTokenIs(VAR)) { String n = sval; nextToken(ID); nextToken(ASS); ExprTree t = CExpr(); t.evalExpr(); defVar(n, t); return t; } if (nextTokenIs(FUNC)) { String n = sval; nextToken(ID); ArrayList params = Params(); defFunc(n, params); nextToken(ASS); ExprTree t = CExpr(); defFuncBody(n, t); return t; } return CExpr(); } // Cond :- Sum [ relop Sum] private ExprTree CExpr() throws ParseError, ExprError { /* Deprecated if (nextTokenIs(IF)) { LinkedList param = new LinkedList(); param.add(CExpr()); nextToken(THEN); param.add(CExpr()); nextToken(ELSE); param.add(CExpr()); return setFuncParams("ite", param); } */ ExprTree result = Sum(); if ( nextTokenIs('>', '<', '=', GE, LE) ) { int op = lastToken; ExprTree t2 = Sum(); result = new ExprTreeBinOp(result, op, t2); } return result; } // Sum :- Product ( ("+"|"-"|"|") Product )* ExprTree Sum() throws ParseError, ExprError { ExprTree result = Product(); while (nextTokenIs('+', '-', '|') ) { int op = lastToken; ExprTree t2 = Product(); result = new ExprTreeBinOp(result, op, t2); } return result; } // Product :- Sum ( ("*"|"/"|"&") Sum )* ExprTree Product() throws ParseError, ExprError { ExprTree result = Value(); while (nextTokenIs('*', '/', '&')) { int op = lastToken; ExprTree f2 = Value(); result = new ExprTreeBinOp(result, op, f2); } return result; } // Params :- "(" CExpr ("," CExpr)* ")" ArrayList Params() throws ParseError, ExprError { if (nextTokenIs('(')) { ArrayList parameters = new ArrayList(); ExprTree e = CExpr(); parameters.add(e); while (nextTokenIs(',')) { e = CExpr(); parameters.add(e); } nextToken(')'); return parameters; } return null; } // Recognizes // Value :- DOUBLE | TRUE | FALSE // | '(' ITE ("," ITE)* ')' // | ID that is a constant or variable. // | ID '(' ITE ("," ITE)* ')' where word is a function on AADD. ExprTree Value() throws ParseError, ExprError { ExprTree val; // Value boolean neg = false; // optional sign. neg = nextTokenIs('-'); // Negative Value. switch(token) { case DOUBLE: val = new ExprTree(new AADD(nval)); nextToken(); break; case '(': nextToken(); val = CExpr(); nextToken(')'); break; case ID: String n = sval; nextToken(); ArrayList params = Params(); if (params == null) val = getVar(n); // Variable from symbol table else val = getFuncCall(n, params); // Function call; consider params in scope. break; default: throw new ParseError("expect value, but read: "+(char) token+" resp. "+ token); } if (neg == true) return new ExprTreeBinOp(new ExprTree(new AADD(0)), '-', val); else return val; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy