zxlovest 发表于 2023-10-31 08:28:15

期货量化:赫兹量化中递归下降解析器

在自动执行交易任务时,可能需要在其执行阶段提供计算算法的灵活性。 例如,当微调程序以闭合(编译)模式分布时,我们可以从众多可能的组合中选择目标函数类型。 特别是在优化智能交易系统或快速评估指标原型时,这很有用。 除了更改对话框中的参数之外,用户还可以更改计算公式。 在这种情况下,我们只需从其文本表达形式计算其数学表达式,而无需更改 MQL 程序代码。可以通过各种解析器来解决此任务,这些解析器可以即时解释公式,将其“编译”为语法树,生成所谓的字节码(计算指令序列),进而执行从而得出计算结果 。 在本文中,我们将研究几种类型的解析器和表达式计算方法。解析器基类(AbstractExpressionProcessor 模板)这是模板类,由于表达式分析结果不仅可以是标量值,而且还可以是描述表达式语法的节点树(特殊类的对象)。 稍后我们会研究如何完成此操作,以及这样做的目的是什么。首先,类对象存储表达式(_expression),其长度(_length),读取字符串(_index)时的当前光标位置,和当前符号(_token)。 它还预留了指示表达式中错误的变量(_failed),和数值比较精度(_precision)。template<typename T>class AbstractExpressionProcessor{    protected:      string _expression;      int _index;      int _length;      ushort _token;      bool _failed;      double _precision;提供了存储变量和链接的特殊表,但是稍后我们将研究相关的 VariableTable 和 FunctionTable 类。      VariableTable *_variableTable;      FunctionTable _functionTable;这些表是由 “key=value” 对组成的关键字=数值对,其中关键字是变量或函数名称的字符串,而数值则是 double(对于变量),或 functor 对象(对于表) 。变量表由引用描述,因为表达式不能包含变量。 对于函数表,解析器始终含有最少的内置函数集合(用户可以扩展),这就是为什么此表由已有对象表示的原因。标准函数表是在方法中填充:      virtual void registerFunctions();下一章节介绍的函数执行的子任务通用于各种解析器,例如切换到下一个字符,对照期望值检查字符(如果不匹配则显示错误),顺序读取满足格式要求的数字, 以及一些用于字符分类的静态辅助方法。      bool _nextToken();      void _match(ushort c, string message, string context = NULL);      bool _readNumber(string &number);      virtual void error(string message, string context = NULL, const bool warning = false);            static bool isspace(ushort c);      static bool isalpha(ushort c);      static bool isalnum(ushort c);      static bool isdigit(ushort c);所有这些函数都在基类中定义,尤其是:template<typename T>bool AbstractExpressionProcessor::_nextToken(){    _index++;    while(_index < _length && isspace(_expression)) _index++;    if(_index < _length)    {      _token = _expression;      return true;    }    else    {      _token = 0;    }    return false;}    template<typename T>void AbstractExpressionProcessor::_match(ushort c, string message, string context = NULL){    if(_token == c)    {      _nextToken();    }    else if(!_failed) // prevent chained errors    {      error(message, context);    }}    template<typename T>bool AbstractExpressionProcessor::_readNumber(string &number){    bool point = false;    while(isdigit(_token) || _token == '.')    {      if(_token == '.' && point)      {      error("Too many floating points", __FUNCTION__);      return false;      }      number += ShortToString(_token);      if(_token == '.') point = true;      _nextToken();    }    return StringLen(number) > 0;}
页: [1]
查看完整版本: 期货量化:赫兹量化中递归下降解析器