mirror of
https://github.com/janet-lang/janet
synced 2024-11-05 16:26:17 +00:00
peg: add support for "true" and "false" primitives to always/never match
The use cases involve user-expandable grammars. For example, consider the IRC nickname specification. > They SHOULD NOT contain any dot character ('.', 0x2E). > Servers MAY have additional implementation-specific nickname restrictions. To implement this, we can do something along these lines: ```janet (def nickname @{:main '(some :allowed) :allowed (! (+ :forbidden/dot :forbidden/user)) # for lax mode, (put nickname :forbidden/dot false) :forbidden/dot "." # to add your own requirements # (put nickname :forbidden/user 'something) :forbidden/user false}) ``` Additionally, it's common in parsing theory to allow matches of the empty string (epsilon). `true` essentially allows for this. Note that this does not strictly add new functionality, you could emulate this previously using `0` and `(! 0)` respectively, but this should be faster and more intuitive. The speed improvement primarily comes from `(! 0)` which is now a single step.
This commit is contained in:
parent
0bd6e85c61
commit
f9ab91511d
@ -735,6 +735,12 @@ static const uint8_t *peg_getrange(Builder *b, Janet x) {
|
||||
return str;
|
||||
}
|
||||
|
||||
static int32_t peg_getboolean(Builder *b, Janet x) {
|
||||
if (!janet_checktype(x, JANET_BOOLEAN))
|
||||
peg_panicf(b, "expected boolean, got %v", x);
|
||||
return janet_unwrap_boolean(x);
|
||||
}
|
||||
|
||||
static int32_t peg_getinteger(Builder *b, Janet x) {
|
||||
if (!janet_checkint(x))
|
||||
peg_panicf(b, "expected integer, got %v", x);
|
||||
@ -1261,6 +1267,13 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
|
||||
default:
|
||||
peg_panic(b, "unexpected peg source");
|
||||
return 0;
|
||||
|
||||
case JANET_BOOLEAN: {
|
||||
int n = peg_getboolean(b, peg);
|
||||
Reserve r = reserve(b, 2);
|
||||
emit_1(r, n ? RULE_NCHAR : RULE_NOTNCHAR, 0);
|
||||
break;
|
||||
}
|
||||
case JANET_NUMBER: {
|
||||
int32_t n = peg_getinteger(b, peg);
|
||||
Reserve r = reserve(b, 2);
|
||||
|
Loading…
Reference in New Issue
Block a user