import java.util.*; /* 文法7のパーサクラス */
class Main {
public static void main
(String[] args
) { Exp s = new Exp();
s.parse(ct);
double i = s.exe();
}
}
int index = 0;
this.test = test;
this.exp = exp;
this.nextToken();
}
if (token == null) {
return token == s;
} else {
return token.equals(s);
}
}
void nextToken() {
char c = 0;
while (index < exp.length()) {
c = exp.charAt(index);
if (c != ' ') {
break;
}
index++;
}
if (exp.length() <= index) {
token = null;
return;
}
if (isNum(c)) {
StringBuilder b = new StringBuilder();
b.append(c);
index++;
while (index < exp.length()) {
c = exp.charAt(index);
if (c == ' ') {
index++;
} else if (!isNum(c)) {
break;
} else {
b.append(c);
index++;
}
}
token = b.toString();
} else {
index++;
}
if (!token.matches(test)) {
}
}
boolean isNum(char c) {
return -1 < "0123456789".indexOf(c);
}
return token;
}
}
abstract class Node { //parse, exeメソッドは全クラスに必須なのでabstractクラスで宣言
public abstract void parse
(Context ct
); public abstract double exe();
}
// Exp -> term Tail1*
class Exp extends Node {
private Term term; //Termオブジェクトを指す変数
private Tail1 tail1; //Tail1オブジェクトを指す変数
private ArrayList <Tail1
> al
= new ArrayList
<Tail1
>(); //Tail1オブジェクトの格納用 (term = new Term()).parse(ct); //Termオブジェクト作成&解析指示
while (ct.match("+") || ct.match("-")) { //加算or引き算の続く限りTail1を作る
(tail1 = new Tail1()).parse(ct); //Tail1オブジェクト生成&解析指示
al.add(tail1); //Tail1オブジェクトをalに格納
}
}
public double exe() {
double value = term.exe();
for (Tail1 tail : al) {
value += tail.exe();
}
return value;
}
}
// Tail1 -> + Term | - Term
class Tail1 extends Node {
private String op
; //加算か減算かを記録する変数 private Term term; //Termオブジェクトを指す変数
if (ct.match("+") || ct.match("-")) { //加算or減算の確認
op = ct.currentToken(); //加算か減算かを記録
ct.nextToken(); //次のトークンを読む
(term = new Term()).parse(ct); //Termオブジェクト作成&解析指示
} else { //'+'か'-'以外の記号で始まっていた場合
System.
out.
println("Tail1:先頭に '+'か'-'がありません"); }
}
public double exe() {
if ("+".equals(op)) {
return term.exe();
} else {
return -term.exe();
}
}
}
// Term -> Fac Tail2*
class Term extends Node {
private Fac fac; //Facオブジェクトを指す変数
private Tail2 tail2; //Tail2オブジェクトを指す変数
private ArrayList <Tail2
> al
= new ArrayList
<Tail2
>(); //Tail2オブジェクトを任意個格納する //ためのオブジェクト
(fac = new Fac()).parse(ct); //Facオブジェクト作成&解析指示
while (ct.match("*") || ct.match("/")) { //乗算or割り算の続く限りTail2を作る
(tail2 = new Tail2()).parse(ct); //Tail2オブジェクト生成&解析指示
al.add(tail2); //Tail2オブジェクトをalに格納
}
}
public double exe() {
double value = fac.exe();
for (Tail2 tail : al) {
value *= tail.exe();
}
return value;
}
}
// Tail2 -> * fac | / fac
class Tail2 extends Node {
private String op
; //乗算か割り算かを記録する変数 private Fac fac; //Facオブジェクトを指す変数
if (ct.match("*") || ct.match("/")) {//乗算or割り算の確認
op = ct.currentToken(); //乗算か割り算かを記録
ct.nextToken(); //トークンを1つ読む
(fac = new Fac()).parse(ct); //Facオブジェクトを作成
} else { //'*'か'/'以外の記号で始まっていた場合
System.
out.
println("Tail2:先頭に '*'か'/'がありません"); }
}
public double exe() {
if ("*".equals(op)) {
return fac.exe();
} else {
return 1.0 / fac.exe();
}
}
}
// Fac -> num | ( Exp )
class Fac extends Node {
private int num; //numの値を格納する変数
private Exp exp; //( Exp )の場合,Expオブジェクトを指す変数
if (ct.currentToken() != null && ct.currentToken().matches("[0-9]+")) {//自然数?
num
= Integer.
parseInt(ct.
currentToken()); //数値に変換しnumに格納 ct.nextToken(); //次のトークンに進む
} else if (ct.match("(")) { //トークンが'('だったら( Exp )
ct.nextToken(); //次のトークンを読む
(exp = new Exp()).parse(ct); //Expオブジェクトを生成
if (ct.match(")")) //閉じカッコがあれば次のトークンを読む
ct.nextToken();
else {//閉じカッコでなければエラー
System.
out.
println("Fac:閉じカッコがありません"); }
} else { //numでも(Exp)でもない場合
System.
out.
println("Fac:numでも(Exp)でもありません"); System.
out.
println(ct.
currentToken()); }
}
public double exe() {
if (exp == null) {
return num;
} else {
return exp.exe();
}
}
}