Created
March 18, 2024 16:40
-
-
Save mmomtchev/8e1c4b7a09e2bcce93fe3cf67892a254 to your computer and use it in GitHub Desktop.
Crude transformer for bison grammars to use named references
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Transform a single bison item to named references | |
* | |
* For example to transform only "c_decl" | |
* | |
* node transform.js Source/CParse/parser.y c_decl Source/CParse/parser.y | |
*/ | |
const fs = require('fs'); | |
let input = fs.readFileSync(process.argv[2], 'utf-8'); | |
console.log(`Transforming ${process.argv[3]}`); | |
const identifier = new RegExp(`\\b(${process.argv[3]})\\b\\s*:`, 'gm'); | |
console.log(identifier) | |
const elements_first = /\s*(([\<\>a-zA-Z0-9_]+\s*)+)/g; | |
const elements_next = /\s*\|\s*(([\<\>a-zA-Z0-9_]+\s*)+)/g; | |
const single_element = /\b([a-zA-Z0-9_]+)\b/g; | |
let m; | |
while ((m = identifier.exec(input)) !== null) { | |
console.log(`Found ( ${m[1]} ) section`); | |
let idx = m.index + m[0].length; | |
let elements = elements_first; | |
while (true) { | |
//console.log(`\tnext block ( ${input.slice(idx, idx + 200)} )`); | |
if (input.slice(idx).match(/^\s*;/)) | |
break; | |
elements.lastIndex = 0; | |
const args = elements.exec(input.slice(idx)); | |
if (!args) break; | |
idx += args.index + args[0].length; | |
let arg; | |
console.log(`\tvariant ( ${args[1]} )`); | |
let narg = 1; | |
let replacements = {}; | |
while ((arg = single_element.exec(args[1])) !== null) { | |
replacements[`$${narg}`] = `$${arg[1]}`; | |
narg++; | |
} | |
console.log(replacements); | |
let end_of_block = idx, start_of_block = idx; | |
let braces = 0; | |
while(true) { | |
switch (input[end_of_block++]) { | |
case '{': braces++; break; | |
case '}': braces--; break; | |
} | |
if (braces === 0) break; | |
} | |
let block = input.slice(idx, end_of_block); | |
//console.log('block', block); | |
for (const r of Object.keys(replacements)) { | |
block = block.replaceAll(new RegExp(`\\${r}\\b`, 'g'), replacements[r]); | |
} | |
input = input.slice(0, start_of_block) + block + input.slice(end_of_block); | |
elements = elements_next; | |
idx = start_of_block + block.length; | |
} | |
} | |
if (process.argv[4]) | |
fs.writeFileSync(process.argv[4], input, 'utf-8'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment