API Reference

Complete API reference for Galore

API Reference

This page documents the main entry points and classes in Galore.

Creating Parsers

newParser()

The main entry point for creating a parser from a grammar DSL string:

import { newParser } from "galore";

const [parser, tokenFunc, itemGraph] = newParser(grammarString, options);

Parameters

ParameterTypeDescription
grammarString string Grammar definition in DSL format
options object Configuration options (see below)

Options

OptionTypeDefaultDescription
type "slr" | "lalr" | "lr1" "lalr" Parser algorithm to use
tokenizer NextTokenFunc auto-generated Custom tokenizer function
debug "all" | "lexer" | "parser" none Enable debug output
leftRecursive boolean true Use left recursion for EBNF expansions
auxNTPrefix string "$" Prefix for auxiliary non-terminals

Returns

A tuple of three values:

  1. parser - The Parser instance
  2. tokenFunc - The generated tokenizer function (or null if custom provided)
  3. itemGraph - The LRItemGraph (useful for debugging)

Example

import { newParser } from "galore";

const [parser, tokenFunc, itemGraph] = newParser(`
  %token NUMBER /[0-9]+/
  %skip /[ \\t\\n]+/

  Expr -> Expr "+" Term | Term ;
  Term -> NUMBER ;
`, { type: "lalr" });

const result = parser.parse("1 + 2 + 3");
console.log(result.value);

Parser Class

parse()

Parse an input string and return the parse tree root:

const result = parser.parse(input, context?);

Parameters

ParameterTypeDescription
input string | Tape Input to parse
context ParserContext Optional parsing context with handlers

Returns

PTNode | null - The root of the parse tree, or null if parsing failed.

See Semantic Actions for details on ParserContext.

Grammar Class

The Grammar class can be used to build grammars programmatically instead of using the DSL.

Creating Symbols

import { Grammar } from "galore";

const g = new Grammar();

// Create terminals
const PLUS = g.newTerm("+");
const NUMBER = g.newTerm("NUMBER");

// Create non-terminals
const Expr = g.newNT("Expr");
const Term = g.newNT("Term");

// Alternative: get or create
const sym1 = g.T("keyword");    // Get or create terminal
const sym2 = g.NT("Statement"); // Get or create non-terminal

Adding Rules

import { Grammar, Str } from "galore";

const g = new Grammar();
const Expr = g.newNT("Expr");
const Term = g.newNT("Term");
const NUMBER = g.newTerm("NUMBER");
const PLUS = g.newTerm("+");

// Add production: Expr -> Expr "+" Term
g.add(Expr, new Str(Expr, PLUS, Term));

// Add production: Expr -> Term
g.add(Expr, new Str(Term));

// Add production: Term -> NUMBER
g.add(Term, new Str(NUMBER));

Helper Methods

// Sequence: A B C
const seq = g.seq(A, B, C);

// Alternation: (A | B | C) - creates auxiliary NT
const choice = g.anyof(A, B, C);

// Optional: A? - creates auxiliary NT
const optional = g.opt(A);

// Zero or more: A* - creates auxiliary NT
const star = g.atleast0(A);

// One or more: A+ - creates auxiliary NT
const plus = g.atleast1(A);

Querying the Grammar

// Get symbol by label
const sym = g.getSym("Expr");

// Get symbol by ID
const sym2 = g.getSymById(5);

// Check symbol types
g.isTerminal("NUMBER");  // true
g.isNT("Expr");          // true

// Get all symbols
g.terminals;        // All terminal symbols
g.nonTerminals;     // User-defined non-terminals
g.auxNonTerminals;  // Auxiliary non-terminals (from EBNF)
g.allSymbols;       // All symbols

// Get rules for a non-terminal
const rules = g.rulesForNT(Expr);

// Iterate through rules
g.forEachRule(null, (rule, index) => {
  console.log(rule.debugString);
});

Grammar Analysis

// First, Follow, and Nullable sets
const firsts = g.firstSets;
const follows = g.followSets;
const nullables = g.nullables;

// Check if symbol is nullable
nullables.has(Expr);

// Get first set for a symbol
firsts.getSet(Expr);

// Get follow set for a symbol
follows.getSet(Expr);

PTNode Class

Parse tree nodes returned by the parser:

class PTNode {
  sym: Sym;              // The grammar symbol
  value: any;            // Semantic value
  children: PTNode[];    // Child nodes
  parent: PTNode | null; // Parent node
  id: number;            // Unique node ID

  // Check if terminal (leaf node)
  get isTerminal(): boolean;

  // Get child by index (negative = from end)
  childAt(index: number): PTNode;

  // Debug output
  debugValue(): any;
}

ParseTable Class

Represents the LR parse table:

class ParseTable {
  grammar: Grammar;

  // Check if table has conflicts
  get hasConflicts(): boolean;

  // Get actions for a state and symbol
  getActions(stateId: number, symbol: Sym): LRAction[];
}

LRAction Types

enum LRActionType {
  ACCEPT,  // Accept input (parsing complete)
  SHIFT,   // Shift token and go to state
  REDUCE,  // Reduce by rule
  GOTO     // Non-terminal transition
}

class LRAction {
  tag: LRActionType;
  gotoState: number | null;  // For SHIFT and GOTO
  rule: Rule | null;         // For REDUCE

  toString(): string;  // "S5", "R3", "Acc", etc.
}

Exports

Galore exports the following from its main entry point:

// Main entry point
export { newParser } from "galore";

// Core classes
export { Grammar, Sym, Str, Rule, RuleAction } from "galore";
export { Parser, ParseTable, LRAction, LRActionType } from "galore";
export { PTNode, PFNode } from "galore";
export { ParseError } from "galore";

// Analysis
export { FirstSets, FollowSets, NullableSet } from "galore";
export { LRItemGraph, LRItemSet, LRItem } from "galore";

// Namespaced exports
export { DSL } from "galore";       // Grammar DSL loader
export { Analyzer } from "galore";  // Grammar transformations
export { Printers } from "galore";  // Debug output utilities
export { LL } from "galore";        // LL parser (experimental)

TypeScript Types

// Tokenizer function type
type NextTokenFunc = (tape: Tape, owner: any) => Token | null;

// Rule action handler
type RuleActionHandler = (
  rule: Rule,
  parent: PTNode,
  ...children: PTNode[]
) => any;

// Parser context
interface ParserContext {
  ruleHandlers: { [name: string]: RuleActionHandler };
  beforeAddingChildNode?: BeforeAddingChildCallback;
  onReduction?: RuleReductionCallback;
  onNextToken?: NextTokenCallback;
  actionResolver?: ActionResolverCallback;
  onTokenError?: TokenErrorCallback;
  buildParseTree?: boolean;
  copySingleChild?: boolean;
}