@miguelduran14/knowflow 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +182 -0
- package/dist/advisories.d.ts +16 -0
- package/dist/advisories.js +364 -0
- package/dist/advisories.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +104 -0
- package/dist/cli.js.map +1 -0
- package/dist/copy-resolver.d.ts +22 -0
- package/dist/copy-resolver.js +74 -0
- package/dist/copy-resolver.js.map +1 -0
- package/dist/dataflow.d.ts +2 -0
- package/dist/dataflow.js +88 -0
- package/dist/dataflow.js.map +1 -0
- package/dist/dossier.d.ts +20 -0
- package/dist/dossier.js +331 -0
- package/dist/dossier.js.map +1 -0
- package/dist/explain/claude.d.ts +14 -0
- package/dist/explain/claude.js +91 -0
- package/dist/explain/claude.js.map +1 -0
- package/dist/explain/explain.d.ts +72 -0
- package/dist/explain/explain.js +126 -0
- package/dist/explain/explain.js.map +1 -0
- package/dist/explain/facts.d.ts +23 -0
- package/dist/explain/facts.js +266 -0
- package/dist/explain/facts.js.map +1 -0
- package/dist/explain/fake.d.ts +14 -0
- package/dist/explain/fake.js +27 -0
- package/dist/explain/fake.js.map +1 -0
- package/dist/explain/openai.d.ts +42 -0
- package/dist/explain/openai.js +102 -0
- package/dist/explain/openai.js.map +1 -0
- package/dist/explain/provider.d.ts +19 -0
- package/dist/explain/provider.js +2 -0
- package/dist/explain/provider.js.map +1 -0
- package/dist/explain/sse.d.ts +10 -0
- package/dist/explain/sse.js +44 -0
- package/dist/explain/sse.js.map +1 -0
- package/dist/flow-parser.d.ts +10 -0
- package/dist/flow-parser.js +503 -0
- package/dist/flow-parser.js.map +1 -0
- package/dist/glossary.d.ts +54 -0
- package/dist/glossary.js +340 -0
- package/dist/glossary.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +7 -0
- package/dist/inventory.js +453 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lines.d.ts +15 -0
- package/dist/lines.js +53 -0
- package/dist/lines.js.map +1 -0
- package/dist/linker.d.ts +17 -0
- package/dist/linker.js +56 -0
- package/dist/linker.js.map +1 -0
- package/dist/mermaid.d.ts +27 -0
- package/dist/mermaid.js +133 -0
- package/dist/mermaid.js.map +1 -0
- package/dist/parser.d.ts +19 -0
- package/dist/parser.js +442 -0
- package/dist/parser.js.map +1 -0
- package/dist/pic.d.ts +29 -0
- package/dist/pic.js +197 -0
- package/dist/pic.js.map +1 -0
- package/dist/references.d.ts +24 -0
- package/dist/references.js +906 -0
- package/dist/references.js.map +1 -0
- package/dist/source-lines.d.ts +56 -0
- package/dist/source-lines.js +114 -0
- package/dist/source-lines.js.map +1 -0
- package/dist/types.d.ts +499 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/gui/dist/assets/ChainCanvas-C37KyhnE.js +1 -0
- package/gui/dist/assets/FlowCanvas-BRklWBCp.js +3 -0
- package/gui/dist/assets/RobotProfessor-BtTDTBDq.js +4220 -0
- package/gui/dist/assets/fira-code-cyrillic-400-normal-UC0NFL4U.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-400-normal-dc1q3VD7.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-500-normal-Bu7VCL72.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-500-normal-CX35h3Mg.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-600-normal-BD56RyRT.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-600-normal-CPRdbepc.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-400-normal-Buh61xzB.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-400-normal-txZ9Fk_1.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-500-normal-CYRspHgm.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-500-normal-CwtLmSFD.woff +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-600-normal-B9wE0zmr.woff2 +0 -0
- package/gui/dist/assets/fira-code-cyrillic-ext-600-normal-DldcyWhZ.woff +0 -0
- package/gui/dist/assets/fira-code-greek-400-normal-B2Gh_Y8s.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-400-normal-DobhaxvF.woff +0 -0
- package/gui/dist/assets/fira-code-greek-500-normal-CVO0IRNt.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-500-normal-DEXIWiey.woff +0 -0
- package/gui/dist/assets/fira-code-greek-600-normal-D_h3X2X5.woff +0 -0
- package/gui/dist/assets/fira-code-greek-600-normal-Dxp52_By.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-ext-400-normal-DR7mBgIM.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-ext-400-normal-DSPUheWg.woff +0 -0
- package/gui/dist/assets/fira-code-greek-ext-500-normal-BO3iq16n.woff2 +0 -0
- package/gui/dist/assets/fira-code-greek-ext-500-normal-CMiNLXER.woff +0 -0
- package/gui/dist/assets/fira-code-greek-ext-600-normal-C-cQDoOk.woff +0 -0
- package/gui/dist/assets/fira-code-greek-ext-600-normal-DtBpFRLc.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-400-normal-C-QZfXAs.woff +0 -0
- package/gui/dist/assets/fira-code-latin-400-normal-DGosTW8U.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-500-normal-B6gioGu8.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-500-normal-aMLC2AMm.woff +0 -0
- package/gui/dist/assets/fira-code-latin-600-normal-BmSSHshu.woff +0 -0
- package/gui/dist/assets/fira-code-latin-600-normal-CvYZpPHg.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-ext-400-normal-DG73JjOf.woff +0 -0
- package/gui/dist/assets/fira-code-latin-ext-400-normal-KSMg0QLl.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-ext-500-normal-CaANqXjI.woff +0 -0
- package/gui/dist/assets/fira-code-latin-ext-500-normal-Crd9e_oI.woff2 +0 -0
- package/gui/dist/assets/fira-code-latin-ext-600-normal-0PFQL1eg.woff +0 -0
- package/gui/dist/assets/fira-code-latin-ext-600-normal-Cb7jxoAi.woff2 +0 -0
- package/gui/dist/assets/fira-code-symbols2-400-normal-_QEZCEwe.woff +0 -0
- package/gui/dist/assets/fira-code-symbols2-500-normal-DwsgbIjQ.woff +0 -0
- package/gui/dist/assets/fira-code-symbols2-600-normal-Dvq6IQE5.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-300-normal-BO7tmGom.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-300-normal-BtNmWoqn.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-400-normal-CKu2TFQr.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-400-normal-D9eUeF-O.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-500-normal-CXfldnQ8.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-500-normal-Daski1k2.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-600-normal-CJ5P9t7t.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-600-normal-JSBvCpTs.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-700-normal-Bl-HczEO.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-700-normal-KyW5QH4H.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-300-normal-BRn8Tsce.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-300-normal-DOtRq9zH.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-400-normal-Cycyekte.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-400-normal-Dd5dApAy.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-500-normal-Cixivk4R.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-500-normal-Dkk5LlrU.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-600-normal-BKgjRriM.woff +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-600-normal-CE6oUZE1.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-700-normal-BfO9TR-w.woff2 +0 -0
- package/gui/dist/assets/fira-sans-cyrillic-ext-700-normal-Gcpdxicj.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-300-normal-D3JfF3y9.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-300-normal-DSgcXl_1.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-400-normal-BFCFncbp.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-400-normal-DQ8sF22y.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-500-normal-C9KT8sAy.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-500-normal-Cy-TUuxE.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-600-normal-BlqpLOpF.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-600-normal-DfHu91YF.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-700-normal-BVfcrbV7.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-700-normal-CJu31rC4.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-300-normal-CodlqOxk.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-300-normal-DVDwbKuK.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-400-normal-ByG7UNQ2.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-400-normal-ClCfNE6D.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-500-normal-Bem4H9fH.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-500-normal-nq-cjB3m.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-600-normal-DPxZoeHL.woff +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-600-normal-fS0evUH3.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-700-normal-C1m6bE4Q.woff2 +0 -0
- package/gui/dist/assets/fira-sans-greek-ext-700-normal-C8J5qYMq.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-300-normal-B2LrTgQS.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-300-normal-Dwkm-oZ7.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-400-normal-66xCkunx.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-400-normal-a0AnQzuD.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-500-normal-Bkfzcwmr.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-500-normal-Bvbxc8ch.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-600-normal-CXKlxLG9.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-600-normal-DtSgd811.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-700-normal-CRhwpWTq.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-700-normal-DgqLm3Fi.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-300-normal-CAROBYR0.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-300-normal-GNF4Ac3G.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-400-normal-BCUwhuGB.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-400-normal-BLG_mAEf.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-500-normal-CFRf4jcC.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-500-normal-OO1QnNpY.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-600-normal-DLMQsaV4.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-600-normal-DTQBTt1m.woff2 +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-700-normal-cfTxGFzJ.woff +0 -0
- package/gui/dist/assets/fira-sans-latin-ext-700-normal-g2Yrd4J5.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-300-normal-BO7He0nF.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-300-normal-CeyOCBN-.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-400-normal-DUVG35gE.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-400-normal-ljDTQFsx.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-500-normal-ChEXCnJy.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-500-normal-UV7M6ot_.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-600-normal-Bxjaclsw.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-600-normal-Dh2KAvU8.woff2 +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-700-normal-DFi88MGY.woff +0 -0
- package/gui/dist/assets/fira-sans-vietnamese-700-normal-j5oLGLJY.woff2 +0 -0
- package/gui/dist/assets/index-CwQzep9r.js +413 -0
- package/gui/dist/assets/index-DUFjnEFT.css +1 -0
- package/gui/dist/assets/theme-BnuhLJ6X.css +1 -0
- package/gui/dist/assets/theme-G7EkTZY2.js +30 -0
- package/gui/dist/index.html +13 -0
- package/package.json +62 -0
package/dist/mermaid.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/** Id de nodo Mermaid válido a partir de un nombre COBOL. En mayúsculas:
|
|
2
|
+
* COBOL es case-insensitive, así que "Main-Para" y "MAIN-PARA." deben
|
|
3
|
+
* acabar en el mismo nodo. */
|
|
4
|
+
function nodeId(name) {
|
|
5
|
+
return name.toUpperCase().replace(/[^A-Z0-9]/g, '_');
|
|
6
|
+
}
|
|
7
|
+
/** Mermaid rompe con comillas dobles dentro de una etiqueta "..." */
|
|
8
|
+
function escapeLabel(text) {
|
|
9
|
+
return text.replace(/"/g, '#quot;');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Etiqueta legible de una arista de flujo. Vive en el motor, no en cada
|
|
13
|
+
* superficie, para que el export Mermaid y el canvas de la GUI digan
|
|
14
|
+
* exactamente lo mismo de la misma arista (ADR-0002: la GUI depende del
|
|
15
|
+
* motor, nunca al revés).
|
|
16
|
+
*/
|
|
17
|
+
export function flowEdgeLabel(edge) {
|
|
18
|
+
const base = () => {
|
|
19
|
+
if (edge.kind === 'call')
|
|
20
|
+
return edge.dynamic ? 'CALL dinámica' : 'CALL';
|
|
21
|
+
if (edge.kind === 'goto')
|
|
22
|
+
return edge.condition ? `GO TO ${edge.condition}` : 'GO TO';
|
|
23
|
+
if (edge.kind === 'fall-through')
|
|
24
|
+
return 'cae en (sin transferencia)';
|
|
25
|
+
if (edge.kind === 'sort-input')
|
|
26
|
+
return edge.thru ? `SORT INPUT THRU ${edge.thru}` : 'SORT INPUT';
|
|
27
|
+
if (edge.kind === 'sort-output')
|
|
28
|
+
return edge.thru ? `SORT OUTPUT THRU ${edge.thru}` : 'SORT OUTPUT';
|
|
29
|
+
let label = 'PERFORM';
|
|
30
|
+
if (edge.thru)
|
|
31
|
+
label += ` THRU ${edge.thru}`;
|
|
32
|
+
if (edge.times !== undefined)
|
|
33
|
+
label += ` ${edge.times} TIMES`;
|
|
34
|
+
if (edge.condition)
|
|
35
|
+
label += ` ${edge.condition}`;
|
|
36
|
+
return label;
|
|
37
|
+
};
|
|
38
|
+
// Las guardas IF/EVALUATE van delante entre corchetes: lo primero que
|
|
39
|
+
// hay que saber de una arista condicional es cuándo ocurre, no qué verbo
|
|
40
|
+
// la produce. Anidadas se unen con AND, que es lo que significan.
|
|
41
|
+
return edge.guards ? `[${edge.guards.join(' AND ')}] ${base()}` : base();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Renderiza los hechos de flujo como diagrama Mermaid (flowchart TD).
|
|
45
|
+
* Es una proyección directa del FlowResult: cada nodo y cada arista del
|
|
46
|
+
* diagrama proviene de un hecho verificado por el parser, y las marcas de
|
|
47
|
+
* fidelidad viajan con él — el nodo de entrada implícito se declara como
|
|
48
|
+
* sintético, un fuente en modo fragmento lleva su aviso visible, y un
|
|
49
|
+
* destino que no existe en el fuente se marca como no encontrado.
|
|
50
|
+
* Formas: párrafos como rectángulos, entrada implícita como estadio,
|
|
51
|
+
* secciones como rectángulo doble, programas externos (CALL) como
|
|
52
|
+
* subrutina.
|
|
53
|
+
*/
|
|
54
|
+
export function flowToMermaid(flow) {
|
|
55
|
+
const out = ['flowchart TD'];
|
|
56
|
+
if (flow.fragment) {
|
|
57
|
+
out.push(' NOTA_FRAGMENTO["⚠ Fragmento sin PROCEDURE DIVISION — parcialmente verificado"]');
|
|
58
|
+
}
|
|
59
|
+
if (flow.nestedPrograms.length > 0) {
|
|
60
|
+
out.push(` NOTA_ANIDADOS["⚠ Programas anidados sin analizar: ${escapeLabel(flow.nestedPrograms.join(', '))}"]`);
|
|
61
|
+
}
|
|
62
|
+
const declared = new Set();
|
|
63
|
+
for (const para of flow.paragraphs) {
|
|
64
|
+
const id = nodeId(para.name);
|
|
65
|
+
declared.add(id);
|
|
66
|
+
let label = para.name;
|
|
67
|
+
if (para.implicit)
|
|
68
|
+
label += ' (entrada implícita)';
|
|
69
|
+
if (para.terminates)
|
|
70
|
+
label += ' — fin';
|
|
71
|
+
if (para.implicit) {
|
|
72
|
+
out.push(` ${id}(["${escapeLabel(label)}"])`);
|
|
73
|
+
}
|
|
74
|
+
else if (para.kind === 'section') {
|
|
75
|
+
out.push(` ${id}[["${escapeLabel(label)} SECTION"]]`);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
out.push(` ${id}["${escapeLabel(label)}"]`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Nodos que solo existen como destino: programas externos (CALL) y
|
|
82
|
+
// destinos no encontrados en el fuente (missingTargets).
|
|
83
|
+
for (const edge of flow.edges) {
|
|
84
|
+
const id = nodeId(edge.to);
|
|
85
|
+
if (declared.has(id))
|
|
86
|
+
continue;
|
|
87
|
+
declared.add(id);
|
|
88
|
+
if (edge.kind === 'call') {
|
|
89
|
+
out.push(` ${id}[["${escapeLabel(edge.to)}"]]`);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
out.push(` ${id}["${escapeLabel(edge.to)} ⟵ no encontrado"]`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
for (const edge of flow.edges) {
|
|
96
|
+
// La caída natural es implícita en el fuente (no hay sentencia que la
|
|
97
|
+
// provoque): flecha punteada para separarla de una transferencia real.
|
|
98
|
+
const arrow = edge.kind === 'fall-through' ? '-.->' : '-->';
|
|
99
|
+
out.push(` ${nodeId(edge.from)} ${arrow}|"${escapeLabel(flowEdgeLabel(edge))}"| ${nodeId(edge.to)}`);
|
|
100
|
+
}
|
|
101
|
+
return out.join('\n') + '\n';
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Renderiza la cadena entre programas como diagrama Mermaid: un nodo por
|
|
105
|
+
* programa y una arista por CALL que cruza la frontera. Igual que el resto
|
|
106
|
+
* de salidas, refleja los hechos tal cual: los programas no aportados y
|
|
107
|
+
* los destinos dinámicos se marcan, nunca se resuelven a ciegas.
|
|
108
|
+
*/
|
|
109
|
+
export function linkedFlowToMermaid(linked) {
|
|
110
|
+
const out = ['flowchart LR'];
|
|
111
|
+
const declared = new Set();
|
|
112
|
+
for (const program of linked.programs) {
|
|
113
|
+
const id = nodeId(program.name);
|
|
114
|
+
declared.add(id);
|
|
115
|
+
out.push(` ${id}["${escapeLabel(program.name)}"]`);
|
|
116
|
+
}
|
|
117
|
+
for (const call of linked.calls) {
|
|
118
|
+
const id = nodeId(call.toProgram);
|
|
119
|
+
if (declared.has(id))
|
|
120
|
+
continue;
|
|
121
|
+
declared.add(id);
|
|
122
|
+
const label = call.dynamic
|
|
123
|
+
? `${call.toProgram} — destino dinámico`
|
|
124
|
+
: `${call.toProgram} — fuente no aportado`;
|
|
125
|
+
out.push(` ${id}["${escapeLabel(label)}"]`);
|
|
126
|
+
}
|
|
127
|
+
for (const call of linked.calls) {
|
|
128
|
+
const label = call.dynamic ? `CALL dinámica (${call.fromParagraph})` : `CALL (${call.fromParagraph})`;
|
|
129
|
+
out.push(` ${nodeId(call.fromProgram)} -->|"${escapeLabel(label)}"| ${nodeId(call.toProgram)}`);
|
|
130
|
+
}
|
|
131
|
+
return out.join('\n') + '\n';
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=mermaid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../src/mermaid.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ParseResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parsea un copybook COBOL y extrae su esquema de campos.
|
|
4
|
+
*
|
|
5
|
+
* Subconjunto cubierto: niveles jerárquicos, PIC (incluidos los editados),
|
|
6
|
+
* OCCURS (fijo y DEPENDING ON reconocido), REDEFINES, niveles 88, niveles
|
|
7
|
+
* 66 RENAMES, USAGE (DISPLAY, COMP, COMP-1, COMP-2, COMP-3, BINARY,
|
|
8
|
+
* PACKED-DECIMAL, POINTER, PROCEDURE-POINTER, FUNCTION-POINTER, INDEX),
|
|
9
|
+
* SYNCHRONIZED con sus bytes de relleno, VALUE como valor inicial, la
|
|
10
|
+
* sección de la DATA DIVISION de cada 01 (FILE / WORKING-STORAGE /
|
|
11
|
+
* LOCAL-STORAGE / LINKAGE), y resolución de COPY (con REPLACING) y EXEC
|
|
12
|
+
* SQL INCLUDE contra `copybooks`. Un member no aportado en `copybooks`
|
|
13
|
+
* queda como hueco explícito en `records` y listado en `missingCopybooks`
|
|
14
|
+
* — nunca se inventa su estructura.
|
|
15
|
+
*
|
|
16
|
+
* Fuera del subconjunto, y por tanto ignorado: JUSTIFIED, BLANK WHEN ZERO,
|
|
17
|
+
* y las secciones REPORT/SCREEN (dejan la sección sin determinar).
|
|
18
|
+
*/
|
|
19
|
+
export declare function parse(source: string, copybooks?: Map<string, string>): ParseResult;
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { alignmentOf, parsePic, usageImpliesFixedSize } from './pic.js';
|
|
2
|
+
import { joinContinuations } from './lines.js';
|
|
3
|
+
import { resolveCopies } from './copy-resolver.js';
|
|
4
|
+
const LEVEL_RE = /^(\d{1,2})\s+([\w-]+)/;
|
|
5
|
+
// El punto es ambiguo en COBOL: dentro de un PIC editado (PIC ZZ,ZZ9.99)
|
|
6
|
+
// es el punto decimal de edición; fuera es el terminador de sentencia. Lo
|
|
7
|
+
// resolvemos con un lookahead: si al punto le sigue un dígito o carácter
|
|
8
|
+
// de edición (Z, 9, *, $, etc.), es parte de la PIC. El `$` (símbolo de
|
|
9
|
+
// moneda) va en el juego de caracteres: sin él, un `PIC $$,$$9.99` no
|
|
10
|
+
// capturaba PIC y el campo se degradaba a un grupo de 0 bytes.
|
|
11
|
+
const PIC_RE = /PIC(?:TURE)?\s+IS\s+([\w()V,\-+*/$]+(?:\.(?=[0-9Z*+\-$])[\w()V,\-+*/$]+)*)|PIC(?:TURE)?\s+([\w()V,\-+*/$]+(?:\.(?=[0-9Z*+\-$])[\w()V,\-+*/$]+)*)/i;
|
|
12
|
+
// El orden importa: las alternativas más largas van primero para que
|
|
13
|
+
// PROCEDURE-POINTER no se lea como POINTER.
|
|
14
|
+
const USAGE_RE = /(?:USAGE\s+IS\s+|USAGE\s+)?\b(COMPUTATIONAL-3|COMPUTATIONAL-2|COMPUTATIONAL-1|COMPUTATIONAL|COMP-3|COMP-2|COMP-1|COMP|BINARY|PACKED-DECIMAL|PROCEDURE-POINTER|FUNCTION-POINTER|POINTER|INDEX|DISPLAY)\b/i;
|
|
15
|
+
const REDEFINES_RE = /REDEFINES\s+([\w-]+)/i;
|
|
16
|
+
// TIMES es opcional en COBOL: `OCCURS 1 TO 10 DEPENDING ON X` (sin TIMES) es
|
|
17
|
+
// la forma más habitual del OCCURS variable, y exigir TIMES dejaba el campo
|
|
18
|
+
// sin reconocer — se trataba como una sola ocurrencia y descuadraba todos
|
|
19
|
+
// los offsets siguientes.
|
|
20
|
+
const OCCURS_RE = /OCCURS\s+(\d+)(?:\s+TO\s+(\d+))?(?:\s+TIMES)?(?:\s+DEPENDING\s+ON\s+([\w-]+))?/i;
|
|
21
|
+
const SIGN_SEPARATE_RE = /SIGN\s+IS\s+(?:LEADING|TRAILING)\s+SEPARATE/i;
|
|
22
|
+
const SYNC_RE = /(?<![\w-])(?:SYNCHRONIZED|SYNC)(?![\w-])/i;
|
|
23
|
+
const RENAMES_RE = /(?<![\w-])RENAMES\s+([\w-]+)(?:\s+(?:THRU|THROUGH)\s+([\w-]+))?/i;
|
|
24
|
+
const VALUE_RE = /VALUES?\s+(?:IS\s+|ARE\s+)?(.+)$/i;
|
|
25
|
+
// VALUE de un campo normal: un solo literal, constante figurativa o número,
|
|
26
|
+
// con un ALL opcional delante. Se lee del texto SIN enmascarar para
|
|
27
|
+
// conservar el literal real.
|
|
28
|
+
const VALUE_FIELD_RE = /(?<![\w-])VALUES?\s+(?:IS\s+)?(ALL\s+)?('[^']*'|"[^"]*"|[+-]?\d+(?:\.\d+)?|[A-Za-z][\w-]*)/i;
|
|
29
|
+
// Cabecera de sección de la DATA DIVISION. Solo las cuatro de almacenamiento
|
|
30
|
+
// de datos; REPORT/SCREEN caen fuera del subconjunto y dejan la sección sin
|
|
31
|
+
// determinar en vez de mal etiquetada.
|
|
32
|
+
const DATA_SECTION_RE = /^\s*(FILE|WORKING-STORAGE|LOCAL-STORAGE|LINKAGE)\s+SECTION\s*\.\s*$/i;
|
|
33
|
+
function canonicalUsage(matched) {
|
|
34
|
+
const u = matched.toUpperCase();
|
|
35
|
+
if (u === 'COMPUTATIONAL-3' || u === 'COMP-3')
|
|
36
|
+
return 'COMP-3';
|
|
37
|
+
if (u === 'COMPUTATIONAL-2' || u === 'COMP-2')
|
|
38
|
+
return 'COMP-2';
|
|
39
|
+
if (u === 'COMPUTATIONAL-1' || u === 'COMP-1')
|
|
40
|
+
return 'COMP-1';
|
|
41
|
+
if (u === 'COMPUTATIONAL' || u === 'COMP')
|
|
42
|
+
return 'COMP';
|
|
43
|
+
if (u === 'PACKED-DECIMAL')
|
|
44
|
+
return 'PACKED-DECIMAL';
|
|
45
|
+
if (u === 'BINARY')
|
|
46
|
+
return 'BINARY';
|
|
47
|
+
if (u === 'POINTER')
|
|
48
|
+
return 'POINTER';
|
|
49
|
+
if (u === 'PROCEDURE-POINTER')
|
|
50
|
+
return 'PROCEDURE-POINTER';
|
|
51
|
+
if (u === 'FUNCTION-POINTER')
|
|
52
|
+
return 'FUNCTION-POINTER';
|
|
53
|
+
if (u === 'INDEX')
|
|
54
|
+
return 'INDEX';
|
|
55
|
+
return 'DISPLAY';
|
|
56
|
+
}
|
|
57
|
+
function parseConditionValues(stmt) {
|
|
58
|
+
const match = VALUE_RE.exec(stmt);
|
|
59
|
+
if (!match)
|
|
60
|
+
return [];
|
|
61
|
+
const tokens = match[1].match(/'[^']*'|"[^"]*"|\S+/g) ?? [];
|
|
62
|
+
return tokens.filter(t => t !== ',');
|
|
63
|
+
}
|
|
64
|
+
function parseStatement(statement) {
|
|
65
|
+
const stmt = statement.replace(/\.\s*$/, '');
|
|
66
|
+
const levelMatch = LEVEL_RE.exec(stmt);
|
|
67
|
+
if (!levelMatch)
|
|
68
|
+
return undefined;
|
|
69
|
+
const level = Number(levelMatch[1]);
|
|
70
|
+
const name = levelMatch[2];
|
|
71
|
+
// Las cláusulas se buscan solo en lo que sigue a "NIVEL NOMBRE" — si se
|
|
72
|
+
// buscaran en la sentencia completa, un nombre de campo que contenga una
|
|
73
|
+
// palabra reservada como componente (p. ej. "SIGNED-DISPLAY") produciría
|
|
74
|
+
// una cláusula inventada que no está en el fuente.
|
|
75
|
+
const rawRest = stmt.slice(levelMatch[0].length);
|
|
76
|
+
if (level === 88) {
|
|
77
|
+
return { kind: 'condition', name, values: parseConditionValues(rawRest) };
|
|
78
|
+
}
|
|
79
|
+
// Un nivel 66 no es un nivel jerárquico: no puede ser hijo de nada ni
|
|
80
|
+
// tener hijos. Metido en el árbol quedaría colgando del último campo
|
|
81
|
+
// elemental y le borraría la longitud, porque un campo con hijos toma
|
|
82
|
+
// la de sus hijos.
|
|
83
|
+
if (level === 66) {
|
|
84
|
+
const renames = RENAMES_RE.exec(rawRest);
|
|
85
|
+
if (!renames)
|
|
86
|
+
return undefined;
|
|
87
|
+
return { kind: 'renames', name, from: renames[1], ...(renames[2] ? { thru: renames[2] } : {}) };
|
|
88
|
+
}
|
|
89
|
+
// El contenido de un literal no es una cláusula: sin esto, un
|
|
90
|
+
// `VALUE 'INDEX'` fabricaría un USAGE que el campo no tiene (ADR-0003).
|
|
91
|
+
// Se conserva la longitud para no descuadrar nada que use posiciones.
|
|
92
|
+
const rest = rawRest.replace(/'[^']*'|"[^"]*"/g, m => ' '.repeat(m.length));
|
|
93
|
+
const picMatch = PIC_RE.exec(rest);
|
|
94
|
+
const picture = picMatch?.[1] ?? picMatch?.[2];
|
|
95
|
+
const usageMatch = USAGE_RE.exec(rest);
|
|
96
|
+
const usage = usageMatch ? canonicalUsage(usageMatch[1]) : undefined;
|
|
97
|
+
const redefinesMatch = REDEFINES_RE.exec(rest);
|
|
98
|
+
const redefines = redefinesMatch?.[1];
|
|
99
|
+
const occursMatch = OCCURS_RE.exec(rest);
|
|
100
|
+
let occurs;
|
|
101
|
+
let occursDepending;
|
|
102
|
+
if (occursMatch) {
|
|
103
|
+
const first = Number(occursMatch[1]);
|
|
104
|
+
const second = occursMatch[2] ? Number(occursMatch[2]) : undefined;
|
|
105
|
+
const dependingOn = occursMatch[3];
|
|
106
|
+
if (dependingOn) {
|
|
107
|
+
occursDepending = second !== undefined
|
|
108
|
+
? { min: first, max: second, dependingOn }
|
|
109
|
+
: { min: 1, max: first, dependingOn };
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
occurs = first;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const signSeparate = SIGN_SEPARATE_RE.test(rest);
|
|
116
|
+
const synchronized = SYNC_RE.test(rest);
|
|
117
|
+
// El valor inicial se lee del texto sin enmascarar: es justo el literal
|
|
118
|
+
// que el enmascarado borra. El `ALL` opcional se conserva verbatim.
|
|
119
|
+
const valueMatch = VALUE_FIELD_RE.exec(rawRest);
|
|
120
|
+
const value = valueMatch ? `${valueMatch[1] ?? ''}${valueMatch[2]}`.trim() : undefined;
|
|
121
|
+
return {
|
|
122
|
+
kind: 'field',
|
|
123
|
+
level,
|
|
124
|
+
name,
|
|
125
|
+
picture,
|
|
126
|
+
usage,
|
|
127
|
+
redefines,
|
|
128
|
+
occurs,
|
|
129
|
+
occursDepending,
|
|
130
|
+
signSeparate,
|
|
131
|
+
synchronized,
|
|
132
|
+
value,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Construye la jerarquía de campos a partir del nivel COBOL, sin resolver
|
|
137
|
+
* todavía offsets ni longitudes de grupo (eso ocurre en `resolveOffsets`).
|
|
138
|
+
*/
|
|
139
|
+
function buildTree(statements) {
|
|
140
|
+
const roots = [];
|
|
141
|
+
const stack = [];
|
|
142
|
+
let lastField;
|
|
143
|
+
// Sección de la DATA DIVISION en curso: se estampa en cada 01/77 raíz
|
|
144
|
+
// que aparezca a partir de su cabecera.
|
|
145
|
+
let currentSection;
|
|
146
|
+
for (const raw of statements) {
|
|
147
|
+
if (raw.kind === 'section') {
|
|
148
|
+
currentSection = raw.section;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (raw.kind === 'condition') {
|
|
152
|
+
if (lastField) {
|
|
153
|
+
const conditionValue = { name: raw.name, values: raw.values };
|
|
154
|
+
lastField.conditionValues = [...(lastField.conditionValues ?? []), conditionValue];
|
|
155
|
+
}
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (raw.kind === 'renames') {
|
|
159
|
+
// Un 66 renombra un tramo del registro 01 que acaba de describirse,
|
|
160
|
+
// así que cuelga del último registro raíz — no de la pila, donde
|
|
161
|
+
// sería un hijo y falsearía longitudes.
|
|
162
|
+
const record = roots[roots.length - 1];
|
|
163
|
+
if (record) {
|
|
164
|
+
const group = {
|
|
165
|
+
name: raw.name,
|
|
166
|
+
from: raw.from,
|
|
167
|
+
...(raw.thru ? { thru: raw.thru } : {}),
|
|
168
|
+
};
|
|
169
|
+
record.renamesGroups = [...(record.renamesGroups ?? []), group];
|
|
170
|
+
}
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (raw.kind === 'unresolved-copy') {
|
|
174
|
+
// level:0 y lengthInBytes:0 son sentinelas, no hechos verificados:
|
|
175
|
+
// ver `type === 'unresolved-copy'` antes de confiar en ellos.
|
|
176
|
+
const field = {
|
|
177
|
+
level: 0,
|
|
178
|
+
name: raw.member,
|
|
179
|
+
type: 'unresolved-copy',
|
|
180
|
+
lengthInBytes: 0,
|
|
181
|
+
offset: 0,
|
|
182
|
+
children: [],
|
|
183
|
+
unresolvedCopyMember: raw.member,
|
|
184
|
+
};
|
|
185
|
+
// Un COPY no lleva nivel propio, así que no hay número con el que
|
|
186
|
+
// decidir dónde encaja exactamente. Lo único que sí sabemos: NUNCA
|
|
187
|
+
// puede ser hijo de un campo elemental (estructuralmente imposible
|
|
188
|
+
// en COBOL) — así que se desapila hasta el grupo abierto más
|
|
189
|
+
// profundo. Sigue siendo una elección, no un hecho verificado: con
|
|
190
|
+
// el member ausente no hay forma de saber si el COPY real habría
|
|
191
|
+
// cerrado ese grupo o seguido añadiéndole campos.
|
|
192
|
+
while (stack.length > 0 && stack[stack.length - 1].type !== 'group') {
|
|
193
|
+
stack.pop();
|
|
194
|
+
}
|
|
195
|
+
const parent = stack.length > 0 ? stack[stack.length - 1] : undefined;
|
|
196
|
+
if (parent) {
|
|
197
|
+
parent.children.push(field);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
if (currentSection)
|
|
201
|
+
field.dataSection = currentSection;
|
|
202
|
+
roots.push(field);
|
|
203
|
+
}
|
|
204
|
+
lastField = field;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const hasOwnSize = !!raw.picture || usageImpliesFixedSize(raw.usage);
|
|
208
|
+
const pic = hasOwnSize ? parsePic(raw.picture, raw.usage, { signSeparate: raw.signSeparate }) : undefined;
|
|
209
|
+
const field = {
|
|
210
|
+
level: raw.level,
|
|
211
|
+
name: raw.name,
|
|
212
|
+
type: pic ? pic.type : 'group',
|
|
213
|
+
...(raw.picture ? { picture: raw.picture.toUpperCase().replace(/\s+/g, '') } : {}),
|
|
214
|
+
...(raw.usage ? { usage: raw.usage } : {}),
|
|
215
|
+
lengthInBytes: pic ? pic.lengthInBytes : 0,
|
|
216
|
+
offset: 0,
|
|
217
|
+
children: [],
|
|
218
|
+
...(raw.redefines ? { redefines: raw.redefines } : {}),
|
|
219
|
+
...(raw.occurs !== undefined ? { occurs: raw.occurs } : {}),
|
|
220
|
+
...(raw.occursDepending ? { occursDepending: raw.occursDepending } : {}),
|
|
221
|
+
// Los punteros e índices van alineados aunque no lleven SYNC escrito.
|
|
222
|
+
...(raw.synchronized || pic?.type === 'pointer' || pic?.type === 'index'
|
|
223
|
+
? { synchronized: true }
|
|
224
|
+
: {}),
|
|
225
|
+
...(raw.value !== undefined ? { value: raw.value } : {}),
|
|
226
|
+
};
|
|
227
|
+
while (stack.length > 0 && stack[stack.length - 1].level >= raw.level) {
|
|
228
|
+
stack.pop();
|
|
229
|
+
}
|
|
230
|
+
const parent = stack.length > 0 ? stack[stack.length - 1] : undefined;
|
|
231
|
+
if (parent) {
|
|
232
|
+
parent.children.push(field);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// La sección solo se estampa en el registro raíz: los hijos son de
|
|
236
|
+
// la misma por construcción, y repetirla sería ruido.
|
|
237
|
+
if (currentSection)
|
|
238
|
+
field.dataSection = currentSection;
|
|
239
|
+
roots.push(field);
|
|
240
|
+
}
|
|
241
|
+
stack.push(field);
|
|
242
|
+
lastField = field;
|
|
243
|
+
}
|
|
244
|
+
return roots;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Alineación que exige un campo: la suya si es elemental, la mayor de su
|
|
248
|
+
* contenido si es grupo. No toca nada — se consulta antes de colocar el
|
|
249
|
+
* campo, cuando sus longitudes finales aún no están calculadas.
|
|
250
|
+
*/
|
|
251
|
+
function requiredAlignment(field) {
|
|
252
|
+
if (field.children.length === 0) {
|
|
253
|
+
return alignmentOf(field.type, field.lengthInBytes, field.synchronized === true);
|
|
254
|
+
}
|
|
255
|
+
let max = 1;
|
|
256
|
+
for (const child of field.children) {
|
|
257
|
+
max = Math.max(max, requiredAlignment(child));
|
|
258
|
+
}
|
|
259
|
+
return max;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Segunda fase: calcula offset y longitud final de cada campo, en orden
|
|
263
|
+
* dentro de cada nivel de hermanos.
|
|
264
|
+
*
|
|
265
|
+
* REDEFINES en COBOL válido siempre aparece contiguo, justo a continuación
|
|
266
|
+
* del campo que redefine (o de otro REDEFINES del mismo campo) — por eso
|
|
267
|
+
* un campo con `redefines` toma el offset del "clúster" que sigue abierto,
|
|
268
|
+
* sin necesidad de buscarlo por nombre. El clúster se cierra al llegar al
|
|
269
|
+
* siguiente campo que NO redefine nada, y el puntero avanza el **máximo**
|
|
270
|
+
* de bytes visto entre el campo base y todas sus vistas — igual que COBOL
|
|
271
|
+
* reserva memoria para la mayor de las vistas solapadas, no solo la base.
|
|
272
|
+
*
|
|
273
|
+
* OCCURS ... DEPENDING ON: `lengthInBytes` del propio campo queda como la
|
|
274
|
+
* longitud de una sola ocurrencia (la longitud real depende de un valor en
|
|
275
|
+
* tiempo de ejecución, así que no se puede fijar). Para que los campos
|
|
276
|
+
* siguientes no se solapen con el peor caso, el puntero de offset sí avanza
|
|
277
|
+
* usando el máximo declarado (o el mínimo si no hay máximo) — una reserva
|
|
278
|
+
* conservadora, no un valor verificado.
|
|
279
|
+
*
|
|
280
|
+
* Huecos sin resolver (type === 'unresolved-copy'): a partir de ahí no se
|
|
281
|
+
* sabe cuántos bytes ocupa lo que falta, así que calcular el offset del
|
|
282
|
+
* siguiente campo como si el hueco midiera 0 bytes sería inventar un
|
|
283
|
+
* número disfrazado de hecho verificado (ADR-0003). En su lugar, se marca
|
|
284
|
+
* `offsetUnknown: true` en el propio hueco y en todo lo que venga después
|
|
285
|
+
* en ese mismo nivel — y, si un grupo contiene un hueco en su interior, el
|
|
286
|
+
* propio grupo (y sus hermanos posteriores en el nivel padre) hereda la
|
|
287
|
+
* marca también, porque su longitud total ya no es fiable.
|
|
288
|
+
*
|
|
289
|
+
* SYNCHRONIZED (y los punteros/índices, alineados de forma implícita):
|
|
290
|
+
* el offset se redondea al alto hasta la frontera que exige el campo,
|
|
291
|
+
* medida desde el principio del registro 01. Los bytes de relleno que
|
|
292
|
+
* quedan delante no son de nadie, pero sí desplazan todo lo que sigue.
|
|
293
|
+
* Un grupo hereda la mayor alineación de su contenido, y si además lleva
|
|
294
|
+
* OCCURS su longitud se redondea para que cada ocurrencia empiece
|
|
295
|
+
* alineada — que es lo que reserva el compilador.
|
|
296
|
+
*
|
|
297
|
+
* Devuelve también `alignment`: lo que el nivel entero exige, para que el
|
|
298
|
+
* padre lo herede.
|
|
299
|
+
*/
|
|
300
|
+
function resolveOffsets(fields, baseOffset) {
|
|
301
|
+
let offset = baseOffset;
|
|
302
|
+
let clusterMaxLength = 0;
|
|
303
|
+
let offsetUnknownFromHere = false;
|
|
304
|
+
let anyUnknown = false;
|
|
305
|
+
let groupAlignment = 1;
|
|
306
|
+
for (const field of fields) {
|
|
307
|
+
// Hay que saber qué alineación exige el campo ANTES de colocarlo, y
|
|
308
|
+
// para un grupo eso depende de su contenido. Se mira sin resolver:
|
|
309
|
+
// resolver dos veces aplicaría dos veces el `*= occurs`.
|
|
310
|
+
const ownAlignment = requiredAlignment(field);
|
|
311
|
+
groupAlignment = Math.max(groupAlignment, ownAlignment);
|
|
312
|
+
if (field.redefines) {
|
|
313
|
+
field.offset = offset;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
offset += clusterMaxLength;
|
|
317
|
+
if (ownAlignment > 1 && offset % ownAlignment !== 0) {
|
|
318
|
+
offset += ownAlignment - (offset % ownAlignment);
|
|
319
|
+
}
|
|
320
|
+
field.offset = offset;
|
|
321
|
+
clusterMaxLength = 0;
|
|
322
|
+
}
|
|
323
|
+
if (offsetUnknownFromHere) {
|
|
324
|
+
field.offsetUnknown = true;
|
|
325
|
+
}
|
|
326
|
+
if (field.type === 'unresolved-copy') {
|
|
327
|
+
field.offsetUnknown = true;
|
|
328
|
+
offsetUnknownFromHere = true;
|
|
329
|
+
}
|
|
330
|
+
if (field.children.length > 0) {
|
|
331
|
+
const placed = resolveOffsets(field.children, field.offset);
|
|
332
|
+
field.lengthInBytes = placed.length;
|
|
333
|
+
// Cada ocurrencia de un OCCURS tiene que empezar alineada, así que
|
|
334
|
+
// el compilador rellena el final del grupo hasta el múltiplo.
|
|
335
|
+
if (field.occurs !== undefined && placed.alignment > 1) {
|
|
336
|
+
const remainder = field.lengthInBytes % placed.alignment;
|
|
337
|
+
if (remainder !== 0)
|
|
338
|
+
field.lengthInBytes += placed.alignment - remainder;
|
|
339
|
+
}
|
|
340
|
+
if (placed.hasUnknown) {
|
|
341
|
+
field.offsetUnknown = true;
|
|
342
|
+
offsetUnknownFromHere = true;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (field.offsetUnknown) {
|
|
346
|
+
anyUnknown = true;
|
|
347
|
+
}
|
|
348
|
+
if (field.occurs) {
|
|
349
|
+
field.lengthInBytes *= field.occurs;
|
|
350
|
+
}
|
|
351
|
+
const ownLength = field.occursDepending
|
|
352
|
+
? field.lengthInBytes * (field.occursDepending.max ?? field.occursDepending.min)
|
|
353
|
+
: field.lengthInBytes;
|
|
354
|
+
clusterMaxLength = Math.max(clusterMaxLength, ownLength);
|
|
355
|
+
}
|
|
356
|
+
offset += clusterMaxLength;
|
|
357
|
+
return { length: offset - baseOffset, hasUnknown: anyUnknown, alignment: groupAlignment };
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Resuelve el offset y la longitud de cada nivel 66 contra el registro ya
|
|
361
|
+
* calculado. Si algún extremo del rango no aparece en el fuente aportado
|
|
362
|
+
* —está en un copybook que falta, por ejemplo— se deja sin resolver en vez
|
|
363
|
+
* de estimarlo (ADR-0003).
|
|
364
|
+
*/
|
|
365
|
+
function resolveRenames(record) {
|
|
366
|
+
const byName = new Map();
|
|
367
|
+
const collect = (field) => {
|
|
368
|
+
byName.set(field.name.toUpperCase(), field);
|
|
369
|
+
for (const child of field.children)
|
|
370
|
+
collect(child);
|
|
371
|
+
};
|
|
372
|
+
collect(record);
|
|
373
|
+
for (const group of record.renamesGroups ?? []) {
|
|
374
|
+
const from = byName.get(group.from.toUpperCase());
|
|
375
|
+
const thru = group.thru ? byName.get(group.thru.toUpperCase()) : from;
|
|
376
|
+
if (!from || !thru)
|
|
377
|
+
continue;
|
|
378
|
+
if (from.offsetUnknown || thru.offsetUnknown)
|
|
379
|
+
continue;
|
|
380
|
+
group.offset = from.offset;
|
|
381
|
+
group.lengthInBytes = thru.offset + thru.lengthInBytes - from.offset;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Parsea un copybook COBOL y extrae su esquema de campos.
|
|
386
|
+
*
|
|
387
|
+
* Subconjunto cubierto: niveles jerárquicos, PIC (incluidos los editados),
|
|
388
|
+
* OCCURS (fijo y DEPENDING ON reconocido), REDEFINES, niveles 88, niveles
|
|
389
|
+
* 66 RENAMES, USAGE (DISPLAY, COMP, COMP-1, COMP-2, COMP-3, BINARY,
|
|
390
|
+
* PACKED-DECIMAL, POINTER, PROCEDURE-POINTER, FUNCTION-POINTER, INDEX),
|
|
391
|
+
* SYNCHRONIZED con sus bytes de relleno, VALUE como valor inicial, la
|
|
392
|
+
* sección de la DATA DIVISION de cada 01 (FILE / WORKING-STORAGE /
|
|
393
|
+
* LOCAL-STORAGE / LINKAGE), y resolución de COPY (con REPLACING) y EXEC
|
|
394
|
+
* SQL INCLUDE contra `copybooks`. Un member no aportado en `copybooks`
|
|
395
|
+
* queda como hueco explícito en `records` y listado en `missingCopybooks`
|
|
396
|
+
* — nunca se inventa su estructura.
|
|
397
|
+
*
|
|
398
|
+
* Fuera del subconjunto, y por tanto ignorado: JUSTIFIED, BLANK WHEN ZERO,
|
|
399
|
+
* y las secciones REPORT/SCREEN (dejan la sección sin determinar).
|
|
400
|
+
*/
|
|
401
|
+
export function parse(source, copybooks = new Map()) {
|
|
402
|
+
// Si el fuente es un programa completo, la definición de datos termina
|
|
403
|
+
// donde empieza la PROCEDURE DIVISION — nada de lo que sigue es un campo.
|
|
404
|
+
const allLines = source.split(/\r?\n/);
|
|
405
|
+
const procedureIndex = allLines.findIndex(line => {
|
|
406
|
+
const body = line.length > 6 ? line.slice(6) : line;
|
|
407
|
+
return /^\s*PROCEDURE\s+DIVISION/i.test(body);
|
|
408
|
+
});
|
|
409
|
+
const dataLines = procedureIndex === -1 ? allLines : allLines.slice(0, procedureIndex);
|
|
410
|
+
const rawStatements = joinContinuations(dataLines);
|
|
411
|
+
// Los nombres de member son case-insensitive: el mapa se normaliza a
|
|
412
|
+
// mayúsculas para que el lookup de resolveCopies siempre encaje.
|
|
413
|
+
const normalizedCopybooks = new Map([...copybooks].map(([name, text]) => [name.toUpperCase(), text]));
|
|
414
|
+
const { statements: resolved, missingCopybooks } = resolveCopies(rawStatements, normalizedCopybooks);
|
|
415
|
+
const statements = [];
|
|
416
|
+
for (const item of resolved) {
|
|
417
|
+
if (item.kind === 'unresolved-copy') {
|
|
418
|
+
statements.push({ kind: 'unresolved-copy', member: item.member });
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
// Una cabecera de sección no es un campo, pero marca de dónde vienen
|
|
422
|
+
// los 01 que la siguen (¿parámetro por LINKAGE, o dato propio?).
|
|
423
|
+
const sectionMatch = DATA_SECTION_RE.exec(item.statement);
|
|
424
|
+
if (sectionMatch) {
|
|
425
|
+
statements.push({ kind: 'section', section: sectionMatch[1].toUpperCase() });
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
const parsed = parseStatement(item.statement);
|
|
429
|
+
if (parsed)
|
|
430
|
+
statements.push(parsed);
|
|
431
|
+
}
|
|
432
|
+
const roots = buildTree(statements);
|
|
433
|
+
// Cada 01/77 de nivel raíz es un área de almacenamiento independiente
|
|
434
|
+
// (no hay FD ni FILE SECTION en el alcance de un copybook): sus offsets
|
|
435
|
+
// internos son relativos a su propio inicio, no continúan entre records.
|
|
436
|
+
for (const root of roots) {
|
|
437
|
+
resolveOffsets([root], 0);
|
|
438
|
+
resolveRenames(root);
|
|
439
|
+
}
|
|
440
|
+
return { records: roots, missingCopybooks };
|
|
441
|
+
}
|
|
442
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/pic.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { DataType } from './types.js';
|
|
2
|
+
export interface PicInfo {
|
|
3
|
+
type: DataType;
|
|
4
|
+
picture: string;
|
|
5
|
+
totalDigits: number;
|
|
6
|
+
decimalDigits: number;
|
|
7
|
+
lengthInBytes: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ParsePicOptions {
|
|
10
|
+
/** SIGN IS LEADING/TRAILING SEPARATE — añade 1 byte extra en DISPLAY */
|
|
11
|
+
signSeparate?: boolean | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parsea una cláusula PIC (y USAGE) y calcula tipo y longitud en bytes.
|
|
15
|
+
* COMP-1/COMP-2 no requieren PIC — su tamaño es fijo (float de 4/8 bytes).
|
|
16
|
+
*/
|
|
17
|
+
export declare function parsePic(rawPicture: string | undefined, usage?: string, options?: ParsePicOptions): PicInfo;
|
|
18
|
+
/** USAGE que no requiere PIC para determinar su tamaño (floats, punteros, índices) */
|
|
19
|
+
export declare function usageImpliesFixedSize(usage?: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Frontera de alineación en bytes que exige un campo, o 1 si no exige
|
|
22
|
+
* ninguna. SYNCHRONIZED alinea los binarios y los flotantes; los punteros
|
|
23
|
+
* y los índices van alineados siempre, lleven SYNC o no.
|
|
24
|
+
*
|
|
25
|
+
* La alineación es relativa al principio del registro 01, y los bytes de
|
|
26
|
+
* relleno que deja delante no pertenecen a ningún campo — por eso hay que
|
|
27
|
+
* contarlos para que los offsets siguientes sean ciertos.
|
|
28
|
+
*/
|
|
29
|
+
export declare function alignmentOf(type: DataType, lengthInBytes: number, synchronized: boolean): number;
|