Java – using the Interpreter pattern on a composite structure

I was asked to use composite, recursive descendant parser and interpreter for expression evaluation

This is the syntax:

<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 job is:

Now, the first thing I notice is that interpreter uses a composite structure, so it seems a good idea to use the evaluate (: Context) method to extend my composite structure

I asked, but I was told it was not the way to do the task It seems that I have built an interpreter tree, starting with a composite tree (it's very boring for me because I already have a tree to use!)

So I used the compound recursion generator to build my tree. It recognizes the input. It doesn't have any kind of problem in building the tree

But the question is: how do I apply the interpreter to my structure?

This is my course map (some are Italian, but it's easy to understand)

If what I mean is correct, the interpreter will use a class for each grammar rule, so I have to make a cond class, then a termb and so on

But can I link them to my portfolio?

Solution

I don't know why you were told not to use the same tree structure I think I'll add an evaluate () method to my expression interface That makes sense to me An expression should know how to evaluate itself

I would say that your current expression interface is exposed too much (such as operands) As an expressive client, I just need to 1) call it, 2) read the result, I guess maybe 3) print Actually, I'd rather use toString () to print directly

You may have noticed that not all expressions require two operands (such as not or negate) This has made some differences from your interface I will simplify it to:

public interface Expression {
   int evaluate();
 }

Then, each of your operations and terminals knows how to evaluate itself (and convert itself into a string)

So I can have specific operations, such as:

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
 }

Now I can easily build trees

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);

I don't even need to access the operands directly

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>