Skip to content

Instantly share code, notes, and snippets.

@mmomtchev
Created March 18, 2024 16:40
Show Gist options
  • Save mmomtchev/8e1c4b7a09e2bcce93fe3cf67892a254 to your computer and use it in GitHub Desktop.
Save mmomtchev/8e1c4b7a09e2bcce93fe3cf67892a254 to your computer and use it in GitHub Desktop.
Crude transformer for bison grammars to use named references
/**
* 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