C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#和Unity中的解释器模式

C#和Unity中的解释器模式使用方式

作者:_克克克

解释器模式定义语言文法并提供解释器,适用于简单DSL和规则系统,优点:易扩展、灵活;缺点:复杂度高、效率低,现代替代方案包括ANTLR等解析工具

概述

解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法表示,并提供一个解释器来解释该语言中的句子。

这种模式主要用于处理特定类型的问题,特别是那些可以被表示为语言句子的领域。

一、解释器模式的核心概念

1. 解释器模式的主要角色

AbstractExpression(抽象表达式)

TerminalExpression(终结符表达式)

NonterminalExpression(非终结符表达式)

Context(上下文)

Client(客户端)

2. 解释器模式的 UML 类图

二、解释器模式的实现方式

1. 基础实现(布尔表达式解释器)

// 上下文 - 存储变量值
public class Context
{
    private readonly Dictionary<string, bool> _variables = new();
  
    public bool GetVariable(string name) => _variables.TryGetValue(name, out var value) ? value : false;
    public void SetVariable(string name, bool value) => _variables[name] = value;
}

// 抽象表达式
public interface IExpression
{
    bool Interpret(Context context);
}

// 终结符表达式 - 变量
public class VariableExpression : IExpression
{
    private readonly string _name;
  
    public VariableExpression(string name) => _name = name;
  
    public bool Interpret(Context context) => context.GetVariable(_name);
}

// 非终结符表达式 - AND
public class AndExpression : IExpression
{
    private readonly IExpression _left;
    private readonly IExpression _right;
  
    public AndExpression(IExpression left, IExpression right)
    {
        _left = left;
        _right = right;
    }
  
    public bool Interpret(Context context) => _left.Interpret(context) && _right.Interpret(context);
}

// 非终结符表达式 - OR
public class OrExpression : IExpression
{
    private readonly IExpression _left;
    private readonly IExpression _right;
  
    public OrExpression(IExpression left, IExpression right)
    {
        _left = left;
        _right = right;
    }
  
    public bool Interpret(Context context) => _left.Interpret(context) || _right.Interpret(context);
}

// 非终结符表达式 - NOT
public class NotExpression : IExpression
{
    private readonly IExpression _expression;
  
    public NotExpression(IExpression expression) => _expression = expression;
  
    public bool Interpret(Context context) => !_expression.Interpret(context);
}

// 客户端代码
class Program
{
    static void Main()
    {
        // 创建上下文并设置变量
        var context = new Context();
        context.SetVariable("A", true);
        context.SetVariable("B", false);
        context.SetVariable("C", true);
  
        // 构建表达式: (A AND B) OR (NOT C)
        var expression = new OrExpression(
            new AndExpression(
                new VariableExpression("A"),
                new VariableExpression("B")),
            new NotExpression(
                new VariableExpression("C")));
  
        // 解释执行
        bool result = expression.Interpret(context);
        Console.WriteLine($"表达式结果为: {result}"); // 输出 False
    }
}

2. 数学表达式解释器(四则运算)

// 上下文 - 存储变量值
public class MathContext
{
    private readonly Dictionary<string, int> _variables = new();
  
    public int GetVariable(string name) => _variables.TryGetValue(name, out var value) ? value : 0;
    public void SetVariable(string name, int value) => _variables[name] = value;
}

// 抽象表达式
public interface IMathExpression
{
    int Interpret(MathContext context);
}

// 终结符表达式 - 数字
public class NumberExpression : IMathExpression
{
    private readonly int _number;
  
    public NumberExpression(int number) => _number = number;
  
    public int Interpret(MathContext context) => _number;
}

// 终结符表达式 - 变量
public class VariableMathExpression : IMathExpression
{
    private readonly string _name;
  
    public VariableMathExpression(string name) => _name = name;
  
    public int Interpret(MathContext context) => context.GetVariable(_name);
}

// 非终结符表达式 - 加法
public class AddExpression : IMathExpression
{
    private readonly IMathExpression _left;
    private readonly IMathExpression _right;
  
    public AddExpression(IMathExpression left, IMathExpression right)
    {
        _left = left;
        _right = right;
    }
  
    public int Interpret(MathContext context) => _left.Interpret(context) + _right.Interpret(context);
}

