欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 解释器模式(大话设计模式)C/C++版本

解释器模式(大话设计模式)C/C++版本

2024/10/24 1:49:11 来源:https://blog.csdn.net/m0_47104421/article/details/140397614  浏览:    关键词:解释器模式(大话设计模式)C/C++版本

解释器模式

C++

#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
#include <regex> /* 编译失败 => https://www.cnblogs.com/rootshaw/p/12910684.html */
#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);}return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>typedef struct Expression Expression;
typedef struct TerminalExpression TerminalExpression;
typedef struct AndExpression AndExpression;
typedef struct Context Context;// 抽象表达式结构体
struct Expression
{bool (*interpret)(struct Expression *, const char *);
};// 终结符表达式结构体
struct TerminalExpression
{struct Expression base;char **infos;size_t num_infos;
};// 非终结符表达式结构体
struct AndExpression
{struct Expression base;struct Expression *smartCity;struct Expression *smartPerson;
};// 上下文结构体
struct Context
{struct Expression *smartAndExpr;
};
bool and_interpret(struct Expression *self, const char *info);
bool terminal_interpret(struct Expression *self, const char *info);// 创建终结符表达式
struct TerminalExpression *create_terminal_expression(char **datas, size_t num_datas)
{struct TerminalExpression *expr = malloc(sizeof(struct TerminalExpression));expr->base.interpret = terminal_interpret;expr->infos = malloc(num_datas * sizeof(char *));expr->num_infos = num_datas;size_t i;for (i = 0; i < num_datas; i++){expr->infos[i] = strdup(datas[i]);}return expr;
}// 创建非终结符表达式
struct AndExpression *create_and_expression(struct Expression *city, struct Expression *person)
{struct AndExpression *expr = malloc(sizeof(struct AndExpression));expr->base.interpret = and_interpret;expr->smartCity = city;expr->smartPerson = person;return expr;
}// 终结符表达式的解释操作
bool terminal_interpret(struct Expression *self, const char *info)
{struct TerminalExpression *expr = (struct TerminalExpression *)self;size_t i;for (i = 0; i < expr->num_infos; i++){if (strcmp(info, expr->infos[i]) == 0){return true;}}return false;
}// 非终结符表达式的解释操作
bool and_interpret(struct Expression *self, const char *info)
{struct AndExpression *expr = (struct AndExpression *)self;char *buffer = strdup(info);char *token = strtok((char *)buffer, "的");bool cityMatched = false;bool personMatched = false;while (token != NULL){if (!cityMatched && expr->smartCity->interpret(expr->smartCity, token)){cityMatched = true;}else if (!personMatched && expr->smartPerson->interpret(expr->smartPerson, token)){personMatched = true;}else{if (buffer)free(buffer);return false;}token = strtok(NULL, "的");}if (buffer)free(buffer);return cityMatched && personMatched;
}// 创建上下文
struct Context *create_context()
{struct Context *ctx = malloc(sizeof(struct Context));char *citys[] = {"成都", "临沂"};char *persons[] = {"老人", "儿童"};struct TerminalExpression *cityExpr = create_terminal_expression(citys, sizeof(citys) / sizeof(citys[0]));struct TerminalExpression *personExpr = create_terminal_expression(persons, sizeof(persons) / sizeof(persons[0]));struct AndExpression *andExpr = create_and_expression(&cityExpr->base, &personExpr->base);ctx->smartAndExpr = &andExpr->base;return ctx;
}// 上下文的解释操作
void context_is_free(struct Context *ctx, const char *info)
{if (ctx->smartAndExpr->interpret(ctx->smartAndExpr, info)){printf("%s , 您本次乘车免费\n", info);}else{printf("%s , 您本次乘车扣费2¥\n", info);}
}// 销毁终结符表达式
void destroy_terminal_expression(struct TerminalExpression *expr)
{size_t i;for (i = 0; i < expr->num_infos; i++){free(expr->infos[i]);}free(expr->infos);free(expr);
}// 销毁非终结符表达式
void destroy_and_expression(struct AndExpression *expr)
{destroy_terminal_expression((struct TerminalExpression *)expr->smartCity);destroy_terminal_expression((struct TerminalExpression *)expr->smartPerson);free(expr);
}// 销毁上下文
void destroy_context(struct Context *ctx)
{struct AndExpression *andExpr = (struct AndExpression *)ctx->smartAndExpr;destroy_and_expression(andExpr);free(ctx);
}int main()
{struct Context *bus = create_context();char *passengers[] = {"成都的老人", "成都的年轻人", "成都的儿童", "临沂的老人", "临沂的年轻人", "临沂的儿童"};size_t i;for (i = 0; i < sizeof(passengers) / sizeof(passengers[0]); i++){context_is_free(bus, passengers[i]);}destroy_context(bus);return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com