The result of a parser function is a discriminated union that
represents either success or failure. In both cases need the
position
field to indicate where in the input stream we are.
This is field is defined in the base interface.
interface Position {
position: number
}
When parsing succeeds we return the the Ok<T>
object. It contains
the result
returned by the parser. Type parameter T
indicates
its type.
interface Ok<T> extends Position {
kind: "ok"
result: T
}
When parsing fails we return the Fail
object. It does not have a
result, but information about the input found
and input expected
.
interface Fail extends Position {
kind: "fail"
found: string
expected: string[]
}
The actual result type is a discriminated union of the Ok<T>
and
Fail
objects.
export type ParseResult<T> = Ok<T> | Fail
The joinExpected
function concatenates the list of expected
inputs from the other
failed parse result into the expected
array of the first one.
export function joinExpected(result: Fail, other: Fail) {
if (other.expected.length > 0)
result.expected = result.expected.concat(other.expected)
}
This function formats the array of expected inputs as a string for printing.
export function expectedAsCsv(result: Fail): string {
return result.expected.map(s => `"${s}"`).join(", ")
}
The following function is used to construct an Ok<T>
result.
export function succeeded<T>(pos: number, res: T): ParseResult<T> {
return {
kind: "ok",
position: pos,
result: res
}
}
The next one constructs a Fail
result.
export function failed<T>(pos: number, fnd: string, exp: string[] = []): ParseResult<T> {
return {
kind: "fail",
position: pos,
found: fnd,
expected: exp
}
}