// 非终结符表达式 - 减法
public class SubtractExpression : IMathExpression
{
    private readonly IMathExpression _left;
    private readonly IMathExpression _right;
  
    public SubtractExpression(IMathExpression left, IMathExpression right)
    {
        _left = left;
        _right = right;
    }
  
    public int Interpret(MathContext context) => _left.Interpret(context) - _right.Interpret(context);
}

// 使用示例
var context = new MathContext();
context.SetVariable("x", 10);
context.SetVariable("y", 5);

// 构建表达式: (x + 5) - (y - 2)
var expression = new SubtractExpression(
    new AddExpression(
        new VariableMathExpression("x"),
        new NumberExpression(5)),
    new SubtractExpression(
        new VariableMathExpression("y"),
        new NumberExpression(2)));

int result = expression.Interpret(context); // 结果为 12

三、解释器模式的特点

1. 优点

2. 缺点

四、解释器模式的使用场景

1. 典型应用场景

领域特定语言(DSL)

数学表达式处理

配置文件解析

编译器/解释器

游戏开发

2. 具体案例

案例1:正则表达式解释器(简化版)
// 抽象表达式
public interface IRegexExpression
{
    bool Interpret(string input);
}

// 终结符表达式 - 字符匹配
public class CharExpression : IRegexExpression
{
    private readonly char _char;
  
    public CharExpression(char c) => _char = c;
  
    public bool Interpret(string input) => input.Length > 0 && input[0] == _char;
}

// 非终结符表达式 - 序列
public class SequenceExpression : IRegexExpression
{
    private readonly List<IRegexExpression> _expressions;
  
    public SequenceExpression(params IRegexExpression[] expressions) 
        => _expressions = new List<IRegexExpression>(expressions);
  
    public bool Interpret(string input)
    {
        string remaining = input;
        foreach (var expr in _expressions)
        {
            if (!expr.Interpret(remaining)) return false;
            remaining = remaining.Substring(1);
        }
        return true;
    }
}

// 非终结符表达式 - 或
public class OrExpression : IRegexExpression
{
    private readonly IRegexExpression _left;
    private readonly IRegexExpression _right;
  
    public OrExpression(IRegexExpression left, IRegexExpression right)
    {
        _left = left;
        _right = right;
    }
  
    public bool Interpret(string input) => _left.Interpret(input) || _right.Interpret(input);
}

// 使用
var regex = new SequenceExpression(
    new CharExpression('a'),
    new OrExpression(
        new CharExpression('b'),
        new CharExpression('c')));

bool match1 = regex.Interpret("ab"); // true
bool match2 = regex.Interpret("ac"); // true
bool match2 = regex.Interpret("ad"); // false
案例2:业务规则引擎
// 业务规则上下文
public class BusinessContext
{
    public Dictionary<string, object> Data { get; } = new();
}

// 条件表达式
public class ConditionExpression
{
    private readonly string _field;
    private readonly object _value;
    private readonly string _operator;
  
    public ConditionExpression(string field, string op, object value)
    {
        _field = field;
        _operator = op;
        _value = value;
    }
  
    public bool Interpret(BusinessContext context)
    {
        if (!context.Data.TryGetValue(_field, out var fieldValue)) return false;
  
        return _operator switch
        {
            "==" => Equals(fieldValue, _value),
            ">" => Comparer.Default.Compare(fieldValue, _value) > 0,
            "<" => Comparer.Default.Compare(fieldValue, _value) < 0,
            _ => false
        };
    }
}

// 规则集
public class RuleSet
{
    private readonly List<ConditionExpression> _conditions = new();
  
    public void AddCondition(ConditionExpression condition) => _conditions.Add(condition);
  
    public bool Evaluate(BusinessContext context)
    {
        return _conditions.All(c => c.Interpret(context));
    }
}

// 使用
var context = new BusinessContext();
context.Data["Age"] = 25;
context.Data["Salary"] = 50000;
context.Data["IsEmployed"] = true;

var rule = new RuleSet();
rule.AddCondition(new ConditionExpression("Age", ">", 18));
rule.AddCondition(new ConditionExpression("Salary", ">", 40000));
rule.AddCondition(new ConditionExpression("IsEmployed", "==", true));

bool eligible = rule.Evaluate(context); // true

五、解释器模式的进阶话题

1. 语法树构建

