From 544a88e9d4faa3f7e34316daaa01d2fa14d1d9f6 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 28 Sep 2020 17:42:38 -0700 Subject: Added +/*/? postfix operators --- compiler.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'compiler.c') diff --git a/compiler.c b/compiler.c index ba53579..5faf0f2 100644 --- a/compiler.c +++ b/compiler.c @@ -24,6 +24,12 @@ static void set_range(vm_op_t *op, ssize_t min, ssize_t max, vm_op_t *pat, vm_op op->args.repetitions.max = max; op->args.repetitions.repeat_pat = pat; op->args.repetitions.sep = sep; + if (!op->start) op->start = pat->start; + if (!op->end) op->end = pat->end; + if (sep) { + if (sep->start < op->start) op->start = sep->start; + if (sep->end > op->end) op->end = sep->end; + } } /* @@ -365,8 +371,26 @@ vm_op_t *bpeg_simplepattern(file_t *f, const char *str) // Postfix operators: postfix: - if (strncmp(after_spaces(str), "==", 2) == 0) { - str = after_spaces(str)+2; + if (f ? str >= f->end : !*str) return op; + str = after_spaces(str); + if (*str == '*' || *str == '+' || *str == '?') { // Repetitions: *, +, ? + char operator = *str; + ++str; + vm_op_t *pat = op; + vm_op_t *sep = NULL; + if (operator != '?' && matchchar(&str, '%')) { + sep = bpeg_simplepattern(f, str); + check(sep, "Expected pattern for separator after '%%'"); + str = sep->end; + } + op = calloc(sizeof(vm_op_t), 1); + set_range(op, operator == '+' ? 1 : 0, operator == '?' ? 1 : -1, pat, sep); + op->start = pat->start; + op->end = str; + op->len = -1; + goto postfix; + } else if (strncmp(str, "==", 2) == 0) { // Equality == + str = after_spaces(str+2); vm_op_t *first = op; vm_op_t *second = bpeg_simplepattern(f, str); check(second, "Expected pattern after '=='"); -- cgit v1.2.3