git.dumitru.net fructose / master src / parser / combinators / SequenceParser.ts
master

Tree @master (Download .tar.gz)

SequenceParser.ts @masterraw · history · blame

import Document from "../../Document";
import DocumentLocation from "../../DocumentLocation";
import Parser from "../Parser";
import ParserError from "../ParserError";
import ParserValue from "../ParserValue";

export default class SequenceParser<T> implements Parser<T[]> {
  public readonly name: string;
  private ps: Array<() => Parser<T>>;

  constructor(ps: Array<() => Parser<T>>) {
    this.ps = ps;
    this.name = `${ps.map((p) => p ? p.name : "").join(" ")}`;
  }

  public parse(doc: Document, loc: DocumentLocation): ParserValue<T[]> | ParserError {
    let curr = loc;
    const accumulator: T[] = [];

    for (const p of this.ps) {
      const result = p().parse(doc, curr);

      if (result instanceof ParserValue) {
        accumulator.push(result.value);
        curr = result.location;
      } else if (result instanceof ParserError) {
        return new ParserError(`expected ${p.name}, got something else`, curr, result);
      }
    }

    return new ParserValue(accumulator, curr);
  }
}