@@ -207,9 +207,39 @@ function or<T>(parsers: ParserComponent<T>[]): ParserComponent<T> {
207207 } ;
208208}
209209
210+ /** Join the parse results of the given parser into an array.
211+ *
212+ * If the parser fails at the first attempt, it will return an empty array.
213+ */
210214function join < T > (
211215 parser : ParserComponent < T > ,
212216 separator : string ,
217+ ) : ParserComponent < T [ ] > {
218+ const Separator = character ( separator ) ;
219+ return ( scanner : Scanner ) : ParseResult < T [ ] > => {
220+ const out : T [ ] = [ ] ;
221+ const first = parser ( scanner ) ;
222+ if ( ! first . ok ) return success ( out ) ;
223+ out . push ( first . body ) ;
224+ while ( ! scanner . eof ( ) ) {
225+ if ( ! Separator ( scanner ) . ok ) break ;
226+ const result = parser ( scanner ) ;
227+ if ( ! result . ok ) {
228+ throw new SyntaxError ( `Invalid token after "${ separator } "` ) ;
229+ }
230+ out . push ( result . body ) ;
231+ }
232+ return success ( out ) ;
233+ } ;
234+ }
235+
236+ /** Join the parse results of the given parser into an array.
237+ *
238+ * This requires the parser to succeed at least once.
239+ */
240+ function join1 < T > (
241+ parser : ParserComponent < T > ,
242+ separator : string ,
213243) : ParserComponent < T [ ] > {
214244 const Separator = character ( separator ) ;
215245 return ( scanner : Scanner ) : ParseResult < T [ ] > => {
@@ -522,7 +552,7 @@ export function symbols(scanner: Scanner): ParseResult<unknown> {
522552 return success ( value ) ;
523553}
524554
525- export const dottedKey = join ( or ( [ bareKey , basicString , literalString ] ) , "." ) ;
555+ export const dottedKey = join1 ( or ( [ bareKey , basicString , literalString ] ) , "." ) ;
526556
527557const BINARY_REGEXP = / 0 b [ 0 1 ] + (?: _ [ 0 1 ] + ) * \b / y;
528558export function binary ( scanner : Scanner ) : ParseResult < number | string > {
@@ -639,11 +669,7 @@ export function inlineTable(
639669 scanner . next ( 2 ) ;
640670 return success ( { } ) ;
641671 }
642- const pairs = surround (
643- "{" ,
644- join ( pair , "," ) ,
645- "}" ,
646- ) ( scanner ) ;
672+ const pairs = surround ( "{" , join ( pair , "," ) , "}" ) ( scanner ) ;
647673 if ( ! pairs . ok ) return failure ( ) ;
648674 let table = { } ;
649675 for ( const pair of pairs . body ) {
0 commit comments