From ef0995c74f60b053b5caac6a12a5b1372805ce8b Mon Sep 17 00:00:00 2001 From: multipleof4 Date: Fri, 26 Sep 2025 08:04:35 -0700 Subject: [PATCH] Refactor: Replace Nearley with Chevrotain parser workflow --- transpiler.js | 53 ++++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/transpiler.js b/transpiler.js index 5eb63c2..7e3630c 100644 --- a/transpiler.js +++ b/transpiler.js @@ -1,5 +1,4 @@ -import nearley from 'nearley'; -import grammar from './grammar.js'; +import { HiLexer, parser, astBuilder } from './parser.js'; /** * Generates JavaScript code from a Hi AST. @@ -7,7 +6,7 @@ import grammar from './grammar.js'; * @returns {string} The equivalent JavaScript code. */ function generate(ast) { - if (!ast) return ''; // Handle potential nulls from grammar + if (!ast) return ''; const generator = { Program: (node) => node.body.map(generate).join('\n'), @@ -51,32 +50,26 @@ function generate(ast) { * @returns {string} The equivalent JavaScript code. */ export function hi2js(sourceCode) { - // 1. Create a nearley parser instance from our compiled grammar - const parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar)); - - try { - // 2. Feed the source code to the parser - parser.feed(sourceCode); - - // 3. Check for ambiguity and get the AST - if (parser.results.length > 1) { - console.warn("Master, the grammar is ambiguous. Using the first parse tree."); - } - if (parser.results.length === 0) { - // Throw an error only if the input was not empty. - if (sourceCode.trim().length > 0) { - throw new Error("Unexpected end of input. The code is incomplete."); - } - return ""; // Return empty string for empty input. - } - const ast = parser.results[0]; - - // 4. Generate JavaScript from the AST - return generate(ast); - - } catch (err) { - // Provide a more helpful error message - const message = err.message.replace(/ Instead, I found a "[^"]+" token here:/, "."); - throw new Error(`Parsing error: ${message}`); + if (!sourceCode.trim()) { + return ""; } + // 1. Lexing + const lexResult = HiLexer.tokenize(sourceCode); + if (lexResult.errors.length > 0) { + throw new Error(`Lexing error: ${lexResult.errors[0].message}`); + } + + // 2. Parsing + parser.input = lexResult.tokens; + const cst = parser.program(); + if (parser.errors.length > 0) { + const err = parser.errors[0]; + throw new Error(`Parsing error: ${err.message}`); + } + + // 3. Building AST from CST + const ast = astBuilder.visit(cst); + + // 4. Generating JavaScript from AST + return generate(ast); }