1- import { parser , type Parser } from '../../parsing.js'
1+ import {
2+ as ,
3+ lazy ,
4+ literal ,
5+ map ,
6+ nothing ,
7+ oneOf ,
8+ oneOrMore ,
9+ sequence ,
10+ zeroOrMore ,
11+ type Parser ,
12+ } from '@matt.kantor/parsing'
213import { atomParser , type Atom } from './atom.js'
314import { optionallySurroundedByParentheses } from './parentheses.js'
415import { trivia } from './trivia.js'
@@ -7,32 +18,32 @@ export type Molecule = { readonly [key: Atom]: Molecule | Atom }
718
819export const unit : Molecule = { }
920
10- export const moleculeParser : Parser < Molecule > = parser . oneOf ( [
21+ export const moleculeParser : Parser < Molecule > = oneOf ( [
1122 optionallySurroundedByParentheses (
12- parser . map (
13- parser . lazy ( ( ) => moleculeAsEntries ( makeIncrementingIndexer ( ) ) ) ,
23+ map (
24+ lazy ( ( ) => moleculeAsEntries ( makeIncrementingIndexer ( ) ) ) ,
1425 Object . fromEntries ,
1526 ) ,
1627 ) ,
17- parser . lazy ( ( ) => sugaredApply ) ,
18- parser . lazy ( ( ) => sugaredFunction ) ,
28+ lazy ( ( ) => sugaredApply ) ,
29+ lazy ( ( ) => sugaredFunction ) ,
1930] )
2031
2132// During parsing molecules and properties are represented as nested arrays (of key/value pairs).
2233// The following utilities make it easier to work with such a structure.
2334
2435const flat = < Output > ( theParser : Parser < readonly Output [ ] > ) =>
25- parser . map ( theParser , output => output . flat ( ) )
36+ map ( theParser , output => output . flat ( ) )
2637
27- const omit = ( theParser : Parser < unknown > ) => parser . as ( theParser , [ ] )
38+ const omit = ( theParser : Parser < unknown > ) => as ( theParser , [ ] )
2839
2940const optional = < Output > (
3041 theParser : Parser < readonly Output [ ] > ,
31- ) : Parser < readonly Output [ ] > => parser . oneOf ( [ theParser , omit ( parser . nothing ) ] )
42+ ) : Parser < readonly Output [ ] > => oneOf ( [ theParser , omit ( nothing ) ] )
3243
3344const withoutOmittedOutputs = < Output > (
3445 theParser : Parser < readonly ( readonly Output [ ] ) [ ] > ,
35- ) => parser . map ( theParser , output => output . filter ( output => output . length > 0 ) )
46+ ) => map ( theParser , output => output . filter ( output => output . length > 0 ) )
3647
3748// Keyless properties are automatically assigned numeric indexes, which uses some mutable state.
3849type Indexer = ( ) => string
@@ -48,37 +59,30 @@ const makeIncrementingIndexer = (): Indexer => {
4859
4960// Language-specific parsers follow.
5061
51- const propertyDelimiter = parser . oneOf ( [
52- parser . sequence ( [
53- optional ( omit ( trivia ) ) ,
54- parser . literal ( ',' ) ,
55- optional ( omit ( trivia ) ) ,
56- ] ) ,
62+ const propertyDelimiter = oneOf ( [
63+ sequence ( [ optional ( omit ( trivia ) ) , literal ( ',' ) , optional ( omit ( trivia ) ) ] ) ,
5764 trivia ,
5865] )
5966
6067const sugaredLookup : Parser < PartialMolecule > =
6168 optionallySurroundedByParentheses (
62- parser . map (
63- parser . sequence ( [
64- parser . literal ( ':' ) ,
65- parser . oneOf ( [ atomParser , moleculeParser ] ) ,
66- ] ) ,
69+ map (
70+ sequence ( [ literal ( ':' ) , oneOf ( [ atomParser , moleculeParser ] ) ] ) ,
6771 ( [ _colon , query ] ) => ( { 0 : '@lookup' , query } ) ,
6872 ) ,
6973 )
7074
7175const sugaredFunction : Parser < PartialMolecule > =
7276 optionallySurroundedByParentheses (
73- parser . map (
77+ map (
7478 flat (
75- parser . sequence ( [
76- parser . map ( atomParser , output => [ output ] ) ,
79+ sequence ( [
80+ map ( atomParser , output => [ output ] ) ,
7781 omit ( trivia ) ,
78- omit ( parser . literal ( '=>' ) ) ,
82+ omit ( literal ( '=>' ) ) ,
7983 omit ( trivia ) ,
80- parser . map (
81- parser . lazy ( ( ) => propertyValue ) ,
84+ map (
85+ lazy ( ( ) => propertyValue ) ,
8286 output => [ output ] ,
8387 ) ,
8488 ] ) ,
@@ -91,16 +95,16 @@ const sugaredFunction: Parser<PartialMolecule> =
9195 ) ,
9296 )
9397
94- const sugaredApply : Parser < PartialMolecule > = parser . map (
95- parser . sequence ( [
96- parser . oneOf ( [ sugaredLookup , parser . lazy ( ( ) => sugaredFunction ) ] ) ,
97- parser . oneOrMore (
98- parser . sequence ( [
99- parser . literal ( '(' ) ,
98+ const sugaredApply : Parser < PartialMolecule > = map (
99+ sequence ( [
100+ oneOf ( [ sugaredLookup , lazy ( ( ) => sugaredFunction ) ] ) ,
101+ oneOrMore (
102+ sequence ( [
103+ literal ( '(' ) ,
100104 optional ( omit ( trivia ) ) ,
101- parser . lazy ( ( ) => propertyValue ) ,
105+ lazy ( ( ) => propertyValue ) ,
102106 optional ( omit ( trivia ) ) ,
103- parser . literal ( ')' ) ,
107+ literal ( ')' ) ,
104108 ] ) ,
105109 ) ,
106110 ] ) ,
@@ -116,52 +120,49 @@ const sugaredApply: Parser<PartialMolecule> = parser.map(
116120)
117121
118122const propertyKey = atomParser
119- const propertyValue = parser . oneOf ( [
123+ const propertyValue = oneOf ( [
120124 sugaredApply , // must come first to avoid ambiguity
121- parser . lazy ( ( ) => moleculeParser ) , // must come second to avoid ambiguity
125+ lazy ( ( ) => moleculeParser ) , // must come second to avoid ambiguity
122126 atomParser ,
123127 sugaredLookup ,
124128] )
125129
126130const namedProperty = flat (
127- parser . sequence ( [
131+ sequence ( [
128132 propertyKey ,
129- omit ( parser . literal ( ':' ) ) ,
133+ omit ( literal ( ':' ) ) ,
130134 optional ( omit ( trivia ) ) ,
131135 propertyValue ,
132136 ] ) ,
133137)
134138
135139const numberedProperty = ( index : Indexer ) =>
136- parser . map ( propertyValue , value => [ index ( ) , value ] )
140+ map ( propertyValue , value => [ index ( ) , value ] )
137141
138142const property = ( index : Indexer ) =>
139143 optionallySurroundedByParentheses (
140- parser . oneOf ( [ namedProperty , numberedProperty ( index ) ] ) ,
144+ oneOf ( [ namedProperty , numberedProperty ( index ) ] ) ,
141145 )
142146
143147const moleculeAsEntries = ( index : Indexer ) =>
144148 withoutOmittedOutputs (
145149 flat (
146- parser . sequence ( [
147- omit ( parser . literal ( '{' ) ) ,
150+ sequence ( [
151+ omit ( literal ( '{' ) ) ,
148152 // Allow initial property not preceded by a delimiter (e.g. `{a b}`).
149- parser . map ( optional ( property ( index ) ) , property => [ property ] ) ,
150- parser . zeroOrMore (
153+ map ( optional ( property ( index ) ) , property => [ property ] ) ,
154+ zeroOrMore (
151155 flat (
152- parser . sequence ( [
153- omit ( propertyDelimiter ) ,
154- parser . lazy ( ( ) => property ( index ) ) ,
155- ] ) ,
156+ sequence ( [ omit ( propertyDelimiter ) , lazy ( ( ) => property ( index ) ) ] ) ,
156157 ) ,
157158 ) ,
158159 optional ( omit ( propertyDelimiter ) ) ,
159- omit ( parser . literal ( '}' ) ) ,
160+ omit ( literal ( '}' ) ) ,
160161 ] ) ,
161162 ) ,
162163 )
163164
164- // This is a lazy workaround for `parser. sequence` returning an array rather than a tuple with
165+ // This is a lazy workaround for `sequence` returning an array rather than a tuple with
165166// definitely-present elements.
166167type PartialMolecule = {
167168 readonly [ key : Atom ] : PartialMolecule | Atom | undefined
0 commit comments