C++设计模式——解释器模式
2022/2/21 17:56:22
本文主要是介绍C++设计模式——解释器模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
解释器模式,给定一个语言,定义他的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子...
#include <iostream> #include <memory> #include <vector> #include <algorithm> #include <regex> #include <set> using namespace std; //抽象表达式类 声明一个抽象的解释操作,这个接口为抽象语法树中的所有的结点共享 class Expression { public: virtual bool Interpret(const std::string& info) = 0; }; //终结符表达式类 实现与文法中的终结符相关联的解释操作 class TerminalExpressin : public Expression { private: std::set<std::string> infos; public: TerminalExpressin(const std::vector<std::string> datas) { infos.insert(datas.begin(), datas.end()); } bool Interpret(const std::string& info) { if (infos.find(info) != infos.end()) return true; return false; } }; //非终结符表达式类 为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2....Rn都需要一个具体的非终结符表达式类 //通过实现抽象表达式的interpret()方法实现解释操作.解释操作以递归方式调用上面所提到的代表R1、R2....Rn中各个符号的实例遍历 class AndExpression : public Expression { private: std::shared_ptr<Expression> smartCity; std::shared_ptr<Expression> smartPerson; public: AndExpression(std::shared_ptr<Expression> city, std::shared_ptr<Expression> person) : smartCity(city), smartPerson(person) {} bool Interpret(const std::string& info) { std::regex pattern("的"); std::vector<std::string> results(std::sregex_token_iterator(info.begin(), info.end(), pattern, -1), std::sregex_token_iterator()); if (results.size() != 2) { std::cout << "输入解释信息有误,无法解析!" << std::endl; return false; } return smartCity->Interpret(results[0]) && smartPerson->Interpret(results[1]); //得到的两个名字 } }; //上下文全局信息类 包括解释器之外的一些全局信息 class Context { private: std::vector<std::string> citys; std::vector<std::string> persons; std::shared_ptr<Expression> smartAndExpr; public: Context() { citys.push_back("成都"); citys.push_back("临沂"); persons.push_back("老人"); persons.push_back("儿童"); smartAndExpr = std::make_shared<AndExpression>(std::make_shared<TerminalExpressin>(citys), std::make_shared<TerminalExpressin>(persons)); } void IsFree(const std::string& info) { if (smartAndExpr->Interpret(info)) { std::cout << info << " , 您本次乘车免费" << std::endl; } else { std::cout << info << ", 您本次乘车扣费2¥" << std::endl; } } }; int main() { std::shared_ptr<Context> bus = std::make_shared<Context>(); std::vector<std::string> passengers = { "成都的老人" , "成都的年轻人" , "成都的儿童" , "临沂的老人" , "临沂的年轻人" , "临沂的儿童" }; for (std::string passenger : passengers) { bus->IsFree(passenger); } system("pause"); return 0; }
优点
当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可以使用解释器模式
很容易的改变和扩展文法,因为该模式使用类来表示文法规则,你可以使用继承来改变或者扩展该文法,也比较容易实现文法,因为定义抽象语法树中各个结点的类的实现大体类似,这些类都是易于直接编写的
比如正则表达式 浏览器
缺点:
解释器模式也有不足的 解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以维护和管理,建议当文法非常复杂时,使用其他技术,比如语法分析程序或者编译器生成器来处理
这篇关于C++设计模式——解释器模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享