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