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
| Parameter | Type | Description |
|---|---|---|
grammarString |
string |
Grammar definition in DSL format |
options |
object |
Configuration options (see below) |
Options
| Option | Type | Default | Description |
|---|---|---|---|
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:
parser- TheParserinstancetokenFunc- The generated tokenizer function (ornullif custom provided)itemGraph- TheLRItemGraph(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
| Parameter | Type | Description |
|---|---|---|
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;
}