Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

customSepByWithSequenceOf of tutorial 4 does allow trailing comma #110

Open
devurandom opened this issue Oct 15, 2023 · 1 comment
Open

Comments

@devurandom
Copy link

devurandom commented Oct 15, 2023

With following code, copied almost unchanged from tutorial 4 (changes are in template arguments, to workaround #109):

import {
    char,
    letters,
    Parser,
    possibly,
    sepBy,
    sequenceOf,
} from "arcsecond";

const customSepByWithSequenceOf = <T>(separatorParser: Parser<string>) => (valueParser: Parser<T>) =>
    sequenceOf([
        sepBy(separatorParser)(valueParser) as Parser<T>,//<< https://github.com/francisrstokes/arcsecond/issues/109
        possibly(separatorParser),
    ]).map(([values, _]) => values);

export const parse = (input: string) => customSepByWithSequenceOf(char(","))(letters).run(input);

I get:

❯ pnpm build

> arcsecond-repro2@0.1.0 build [REDACTED]/arcsecond-repro2
> tsc -p .

❯ node
Welcome to Node.js v18.17.1.
Type ".help" for more information.
> p = await import("./dist/parser.js?v1")
[Module: null prototype] { parse: [Function: parse] }
> p.parse("a,b,")
{
  isError: true,
  error: 'ParseError (position 4): Expecting letters',
  index: 4,
  data: null
}

customSepByWithSequenceOf is unable to parse a list with trailing comma, which according to https://github.com/francisrstokes/arcsecond/blob/main/tutorial/tutorial-part-4.md#writing-custom-combinators it should be able to do.

Please find a complete example in https://github.com/devurandom/arcsecond-issue-110-repro.

@devurandom
Copy link
Author

The coroutine example works with small changes:

const sepByTrailing = <T>(sep: Parser<string>, val: Parser<T>) =>
    coroutine((run) => {
        const results: T[] = [];

        while (true) {
            const valResult = run(either(val));
            if (valResult.isError) break;

            results.push(valResult.value);

            const sepResult = run(either(sep));
            if (sepResult.isError) break;
        }

        return results;
    });

I used <T>(sep: Parser<string>, val: Parser<T>) => ... instead of separatorParser => valueParser => ... to avoid #109.

I results.push(valResult.value) instead of results.push(valResult), because I did not want to work with any[], but was unable find type for results to make this happen. I tried variations of ResultType<T, E, D>[], but got:

TS2345: Argument of type  { isError: boolean; value: T; }  is not assignable to parameter of type  ResultType<T, E, D> 
  Type  { isError: boolean; value: T; }  is missing the following properties from type  Ok<T, D> :  index, result, data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant