11import {
2- as ,
32 lazy ,
43 literal ,
54 map ,
@@ -29,18 +28,9 @@ export const moleculeParser: Parser<Molecule> = oneOf([
2928 lazy ( ( ) => sugaredFunction ) ,
3029] )
3130
32- // During parsing molecules and properties are represented as nested arrays (of key/value pairs).
33- // The following utilities make it easier to work with such a structure.
34-
35- const omit = ( theParser : Parser < unknown > ) => as ( theParser , [ ] )
36-
3731const optional = < Output > (
38- theParser : Parser < readonly Output [ ] > ,
39- ) : Parser < readonly Output [ ] > => oneOf ( [ theParser , omit ( nothing ) ] )
40-
41- const withoutOmittedOutputs = < Output > (
42- theParser : Parser < readonly ( readonly Output [ ] ) [ ] > ,
43- ) => map ( theParser , output => output . filter ( output => output . length > 0 ) )
32+ parser : Parser < NonNullable < Output > > ,
33+ ) : Parser < Output | undefined > => oneOf ( [ parser , nothing ] )
4434
4535// Keyless properties are automatically assigned numeric indexes, which uses some mutable state.
4636type Indexer = ( ) => string
@@ -54,8 +44,6 @@ const makeIncrementingIndexer = (): Indexer => {
5444 }
5545}
5646
57- // Language-specific parsers follow.
58-
5947const propertyDelimiter = oneOf ( [
6048 sequence ( [ optional ( trivia ) , literal ( ',' ) , optional ( trivia ) ] ) ,
6149 trivia ,
@@ -130,28 +118,31 @@ const property = (index: Indexer) =>
130118 oneOf ( [ namedProperty , numberedProperty ( index ) ] ) ,
131119 )
132120
133- const moleculeAsEntries = ( index : Indexer ) =>
134- withoutOmittedOutputs (
135- map (
136- sequence ( [
137- literal ( '{' ) ,
138- // Allow initial property not preceded by a delimiter (e.g. `{a b}`).
139- map ( optional ( property ( index ) ) , property => [ property ] ) ,
140- zeroOrMore (
141- map (
142- sequence ( [ propertyDelimiter , property ( index ) ] ) ,
143- ( [ _delimiter , property ] ) => property ,
144- ) ,
121+ const moleculeAsEntries = (
122+ index : Indexer ,
123+ ) : Parser < readonly ( readonly [ string , string | Molecule ] ) [ ] > =>
124+ map (
125+ sequence ( [
126+ literal ( '{' ) ,
127+ // Allow initial property not preceded by a delimiter (e.g. `{a b}`).
128+ optional ( property ( index ) ) ,
129+ zeroOrMore (
130+ map (
131+ sequence ( [ propertyDelimiter , property ( index ) ] ) ,
132+ ( [ _delimiter , property ] ) => property ,
145133 ) ,
146- optional ( omit ( propertyDelimiter ) ) ,
147- literal ( '}' ) ,
148- ] ) ,
149- ( [
150- _openingBrace ,
151- optionalInitialProperty ,
152- remainingProperties ,
153- _delimiter ,
154- _closingBrace ,
155- ] ) => [ ...optionalInitialProperty , ...remainingProperties ] ,
156- ) ,
134+ ) ,
135+ optional ( propertyDelimiter ) ,
136+ literal ( '}' ) ,
137+ ] ) ,
138+ ( [
139+ _openingBrace ,
140+ optionalInitialProperty ,
141+ remainingProperties ,
142+ _delimiter ,
143+ _closingBrace ,
144+ ] ) =>
145+ optionalInitialProperty === undefined
146+ ? remainingProperties
147+ : [ optionalInitialProperty , ...remainingProperties ] ,
157148 )
0 commit comments