defer primitive
Signature
ts
interface Deferred<T> extends Parser<T> {
with(parser: Parser<T>): void
}
function defer<T>(): Deferred<T>
Description
defer
is a special parser that has an additional with
method, which must be used to define the parser, before it is called. This parser is tailored for creating mutually recursive parsers.
Example
Combinators and parsers used in this section
In the example below we are parsing simple nested tuples like (1,2,(3,(4,5)))
into an AST, which then can be somehow manipulated. Every parsed node also has a span, that is location information.
ts
interface NumberNode {
type: 'number'
span: Span
value: number
}
interface ListNode {
type: 'list'
span: Span
value: Array<NumberNode | ListNode>
}
const TupleList = defer<ListNode>()
const TupleNumber = defer<NumberNode>()
TupleNumber.with(
map(
integer(),
(value, span) => ({ type: 'number', span, value })
)
)
TupleList.with(
map(
takeMid(
string('('),
sepBy(choice(TupleList, TupleNumber), string(',')),
string(')')
),
(value, span) => ({ type: 'list', span, value })
)
)
If we run our parser and feed it with input:
ts
run(TupleList).with('(1,2,(3,(4,5)))')
We will get the following result:
Success
ts
{
isOk: true,
span: [ 0, 15 ],
pos: 15,
value: {
type: 'list',
span: [ 0, 15 ],
value: [
{ type: 'number', span: [ 1, 2 ], value: 1 },
{ type: 'number', span: [ 3, 4 ], value: 2 },
{
type: 'list',
span: [ 5, 14 ],
value: [
{ type: 'number', span: [ 6, 7 ], value: 3 },
{
type: 'list',
span: [ 8, 13 ],
value: [
{ type: 'number', span: [ 9, 10 ], value: 4 },
{ type: 'number', span: [ 11, 12 ], value: 5 }
]
}
]
}
]
}
}