Ir al contenido

GRAMÁTICA v2 — Motor de expresiones

La definición exacta de lo que se puede escribir en una expresión. Admite dos formas de escribir lo mismo —al estilo C# y al estilo Python—, y una expresión escrita con la versión anterior sigue valiendo tal cual. Si buscas ejemplos y no la definición, empieza por la guía rápida o el manual.

Principios

Tokens

TokenFormaEjemplo
Númerodígitos con . decimal opcional (sin separador miles)123, 0.5, 1234.56
String"..." o '...'; escapes \\ \" \' \n \t"IVA", '21%'
Fecha#yyyy-MM-dd#, #yyyy-MM-dd HH:mm#, #... HH:mm:ss##2026-06-10#
Booleanotrue, false
Nullnull o None (alias, v2)
Campo[Nombre Campo] (admite espacios y acentos)[Total Línea]
Identificadorletra o _ + letras/dígitos/_PageNumber, tipoIva
AgregadoAGG(identificador) — forma especial, compat reportsAGG(totalVentas)

Gramática (EBNF) — Nivel 1

expresion      := condicional
condicional    := coalesce ( '?' expresion ':' expresion
                           | 'if' coalesce 'else' condicional )?   // forma Python (v2)
coalesce       := logicaOr ('??' logicaOr)*
logicaOr       := logicaAnd (('||' | 'or') logicaAnd)*
logicaAnd      := igualdad (('&&' | 'and') igualdad)*
igualdad       := relacional (('==' | '!=' | '<>') relacional)*
relacional     := aditiva (('<' | '<=' | '>' | '>=') aditiva)*
aditiva        := multiplicativa (('+' | '-') multiplicativa)*
multiplicativa := unaria (('*' | '/' | '%') unaria)*
unaria         := ('-' | '!' | 'not') unaria | postfija
postfija       := primaria ('.' identificador argumentos?)*      // solo los miembros permitidos
primaria       := numero | cadena | fecha | 'true' | 'false' | 'null'
                | '[' nombreCampo ']'
                | 'AGG' '(' identificador ')'
                | identificador argumentos?                       // símbolo o función whitelist
                | '(' expresion ')'
argumentos     := '(' (expresion (',' expresion)*)? ')'

Tipos y conversiones

Tipos del lenguaje: Null, Boolean, Decimal, String, DateTime.

Semántica de null (lógica trivaluada, compatible MS SQL / PostgreSQL)

OperaciónResultado
null + 5, null * x, -nullnull (toda aritmética propaga)
"a" + nullnull (como +/`\\ en SQL; Concat` ignora null)
a == b con un null en runtimenull (desconocido)
x == null / x != null (literal)true/false — actúa como IS [NOT] NULL
true or nulltrue
false or nullnull
true and nullnull
false and nullfalse
not nullnull
Condición de ?: (o if) = nullse toma la rama de false (como WHERE en SQL)
null ?? xx (equivale a Coalesce(null, x))

Funciones whitelist v1

Nombres en inglés estilo SQL/C# (los que el usuario de SQL ya conoce); case-insensitive. Alias en español: posibles más adelante, no en v1.

Añadir una función = una entrada en el registro de funciones (nombre, aridad, tipos, pureza). Las funciones de nivel 1 son puras (sin efectos); Now/Today lo son por el reloj fijado.

Errores

Cuatro categorías, todas con posición (índice y extracto) y mensaje en español:

  1. Parse (ExpressionParseException): token inesperado/esperado. Incluye el caso = → «use ==».
  2. Binding (ExpressionBindException): símbolo o función desconocidos; sugerencia por
  3. Permisos (ExpressionPermissionException): símbolo de un área no accesible para el usuario.
  4. Runtime (ExpressionRuntimeException): división por cero, conversión fallida, tipo

Nivel 2 — Script

Reutiliza íntegra la gramática de expresión. Solo añade sentencias:

script      := sentencia+
sentencia   := declaracion | asignacion | si | mientras | porCada | devolver
             | bloque | expresion ';'
declaracion := 'var' identificador '=' expresion ';'
asignacion  := identificador '=' expresion ';'
si          := 'if' '(' expresion ')' sentencia ('else' sentencia)?
mientras    := 'while' '(' expresion ')' sentencia
porCada     := 'foreach' '(' 'var' identificador 'in' expresion ')' sentencia
devolver    := 'return' expresion? ';'
bloque      := '{' sentencia* '}'    // abre un scope hijo

Reglas (definitivas en v1):