通常需要配合解析器将输入文本转换为抽象语法树(AST):

public class Parser
{
    public IExpression Parse(string input)
    {
        // 简单实现 - 实际需要更复杂的词法/语法分析
        if (input.Contains("AND"))
        {
            var parts = input.Split(new[] {" AND "}, StringSplitOptions.None);
            return new AndExpression(Parse(parts[0]), Parse(parts[1]));
        }
        else if (input.Contains("OR"))
        {
            var parts = input.Split(new[] {" OR "}, StringSplitOptions.None);
            return new OrExpression(Parse(parts[0]), Parse(parts[1]));
        }
        else
        {
            return new VariableExpression(input.Trim());
        }
    }
}

// 使用
var parser = new Parser();
var expression = parser.Parse("A AND B OR C");

2. 使用访问者模式遍历语法树

public interface IExpressionVisitor
{
    void Visit(VariableExpression exp);
    void Visit(AndExpression exp);
    void Visit(OrExpression exp);
}

public class PrintVisitor : IExpressionVisitor
{
    public void Visit(VariableExpression exp) => Console.Write(exp.Name);
  
    public void Visit(AndExpression exp)
    {
        Console.Write("(");
        exp.Left.Accept(this);
        Console.Write(" AND ");
        exp.Right.Accept(this);
        Console.Write(")");
    }
  
    public void Visit(OrExpression exp)
    {
        Console.Write("(");
        exp.Left.Accept(this);
        Console.Write(" OR ");
        exp.Right.Accept(this);
        Console.Write(")");
    }
}

// 在表达式接口中添加Accept方法
public interface IExpression
{
    bool Interpret(Context context);
    void Accept(IExpressionVisitor visitor);
}

3. 解释器模式与编译器技术的区别

特性解释器模式编译器
执行方式直接执行语法树生成中间代码/机器码
效率较低(每次解释)较高(预先编译)
灵活性高(可动态修改)低(编译后固定)
实现复杂度相对简单复杂
适用场景简单DSL、动态需求通用编程语言

六、解释器模式的最佳实践

控制文法复杂度

共享终结符

分离解析与解释

考虑性能优化

合理使用组合

七、解释器模式与其他模式的关系

与组合模式

与访问者模式

与享元模式

与策略模式

八、现代替代方案

对于复杂语言处理,现代开发中更常用:

解析器生成器

表达式树

脚本引擎

总结一下:

解释器模式在C#中适用于:

关键优势

✅ 易于实现简单语言的解释执行

✅ 灵活扩展语法规则

✅ 分离语法定义与执行

适用限制

❌ 不适合复杂文法(类爆炸问题)

❌ 性能不如编译执行

❌ 维护成本随文法复杂度增加

在实际开发中,应权衡需求复杂度,对于简单DSL可以使用解释器模式快速实现,对于复杂语言处理建议使用专业解析工具。

九、在Uniry中的应用

示例1:简单数学表达式解释器

using UnityEngine;
using System.Collections.Generic;

// 抽象表达式
public abstract class Expression
{
    public abstract int Interpret(Dictionary<string, int> context);
}

// 终结符表达式 - 变量
public class VariableExpression : Expression
{
    private string name;
  
    public VariableExpression(string name)
    {
        this.name = name;
    }
  
    public override int Interpret(Dictionary<string, int> context)
    {
        // 从上下文中获取变量值
        if (context.ContainsKey(name))
        {
            return context[name];
        }
        throw new System.Exception($"变量 {name} 未定义");
    }
}

// 终结符表达式 - 常量
public class ConstantExpression : Expression
{
    private int value;
  
    public ConstantExpression(int value)
    {
        this.value = value;
    }
  
    public override int Interpret(Dictionary<string, int> context)
    {
        return value;
    }
}

// 非终结符表达式 - 加法
public class AddExpression : Expression
{
    private Expression left;
    private Expression right;
  
    public AddExpression(Expression left, Expression right)
    {
        this.left = left;
        this.right = right;
    }
  
    public override int Interpret(Dictionary<string, int> context)
    {
        return left.Interpret(context) + right.Interpret(context);
    }
}

// 非终结符表达式 - 减法
public class SubtractExpression : Expression
{
    private Expression left;
    private Expression right;
  
