All files / transpiler/logic/parser CNextSourceParser.ts

100% Statements 14/14
100% Branches 0/0
100% Functions 5/5
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83                                                                          1246x 1246x 1246x 1246x   1246x 1246x               36x                         1246x 1246x 1246x 1246x   1246x 1246x   1246x                    
/**
 * CNextSourceParser
 * Handles parsing of C-Next source code with error collection.
 *
 * Extracted from Pipeline.ts to reduce duplication and improve testability.
 */
 
import { CharStream, CommonTokenStream } from "antlr4ng";
 
import { CNextLexer } from "./grammar/CNextLexer";
import { CNextParser, ProgramContext } from "./grammar/CNextParser";
import ITranspileError from "../../../lib/types/ITranspileError";
 
/**
 * Result of parsing C-Next source code
 */
interface IParseResult {
  /** The parsed AST */
  tree: ProgramContext;
  /** Token stream for code generation */
  tokenStream: CommonTokenStream;
  /** Any parse errors encountered */
  errors: ITranspileError[];
  /** Number of top-level declarations */
  declarationCount: number;
}
 
/**
 * Parses C-Next source code and collects errors
 */
class CNextSourceParser {
  /**
   * Parse C-Next source code
   * @param source - The source code string to parse
   * @returns Parse result with tree, token stream, errors, and declaration count
   */
  static parse(source: string): IParseResult {
    const charStream = CharStream.fromString(source);
    const lexer = new CNextLexer(charStream);
    const tokenStream = new CommonTokenStream(lexer);
    const parser = new CNextParser(tokenStream);
 
    const errors: ITranspileError[] = [];
    const errorListener = {
      syntaxError(
        _recognizer: unknown,
        _offendingSymbol: unknown,
        line: number,
        charPositionInLine: number,
        msg: string,
      ) {
        errors.push({
          line,
          column: charPositionInLine,
          message: msg,
          severity: "error" as const,
        });
      },
      reportAmbiguity() {},
      reportAttemptingFullContext() {},
      reportContextSensitivity() {},
    };
 
    // Add error listener to both lexer and parser
    lexer.removeErrorListeners();
    lexer.addErrorListener(errorListener);
    parser.removeErrorListeners();
    parser.addErrorListener(errorListener);
 
    const tree = parser.program();
    const declarationCount = tree.declaration().length;
 
    return {
      tree,
      tokenStream,
      errors,
      declarationCount,
    };
  }
}
 
export default CNextSourceParser;