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

解释器模式

C++

cpp 复制代码
#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

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;
}
相关推荐
时光の尘2 小时前
C语言菜鸟入门·关键字·int的用法
c语言·开发语言·数据结构·c++·单片机·链表·c
Edward-tan2 小时前
c语言数据结构与算法--简单实现线性表(顺序表+链表)的插入与删除
c语言·开发语言·链表
武昌库里写JAVA2 小时前
一文读懂Redis6的--bigkeys选项源码以及redis-bigkey-online项目介绍
c语言·开发语言·数据结构·算法·二维数组
程序员与背包客_CoderZ3 小时前
C++设计模式——Abstract Factory Pattern抽象工厂模式
c语言·开发语言·c++·设计模式·抽象工厂模式
zzzhpzhpzzz3 小时前
设计模式——组合实体模式
设计模式
Mcworld8575 小时前
C语言:strcpy
c语言·开发语言
人才程序员5 小时前
详解Qt QStorageInfo 存储信息类
c语言·开发语言·c++·后端·qt·界面
ZHOUPUYU5 小时前
最新‌VSCode保姆级安装教程(附安装包)
c语言·开发语言·c++·ide·windows·vscode·编辑器
爱学嵌入式的菜鸟5 小时前
Linux应用编程(C语言编译过程)
linux·c语言·ubuntu
Best_Me076 小时前
快速排序算法-C语言
c语言·算法·排序算法