    public SubtractExpression(Expression left, Expression right)
    {
        this.left = left;
        this.right = right;
    }
  
    public override int Interpret(Dictionary<string, int> context)
    {
        return left.Interpret(context) - right.Interpret(context);
    }
}

// 非终结符表达式 - 乘法
public class MultiplyExpression : Expression
{
    private Expression left;
    private Expression right;
  
    public MultiplyExpression(Expression left, Expression right)
    {
        this.left = left;
        this.right = right;
    }
  
    public override int Interpret(Dictionary<string, int> context)
    {
        return left.Interpret(context) * right.Interpret(context);
    }
}

// 表达式解析器
public class ExpressionParser
{
    private Dictionary<string, int> variables = new Dictionary<string, int>();
  
    // 解析表达式字符串
    public Expression Parse(string expression)
    {
        // 这里简化处理,实际应用中需要更复杂的解析逻辑
        if (expression.Contains("+"))
        {
            string[] parts = expression.Split('+');
            return new AddExpression(Parse(parts[0]), Parse(parts[1]));
        }
        else if (expression.Contains("-"))
        {
            string[] parts = expression.Split('-');
            return new SubtractExpression(Parse(parts[0]), Parse(parts[1]));
        }
        else if (expression.Contains("*"))
        {
            string[] parts = expression.Split('*');
            return new MultiplyExpression(Parse(parts[0]), Parse(parts[1]));
        }
        else if (int.TryParse(expression, out int value))
        {
            return new ConstantExpression(value);
        }
        else
        {
            return new VariableExpression(expression);
        }
    }
  
    // 设置变量值
    public void SetVariable(string name, int value)
    {
        variables[name] = value;
    }
  
    // 获取当前变量表
    public Dictionary<string, int> GetContext()
    {
        return variables;
    }
}

// 测试代码
public class MathInterpreterTest : MonoBehaviour
{
    void Start()
    {
        ExpressionParser parser = new ExpressionParser();
  
        // 设置变量
        parser.SetVariable("x", 10);
        parser.SetVariable("y", 5);
  
        // 解析并计算表达式
        TestExpression(parser, "x+y");       // 10 + 5 = 15
        TestExpression(parser, "x-y");       // 10 - 5 = 5
        TestExpression(parser, "x*y");       // 10 * 5 = 50
        TestExpression(parser, "x+y*2");     // 10 + (5 * 2) = 20
    }
  
    void TestExpression(ExpressionParser parser, string expression)
    {
        Expression exp = parser.Parse(expression);
        int result = exp.Interpret(parser.GetContext());
        Debug.Log($"{expression} = {result}");
    }
}

示例2:简单AI行为脚本解释器

using UnityEngine;
using System.Collections.Generic;

// 抽象行为表达式
public abstract class AIActionExpression
{
    public abstract void Interpret(AIContext context);
}

// 移动行为
public class MoveAction : AIActionExpression
{
    private string direction;
    private float distance;
  
    public MoveAction(string direction, float distance)
    {
        this.direction = direction.ToLower();
        this.distance = distance;
    }
  
    public override void Interpret(AIContext context)
    {
        Vector3 moveVector = Vector3.zero;
  
        switch (direction)
        {
            case "forward":
                moveVector = context.AITransform.forward * distance;
                break;
            case "back":
                moveVector = -context.AITransform.forward * distance;
                break;
            case "left":
                moveVector = -context.AITransform.right * distance;
                break;
            case "right":
                moveVector = context.AITransform.right * distance;
                break;
            case "up":
                moveVector = context.AITransform.up * distance;
                break;
            case "down":
                moveVector = -context.AITransform.up * distance;
                break;
        }
  
        context.AITransform.position += moveVector;
        Debug.Log($"AI移动: {direction} {distance}米");
    }
}

// 等待行为
public class WaitAction : AIActionExpression
{
    private float seconds;
  
    public WaitAction(float seconds)
    {
        this.seconds = seconds;
    }
  
    public override void Interpret(AIContext context)
    {
        Debug.Log($"AI等待: {seconds}秒");
        // 实际游戏中可以使用协程实现等待
    }
}

// 攻击行为
public class AttackAction : AIActionExpression
{
    private string target;
  
    public AttackAction(string target)
    {
        this.target = target;
    }
  
