FruitsConfits - A well typed and sugared parser combinator framework for TypeScript/JavaScript.
npm install fruitsconfitssh
npm install fruitsconfits
`
> NOTICE:
> Use with webpack >= 5
>
> If you get the error:
>
> `
> Module not found: Error: Can't resolve '(importing/path/to/filename)'
> in '(path/to/node_modules/path/to/dirname)'
> Did you mean '(filename).js'?
>
> Add following setting to your webpack.config.js.
>
> `js
> {
> test: /\.m?js/,
> resolve: {
> fullySpecified: false,
> },
> },
> `
>
> On webpack >= 5, the extension in the request is mandatory for it to be fully specified
> if the origin is a '.mjs' file or a '.js' file where the package.json contains '"type": "module"'.
$3
See CHANGELOG.md.
Features
* Build a lexer or parser for a string or object list by parser combinator.
* The parser can receive user data context and acts as a reducer.
* Sugar sweet API syntaxes.
High level APIs
$3
Get the string parser generators.
`ts
export function getStringParsers(
params: {
rawToToken: (rawToken: string) => R,
concatTokens: (tokens: R[]) => R[],
});
`
#### params
* rawToToken : function to convert string token to AST element.
* concatTokens : function to merge two AST elements into one AST element.
#### returns
returns an object that containing the parsers.
* seq(needle: string)
* parser to match the sequence needle
* cls(...needles: string[])
* parser to match the sequence classes needles
* notCls(...needles: string[])
* parser to match the negation of sequence classes needles
* clsFn(needle: (src: string) => number)
* parser to match the sequence class needle
* the class is defined by the lambda function
* classes
* alpha
* parser to match the sequence of us-ascii alphabetic characters
* upper
* parser to match the sequence of us-ascii upper alphabetic characters
* lower
* parser to match the sequence of us-ascii lower alphabetic characters
* num
* parser to match the sequence of us-ascii decimal numeric characters
* nonzero
* parser to match the sequence of us-ascii decimal numeric characters except 0
* bin
* parser to match the sequence of us-ascii binary numeric characters
* oct
* parser to match the sequence of us-ascii octal numeric characters
* hex
* parser to match the sequence of us-ascii hexadecimal numeric characters
* alnum
* parser to match the sequence of us-ascii alphabetic and numeric characters
* space
* parser to match the sequence of whitespace characters except newline (CR/LF) characters
* the whitespace characters definition conform to javascript regexp
* spaceWithinSingleLine
* parser to match the sequence of whitespace characters
* the whitespace characters definition conform to javascript regexp
* ctrl
* parser to match the sequence of control characters
* the control characters definition conform to javascript regexp
* newline
* parser to match the sequence of newline (CR/LF) characters
* word
* parser to match the negation of the sequence of whitespaces and control characters
* the whitespace and control characters definition conform to javascript regexp
* any
* parser to match the sequence class that matches to any token
* numbers
* bin(...prefixes: StringParserFnWithCtx
* parse a binary number
* oct(...prefixes: StringParserFnWithCtx
* parse a octal number
* hex(...prefixes: StringParserFnWithCtx
* parse a hex number
* int
* parse a javascript style integer number
* bigint
* parse a javascript style bigint number
* float
* parse a javascript style floating point number
* isParam(criteria: (o: any) => boolean, conv?: (o: any) => any)
* parser to match a ES6 template strings parameter value
* cat(...parsers: StringParserFnWithCtx
* parser that combine and concatenate the parsing results of parsers
* once(parser: StringParserFnWithCtx
* parser to match once to the parsing results of parser
* repeat(parser: StringParserFnWithCtx
* parser to match zero or more times to the parsing results of parser
* qty(min?: number, max?: number) => (parser: StringParserFnWithCtx
* parser to match min to max times to the parsing results of parser
* if min and max are ommitted, it is same as repeat parser
* if max is ommitted, it matches min or more times
* zeroWidth(helper?: () => R)
* parser to match any zero width and return result that is provided by helper
* err(message: string)
* parser to match any zero width and raise the error that has message
* beginning(helper?: () => R)
* parser to match zero width beginning of input and return result that is provided by helper
* end(helper?: () => R)
* parser to match zero width end of input and return result that is provided by helper
* first(...parsers: StringParserFnWithCtx
* parser to match the first matched parser in the parsers
* or(...parsers: StringParserFnWithCtx
* parser to match the most long matched parser in the parsers
* combine(...parsers: StringParserFnWithCtx
* parser that combine parsers parsers
* erase(...parsers: StringParserFnWithCtx
* parser that combine parsers parsers and return empty result []
* trans(fn: (tokens: R[]) => R[]) => (...parsers: StringParserFnWithCtx
* parser that combine parsers parsers and transform the result by fn
* ahead(...parsers: StringParserFnWithCtx
* parser to match zero width by reading ahead and matching with parsers
* behind(n: number, helper?: () => R)(...parsers: StringParserFnWithCtx
* parser to match zero width by reading behind and matching with parsers and return result that is provided by helper
* rules(args: ApplyProductionRulesArg
* parser to match the production rules args
* args.rules : production rules
* args.maxApply : maximum number of production rules applied
* args.check : end condition of production rules
* makeProgram
* parser to enclose most outer
* converts the internal ParseError thrown to a return value
$3
Get the object list parser generators.
`ts
export function getObjectParsers, C, R>(
params: {
rawToToken: (rawToken: T[number]) => R,
concatTokens: (tokens: R[]) => R[],
comparator: (a: T[number], b: T[number]) => boolean,
});
`
#### params
* rawToToken : function to convert the input object list item to AST element.
* concatTokens : function to merge two AST elements into one AST element.
* comparator : function to compare two input object list items.
#### returns
returns an object that containing the parsers.
* seq(needle: T)
* parser to match the sequence needle
* cls(...needles: T[number][])
* parser to match the sequence classes needles
* notCls(...needles: T[number][])
* parser to match the negation of sequence classes needles
* clsFn(needle: (src: T[number]) => boolean)
* parser to match the sequence class needle
* the class is defined by the lambda function
* classes
* any
* parser to match the sequence class that matches to any token
* cat(...parsers: ParserFnWithCtx
* parser that combine and concatenate the parsing results of parsers
* once(parser: ParserFnWithCtx
* parser to match once to the parsing results of parser
* repeat(parser: ParserFnWithCtx
* parser to match zero or more times to the parsing results of parser
* qty(min?: number, max?: number) => (parser: ParserFnWithCtx
* parser to match min to max times to the parsing results of parser
* if min and max are ommitted, it is same as repeat parser
* if max is ommitted, it matches min or more times
* zeroWidth(helper?: () => R)
* parser to match any zero width and return result that is provided by helper
* err(message: string)
* parser to match any zero width and raise the error that has message
* beginning(helper?: () => R)
* parser to match zero width beginning of input and return result that is provided by helper
* end(helper?: () => R)
* parser to match zero width end of input and return result that is provided by helper
* first(...parsers: ParserFnWithCtx
* parser to match the first matched parser in the parsers
* or(...parsers: ParserFnWithCtx
* parser to match the most long matched parser in the parsers
* combine(...parsers: ParserFnWithCtx
* parser that combine parsers parsers
* erase(...parsers: ParserFnWithCtx
* parser that combine parsers parsers and return empty result []
* trans(fn: (tokens: R[]) => R[]) => (...parsers: ParserFnWithCtx
* parser that combine parsers parsers and transform the result by fn
* ahead(...parsers: ParserFnWithCtx
* parser to match zero width by reading ahead and matching with parsers
* behind(n: number, helper?: () => R)(...parsers: ParserFnWithCtx
* parser to match zero width by reading behind and matching with parsers and return result that is provided by helper
* rules(args: ApplyProductionRulesArg
* parser to match the production rules args
* args.rules : production rules
* args.maxApply : maximum number of production rules applied
* args.check : end condition of production rules
* makeProgram
* parser to enclose most outer
* converts the internal ParseError thrown to a return value
$3
Build a parser input.
Example:
`ts
...
const program = makeProgram(trans(tokens => tokens)(
erase(repeat(commentOrSpace)),
first(listValue, objectValue, constExpr(end())),
erase(repeat(commentOrSpace)),
end(), ));
export function parse(s: string) {
const z = program(parserInput(s));
if (! z.succeeded) {
throw new Error(formatErrorMessage(z));
}
return z.tokens[0].value;
}
`
$3
Build a parser input from ES6 template strings.
Example:
`ts
const program = makeProgram(combine(
seq('Hello,'),
isParam(o => String(o) === 'world'),
seq('!'),
end(), ));
export function parse(strings: TemplateStringsArray, ...values: any[]) {
const z = program(templateStringsParserInput(strings, values));
if (! z.succeeded) {
throw new Error(formatErrorMessage(z));
}
return z.tokens;
}
``