mirror of
https://github.com/HeyPuter/puter.git
synced 2026-01-29 08:59:10 -06:00
Implement 'trailing' parameter for repeat() parser
This commit is contained in:
@@ -73,7 +73,7 @@ export class Optional extends Parser {
|
||||
/**
|
||||
* Parses a repeated sequence of values with separators between them.
|
||||
* @param value_parser Parser for the value
|
||||
* @param separator_parser Parser for the separator
|
||||
* @param separator_parser Parser for the separator, optional
|
||||
* @param trailing Whether to allow a trailing separator
|
||||
*/
|
||||
export class Repeat extends Parser {
|
||||
@@ -85,40 +85,49 @@ export class Repeat extends Parser {
|
||||
|
||||
_parse (stream) {
|
||||
const results = [];
|
||||
for ( ;; ) {
|
||||
const subStream = stream.fork();
|
||||
const subStream = stream.fork();
|
||||
|
||||
// Value
|
||||
const result = this.value_parser.parse(subStream);
|
||||
if ( result.status === UNRECOGNIZED ) {
|
||||
break;
|
||||
}
|
||||
if ( result.status === INVALID ) {
|
||||
return { status: INVALID, value: result };
|
||||
}
|
||||
// Parse first value
|
||||
const result = this.value_parser.parse(subStream);
|
||||
if ( result.status === INVALID )
|
||||
return { status: INVALID, value: result };
|
||||
|
||||
if ( result.status === VALUE ) {
|
||||
stream.join(subStream);
|
||||
if ( ! result.$discard ) results.push(result);
|
||||
if (!result.$discard) results.push(result);
|
||||
|
||||
// Separator
|
||||
if ( ! this.separator_parser ) {
|
||||
continue;
|
||||
}
|
||||
const separatorResult = this.separator_parser.parse(subStream);
|
||||
if ( separatorResult.status === UNRECOGNIZED ) {
|
||||
break;
|
||||
}
|
||||
if ( separatorResult.status === INVALID ) {
|
||||
return { status: INVALID, value: separatorResult };
|
||||
}
|
||||
stream.join(subStream);
|
||||
if ( ! result.$discard ) results.push(separatorResult);
|
||||
// Repeatedly parse <separator> <value>
|
||||
for (;;) {
|
||||
// Separator
|
||||
if (!this.separator_parser)
|
||||
continue;
|
||||
|
||||
// TODO: Detect trailing separator and reject it if trailing==false
|
||||
const separatorResult = this.separator_parser.parse(subStream);
|
||||
if (separatorResult.status === UNRECOGNIZED)
|
||||
break;
|
||||
if (separatorResult.status === INVALID)
|
||||
return { status: INVALID, value: separatorResult };
|
||||
stream.join(subStream);
|
||||
if (!separatorResult.$discard) results.push(separatorResult);
|
||||
|
||||
// Value
|
||||
const result = this.value_parser.parse(subStream);
|
||||
if (result.status === UNRECOGNIZED) {
|
||||
// If we failed to parse a value, we have a trailing separator
|
||||
if (this.trailing === false)
|
||||
return { status: INVALID, value: result };
|
||||
break;
|
||||
}
|
||||
if (result.status === INVALID)
|
||||
return { status: INVALID, value: result };
|
||||
|
||||
stream.join(subStream);
|
||||
if (!result.$discard) results.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
if ( results.length === 0 ) {
|
||||
if ( results.length === 0 )
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
|
||||
return { status: VALUE, value: results };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user