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

Tree @master (Download .tar.gz)

ZeroOrMoreParser.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 ZeroOrMoreParser<T> implements Parser<T[]> {
  public readonly name: string;
  private p: () => Parser<T>;

  constructor(p: () => Parser<T>) {
    this.p = p;
    this.name = `(${p().name})*`;
  }

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

    while (true) {
      const result = this.p().parse(doc, curr);

      if (result instanceof ParserError) {
        break;
      } else if (result instanceof ParserValue) {
        if (result.value === null) {
          break;
        }

        accumulator.push(result.value);
        curr = result.location;
      }
    }

    return new ParserValue(accumulator, curr);
  }
}