赞
踩
模式名称:解析器模式
模式分类:行为型
模式意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
结构图:
适用于:
当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时,以下情况效果最好:
1、该文法简单。对于复杂的发文,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无须构建抽象语法树即可解释表达式,这样可以节省空间还可能节省时间。
2、效率不是一个关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。不过,即使在这种情况下,转换器仍然可用该模式实现。
这里假设我们希望以文本的方式记录游戏命令过程比如:[[UnitItem]]{{attack}}[[UnitItem]] ,类似这种[[单位]]{{命令}}为格式,然后通过解析器解析成实际的命令
意图:给定一个语言(命令备忘录语言),定义它的文法的一种表示([[单位]]{{命令}}),并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
表达式接口
- export interface IExpression {
- interpret(context: UnitCommandUnitContext): void;
- }
单位表达式及解析方法
- export class UnitItemExpression implements IExpression {
- private unitItemId: string;
- constructor(unitItemId: string) {
- this.unitItemId = unitItemId;
- }
- interpret(context: UnitCommandUnitContext): void {
- // 执行与终结符相关的解释操作
- let unitItem = context.getUnitItem(this.unitItemId)
- console.log("解析到单位项:", unitItem);
- context.setUnitItem(unitItem)
- }
- }
“命令”表达式及解析方法
- export class CommandExpression implements IExpression {
- private commandId: string;
-
- constructor(commandId: string) {
- this.commandId = commandId;
- }
- interpret(context: UnitCommandUnitContext): void {
- // 执行与终结符相关的解释操作
- let command = context.getCommand(this.commandId)
- console.log("解析到命令:", command);
- context.setCommand(command);
- }
- }
“遍历解析”表达式及解析方法
- export class CommandSequenceExpression implements IExpression {
- private expressions: IExpression[];
-
- constructor(expressions: IExpression[]) {
- this.expressions = expressions;
- }
-
- interpret(context: UnitCommandUnitContext): void {
- for (const expression of this.expressions) {
- expression.interpret(context);
- }
- context.executeCommand()
- }
- }
单位 操作命令 另一个单位 的context
- // 单位 操作命令 另一个单位 的context
- export class UnitCommandUnitContext {
- command: ICommand = null
- fromUnitItem: UnitItem<any> = null
- toUnitItem: UnitItem<any> = null
- getUnitItem(unitItemId: string) {
- return xhgame.game.battleEntity.model.unitItemMap.get(unitItemId)
- }
- getCommand(commandId: string) {
- // todo 其他补充
- return new AttackCommand(null, null)
- }
- setCommand(command: ICommand) {
- this.command = command
- }
- setUnitItem(unitItem: UnitItem<any>) {
- if (this.fromUnitItem == null) {
- this.fromUnitItem = unitItem
- }
- if (this.toUnitItem == null) {
- this.toUnitItem = unitItem
- }
- }
- executeCommand() {
- if (this.command instanceof AttackCommand) {
- this.command.setUnitItem(this.fromUnitItem)
- this.command.setTargetUnitItem(this.toUnitItem)
- this.command.execute()
- }
- }
- }
- // 创建一个 单位 操作命令 另一个单位的上下文
- const unitCommandUnitContext = new UnitCommandUnitContext();
- // 解析文本为 UnitItem.20 的单位对 UnitItem.21 的单位发动攻击
- // 目前为了后期拓展下列以:[[单位]]{{命令}}为格式
- const commandText = "[[UnitItem.20]]{{attack}}[[UnitItem.21]]";
- // 构建抽象语法树
- const expressions: IExpression[] = [];
- const regex = /\[\[([^\]]+)\]\]|\{\{([^\}]+)\}\}|\[\{([^\}]+)\}\]|\[<([^\>]+)>\]/g;
- let match;
- while ((match = regex.exec(commandText)) !== null) {
- console.log(match)
- const token = match[0];
- const unitItemId = match[1]; // 捕获组1中的内容为单位项ID
- const commandId = match[2]; // 捕获组2中的内容为命令ID
- if (unitItemId !== undefined) {
- expressions.push(new UnitItemExpression(unitItemId));
- } else if (commandId !== undefined) {
- expressions.push(new CommandExpression(commandId));
- }
- }
- console.log('expressions', expressions)
- // “遍历解析”表达式
- const commandSequence = new CommandSequenceExpression(expressions);
- commandSequence.interpret(unitCommandUnitContext);
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。