Skip to content

Commit

Permalink
Rename main class
Browse files Browse the repository at this point in the history
  • Loading branch information
barsdeveloper committed Dec 15, 2023
1 parent 7b897f6 commit ecb98f9
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 178 deletions.
51 changes: 26 additions & 25 deletions src/Regexer.js → src/Parsernostrum.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import AlternativeParser from "./parser/AlternativeParser.js"
import ChainedParser from "./parser/ChainedParser.js"
import FailureParser from "./parser/FailureParser.js"
import LazyParser from "./parser/LazyParser.js"
import LookaroundParser from "./parser/LookaroundParser.js"
import Lookahead from "./parser/Lookahead.js"
import MapParser from "./parser/MapParser.js"
import Parser from "./parser/Parser.js"
import RegExpParser from "./parser/RegExpParser.js"
Expand All @@ -13,11 +13,11 @@ import SuccessParser from "./parser/SuccessParser.js"
import TimesParser from "./parser/TimesParser.js"

/** @template {Parser<any>} T */
export default class Regexer {
export default class Parsernostrum {

#parser

/** @type {(new (parser: Parser<any>) => Regexer<typeof parser>) & typeof Regexer} */
/** @type {(new (parser: Parser<any>) => Parsernostrum<typeof parser>) & typeof Parsernostrum} */
Self

static #numberMapper = v => Number(v)
Expand Down Expand Up @@ -136,9 +136,9 @@ export default class Regexer {
// Combinators

/**
* @template {[Regexer<any>, Regexer<any>, ...Regexer<any>[]]} P
* @template {[Parsernostrum<any>, Parsernostrum<any>, ...Parsernostrum<any>[]]} P
* @param {P} parsers
* @returns {Regexer<SequenceParser<UnwrapParser<P>>>}
* @returns {Parsernostrum<SequenceParser<UnwrapParser<P>>>}
*/
static seq(...parsers) {
const results = new this(new SequenceParser(...parsers.map(p => p.getParser())))
Expand All @@ -147,35 +147,35 @@ export default class Regexer {
}

/**
* @template {[Regexer<any>, Regexer<any>, ...Regexer<any>[]]} P
* @template {[Parsernostrum<any>, Parsernostrum<any>, ...Parsernostrum<any>[]]} P
* @param {P} parsers
* @returns {Regexer<AlternativeParser<UnwrapParser<P>>>}
* @returns {Parsernostrum<AlternativeParser<UnwrapParser<P>>>}
*/
static alt(...parsers) {
// @ts-expect-error
return new this(new AlternativeParser(...parsers.map(p => p.getParser())))
}

/**
* @template {Regexer<any>} P
* @template {Parsernostrum<any>} P
* @param {P} parser
*/
static lookahead(parser) {
return new this(new LookaroundParser(parser.getParser(), LookaroundParser.Type.POSITIVE_AHEAD))
return new this(new Lookahead(parser.getParser(), Lookahead.Type.POSITIVE_AHEAD))
}

/**
* @template {Regexer<any>} P
* @template {Parsernostrum<any>} P
* @param {() => P} parser
* @returns {Regexer<LazyParser<UnwrapParser<P>>>}
* @returns {Parsernostrum<LazyParser<UnwrapParser<P>>>}
*/
static lazy(parser) {
return new this(new LazyParser(parser))
}

/**
* @param {Number} min
* @returns {Regexer<TimesParser<T>>}
* @returns {Parsernostrum<TimesParser<T>>}
*/
times(min, max = min) {
// @ts-expect-error
Expand All @@ -196,59 +196,60 @@ export default class Regexer {
return this.times(0, n)
}

/** @returns {Regexer<T?>} */
/** @returns {Parsernostrum<T?>} */
opt() {
// @ts-expect-error
return this.Self.alt(this, this.Self.success())
}

/**
* @template {Regexer<Parser<any>>} P
* @template {Parsernostrum<Parser<any>>} P
* @param {P} separator
*/
sepBy(separator, allowTrailing = false) {
const results = this.Self.seq(
this,
this.Self.seq(separator, this).map(Regexer.#secondElementGetter).many()
this.Self.seq(separator, this).map(Parsernostrum.#secondElementGetter).many()
)
.map(Regexer.#arrayFlatter)
.map(Parsernostrum.#arrayFlatter)
return results
}

skipSpace() {
return this.Self.seq(this, this.Self.optWhitespace).map(Regexer.#firstElementGetter)
return this.Self.seq(this, this.Self.optWhitespace).map(Parsernostrum.#firstElementGetter)
}

/**
* @template R
* @param {(v: ParserValue<T>) => R} fn
* @returns {Regexer<MapParser<T, R>>}
* @template P
* @param {(v: ParserValue<T>) => P} fn
* @returns {Parsernostrum<MapParser<T, P>>}
*/
map(fn) {
// @ts-expect-error
return new this.Self(new MapParser(this.#parser, fn))
}

/**
* @template {Regexer<any>} R
* @param {(v: ParserValue<T>, input: String, position: Number) => R} fn
* @template {Parsernostrum<any>} P
* @param {(v: ParserValue<T>, input: String, position: Number) => P} fn
*/
chain(fn) {
return new this.Self(new ChainedParser(this.#parser, fn))
}

/**
* @param {(v: ParserValue<T>, input: String, position: Number) => boolean} fn
* @return {Regexer<T>}
* @return {Parsernostrum<T>}
*/
assert(fn) {
return /** @type {Regexer<T>} */(this.chain((v, input, position) => fn(v, input, position)
return /** @type {Parsernostrum<T>} */(this.chain((v, input, position) => fn(v, input, position)
? this.Self.success().map(() => v)
: this.Self.failure()
))
}

join(value = "") {
return this.map(Regexer.#joiner)
return this.map(Parsernostrum.#joiner)
}

toString(indent = 0, newline = false) {
Expand Down
6 changes: 3 additions & 3 deletions src/Reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export default class Reply {
})
}

/** @param {Regexer<Parser<any>>} regexer */
static makeContext(regexer = null, input = "") {
/** @param {Parsernostrum<Parser<any>>} parsernostrum */
static makeContext(parsernostrum = null, input = "") {
return /** @type {Context} */({
regexer: regexer,
parsernostrum: parsernostrum,
input: input,
visited: new Map(),
})
Expand Down
42 changes: 21 additions & 21 deletions src/grammars/JsonGrammar.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import Parser from "../parser/Parser.js"
import Regexer from "../Regexer.js"
import Parsernostrum from "../Parsernostrum.js"

const R = Regexer
const P = Parsernostrum

export default class JsonGrammar {

static #null = R.str("null").map(() => null)
static #true = R.str("true").map(() => true)
static #false = R.str("false").map(() => false)
static #string = R.doubleQuotedString
static #number = R.numberExponential
/** @type {Regexer<Parser<any[]>>} */
static #array = R.seq(
R.regexp(/\[\s*/),
R.lazy(() => this.json).sepBy(R.regexp(/\s*,\s*/)),
R.regexp(/\s*\]/)
static #null = P.str("null").map(() => null)
static #true = P.str("true").map(() => true)
static #false = P.str("false").map(() => false)
static #string = P.doubleQuotedString
static #number = P.numberExponential
/** @type {Parsernostrum<Parser<any[]>>} */
static #array = P.seq(
P.regexp(/\[\s*/),
P.lazy(() => this.json).sepBy(P.regexp(/\s*,\s*/)),
P.regexp(/\s*\]/)
).map(([_0, values, _2]) => values)
/** @type {Regexer<Parser<Object>>} */
static #object = R.seq(
R.regexp(/\{\s*/),
R.seq(
/** @type {Parsernostrum<Parser<Object>>} */
static #object = P.seq(
P.regexp(/\{\s*/),
P.seq(
this.#string,
R.regexp(/\s*:\s*/),
R.lazy(() => this.json),
P.regexp(/\s*:\s*/),
P.lazy(() => this.json),
)
.map(([k, _1, v]) => ({ [k]: v }))
.sepBy(R.regexp(/\s*,\s*/))
.sepBy(P.regexp(/\s*,\s*/))
.map(v => v.reduce((acc, cur) => ({ ...acc, ...cur }), ({}))),
R.regexp(/\s*}/)
P.regexp(/\s*}/)
).map(([_0, object, _2]) => object)

static json = R.alt(
static json = P.alt(
this.#string,
this.#number,
this.#object,
Expand Down
46 changes: 23 additions & 23 deletions src/grammars/MathGrammar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Regexer from "../Regexer.js"
import Parsernostrum from "../Parsernostrum.js"

const R = Regexer
const P = Parsernostrum

export default class MathGrammar {

Expand Down Expand Up @@ -34,60 +34,60 @@ export default class MathGrammar {
return numbers.pop()
}

static #number = R.number.map(v => Number(v))
static #number = P.number.map(v => Number(v))

static #opFragment = R.lazy(() =>
R.seq(
R.optWhitespace,
R.alt(
R.str("^").map(() => ({
static #opFragment = P.lazy(() =>
P.seq(
P.optWhitespace,
P.alt(
P.str("^").map(() => ({
precedence: 20,
rightAssociative: true,
function: (a, b) => Math.pow(a, b),
})),
R.str("*").map(() => ({
P.str("*").map(() => ({
precedence: 10,
rightAssociative: false,
function: (a, b) => a * b,
})),
R.str("/").map(() => ({
P.str("/").map(() => ({
precedence: 10,
rightAssociative: false,
function: (a, b) => a / b,
})),
R.str("+").map(() => ({
P.str("+").map(() => ({
precedence: 0,
rightAssociative: false,
function: (a, b) => a + b,
})),
R.str("-").map(() => ({
P.str("-").map(() => ({
precedence: 0,
rightAssociative: false,
function: (a, b) => a - b,
})),
).map(v => v),
R.optWhitespace,
P.optWhitespace,
MathGrammar.expressionFragment,
)
.map(([_0, operator, _2, expressionFragment]) => [operator, ...expressionFragment])
.atLeast(1)
.map(values => values.flatMap(v => v)),
)

static #termFragment = R.lazy(() =>
R.alt(
static #termFragment = P.lazy(() =>
P.alt(
MathGrammar.#number.map(v => [v]),
R.seq(
R.str("("),
R.optWhitespace,
R.lazy(() => MathGrammar.expressionFragment),
R.optWhitespace,
R.str(")"),
P.seq(
P.str("("),
P.optWhitespace,
P.lazy(() => MathGrammar.expressionFragment),
P.optWhitespace,
P.str(")"),
).map(([_0, _1, entries]) => [this.#evaluate(entries)])
))

static expressionFragment = R.alt(
R.seq(
static expressionFragment = P.alt(
P.seq(
MathGrammar.#termFragment,
MathGrammar.#opFragment
).map(([term, fragment]) => [...term, ...fragment]),
Expand Down
2 changes: 1 addition & 1 deletion src/parser/ChainedParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Reply from "../Reply.js"

/**
* @template {Parser<any>} T
* @template {(v: ParserValue<T>, input: String, position: Number) => Regexer<Parser<any>>} C
* @template {(v: ParserValue<T>, input: String, position: Number) => Parsernostrum<Parser<any>>} C
* @extends Parser<ReturnType<C>>
*/
export default class ChainedParser extends Parser {
Expand Down
6 changes: 3 additions & 3 deletions src/parser/LazyParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class LazyParser extends Parser {
/** @type {T} */
#resolvedPraser

/** @param {() => Regexer<T>} parser */
/** @param {() => Parsernostrum<T>} parser */
constructor(parser) {
super()
this.#parser = parser
Expand All @@ -33,10 +33,10 @@ export default class LazyParser extends Parser {
* @param {P} parsers
*/
wrap(...parsers) {
const regexerConstructor = /** @type {ConstructorType<Regexer<typeof parsers[0]>>} */(
const parsernostrumConstructor = /** @type {ConstructorType<Parsernostrum<typeof parsers[0]>>} */(
this.#parser().constructor
)
return new LazyParser(() => new regexerConstructor(parsers[0]))
return new LazyParser(() => new parsernostrumConstructor(parsers[0]))
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/parser/LookaroundParser.js → src/parser/Lookahead.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Parser from "./Parser.js"
import Reply from "../Reply.js"

/** @template {Parser<any>} T */
export default class LookaroundParser extends Parser {
export default class Lookahead extends Parser {

#parser
get parser() {
Expand Down Expand Up @@ -44,7 +44,7 @@ export default class LookaroundParser extends Parser {
* @param {P} parsers
*/
wrap(...parsers) {
return new LookaroundParser(parsers[0], this.#type)
return new Lookahead(parsers[0], this.#type)
}

/**
Expand All @@ -53,13 +53,13 @@ export default class LookaroundParser extends Parser {
*/
parse(context, position) {
if (
this.#type === LookaroundParser.Type.NEGATIVE_BEHIND
|| this.#type === LookaroundParser.Type.POSITIVE_BEHIND
this.#type === Lookahead.Type.NEGATIVE_BEHIND
|| this.#type === Lookahead.Type.POSITIVE_BEHIND
) {
throw new Error("Lookbehind is not implemented yet")
} else {
const result = this.#parser.parse(context, position)
return result.status == (this.#type === LookaroundParser.Type.POSITIVE_AHEAD)
return result.status == (this.#type === Lookahead.Type.POSITIVE_AHEAD)
? Reply.makeSuccess(position, "")
: Reply.makeFailure(position)
}
Expand Down
Loading

0 comments on commit ecb98f9

Please sign in to comment.