2026-05-10 22:20:05 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Tokenizer.mqh |
|
|
|
|
|
//| Copyright 2026, Niquel Mendoza. |
|
|
|
|
|
//| https://www.mql5.com/es/users/nique_372 |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, Niquel Mendoza."
|
|
|
|
|
#property link "https://www.mql5.com/es/users/nique_372"
|
|
|
|
|
#property strict
|
|
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
#ifndef EXPRESSEVALBYLEO_SRC_BOOLEAN_EVAL_MQH
|
|
|
|
|
#define EXPRESSEVALBYLEO_SRC_BOOLEAN_EVAL_MQH
|
|
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "Defines.mqh"
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-05-13 16:29:52 -05:00
|
|
|
struct CBoleanOpsTokenizer : public CTokenizerBase
|
2026-05-10 22:20:05 -05:00
|
|
|
{
|
|
|
|
|
private:
|
2026-05-11 12:24:14 -05:00
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
ENUM_OPS_TOKENIZER_BOOLEAN_ERR m_last_err;
|
|
|
|
|
|
|
|
|
|
public:
|
2026-05-11 12:24:14 -05:00
|
|
|
CBoleanOpsTokenizer(void) : m_last_err(WRONG_VALUE) {}
|
2026-05-10 22:20:05 -05:00
|
|
|
~CBoleanOpsTokenizer(void) {}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-14 16:54:23 -05:00
|
|
|
bool Tokenize(const string& text, TokenOpsBoolean& tokns[]);
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
__forceinline ENUM_OPS_TOKENIZER_BOOLEAN_ERR LastError() const { return m_last_err; }
|
|
|
|
|
string FormatLastError(const string& text) const;
|
|
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
//---
|
|
|
|
|
static void PrintValues(const TokenOpsBoolean& tokens[]);
|
|
|
|
|
};
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-05-14 16:54:23 -05:00
|
|
|
bool CBoleanOpsTokenizer::Tokenize(const string &text, TokenOpsBoolean& tokns[])
|
2026-05-10 22:20:05 -05:00
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
m_len = StringLen(text);
|
|
|
|
|
m_pos = 0;
|
|
|
|
|
m_err_pos = 0;
|
|
|
|
|
m_last_err = WRONG_VALUE;
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-14 16:54:23 -05:00
|
|
|
int reserve_size = 16;
|
|
|
|
|
ArrayResize(tokns, reserve_size);
|
2026-05-10 22:20:05 -05:00
|
|
|
int current_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
while(m_pos < m_len)
|
|
|
|
|
{
|
|
|
|
|
//--- Saltamos espacios
|
|
|
|
|
if(text[m_pos] < 33)
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(text[m_pos])
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
//--- No es igual
|
2026-05-11 06:59:45 -05:00
|
|
|
case '!':
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
if(m_pos < m_len && text[m_pos] == '=')
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_OPERADOR_BOLEANO | int(BOOLEAN_OP_TYPE_NO_IGUAL) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-11 06:59:45 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_last_err = OPS_TOKENIZER_BOOLEAN_ERR_OP_NO_IGUAL_MAL_FORMADO;
|
|
|
|
|
m_err_pos = m_pos - 1; // inicio previo
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-11 06:59:45 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
//--- String
|
|
|
|
|
case '"':
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_STRING;
|
|
|
|
|
if(!CGenericParser::UnescapeString(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size]))
|
2026-05-10 22:20:05 -05:00
|
|
|
return false;
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- LLmada a funcion custom
|
2026-05-11 12:24:14 -05:00
|
|
|
case '#':
|
2026-05-10 22:20:05 -05:00
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_CUSTOM_FUNCTION_CALL;
|
2026-05-11 10:55:50 -05:00
|
|
|
if(!CGenericParser::ParseFunction(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size]))
|
2026-05-10 22:20:05 -05:00
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
return false;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-12 15:55:49 -05:00
|
|
|
//--- Uso de varible
|
|
|
|
|
case '$':
|
|
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_VARIABLE;
|
|
|
|
|
CGenericParser::ParseVariable(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size]);
|
|
|
|
|
AST_OPS_CHECK_RESIZE
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break; // Salimos
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
//--- Inicio de paraenteisis
|
|
|
|
|
case '(':
|
|
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_PARA_INI;
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Final de parentenisis
|
|
|
|
|
case ')':
|
|
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_PARA_END;
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 10:55:50 -05:00
|
|
|
// Numero negativo
|
2026-05-10 22:20:05 -05:00
|
|
|
case '-':
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_NUMBER;
|
|
|
|
|
if(!CGenericParser::ParseNumberNoHex(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size], m_pos++))
|
2026-05-10 22:20:05 -05:00
|
|
|
return false;
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Menor (o menor igual que)
|
|
|
|
|
case '<':
|
|
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_OPERADOR_BOLEANO;
|
|
|
|
|
if(m_pos + 1 < m_len && text[m_pos + 1] == '=')
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type |= int(BOOLEAN_OP_TYPE_MENOR_IGUAL) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type |= int(BOOLEAN_OP_TYPE_MENOR) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Igualdad
|
|
|
|
|
case '=':
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
if(m_pos < m_len && text[m_pos] == '=')
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_OPERADOR_BOLEANO | int(BOOLEAN_OP_TYPE_IGUAL) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_last_err = OPS_TOKENIZER_BOOLEAN_ERR_OP_IGUAL_MAL_FORMADO;
|
|
|
|
|
m_err_pos = m_pos - 1; // inicio previo
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Mayor (o mayor igual que)
|
|
|
|
|
case '>':
|
|
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_OPERADOR_BOLEANO;
|
|
|
|
|
if(m_pos + 1 < m_len && text[m_pos + 1] == '=')
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type |= int(BOOLEAN_OP_TYPE_MAYOR_IGUAL) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type |= int(BOOLEAN_OP_TYPE_MAYOR) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- LLamada a funcion build-in
|
|
|
|
|
case '@':
|
|
|
|
|
{
|
2026-05-12 22:31:44 -05:00
|
|
|
// Dentro de las funciones BUILD-IN
|
|
|
|
|
// Estaran todas las de Math* String*
|
|
|
|
|
// Aparte de @sop y @mop que signfica "string operations" y "math operations (Tokenizer math)" ejemplo:
|
|
|
|
|
// @mop(10 * 20 * 30 * ($val & 20))
|
|
|
|
|
// @sop(10 * "ab")
|
2026-05-10 22:20:05 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_BUILD_IN_FUNCTION_CALL;
|
2026-05-11 10:55:50 -05:00
|
|
|
if(!CGenericParser::ParseFunction(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size]))
|
2026-05-10 22:20:05 -05:00
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
return false;
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case 'R':
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_STRING;
|
|
|
|
|
if(!CGenericParser::ParseRawString(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size]))
|
2026-05-11 11:46:04 -05:00
|
|
|
{
|
2026-05-10 22:20:05 -05:00
|
|
|
return false;
|
2026-05-11 11:46:04 -05:00
|
|
|
}
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-11 06:59:45 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case 't':
|
|
|
|
|
{
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_BOOLEAN | int(1) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-11 06:59:45 -05:00
|
|
|
//---
|
|
|
|
|
while(text[m_pos] != ' ' && m_pos < m_len)
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
}
|
|
|
|
|
/// Ahora mismo estamos en el espacio... siguiente caracter es el valido
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case 'f':
|
|
|
|
|
{
|
|
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_BOOLEAN;
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-11 06:59:45 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
while(text[m_pos] != ' ' && m_pos < m_len)
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
}
|
|
|
|
|
/// Ahora mismo estamos en el espacio... siguiente caracter es el valido
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
//---
|
|
|
|
|
case 'o':
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
|
|
|
|
|
//--- Obtenemos el operador
|
|
|
|
|
ENUM_AST_LOGIC_OPERATOR op_type = AST_LOGIC_OPERATOR_OR;
|
|
|
|
|
const ushort op = text[m_pos];
|
|
|
|
|
if(op == 'X') // Xor | Xnor
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(m_pos + 1 >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = OPS_TOKENIZER_BOOLEAN_ERR_OP_LOGICO_X_MAL_FORMADO;
|
|
|
|
|
m_err_pos = m_pos - 1;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
op_type = text[m_pos + 1] == 'o' ? AST_LOGIC_OPERATOR_XOR : AST_LOGIC_OPERATOR_XNOR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if(op == 'A') // And
|
|
|
|
|
op_type = AST_LOGIC_OPERATOR_AND;
|
|
|
|
|
else
|
|
|
|
|
if(op == 'N') // Nand | Nor
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(m_pos + 1 >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = OPS_TOKENIZER_BOOLEAN_ERR_OP_LOGICO_N_MAL_FORMADO;
|
|
|
|
|
m_err_pos = m_pos - 1;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
op_type = text[m_pos + 1] == 'a' ? AST_LOGIC_OPERATOR_NAND : AST_LOGIC_OPERATOR_NOR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_pos += g_arr_ast_logic_op_len_for_parser[op_type];
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 10:55:50 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_OPERADOR_LOGICO | int(op_type) << AST_LOGIC_EXTRA_TYPE_START_BIT;
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
if(IsDigit(text[m_pos]))
|
|
|
|
|
{
|
2026-05-11 12:24:14 -05:00
|
|
|
tokns[current_size].type = BOOLEAN_OPS_TOKEN_TYPE_VALUE_NUMBER;
|
2026-05-11 10:55:50 -05:00
|
|
|
if(!CGenericParser::ParseNumber(text, m_len, m_pos, (int&)m_last_err, m_err_pos, tokns[current_size]))
|
2026-05-10 22:20:05 -05:00
|
|
|
return false;
|
|
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
AST_OPS_CHECK_RESIZE
|
2026-05-10 22:20:05 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_last_err = OPS_TOKENIZER_BOOLEAN_ERR_CARACTER_INVALIDO;
|
|
|
|
|
m_err_pos = m_pos;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Siguiente
|
|
|
|
|
m_pos++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
ArrayResize(tokns, current_size);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
string CBoleanOpsTokenizer::FormatLastError(const string& text) const
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(m_last_err == WRONG_VALUE)
|
|
|
|
|
{
|
|
|
|
|
return "Not errors found";
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
//---
|
2026-05-11 11:46:04 -05:00
|
|
|
|
|
|
|
|
const uint r_err = m_last_err & 0xFFFFFF;
|
2026-05-11 12:24:14 -05:00
|
|
|
//Print(m_last_err, " & 0xFFFFFF = ", r_err);
|
2026-05-11 10:55:50 -05:00
|
|
|
const int type = m_last_err >> AST_LOGIC_ERR_TYPE_START_BIT;
|
|
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
//---
|
|
|
|
|
int line = 0, col = 0;
|
2026-05-11 11:46:04 -05:00
|
|
|
GetCharPosLocation(m_err_pos, text, col, line);
|
2026-05-10 22:20:05 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
string error_msg = "";
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 12:24:14 -05:00
|
|
|
// Print(type, " | ", r_err);
|
2026-05-11 10:55:50 -05:00
|
|
|
if(type == AST_LOGIC_ERR_TYPE_EXTERNAL)
|
2026-05-10 22:20:05 -05:00
|
|
|
{
|
2026-05-11 11:46:04 -05:00
|
|
|
CGenericParser::FormatErr(r_err, error_msg);
|
2026-05-11 10:55:50 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-05-11 11:46:04 -05:00
|
|
|
switch(r_err)
|
2026-05-11 10:55:50 -05:00
|
|
|
{
|
|
|
|
|
case OPS_TOKENIZER_BOOLEAN_ERR_OP_IGUAL_MAL_FORMADO:
|
|
|
|
|
error_msg = "Malformed equality operator, expected '=='";
|
|
|
|
|
break;
|
2026-05-10 22:20:05 -05:00
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
case OPS_TOKENIZER_BOOLEAN_ERR_OP_LOGICO_X_MAL_FORMADO:
|
|
|
|
|
error_msg = "Malformed logical operator 'oXor', expected 'oXor'";
|
|
|
|
|
break;
|
2026-05-10 22:20:05 -05:00
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
case OPS_TOKENIZER_BOOLEAN_ERR_OP_LOGICO_N_MAL_FORMADO:
|
|
|
|
|
error_msg = "Malformed logical operator starting with 'o', expected 'oAnd', 'oOr', 'oXor', or 'oNand'";
|
|
|
|
|
break;
|
2026-05-10 22:20:05 -05:00
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
case OPS_TOKENIZER_BOOLEAN_ERR_CARACTER_INVALIDO:
|
|
|
|
|
error_msg = "Invalid character in expression";
|
|
|
|
|
break;
|
2026-05-10 22:20:05 -05:00
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
case OPS_TOKENIZER_BOOLEAN_ERR_OP_NO_IGUAL_MAL_FORMADO:
|
|
|
|
|
error_msg = "Malformed equality operator, expected '!='";
|
|
|
|
|
break;
|
2026-05-11 06:59:45 -05:00
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
default:
|
|
|
|
|
error_msg = "Unknown error";
|
|
|
|
|
break;
|
|
|
|
|
}
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-05-11 11:46:04 -05:00
|
|
|
return error_msg + StringFormat(" [Line %d, Col %d]", line, col);
|
2026-05-10 22:20:05 -05:00
|
|
|
}
|
|
|
|
|
|
2026-05-11 10:55:50 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
static void CBoleanOpsTokenizer::PrintValues(const TokenOpsBoolean &tokens[])
|
|
|
|
|
{
|
|
|
|
|
const int t = ArraySize(tokens);
|
|
|
|
|
Print(" TYPE | VALUE");
|
|
|
|
|
for(int i = 0; i < t; i++)
|
|
|
|
|
{
|
|
|
|
|
const int v = tokens[i].type & 0xFFFF;
|
2026-05-14 16:54:23 -05:00
|
|
|
PrintFormat("%s | %s", EnumToString(ENUM_AST_BOOLEAN_OPS_TOKEN_TYPE(v)), tokens[i].vs);
|
2026-05-11 10:55:50 -05:00
|
|
|
}
|
|
|
|
|
}
|
2026-05-11 12:24:14 -05:00
|
|
|
|
2026-05-10 22:20:05 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-05-11 10:55:50 -05:00
|
|
|
#endif // EXPRESSEVALBYLEO_SRC_BOOLEAN_EVAL_MQH
|