这是语法:
<cond> → <termb> [OR <termb>]* <termb>→<factb>[AND <factb>]* <factb>→<expr> RELOP <expr> | NOT <factb> | OPAR <cond> CPAR <expr> → [PLUS | MINUS] <term> [(PLUS <term>) | (MINUS <term>)]* <term> → <termp> [(MULT <termp>) | (DIV <termp>) | (REM <termp>)]* <termp> → <fact> [POWER <fact>]* <fact> → ID | NUM | OPAR1 <expr> CPAR1 ----TERMINALS---- ID → ("A" | ... | "Z" | "a" | ...| "z") [("A"| ... | "Z" | "a" | ...| "z" | "0" | ... | "9")]* NUM → ("0" | ... | "9") [("0" | ... | "9")]* OPAR → "(" CPAR → ")" OPAR1 → "[" CPAR1 → "]" RELOP → EQ | NEQ | GT | GE | LT | LE EQ → "= =" NEQ → "!=" GT → ">" GE → ">=" LT → "<" LE → "<=" POWER → "^" DIV → "/" REM → "%" MULT → "*" MINUS → "−" PLUS → "+" AND → “and” or “&&” OR → “or” or “||” NOT → “not” or “!”
作业是:
The goal of the project,based on Composite,Recursive Builder and
Interpreter,is to get a conditional expression,do a Syntax analysis
and build its composite tree. Starting from the tree,you’ve got to
evaluate the result of the condition,based on an external context
(read from a properties file) that contains the value of the internal
variables
现在,我注意到的第一件事是,Interpreter使用了一个Composite结构,所以使用evaluate(:Context)方法扩展我的Composite结构似乎是个好主意.
我问过,但是我被告知这不是做这个任务的方式.
似乎我已经建立了解释器树,从复合树开始(对我而言,这是非常无聊的,因为我已经有一棵树可以使用了!).
所以我使用复合递归生成器构建了我的树,它识别输入,它构建树没有任何种类的问题.
但问题是:我如何将解释器应用于我的结构?
这是我的课程图(有些是意大利语,但这是很容易理解的)
如果我的意思是正确的,口译员会为每个语法规则使用一个类,所以我必须做一个cond类,然后是一个termb等等.
但是我可以将它们链接到我的组合?
解决方法
我会说你当前的表达式界面暴露太多(如操作数).作为表达的客户,我只需要1)调用它,2)读取结果,我猜也许3)打印.其实,我宁愿使用toString()直接打印.
你可能已经注意到,但并不是所有的表达式都需要2个操作数(例如NOT或NEGATE).这已经与您的界面产生了一些差异.我会简化为:
public interface Expression { int evaluate(); }
然后,您的每个操作和终端都知道如何评估自身(并将其自身转换为字符串).
所以我可以有具体的操作,如:
public class Terminal implements Expression { private final int value; public Terminal(int value) { this.value = value; } public int evaluate() { return value; } public String toString() { return String.valueOf(value); } } public class Add implements Expression { private final Expression left; private final Expression right; public Add(Expression left,Expression right) { this.left = left; this.right = right; } public String toString() { return left.toString() + " + " + right.toString(); } // leave the rest for you }
现在我可以很容易地构建树
Expression expr = new Add(new Terminal(1),new Subtract(new Terminal(2),new Terminal(3))); int result = expr.evaluate(); System.out.print(expr.toString() + " = " + result);
我甚至不需要直接访问各个操作数.