Skip to main content
Module

x/ohm_js/src/pexprs-main.js

A library and language for building parsers, interpreters, compilers, etc.
Go to Latest
File
import {UnicodeCategories} from './UnicodeCategories.js';import * as common from './common.js';
// --------------------------------------------------------------------// Private stuff// --------------------------------------------------------------------
// General stuff
export class PExpr { constructor() { if (this.constructor === PExpr) { throw new Error("PExpr cannot be instantiated -- it's abstract"); } }
// Set the `source` property to the interval containing the source for this expression. withSource(interval) { if (interval) { this.source = interval.trimmed(); } return this; }}
// Any
export const any = Object.create(PExpr.prototype);
// End
export const end = Object.create(PExpr.prototype);
// Terminals
export class Terminal extends PExpr { constructor(obj) { super(); this.obj = obj; }}
// Ranges
export class Range extends PExpr { constructor(from, to) { super(); this.from = from; this.to = to; // If either `from` or `to` is made up of multiple code units, then // the range should consume a full code point, not a single code unit. this.matchCodePoint = from.length > 1 || to.length > 1; }}
// Parameters
export class Param extends PExpr { constructor(index) { super(); this.index = index; }}
// Alternation
export class Alt extends PExpr { constructor(terms) { super(); this.terms = terms; }}
// Extend is an implementation detail of rule extension
export class Extend extends Alt { constructor(superGrammar, name, body) { const origBody = superGrammar.rules[name].body; super([body, origBody]);
this.superGrammar = superGrammar; this.name = name; this.body = body; }}
// Splice is an implementation detail of rule overriding with the `...` operator.export class Splice extends Alt { constructor(superGrammar, ruleName, beforeTerms, afterTerms) { const origBody = superGrammar.rules[ruleName].body; super([...beforeTerms, origBody, ...afterTerms]);
this.superGrammar = superGrammar; this.ruleName = ruleName; this.expansionPos = beforeTerms.length; }}
// Sequences
export class Seq extends PExpr { constructor(factors) { super(); this.factors = factors; }}
// Iterators and optionals
export class Iter extends PExpr { constructor(expr) { super(); this.expr = expr; }}
export class Star extends Iter {}export class Plus extends Iter {}export class Opt extends Iter {}
Star.prototype.operator = '*';Plus.prototype.operator = '+';Opt.prototype.operator = '?';
Star.prototype.minNumMatches = 0;Plus.prototype.minNumMatches = 1;Opt.prototype.minNumMatches = 0;
Star.prototype.maxNumMatches = Number.POSITIVE_INFINITY;Plus.prototype.maxNumMatches = Number.POSITIVE_INFINITY;Opt.prototype.maxNumMatches = 1;
// Predicates
export class Not extends PExpr { constructor(expr) { super(); this.expr = expr; }}
export class Lookahead extends PExpr { constructor(expr) { super(); this.expr = expr; }}
// "Lexification"
export class Lex extends PExpr { constructor(expr) { super(); this.expr = expr; }}
// Rule application
export class Apply extends PExpr { constructor(ruleName, args = []) { super(); this.ruleName = ruleName; this.args = args; }
isSyntactic() { return common.isSyntactic(this.ruleName); }
// This method just caches the result of `this.toString()` in a non-enumerable property. toMemoKey() { if (!this._memoKey) { Object.defineProperty(this, '_memoKey', {value: this.toString()}); } return this._memoKey; }}
// Unicode character
export class UnicodeChar extends PExpr { constructor(category) { super(); this.category = category; this.pattern = UnicodeCategories[category]; }}