mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 14:20:22 +08:00
feat(parsely): Add stringUntil() parser
The counterpart of stringOf(), it reads characters until it matches its parameter.
This commit is contained in:
parent
5656d9d42f
commit
d46b043c5d
@ -1,6 +1,6 @@
|
||||
import { adapt_parser, VALUE } from './parser.js';
|
||||
import { Discard, FirstMatch, Optional, Repeat, Sequence } from './parsers/combinators.js';
|
||||
import { Fail, Literal, None, StringOf, Symbol } from './parsers/terminals.js';
|
||||
import { Fail, Literal, None, StringOf, StringUntil, Symbol } from './parsers/terminals.js';
|
||||
|
||||
class ParserWithAction {
|
||||
#parser;
|
||||
@ -89,6 +89,7 @@ export const standard_parsers = () => {
|
||||
repeat: Repeat,
|
||||
sequence: Sequence,
|
||||
stringOf: StringOf,
|
||||
stringUntil: StringUntil,
|
||||
symbol: Symbol,
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,53 @@ export class StringOf extends Parser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses characters into a string, until it encounters the given character, unescaped.
|
||||
* @param testOrCharacter End of the string. Either a character, or a function that takes a character,
|
||||
* and returns whether it ends the string.
|
||||
* @param escapeCharacter Character to use as the escape character. By default, is '\'.
|
||||
*/
|
||||
export class StringUntil extends Parser {
|
||||
_create(testOrCharacter, { escapeCharacter = '\\' } = {}) {
|
||||
if (typeof testOrCharacter === 'string') {
|
||||
this.test = (c => c === testOrCharacter);
|
||||
} else {
|
||||
this.test = testOrCharacter;
|
||||
}
|
||||
this.escapeCharacter = escapeCharacter;
|
||||
}
|
||||
|
||||
_parse(stream) {
|
||||
const subStream = stream.fork();
|
||||
let text = '';
|
||||
let lastWasEscape = false;
|
||||
|
||||
while (true) {
|
||||
let { done, value } = subStream.look();
|
||||
if ( done ) break;
|
||||
if ( !lastWasEscape && this.test(value) )
|
||||
break;
|
||||
|
||||
subStream.next();
|
||||
if (value === this.escapeCharacter) {
|
||||
lastWasEscape = true;
|
||||
continue;
|
||||
}
|
||||
lastWasEscape = false;
|
||||
text += value;
|
||||
}
|
||||
|
||||
if (lastWasEscape)
|
||||
return INVALID;
|
||||
|
||||
if (text.length === 0)
|
||||
return UNRECOGNIZED;
|
||||
|
||||
stream.join(subStream);
|
||||
return { status: VALUE, $: 'stringUntil', value: text };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an object defined by the symbol registry.
|
||||
* @param symbolName The name of the symbol to parse.
|
||||
|
Loading…
Reference in New Issue
Block a user