解析器模式(C++)

定义

给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。

应用场景

  • 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
  • 在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

结构

在这里插入图片描述

代码示例

//Interpreter.h
/****************************************************/
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
 
using namespace std;
 
// 抽象表达式类
class Expression 
{
    
    
public:
	// 解释
	virtual int interpret() = 0;
 
};
 
// 数字表达式类
class NumberExpression : public Expression 
{
    
    
public:
	// 构造函数
	NumberExpression(int num) : number(num) {
    
    }
 
	// 解释
	virtual int interpret() {
    
     return number; }
 
private:
	int number;
};
 
// 加法表达式类
class AddExpression : public Expression 
{
    
    
public:
	// 构造函数
	AddExpression(Expression* left, Expression* right) : left(left), right(right) {
    
    }
 
	// 解释
	virtual int interpret() {
    
     return left->interpret() + right->interpret(); }
 
private:
	Expression* left;
	Expression* right;
};
 
// 减法表达式类
class SubExpression : public Expression 
{
    
    
public:
	// 构造函数
	SubExpression(Expression* left, Expression* right) : left(left), right(right) {
    
    }
 
	// 解释
	virtual int interpret() {
    
     return left->interpret() - right->interpret(); }
 
private:
	Expression* left;
	Expression* right;
};
 
// 解释器类
class Interpreter 
{
    
    
public:
	// 构造函数
	Interpreter(string exp) : expression(exp) {
    
    }
 
	// 解释
	int interpret() {
    
    
		stack<Expression*> s;
		// 遍历表达式字符
		for (int i = 0; i < expression.length(); i++) {
    
    
			if (isdigit(expression[i])) {
    
    
				// 识别数字
				int j = i;
				while (j < expression.length() && isdigit(expression[j])) {
    
    
					j++;
				}
				int num = stoi(expression.substr(i, j - i));
				s.push(new NumberExpression(num));
				i = j - 1;
			}
			else if (expression[i] == '+') {
    
    
				// 把左数提取出来
				Expression* left = s.top();
				s.pop();
				// 识别右数
				int j = i + 1;
				while (j < expression.length() && isdigit(expression[j])) {
    
    
					j++;
				}
				Expression* right = new NumberExpression(stoi(expression.substr(i + 1, j - (i + 1))));
				// 左数+右数的表达式放入栈中
				s.push(new AddExpression(left, right));
				i = j - 1;
			}
			else if (expression[i] == '-') {
    
    
				// 把左数提取出来
				Expression* left = s.top();
				s.pop();
				// 识别右数
				int j = i + 1;
				while (j < expression.length() && isdigit(expression[j])) {
    
    
					j++;
				}
				Expression* right = new NumberExpression(stoi(expression.substr(i + 1, j - (i + 1))));
				// 左数-右数的表达式放入栈中
				s.push(new SubExpression(left, right));
				i = j - 1;
			}
		}
		return s.top()->interpret();
	}
 
private:
	string expression;
};


#endif
//test.cpp
/****************************************************/
#include "Interpreter.h"

#include <unordered_map>
int main()
{
    
    
	unordered_map<string, int> variables;
	string input;
	while (getline(cin, input)) {
    
    
		cout << "input:" << input << endl;
		Interpreter interpreter(input);
		variables[input] = interpreter.interpret();
		cout << "result:" << variables[input] << endl;
	}
	return 0;
}

运行结果
在这里插入图片描述

要点总结

  • Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式。
  • 使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
  • Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interperter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

猜你喜欢

转载自blog.csdn.net/weixin_47424753/article/details/132155457
今日推荐