fruitsconfits
Version:
FruitsConfits - A well typed and sugared parser combinator framework for TypeScript/JavaScript.
63 lines (46 loc) • 1.84 kB
text/typescript
// Copyright (c) 2019 Shellyl_N and Authors
// license: ISC
// https://github.com/shellyln
import { parserInput } from '../../lib/types';
import { formatErrorMessage } from '../../lib/parser';
import { getStringParsers } from '../../lib/string-parser';
type Ctx = undefined;
type Ast = string | string[];
const $s = getStringParsers<Ctx, Ast>({
rawToToken: rawToken => rawToken,
concatTokens: tokens => (tokens.length ?
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
[tokens.reduce((a, b) => a as string + b)] : []),
});
const {seq, cls, notCls, classes, cat,
repeat, end, first, combine, erase, trans, ahead,
makeProgram} = $s;
const quoted = trans(input => input.length ? input : [''])(
erase(repeat(classes.spaceWithinSingleLine), cls('"')),
cat(repeat(first(
trans(input => ['"'])(seq('""')),
notCls('"'),
))),
erase(cls('"'), repeat(erase(classes.spaceWithinSingleLine))), );
const nakid = trans(input => input.length ? input : [''])(
erase(repeat(classes.spaceWithinSingleLine)),
cat(repeat(first(
erase(classes.spaceWithinSingleLine, ahead(cls(',', '\r\n', '\n', '\r'))),
notCls(',', '\r\n', '\n', '\r'),
))), );
const cell = first(quoted, nakid);
const row = trans(input => [input as string[]])(
cell,
repeat(combine(erase(seq(',')), cell)), );
const rows = makeProgram(combine(
row,
repeat(combine(erase(classes.newline), row)),
end(), ));
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function parse(s: string) {
const z = rows(parserInput(s));
if (! z.succeeded) {
throw new Error(formatErrorMessage(z));
}
return z.tokens as string[][];
}