Skip to content
Snippets Groups Projects
Select Git revision
  • 9d730e95fb89c5ac74e2d919ec5d69a83910ae9c
  • master default protected
  • rednatco-v2
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
41 results

monadic-parser.ts

Blame
  • monadic-parser.ts 18.85 KiB
    /**
     * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
     *
     * @author David Sehnal <david.sehnal@gmail.com>
     */
    
    /**
     * Adapted from Parsimmon (https://github.com/jneen/parsimmon)
     * Copyright (c) 2011-present J. Adkisson (http://jneen.net).
     */
    
    export class MonadicParser<A> {
        constructor(public _: MonadicParser.Action<A>) { }
    
        parse(input: string): MonadicParser.ParseResult<A> {
            const result = this.skip(MonadicParser.eof)._(input, 0);
            if (result.status) {
                return { success: true, value: result.value };
            }
            return { success: false, index: makeLineColumnIndex(input, result.furthest), expected: result.expected };
        };
    
        tryParse(str: string) {
            const result = this.parse(str);
            if (result.success) {
                return result.value;
            } else {
                const msg = formatError(str, result);
                const err = new Error(msg);
                throw err;
            }
        }
    
        or<B>(alternative: MonadicParser<B>): MonadicParser<A | B> {
            return MonadicParser.alt(this, alternative);
        }
    
        trim<B>(parser: MonadicParser<B> | string): MonadicParser<A> {
            return this.wrap(parser, parser);
        }
    
        wrap<L, R>(leftParser: MonadicParser<L> | string, rightParser: MonadicParser<R> | string): MonadicParser<A> {
            return seqPick(1,
                typeof leftParser === 'string' ? MonadicParser.string(leftParser) : leftParser,
                this,
                typeof rightParser === 'string' ? MonadicParser.string(rightParser) : rightParser);
        }
    
        thru<B>(wrapper: (p: MonadicParser<A>) => MonadicParser<B>) {
            return wrapper(this);
        }
    
        then<B>(next: MonadicParser<B>): MonadicParser<B> {
            return seqPick(1, this, next);
        }
    
        many() {
            return new MonadicParser((input, i) => {
                const accum: A[] = [];
                let result: MonadicParser.Result<A> | undefined = void 0;
    
                while (true) {
                    result = mergeReplies(this._(input, i), result);
                    if (result.status) {
                        if (i === result.index) {
                            throw new Error('infinite loop detected in .many() parser --- calling .many() on a parser which can accept zero characters is usually the cause');
                        }
                        i = result.index;
                        accum.push(result.value);
                    } else {