    public override void Interpret(AIContext context)
    {
        Debug.Log($"AI攻击: {target}");
        // 实际游戏中这里会实现攻击逻辑
    }
}

// AI行为序列
public class ActionSequence : AIActionExpression
{
    private List<AIActionExpression> actions = new List<AIActionExpression>();
  
    public void AddAction(AIActionExpression action)
    {
        actions.Add(action);
    }
  
    public override void Interpret(AIContext context)
    {
        foreach (var action in actions)
        {
            action.Interpret(context);
        }
    }
}

// AI上下文
public class AIContext
{
    public Transform AITransform { get; set; }
    public Dictionary<string, object> Variables { get; } = new Dictionary<string, object>();
}

// AI脚本解析器
public class AIScriptParser
{
    public AIActionExpression Parse(string script)
    {
        ActionSequence sequence = new ActionSequence();
  
        // 分割脚本为多行
        string[] lines = script.Split(new[] { '\n', ';' }, System.StringSplitOptions.RemoveEmptyEntries);
  
        foreach (string line in lines)
        {
            string trimmedLine = line.Trim();
            if (string.IsNullOrEmpty(trimmedLine)) continue;
      
            // 分割命令和参数
            string[] parts = trimmedLine.Split(new[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 0) continue;
      
            string command = parts[0].ToLower();
      
            switch (command)
            {
                case "move":
                    if (parts.Length >= 3)
                    {
                        string direction = parts[1];
                        if (float.TryParse(parts[2], out float distance))
                        {
                            sequence.AddAction(new MoveAction(direction, distance));
                        }
                    }
                    break;
          
                case "wait":
                    if (parts.Length >= 2 && float.TryParse(parts[1], out float seconds))
                    {
                        sequence.AddAction(new WaitAction(seconds));
                    }
                    break;
          
                case "attack":
                    if (parts.Length >= 2)
                    {
                        sequence.AddAction(new AttackAction(parts[1]));
                    }
                    break;
            }
        }
  
        return sequence;
    }
}

// AI控制器
public class AIController : MonoBehaviour
{
    public string aiScript = @"
        move forward 5
        wait 2
        attack player
        move back 3
        wait 1
    ";
  
    private AIContext context;
    private AIActionExpression behavior;
  
    void Start()
    {
        context = new AIContext { AITransform = transform };
  
        AIScriptParser parser = new AIScriptParser();
        behavior = parser.Parse(aiScript);
  
        // 执行AI脚本
        behavior.Interpret(context);
    }
}

示例3:对话条件解释器

using UnityEngine;
using System.Collections.Generic;

// 抽象条件表达式
public abstract class ConditionExpression
{
    public abstract bool Interpret(DialogueContext context);
}

// 变量条件
public class VariableCondition : ConditionExpression
{
    private string variableName;
    private int expectedValue;
    private string comparison; // "==", ">", "<", etc.
  
    public VariableCondition(string variableName, string comparison, int expectedValue)
    {
        this.variableName = variableName;
        this.comparison = comparison;
        this.expectedValue = expectedValue;
    }
  
    public override bool Interpret(DialogueContext context)
    {
        if (!context.Variables.ContainsKey(variableName))
        {
            Debug.LogWarning($"变量 {variableName} 未定义");
            return false;
        }
  
        int actualValue = context.Variables[variableName];
  
        switch (comparison)
        {
            case "==": return actualValue == expectedValue;
            case "!=": return actualValue != expectedValue;
            case ">": return actualValue > expectedValue;
            case "<": return actualValue < expectedValue;
            case ">=": return actualValue >= expectedValue;
            case "<=": return actualValue <= expectedValue;
            default:
                Debug.LogWarning($"未知比较运算符: {comparison}");
                return false;
        }
    }
}

// 逻辑与条件
public class AndCondition : ConditionExpression
{
    private ConditionExpression left;
    private ConditionExpression right;
  
    public AndCondition(ConditionExpression left, ConditionExpression right)
    {
        this.left = left;
        this.right = right;
    }
  
    public override bool Interpret(DialogueContext context)
    {
        return left.Interpret(context) && right.Interpret(context);
    }
}

// 逻辑或条件
public class OrCondition : ConditionExpression
{
    private ConditionExpression left;
    private ConditionExpression right;
  
