public class Arithmetic {
/*
Expression ::= Expression + Term | Term
Term ::= Term * Factor | Factor
Factor ::= Const | '(' Expression ')'
*/
/*
Expression ::= Term Expression2
Expression2 ::= '+' Term Expression2 | End
Term ::= Factor Term2
Term2 ::= '*' Factor Term2 | End
Factor ::= Const | '(' Expression ')'
*/
public static Lexer lex;
public static void main (String [] argv) {
lex = new Lexer (argv [0]);
System.out.println (argv [0]);
Expr expr = new Expr ();
expr.print (" ");
System.out.println (expr.parse ());
}
public static class Lexer {
String ToParse;
int i;
int undoi;
Lexer (String ToParse) {
this.ToParse = ToParse;
i = 0;
}
public void undo () {
i = undoi;
}
String lexer () {
char ch;
String ret = "";
if (i >= ToParse.length ()) {
ret = "END";
}
else if ((ch = (ToParse.charAt (i))) == '+') {
undoi = i;
i++;
ret = "+";
}
else if (ch == '*') {
undoi = i;
i++;
ret = "*";
}
else if (ch == '(') {
undoi = i;
i++;
ret = "(";
}
else if (ch == ')') {
undoi = i;
i++;
ret = ")";
}
else if ((ch >= '0') && (ch <= '9')) {
undoi = i;
ret = "";
while (((ch = ToParse.charAt (i)) >= '0') && (ToParse.charAt (i) <= '9')) {
ret = ret + ch;
i++;
if (i >= ToParse.length ())
break;
}
}
return ret;
}
}
public static class Tree {
Tree l;
Tree r;
String v;
public Tree () {
this.v = null;
this.l = null;
this.r = null;
}
public void print (String str) {
if (this != null) {
System.out.println (str + this.v);
if (this.l != null)
this.l.print (str + " ");
if (this.r != null)
this.r.print (str + " ");
}
}
public int parse () {
if (this.v == "+") {
if ((this.l == null) || (this.r == null)) {
System.out.println ("Syntax error");
System.exit (1);
}
return this.l.parse () + this.r.parse ();
}
if (this.v == "*") {
if ((this.l == null) || (this.r == null)) {
System.out.println ("Syntax error");
System.exit (1);
}
return this.l.parse () * this.r.parse ();
}
else if (this.v == null) {
if (this.l == null) {
System.out.println ("Syntax error");
System.exit (1);
}
return 0 + this.l.parse ();
}
else if ((this.v.charAt (0) >= '0') && (this.v.charAt (0) <= '9')) {
return Integer.parseInt (v);
}
return 0;
}
}
public static class Expr extends Tree {
public Expr () {
this.l = new Term ();
this.r = new Expr2 ();
this.v = "+";
}
}
public static class Expr2 extends Tree {
public Expr2 () {
if (lex.lexer () == "+") {
this.v = "+";
this.l = new Term ();
this.r = new Expr2 ();
}
else {
lex.undo ();
this.v = "0";
this.l = null;
this.r = null;
}
}
}
public static class Term extends Tree {
public Term () {
this.l = new Factor ();
this.r = new Term2 ();
this.v = "*";
}
}
public static class Term2 extends Tree {
public Term2 () {
if (lex.lexer () == "*") {
this.v = "*";
this.l = new Factor ();
this.r = new Term2 ();
}
else {
lex.undo ();
this.v = "1";
this.l = null;
this.r = null;
}
}
}
public static class Factor extends Tree {
String ch;
public Factor () {
String val;
if ((val = lex.lexer ()) == "(") {
this.l = new Expr ();
this.r = null;
if (lex.lexer () != ")") {
System.out.println ("Syntax error");
System.exit (1);
}
}
else if (val != "END") {
this.v = val;
this.l = null;
this.r = null;
}
}
}
}