/** class Expr, our internal representation of an expression * in the D1 language. * See http://www.radford.edu/itec380/2022fall-ibarland/Homeworks/Project/ * * @author Ian Barland * @version 2023.Apr.10 */ import java.util.*; interface Expr { /** Evaluate a given Expr. * @return the Value this Expr evaluates to. * (In D0, all values are numbers (doubles), but * in B3 that will change, which is why we have * pre-emptively made the return type 'Value'.) */ abstract public Value eval(); /** Return a String representation of this Expr. * The result will be something which can be * passed into 'parse(String)' to get the same * Expr back. That is, toString and parse are * inverses of each other. * @return a String representation of this Expr. */ abstract public String toString(); /** Return (our internal representation of) the expression s. * @param s The source code for exactly one Expr. Must by syntactically correct. * @return (our internal representation of) the expression s. */ public static Expr parse(String s) { return Expr.parse(new java.util.Scanner(s)); } public static final String PUNCTUATION = "@=^{}><;!~#:?|\\(\\)\\[\\]/\\\\"; //as a regex-class // Note: Beware declaring '-' or '.' or '+' as punctuation -- that means // those chars can't appear as part of a number. /** Return (our internal representation of) the expression s. * @param s A scanner reading the source code for exactly one Expr. * Must by syntactically correct. * @param * @return (our internal representation of) the expression s. */ public static Expr parse(Scanner s) { return parse(s,PUNCTUATION); } public static Expr parse(java.util.Scanner s, String punctuation) { if (UtilIan.hasNextDoubleSplittingBy(s,punctuation)) { return Num.parse(s,punctuation); } else if (UtilIan.hasNextSplittingBy(s, Paren.START_TOKEN, punctuation) ) { return Paren.parse(s,punctuation); } else if (UtilIan.hasNextSplittingBy(s, BinOp.START_TOKEN,punctuation) ) { return BinOp.parse(s,punctuation); } else if (UtilIan.hasNextSplittingBy(s, IfZero.START_TOKEN, punctuation) ) { return IfZero.parse(s,punctuation); } else { /* Unknown syntax! */ String tokens = ""; while (s.hasNext()) { tokens += UtilIan.nextSplittingBy(s,punctuation) + " "; } throw new java.util.InputMismatchException( "Expr.parse: something has gone awry! Encountered \"" + tokens + "\""); } } /* Note that I removed some sanity-checks from 'parse', so that students can concentrate on the code/algorithm. E.g. assert UtilIan.hasNextSplittingBy(s,"gondor",PUNCTUATION) : "Expected `gondor` after `" + subExpr1.toString() + "`, got `" + UtilIan.nextSplittingBy(s,PUNCTUATION) + "`"; */ }