    public OrCondition(ConditionExpression left, ConditionExpression right)
    {
        this.left = left;
        this.right = right;
    }
  
    public override bool Interpret(DialogueContext context)
    {
        return left.Interpret(context) || right.Interpret(context);
    }
}

// 非条件
public class NotCondition : ConditionExpression
{
    private ConditionExpression condition;
  
    public NotCondition(ConditionExpression condition)
    {
        this.condition = condition;
    }
  
    public override bool Interpret(DialogueContext context)
    {
        return !condition.Interpret(context);
    }
}

// 对话上下文
public class DialogueContext
{
    public Dictionary<string, int> Variables { get; } = new Dictionary<string, int>();
}

// 条件解析器
public class ConditionParser
{
    public ConditionExpression Parse(string conditionStr)
    {
        // 这里简化处理,实际应用中需要更复杂的解析逻辑
        if (conditionStr.Contains("&&"))
        {
            string[] parts = conditionStr.Split(new[] { "&&" }, System.StringSplitOptions.RemoveEmptyEntries);
            return new AndCondition(Parse(parts[0]), Parse(parts[1]));
        }
        else if (conditionStr.Contains("||"))
        {
            string[] parts = conditionStr.Split(new[] { "||" }, System.StringSplitOptions.RemoveEmptyEntries);
            return new OrCondition(Parse(parts[0]), Parse(parts[1]));
        }
        else if (conditionStr.StartsWith("!"))
        {
            return new NotCondition(Parse(conditionStr.Substring(1)));
        }
        else
        {
            // 解析变量条件 如: "health > 50"
            string[] parts = conditionStr.Split(new[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 3)
            {
                string varName = parts[0];
                string op = parts[1];
                if (int.TryParse(parts[2], out int value))
                {
                    return new VariableCondition(varName, op, value);
                }
            }
        }
  
        throw new System.Exception($"无法解析条件: {conditionStr}");
    }
}

// 对话选项
public class DialogueOption
{
    public string Text { get; }
    public ConditionExpression Condition { get; }
  
    public DialogueOption(string text, ConditionExpression condition = null)
    {
        Text = text;
        Condition = condition;
    }
  
    public bool IsAvailable(DialogueContext context)
    {
        return Condition == null || Condition.Interpret(context);
    }
}

// 测试代码
public class DialogueConditionTest : MonoBehaviour
{
    void Start()
    {
        DialogueContext context = new DialogueContext();
        context.Variables["health"] = 75;
        context.Variables["hasKey"] = 1;
        context.Variables["karma"] = -10;
  
        ConditionParser parser = new ConditionParser();
  
        TestCondition(parser, context, "health > 50");  // true
        TestCondition(parser, context, "hasKey == 1"); // true
        TestCondition(parser, context, "karma >= 0");   // false
        TestCondition(parser, context, "health > 50 && hasKey == 1"); // true
        TestCondition(parser, context, "health > 50 || karma >= 0");  // true
        TestCondition(parser, context, "!hasKey == 1"); // false
  
        // 创建对话选项
        DialogueOption option1 = new DialogueOption("攻击敌人", parser.Parse("health > 50"));
        DialogueOption option2 = new DialogueOption("和平解决", parser.Parse("karma >= 0"));
        DialogueOption option3 = new DialogueOption("逃跑", null); // 无条件
  
        Debug.Log($"选项1可用: {option1.IsAvailable(context)}"); // true
        Debug.Log($"选项2可用: {option2.IsAvailable(context)}"); // false
        Debug.Log($"选项3可用: {option3.IsAvailable(context)}"); // true
    }
  
    void TestCondition(ConditionParser parser, DialogueContext context, string conditionStr)
    {
        ConditionExpression condition = parser.Parse(conditionStr);
        bool result = condition.Interpret(context);
        Debug.Log($"{conditionStr} = {result}");
    }
}

在Unity中的实现建议

  1. 结合ScriptableObject:可以将表达式配置为ScriptableObject,便于在编辑器中设置
  2. 使用解析器生成器:对于复杂文法,考虑使用ANTLR等解析器生成器
  3. 限制文法复杂度:保持解释的语言简单,避免过度设计
  4. 缓存解析结果:对于频繁使用的表达式,可以缓存解析结果提高性能
  5. 与事件系统结合:将解释结果转换为游戏事件,降低耦合度

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文