实现解释器模式示例,添加抽象表达式、终结符表达式及解析器类,增强代码可读性
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
实例:
|
||||
定义一种运算符,减号是加法,加号是减法。
|
||||
*/
|
||||
|
||||
// 抽象表达式
|
||||
interface Expression {
|
||||
interpret(): number;
|
||||
}
|
||||
|
||||
// 终结符表达式:数字
|
||||
class NumberExpression implements Expression {
|
||||
private token: string;
|
||||
constructor(token: string) {
|
||||
this.token = token;
|
||||
}
|
||||
interpret(): number {
|
||||
return parseInt(this.token);
|
||||
}
|
||||
}
|
||||
|
||||
// 非终结符表达式:加法
|
||||
class AddExpression implements Expression {
|
||||
private left: Expression;
|
||||
private right: Expression;
|
||||
constructor(left: Expression, right: Expression) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
interpret(): number {
|
||||
return this.left.interpret() - this.right.interpret();
|
||||
}
|
||||
}
|
||||
|
||||
// 非终结符表达式:减法
|
||||
class SubExpression implements Expression {
|
||||
private left: Expression;
|
||||
private right: Expression;
|
||||
constructor(left: Expression, right: Expression) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
interpret(): number {
|
||||
return this.left.interpret() + this.right.interpret();
|
||||
}
|
||||
}
|
||||
|
||||
// 非终结符表达式工厂方法类型
|
||||
type ExpressionFactory = (prev: Expression, next: string) => Expression;
|
||||
|
||||
class Parser {
|
||||
private exp: string[];
|
||||
private index: number;
|
||||
private prev: Expression | null;
|
||||
private factories: { [key: string]: ExpressionFactory };
|
||||
|
||||
constructor() {
|
||||
this.exp = [];
|
||||
this.index = 0;
|
||||
this.prev = null;
|
||||
this.factories = {
|
||||
"-": (prev: Expression, next: string) =>
|
||||
new SubExpression(prev, new NumberExpression(next)),
|
||||
"+": (prev: Expression, next: string) =>
|
||||
new AddExpression(prev, new NumberExpression(next)),
|
||||
};
|
||||
}
|
||||
|
||||
newNumberExpression(token: string): Expression {
|
||||
return new NumberExpression(token);
|
||||
}
|
||||
|
||||
parse(raw: string): Expression {
|
||||
this.exp = raw.trim().split(/\s+/);
|
||||
this.index = 0;
|
||||
this.prev = null;
|
||||
|
||||
while (this.index < this.exp.length) {
|
||||
let token = this.exp[this.index];
|
||||
if (this.factories[token]) {
|
||||
const factory = this.factories[token];
|
||||
this.index++;
|
||||
if (this.index >= this.exp.length) {
|
||||
console.log("Last token is an operator, Ignored.");
|
||||
break;
|
||||
}
|
||||
if (this.prev === null) {
|
||||
console.log(
|
||||
"Expression cannot start with an operator, Initialized with 0."
|
||||
);
|
||||
this.prev = this.newNumberExpression("0");
|
||||
}
|
||||
token = this.exp[this.index];
|
||||
this.prev = factory(this.prev, token);
|
||||
} else {
|
||||
this.prev = this.newNumberExpression(token);
|
||||
}
|
||||
this.index++;
|
||||
}
|
||||
if (this.prev === null) {
|
||||
console.log("No valid expression parsed.");
|
||||
return this.newNumberExpression("0");
|
||||
}
|
||||
return this.prev;
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
console.log("========== 解释器模式 ==========");
|
||||
const parser = new Parser();
|
||||
let raw;
|
||||
raw = "10 - 5";
|
||||
console.log(`${raw} = ?`);
|
||||
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||
|
||||
console.log("-----");
|
||||
raw = "10 + 5";
|
||||
console.log(`${raw} = ?`);
|
||||
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||
|
||||
console.log("-----");
|
||||
raw = "20 - 4 + 2 - 1";
|
||||
console.log(`${raw} = ?`);
|
||||
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||
|
||||
console.log("-----");
|
||||
raw = " - 4 + 2 - ";
|
||||
console.log(`${raw} = ?`);
|
||||
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||
|
||||
console.log("\n======== 解释器模式结束 ========");
|
||||
})();
|
||||
Reference in New Issue
Block a user