feat(charka): charka-parser — COBOL'85 (subconjunto) a AST

Segunda etapa del transpilador: Vec<Token> -> Program. Alcance v1 = el
esqueleto del programa.

- parse(&[Token]) -> Result<Program, ParseError>. AST: Program
  (program_id, data, paragraphs), DataItem, Paragraph, Sentence.
- Particiona el flujo en las 4 divisions por sus encabezados; extrae el
  PROGRAM-ID de la IDENTIFICATION.
- DATA division -> árbol de DataItem: nivel, nombre, PICTURE
  reensamblado (S9 ( 5 ) V99 -> S9(5)V99) y VALUE. Anida por número de
  nivel (01/77 raíces, 88 cuelga del precedente).
- PROCEDURE division -> Vec<Paragraph> con Sentence de tokens crudos
  (sin parseo de statement). Sentencias previas al primer encabezado
  van a un párrafo implícito "".
- Tolerante: salta SECTION, FD/SD y cláusulas que no sean PIC/VALUE.
- 15 tests verdes; fmt + clippy limpios.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-21 20:04:00 +00:00
parent ab56b35e9f
commit d3cdbb2d2d
7 changed files with 773 additions and 7 deletions
+27 -7
View File
@@ -10,8 +10,9 @@ embebido, dialectos IBM Enterprise) es un esfuerzo multi-mes.
| crate | tipo | rol |
| -------------- | ---- | ------------------------------------------------------------ |
| `charka-bcd` | lib | Aritmética decimal de punto fijo con semántica COBOL: `Picture`, `Decimal`, redondeo, `ON SIZE ERROR` |
| `charka-lexer` | lib | Tokenizador COBOL: formato fijo (tarjeta de 80 columnas) y libre |
| `charka-bcd` | lib | Aritmética decimal de punto fijo con semántica COBOL: `Picture`, `Decimal`, redondeo, `ON SIZE ERROR` |
| `charka-lexer` | lib | Tokenizador COBOL: formato fijo (tarjeta de 80 columnas) y libre |
| `charka-parser` | lib | Parser COBOL'85 (subconjunto): tokens → AST (`Program`) |
## charka-bcd
@@ -43,16 +44,35 @@ Primera etapa del pipeline: texto COBOL → secuencia de `Token`.
- Limitación v1: sin continuación de literales entre líneas
(indicador `-`).
## charka-parser
Segunda etapa: tokens → AST. Alcance v1 — el **esqueleto del programa**.
- `parse(&[Token]) -> Result<Program, ParseError>`.
- `Program { program_id, data: Vec<DataItem>, paragraphs: Vec<Paragraph> }`.
- **DATA division** → árbol de `DataItem` (`level`, `name`, `picture`,
`value`, `children`). Reensambla la cláusula `PICTURE` desde sus
tokens (`S9` `(` `5` `)` `V99``S9(5)V99`); anida por número de
nivel (01 y 77 son raíces; 88 cuelga del ítem precedente).
- **PROCEDURE division** → `Vec<Paragraph>`, cada `Paragraph` con sus
`Sentence` (tokens crudos — sin parseo a nivel de statement). Las
sentencias previas al primer encabezado van a un párrafo implícito
de nombre "".
- Tolerante: salta encabezados de `SECTION`, entradas `FD`/`SD` y
cláusulas de datos que no sean `PICTURE`/`VALUE`. `ParseError` sólo
ante nivel inválido o dato sin nombre.
- Limitación v1: no parsea statements, ni la ENVIRONMENT division, ni
CICS / SQL embebido / dialectos IBM.
## Estado
`charka-bcd` (22 tests) y `charka-lexer` (17 tests) implementados y
verdes. **Pendiente** — el resto del transpilador (Fase D del plan
macro):
`charka-bcd` (22 tests), `charka-lexer` (17 tests) y `charka-parser`
(15 tests) implementados y verdes. **Pendiente** — el resto del
transpilador (Fase D del plan macro):
| crate pendiente | rol |
| ----------------- | ---------------------------------------------------- |
| `charka-parser` | parser COBOL'85 → AST (luego CICS + SQL embebido) |
| `charka-ir` | representación intermedia |
| `charka-ir` | representación intermedia (parseo de statements) |
| `charka-codegen` | emisión de Rust |
| `charka-shadow` | validador en sombra (original vs transpilado) |
| `charka-runtime` | runtime determinista (sobre `charka-bcd`) |