給定一種語言,定義其文法表示,並提供一個解釋器,使用該表示來解釋語言中的句子。適用於:文法較簡單、需要頻繁解釋執行的場景。
| 角色 | 職責 |
|---|---|
| AbstractExpression | 聲明抽象解釋操作 interpret(),所有節點共享 |
| TerminalExpression | 實現終結符(如音符)的解釋邏輯 |
| NonterminalExpression | 實現非終結符(如音階)的解釋邏輯,包含子表達式 |
| Context | 包含解釋過程中需共享的全局信息(如演奏文本) |
文法:PlayContext 存儲演奏文本(如 "O 2 C 0.5 D 1 ...")。Expression 解析文本首個 token,派生類 Note 處理音符,Scale 處理音階。
// 抽象表達式
class Expression {
public:
virtual void interpret(PlayContext* ctx) {
if (ctx->getText().empty()) return;
// 解析首個 key-value 對
string key = parseKey(ctx), value = parseValue(ctx);
execute(key, value); // 具體執行留給子類
// 移除已解析部分,遞歸處理剩餘
ctx->setText(remainingText);
}
virtual void execute(string key, string value) = 0;
};
// 終結符:音符
class Note : public Expression {
void execute(string key, string value) override {
string note;
switch(key[0]) {
case 'C': note="1"; break;
case 'D': note="2"; break;
// ... E→3, F→4, G→5, A→6, B→7
}
cout << note << " ";
}
};
// 非終結符:音階
class Scale : public Expression {
void execute(string key, string value) override {
cout << (key=="O" ? "低音" : "高音") << " ";
}
};
int main() {
PlayContext ctx;
ctx.setText("O 2 C 0.5 D 1 E 0.5 ..."); // 上海灘樂譜
Expression* expr = nullptr;
while (!ctx.getText().empty()) {
char c = ctx.getText()[0];
if (c == 'O') expr = new Scale();
else expr = new Note(); // C,D,E,F,G,A,B,P
expr->interpret(&ctx);
delete expr;
}
}
解釋器模式將文法規則封裝為類層次結構,通過遞歸下降解析實現語言處理。適合簡單 DSL(領域特定語言),如配置文件解析、規則引擎、查詢語言等。