Combinadores Sintácticos de Gram
Los combinadores sintácticos son las unidades fundamentales del parser de Gram (gram.core.combinators). Cada combinador hereda de Combinator y define cómo se consumen, repiten, bifurcan o transforman en nodos del Árbol de Sintaxis Abstracta (ASTNode) los tokens proporcionados por Parser.
Los combinadores se integran con:
- Puntos de Control (
parser.savepoint/parser.restore): Las ramas fallidas revierten el cursor de tokens (pos), el cursor virtual (vpos), la profundidad de delimitadores,parser.storage,parser.tk_tagsy las sustituciones en sitio (parser.replace_token_at). - Ámbitos de Fallo Aislados (
analyzer.failure_scope): Las exploraciones especulativas (Alt,Opt,Many,Some,Separator,Until,If,Not,Peek) aíslan los fallos candidatos para que las ramas descartadas no contaminen el diagnóstico final. - RayTracing (
analyzer.raytracing): Controlado medianteASTAnalyzer(..., trace="off" | "basic" | "detailed").
Categorías de Combinadores
| Categoría | Combinadores | Propósito |
|---|---|---|
| 01. Coincidencia | MatchToken, MatchKeyword, MatchGroup, MatchSeqSymbol, generador_expr |
Consumen un único token por tipo de Token, palabra clave, grupo léxico (WordGroup) o patrón regex. |
| 02. Estructurales | Seq, Alt, Opt, Enclosed |
Secuencias ordenadas (+), alternativas priorizadas (|), cláusulas opcionales ($0..1$) y bloques delimitados por paréntesis, corchetes o llaves. |
| 03. Repetición | Many, Some, Until, UntilIndent, Separator |
Bucles $0..n$ y $1..n$, escaneo de tokens hasta un combinador objetivo o nivel de indentación, y listas delimitadas (ArrayNode). |
| 04. Reglas y Almacenamiento | RuleItem, Ref, Item, Literal, Save, Load |
Reglas de producción declarativas, referencias a reglas (ASTRef), secuencias atómicas (ItemNode), literales primitivos (LiteralNode) y operaciones en parser.storage. |
| 05. Lookahead y Control | Peek, Not, If, Skip, Tag, Tokenize, ErrorCombinator |
Lookahead positivo/negativo de ancho cero, bifurcaciones condicionales, señales de control de flujo, etiquetado de tokens (parser.tk_tags), tokens compuestos y captura de errores. |
| 06. Validación Fluida | Req |
Validación encadenada y transformaciones en sitio sobre una copia del token antes de la delegación al AST. |
| 08. Preprocesamiento y expectativas | Preprocess, Convert, Expected |
Validaciones personalizadas, conversiones lógicas de identificadores y aserciones estrictas sobre el flujo. |
| 07. Expresiones Pratt | ArithmeticExpr, ConditionalExpr, DualExpr |
Análisis de expresiones Top-Down Operator Precedence (Pratt) para operadores prefijos unarios (ASTUnaryOp) e infijos binarios (ASTBinaryOp). |
Contrato de Ejecución Central
Cada combinador hereda de Combinator (gram.core.combinators.base.Combinator) e implementa el método parse:
def parse(self, analyzer: ASTAnalyzer) -> Any:
...
Convenciones de Retorno
- Nodo(s) Coincidentes: Avanza
parser.postras consumir los tokens y devuelve unASTNode, unalistde nodos o unTokenType. - Omisión Limpia (
[]): Devuelto porOpt(cuando no coincide en su posición inicial),Many(cuando coinciden 0 iteraciones),Peek,NotyEnclosed(..., allow_empty=True)vacío. Dentro deSeq, un resultado[]se considera un paso exitoso sin añadir una lista vacía a la salida deSeq. - Fallo (
None): Restaura elparseral punto de control del combinador y registra o prepara un error de diagnóstico.
Sobrecarga de Operadores en Combinator
comb_a + comb_bconstruye unSeq(comb_a, comb_b)aplanado.comb_a | comb_bconstruye unAlt(comb_a, comb_b)aplanado.
Modos de Traza (ASTAnalyzer(..., trace=...))
trace="off": DesactivaRayTracingy evita registrar callbacks enparser.hookr.trace="basic"(por defecto): Registra combinadores evaluados (ignore=False) y niveles de anidamiento enraytracing.trace, nombres de reglas enraytracing.pathsy ramas enraytracing.branches.trace="detailed": Registra adicionalmente instancias deTraceRecord(combinator,depth,start,end,outcome,exception_type) para cada combinador evaluado, y rastrea retrocesos enraytracing.backtracksyraytracing.furthest. Se formatea conraytracing.detailed().