{"version":3,"sources":["../src/combinators/attempt.ts","../src/combinators/many.ts","../src/combinators/map.ts","../src/combinators/sequence.ts","../src/combinators/chain.ts","../src/combinators/choice.ts","../src/combinators/error.ts","../src/combinators/lookahead.ts","../src/parsers/nothing.ts","../src/combinators/optional.ts","../src/combinators/sepBy.ts","../src/combinators/take.ts","../src/combinators/until.ts","../src/combinators/when.ts"],"names":["attempt","parser","input","pos","result","many","values","nextPos","many1","resultP","resultR","map","fn","span","mapTo","value","sequence","ps","toLR","left","right","op","chainl","choice","first","rest","nextResult","error","expected","lookahead","nothing","_","optional","sepBy","sep","resultS","sepBy1","toLeft","toMiddle","middle","toRight","toSides","takeLeft","p1","p2","takeMid","p3","takeRight","takeSides","takeUntil","terminator","resultT","skipUntil","when","context"],"mappings":"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","sourcesContent":["import type { Parser } from '@types'\n\n/**\n * Applies `parser` without consuming any input. It doesn't care if `parser` succeeds or fails, it\n * won't consume any input.\n *\n * @param parser - Parser to apply\n *\n * @returns Result of `parser`\n */\nexport function attempt<T>(parser: Parser<T>): Parser<T> {\n  return {\n    parse(input, pos) {\n      const result = parser.parse(input, pos)\n\n      switch (result.isOk) {\n        // If parser succeeded, keep the position untouched.\n        case true: {\n          return {\n            isOk: true,\n            span: [pos, pos],\n            pos,\n            value: result.value\n          }\n        }\n\n        // If parser failed, keep the position untouched as well.\n        case false: {\n          return {\n            isOk: false,\n            span: [pos, pos],\n            pos,\n            expected: result.expected\n          }\n        }\n      }\n    }\n  }\n}\n","import type { Parser, SucceedingParser } from '@types'\n\n/**\n * Applies `parser` *zero* or more times, collecting its results. Never fails.\n *\n * @param parser - Parser to apply\n *\n * @returns Array of the returned values of `parser`\n */\nexport function many<T>(parser: Parser<T>): SucceedingParser<Array<T>> {\n  return {\n    parse(input, pos) {\n      const values: Array<T> = []\n      let nextPos = pos\n\n      while (nextPos < input.length) {\n        const result = parser.parse(input, nextPos)\n\n        if (result.isOk) {\n          values.push(result.value)\n          nextPos = result.pos\n        } else {\n          break\n        }\n      }\n\n      return {\n        isOk: true,\n        span: [pos, nextPos],\n        pos: nextPos,\n        value: values\n      }\n    }\n  }\n}\n\n/**\n * Applies `parser` *one* or more times, collecting its results.\n *\n * @param parser - Parser to apply\n *\n * @returns Array of the returned values of `parser`\n */\nexport function many1<T>(parser: Parser<T>): Parser<Array<T>> {\n  return {\n    parse(input, pos) {\n      const resultP = parser.parse(input, pos)\n\n      if (resultP.isOk) {\n        const values: Array<T> = []\n        let nextPos = resultP.pos\n\n        values.push(resultP.value)\n\n        while (nextPos < input.length) {\n          const resultR = parser.parse(input, nextPos)\n\n          if (resultR.isOk) {\n            values.push(resultR.value)\n            nextPos = resultR.pos\n            continue\n          }\n\n          break\n        }\n\n        return {\n          isOk: true,\n          span: [pos, nextPos],\n          pos: nextPos,\n          value: values\n        }\n      }\n\n      return resultP\n    }\n  }\n}\n","import type { Parser, Span } from '@types'\n\n/**\n * Applies `fn` to the `parser`'s result.\n *\n * @param parser - Parser to apply\n * @param fn - Function to apply to `parser`'s result\n *\n * @returns Result of `fn`\n */\nexport function map<T, R>(parser: Parser<T>, fn: (value: T, span: Span) => R): Parser<R> {\n  return {\n    parse(input, pos) {\n      const result = parser.parse(input, pos)\n\n      switch (result.isOk) {\n        case true: {\n          const span: Span = [pos, result.pos]\n\n          return {\n            isOk: true,\n            span,\n            pos: result.pos,\n            value: fn(result.value, span)\n          }\n        }\n\n        case false: {\n          return result\n        }\n      }\n    }\n  }\n}\n\n/**\n * Maps the `parser`'s result to a constant `value`.\n *\n * @param parser - Parser to apply\n * @param value - Value to map `parser`'s result to\n *\n * @returns `value`\n */\nexport function mapTo<T, R>(parser: Parser<T>, value: R): Parser<R> {\n  return map(parser, () => value)\n}\n","import type { Parser, ToTuple, ToTupleOrArray } from '@types'\n\n/**\n * Applies `ps` parsers in order, until *all* of them succeed.\n *\n * @param ps - Parsers to apply\n *\n * @returns Tuple of values returned by `ps` parsers\n */\nexport function sequence<T extends Array<Parser<unknown>>>(...ps: T): Parser<ToTuple<T>>\nexport function sequence<T extends Array<Parser<unknown>>>(...ps: T): Parser<ToTupleOrArray<T>>\nexport function sequence<T>(...ps: Array<Parser<T>>): Parser<Array<T>> {\n  return {\n    parse(input, pos) {\n      const values: Array<T> = []\n      let nextPos = pos\n\n      for (const parser of ps) {\n        const result = parser.parse(input, nextPos)\n\n        switch (result.isOk) {\n          case true: {\n            values.push(result.value)\n            nextPos = result.pos\n            break\n          }\n\n          case false: {\n            return result\n          }\n        }\n      }\n\n      return {\n        isOk: true,\n        span: [pos, nextPos],\n        pos: nextPos,\n        value: values\n      }\n    }\n  }\n}\n","import { many } from './many'\nimport { map } from './map'\nimport { sequence } from './sequence'\n\nimport type { Parser } from '@types'\n\n/** @internal */\ntype Fn<L, R> = (left: L, right: R) => L\n\n/** @internal */\nfunction toLR<T, L extends T, R>(fn: Fn<T, R>) {\n  return ([left, right]: [L, Array<R>]): T => {\n    return right.reduce<T>((result, op) => fn(result, op), left)\n  }\n}\n\n/**\n * Parses *zero* or more occurrences of `parser`, separated by `op` (in [EBNF] notation:\n * `parser (op parser)*`). Returns a value obtained by a recursive left-associative application of\n * `fn` to the values returned by `op` and `parser`.\n *\n * This combinator is particularly useful for eliminating left recursion, which typically occurs in\n * expression grammars.\n *\n * [EBNF]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form\n *\n * @param parser - Parser to apply\n * @param op - Separating parser\n * @param fn - Left-associative function to apply to the values returned by `op` and `parser`\n *\n * @returns Value from `fn`\n */\nexport function chainl<T, L extends T, R>(\n  parser: Parser<L>,\n  op: Parser<R>,\n  fn: Fn<T, R>\n): Parser<T> {\n  return map(sequence(parser, many(op)), toLR(fn))\n}\n","import type { Parser, ToUnion } from '@types'\n\n/**\n * Applies `ps` parsers in order until one of them succeeds.\n *\n * @param ps - Parsers to apply\n *\n * @returns Value of the succeeding parser\n */\nexport function choice<T extends Array<Parser<unknown>>>(...ps: T): Parser<ToUnion<T>>\nexport function choice<T>(...ps: Array<Parser<T>>): Parser<T> {\n  return {\n    parse(input, pos) {\n      // It's \"guaranteed\" by type system that there will be at least two parsers, so I'm not gonna\n      // bother checking for `ps` length and asserting it, because it would hit performance.\n      const [first, ...rest] = ps\n\n      // Run the first parser to infer the type.\n      let nextResult = first.parse(input, pos)\n\n      // Test other alternatives if the first one fails.\n      if (!nextResult.isOk) {\n        for (const parser of rest) {\n          const result = parser.parse(input, pos)\n\n          switch (result.isOk) {\n            case true: {\n              return result\n            }\n\n            case false: {\n              if (!nextResult || nextResult.pos < result.pos) {\n                nextResult = result\n              }\n            }\n          }\n        }\n      }\n\n      return nextResult\n    }\n  }\n}\n","import type { Parser } from '@types'\n\n/**\n * Replaces `parser`'s error message with `expected`.\n *\n * @param parser - Parser of which error message should be replaced\n * @param expected - New error message\n *\n * @returns Unchanged `parser`'s result or failure with new error message\n */\nexport function error<T>(parser: Parser<T>, expected: string): Parser<T> {\n  return {\n    parse(input, pos) {\n      const result = parser.parse(input, pos)\n\n      switch (result.isOk) {\n        case true: {\n          return result\n        }\n\n        case false: {\n          return {\n            isOk: false,\n            span: [pos, result.pos],\n            pos: result.pos,\n            expected\n          }\n        }\n      }\n    }\n  }\n}\n","import type { Parser } from '@types'\n\n/**\n * Applies `parser` without consuming any input. If `parser` fails and consumes some input, so does\n * `lookahead`.\n *\n * @param parser - Parser to apply\n *\n * @returns Result of `parser`\n */\nexport function lookahead<T>(parser: Parser<T>): Parser<T> {\n  return {\n    parse(input, pos) {\n      const result = parser.parse(input, pos)\n\n      switch (result.isOk) {\n        // If parser succeeded, keep the position untouched.\n        case true: {\n          return {\n            isOk: true,\n            span: result.span,\n            pos,\n            value: result.value\n          }\n        }\n\n        // If the parser failed, then still advance the pos cursor.\n        case false: {\n          return result\n        }\n      }\n    }\n  }\n}\n","import type { Parser } from '@types'\n\n/**\n * Simply resolves to `null`.\n *\n * @returns `null`.\n */\nexport function nothing(): Parser<null> {\n  return {\n    parse(_, pos) {\n      return {\n        isOk: true,\n        span: [pos, pos],\n        pos,\n        value: null\n      }\n    }\n  }\n}\n","import { choice } from './choice'\n\nimport { nothing } from '@parsers'\nimport type { Parser } from '@types'\n\n/**\n * Applies `parser`. Only fails if `parser` fails.\n *\n * @param parser - Parser to apply\n *\n * @returns Result of `parser` or `null`\n */\nexport function optional<T>(parser: Parser<T>): Parser<T | null> {\n  return choice(parser, nothing())\n}\n","import { many } from './many'\nimport { sequence } from './sequence'\n\nimport type { Parser } from '@types'\n\n/**\n * Parses *zero* or more occurrences of `parser`, separated by `sep`. Never fails.\n *\n * @param parser - Parser to apply\n * @param sep - Separating parser\n *\n * @returns List of values (without separator) returned by `parser`\n */\nexport function sepBy<T, S>(parser: Parser<T>, sep: Parser<S>): Parser<Array<T>> {\n  return {\n    parse(input, pos) {\n      // Run the parser once to get the first value.\n      const resultP = parser.parse(input, pos)\n\n      // If the parser succeeds, run the parser and separator parser many times.\n      if (resultP.isOk) {\n        const resultS = many(sequence(sep, parser)).parse(input, resultP.pos)\n        const values = [resultP.value]\n\n        // If the parsers succeed, concatenate the values sans the separator.\n        for (const [, value] of resultS.value) {\n          values.push(value)\n        }\n\n        return {\n          isOk: true,\n          span: [pos, resultS.pos],\n          pos: resultS.pos,\n          value: values\n        }\n      }\n\n      return {\n        isOk: true,\n        span: [pos, pos],\n        pos,\n        value: []\n      }\n    }\n  }\n}\n\n/**\n * Parses *one* or more occurrences of `parser`, separated by `sep`.\n *\n * @param parser - Parser to apply\n * @param sep - Separating parser\n *\n * @returns List of values (without separator) returned by `parser`\n */\nexport function sepBy1<T, S>(parser: Parser<T>, sep: Parser<S>): Parser<Array<T>> {\n  return {\n    parse(input, pos) {\n      // Run the parser once to get the first value.\n      const resultP = parser.parse(input, pos)\n\n      // If the parser succeeds, run the parser and separator parser many times.\n      if (resultP.isOk) {\n        const resultS = many(sequence(sep, parser)).parse(input, resultP.pos)\n        const values = [resultP.value]\n\n        // If the parsers succeed, concatenate the values sans the separator.\n        for (const [, value] of resultS.value) {\n          values.push(value)\n        }\n\n        return {\n          isOk: true,\n          span: [pos, resultS.pos],\n          pos: resultS.pos,\n          value: values\n        }\n      }\n\n      return {\n        isOk: false,\n        span: [pos, resultP.pos],\n        pos: resultP.pos,\n        expected: resultP.expected\n      }\n    }\n  }\n}\n","import { map } from './map'\nimport { sequence } from './sequence'\n\nimport type { Parser } from '@types'\n\nconst toLeft = <T1, T2>([left]: [T1, T2]): T1 => left\nconst toMiddle = <T1, T2, T3>([, middle]: [T1, T2, T3]): T2 => middle\nconst toRight = <T1, T2>([, right]: [T1, T2]): T2 => right\nconst toSides = <T1, T2, T3>([left, _, right]: [T1, T2, T3]): [T1, T3] => [left, right]\n\n/**\n * Takes exactly **two** parsers and applies them in order, returning the result of the leftmost\n * `p1` parser.\n *\n * @param p1 - First parser to apply\n * @param p2 - Second parser to apply\n *\n * @returns Result of the leftmost `p1` parser\n */\nexport function takeLeft<T1, T2>(p1: Parser<T1>, p2: Parser<T2>): Parser<T1> {\n  return map(sequence(p1, p2), toLeft)\n}\n\n/**\n * Takes exactly **three** parsers and applies them in order, returning the result of the `p2`\n * parser in the middle.\n *\n * @param p1 - First parser to apply\n * @param p2 - Second parser to apply\n * @param p3 - Third parser to apply\n *\n * @returns Result of the `p2` parser in the middle\n */\nexport function takeMid<T1, T2, T3>(p1: Parser<T1>, p2: Parser<T2>, p3: Parser<T3>): Parser<T2> {\n  return map(sequence(p1, p2, p3), toMiddle)\n}\n\n/**\n * Takes exactly **two** parsers and applies them in order, returning the result of the rightmost\n * `p2` parser.\n *\n * @param p1 - First parser to apply\n * @param p2 - Second parser to apply\n *\n * @returns Result of the rightmost `p2` parser\n */\nexport function takeRight<T1, T2>(p1: Parser<T1>, p2: Parser<T2>): Parser<T2> {\n  return map(sequence(p1, p2), toRight)\n}\n\n/**\n * Takes exactly **three** parsers and applies them in order, returning a tuple of the results of\n * `p1` and `p3` parsers.\n *\n * @param p1 - First parser to apply\n * @param p2 - Second parser to apply\n * @param p3 - Third parser to apply\n *\n * @returns Results of `p1` and `p3` parsers as a tuple\n */\nexport function takeSides<T1, T2, T3>(\n  p1: Parser<T1>,\n  p2: Parser<T2>,\n  p3: Parser<T3>\n): Parser<[T1, T3]> {\n  return map(sequence(p1, p2, p3), toSides)\n}\n","import type { Parser } from '@types'\n\n/**\n * Applies source `parser`, collects its output, and stops after `terminator` parser succeeds.\n *\n * @param parser - Parser to apply\n * @param terminator - Terminating parser to stop after\n *\n * @returns Tuple of values collected by `parser` and `terminator`\n */\nexport function takeUntil<T, S>(parser: Parser<T>, terminator: Parser<S>): Parser<[Array<T>, S]> {\n  return {\n    parse(input, pos) {\n      const values: Array<T> = []\n      let nextPos = pos\n\n      while (true) {\n        const resultT = terminator.parse(input, nextPos)\n\n        switch (resultT.isOk) {\n          // If ok, then we stumbled upon a terminating parser, so push final matches, and then\n          // return accumulated values.\n          case true: {\n            return {\n              isOk: true,\n              span: [pos, resultT.pos],\n              pos: resultT.pos,\n              value: [values, resultT.value]\n            }\n          }\n\n          // Otherwise try to run source parser and push results into `values`.\n          // If it fails, then return early and stop parsing.\n          case false: {\n            const resultP = parser.parse(input, nextPos)\n\n            if (resultP.isOk) {\n              values.push(resultP.value)\n              nextPos = resultP.pos\n              continue\n            }\n\n            return resultP\n          }\n        }\n      }\n    }\n  }\n}\n\n/**\n * Applies source `parser`, ignores its output, and stops after `terminator` parser succeeds.\n *\n * @param parser - Parser to apply\n * @param terminator - Terminating parser to stop after\n *\n * @returns Value of `terminator` parser\n */\nexport function skipUntil<T, S>(parser: Parser<T>, terminator: Parser<S>): Parser<S> {\n  return {\n    parse(input, pos) {\n      let nextPos = pos\n\n      while (true) {\n        const resultT = terminator.parse(input, nextPos)\n\n        switch (resultT.isOk) {\n          // If ok, then we stumbled upon a terminating parser, so return its value.\n          case true: {\n            return {\n              isOk: true,\n              span: [pos, resultT.pos],\n              pos: resultT.pos,\n              value: resultT.value\n            }\n          }\n\n          // Otherwise try to run source parser *ignoring* its results.\n          // If it fails, then return early and stop parsing.\n          case false: {\n            const resultP = parser.parse(input, nextPos)\n\n            if (resultP.isOk) {\n              nextPos = resultP.pos\n              continue\n            }\n\n            return resultP\n          }\n        }\n      }\n    }\n  }\n}\n","import type { Parser, ToParser } from '@types'\n\n/**\n * Context provided to a callback for producing conditional/chained parser.\n *\n * @internal\n */\ninterface Context<T> {\n  value: T\n  input: string\n  pos: number\n}\n\n/**\n * Creates chained, context-aware `parser`, that may depend on the output of the `context` parser.\n *\n * @param context - Source (context) parser\n * @param parser - Function that returns a new parser\n *\n * @returns New parser\n */\nexport function when<T, R extends Parser<unknown>>(\n  context: Parser<T>,\n  parser: (ctx: Context<T>) => R\n): ToParser<R> {\n  return {\n    parse(input, pos) {\n      const result = context.parse(input, pos)\n\n      switch (result.isOk) {\n        case true: {\n          return parser({ value: result.value, pos: result.pos, input }).parse(input, result.pos)\n        }\n\n        case false: {\n          return result\n        }\n      }\n    }\n  } as ToParser<R>\n}\n"]}