Added `a,b,c support

This commit is contained in:
Bruce Hill 2020-12-19 18:53:51 -08:00
parent c477bfdbd5
commit c28e647259
3 changed files with 54 additions and 20 deletions

View File

@ -44,6 +44,7 @@ Pattern | Meaning
`_` | Zero or more whitespace characters (excluding newlines)
`` `c `` | The literal character `c`
`` `a-z `` | The character range `a` through `z`
`` `a,b `` | The character `a` or the character `b`
`\n`, `\033`, `\x0A`, etc. | An escape sequence character
`\x00-xFF` | An escape sequence range (byte `0x00` through `0xFF` here)
`!pat` | `pat` does not match at the current position

4
bp.1
View File

@ -111,6 +111,10 @@ The literal \fBcharacter-\fI<c>\fR
.B `\fI<c1>\fB-\fI<c2>\fR
The \fBcharacter-range-\fI<c1>\fB-to-\fI<c2>\fR
.B `\fI<c1>\fB,\fI<c2>\fR
The literal \fBcharacter-\fI<c1>\fB-or-\fI<c2>\fR (can include arbitrarily many
comma-separated characters or character ranges).
.B \\\\\fI<esc>\fR
The \fBescape-sequence-\fI<esc>\fR (\fB\\n\fR, \fB\\x1F\fR, \fB\\033\fR, etc.)

View File

@ -142,27 +142,56 @@ vm_op_t *bpeg_simplepattern(file_t *f, const char *str)
}
// Char literals
case '`': {
char c = *str;
++str;
if (!c || c == '\n')
file_err(f, str, str, "There should be a character here after the '`'");
op->len = 1;
if (matchchar(&str, '-')) { // Range
char c2 = *str;
if (!c2 || c2 == '\n')
file_err(f, str, str, "There should be a character here to complete the character range.");
if (c2 < c)
file_err(f, origin, str+1, "Character ranges must be low-to-high, but this is high-to-low.");
op->op = VM_RANGE;
op->args.range.low = (unsigned char)c;
op->args.range.high = (unsigned char)c2;
vm_op_t *all = NULL;
do {
char c = *str;
if (!c || c == '\n')
file_err(f, str, str, "There should be a character here after the '`'");
if (op == NULL)
op = new(vm_op_t);
op->start = str-1;
op->len = 1;
++str;
} else {
op->op = VM_STRING;
char *s = xcalloc(sizeof(char), 2);
s[0] = c;
op->args.s = s;
}
if (matchchar(&str, '-')) { // Range
char c2 = *str;
if (!c2 || c2 == '\n')
file_err(f, str, str, "There should be a character here to complete the character range.");
op->op = VM_RANGE;
if (c < c2) {
op->args.range.low = (unsigned char)c;
op->args.range.high = (unsigned char)c2;
} else {
op->args.range.low = (unsigned char)c2;
op->args.range.high = (unsigned char)c;
}
++str;
} else {
op->op = VM_STRING;
char *s = xcalloc(sizeof(char), 2);
s[0] = c;
op->args.s = s;
}
op->end = str;
if (all == NULL) {
all = op;
} else {
vm_op_t *either = new(vm_op_t);
either->op = VM_OTHERWISE;
either->start = all->start;
either->end = op->end;
either->args.multiple.first = all;
either->args.multiple.second = op;
either->len = 1;
all = either;
}
op = NULL;
} while (matchchar(&str, ','));
op = all;
break;
}
// Escapes