summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-10-16 13:56:13 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-10-17 22:25:18 +0300
commit297d8469b8fcaa072630c9561695edb001d96232 (patch)
tree04e7bfb9ddb60a8a8b84feb59c95c9d7cf4627b4
parent391db8669b77e50eebe4d1583749430a3549fab7 (diff)
downloadmicropython-297d8469b8fcaa072630c9561695edb001d96232.tar.gz
micropython-297d8469b8fcaa072630c9561695edb001d96232.zip
modure: Update to re1.5 v0.6.1, fixed and extended character class support.
-rw-r--r--extmod/re1.5/charclass.c8
-rw-r--r--extmod/re1.5/compilecode.c10
-rw-r--r--extmod/re1.5/dumpcode.c8
-rw-r--r--extmod/re1.5/re1.5.h1
-rw-r--r--extmod/re1.5/recursiveloop.c1
-rw-r--r--tests/extmod/ure1.py16
6 files changed, 35 insertions, 9 deletions
diff --git a/extmod/re1.5/charclass.c b/extmod/re1.5/charclass.c
index c9f617592b..c9df403750 100644
--- a/extmod/re1.5/charclass.c
+++ b/extmod/re1.5/charclass.c
@@ -3,9 +3,11 @@
int _re1_5_classmatch(const char *pc, const char *sp)
{
// pc points to "cnt" byte after opcode
+ int is_positive = (pc[-1] == Class);
int cnt = *pc++;
while (cnt--) {
- if (!(*sp >= *pc && *sp <= pc[1])) return 0;
+ if (*sp >= *pc && *sp <= pc[1]) return is_positive;
+ pc += 2;
}
- return 1;
-} \ No newline at end of file
+ return !is_positive;
+}
diff --git a/extmod/re1.5/compilecode.c b/extmod/re1.5/compilecode.c
index a7942b1216..2ed38d02c3 100644
--- a/extmod/re1.5/compilecode.c
+++ b/extmod/re1.5/compilecode.c
@@ -48,6 +48,7 @@ int re1_5_sizecode(const char *re)
case '[': {
pc += 2;
re++;
+ if (*re == '^') re++;
while (*re != ']') {
if (!*re) return -1;
if (re[1] == '-') {
@@ -91,10 +92,15 @@ const char *_compilecode(const char *re, ByteProg *prog)
case '[': {
int cnt;
term = pc;
- EMIT(pc++, Class);
+ re++;
+ if (*re == '^') {
+ EMIT(pc++, ClassNot);
+ re++;
+ } else {
+ EMIT(pc++, Class);
+ }
pc++; // Skip # of pair byte
prog->len++;
- re++;
for (cnt = 0; *re != ']'; re++, cnt++) {
if (!*re) return NULL;
EMIT(pc++, *re);
diff --git a/extmod/re1.5/dumpcode.c b/extmod/re1.5/dumpcode.c
index ca41cfeda4..1e2377675a 100644
--- a/extmod/re1.5/dumpcode.c
+++ b/extmod/re1.5/dumpcode.c
@@ -32,9 +32,11 @@ void re1_5_dumpcode(ByteProg *prog)
case Any:
printf("any\n");
break;
- case Class: {
- int num = code[pc++];
- printf("class %d", num);
+ case Class:
+ case ClassNot: {
+ int num = code[pc];
+ printf("class%s %d", (code[pc - 1] == ClassNot ? "not" : ""), num);
+ pc++;
while (num--) {
printf(" 0x%02x-0x%02x", code[pc], code[pc + 1]);
pc += 2;
diff --git a/extmod/re1.5/re1.5.h b/extmod/re1.5/re1.5.h
index ac41bab8f3..d8c1cf3e54 100644
--- a/extmod/re1.5/re1.5.h
+++ b/extmod/re1.5/re1.5.h
@@ -81,6 +81,7 @@ enum /* Inst.opcode */
Char = CONSUMERS,
Any,
Class,
+ ClassNot,
ASSERTS = 0x50,
Bol = ASSERTS,
diff --git a/extmod/re1.5/recursiveloop.c b/extmod/re1.5/recursiveloop.c
index 26c6da43de..f133b5d9b1 100644
--- a/extmod/re1.5/recursiveloop.c
+++ b/extmod/re1.5/recursiveloop.c
@@ -24,6 +24,7 @@ recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int n
sp++;
continue;
case Class:
+ case ClassNot:
if (!_re1_5_classmatch(pc, sp))
return 0;
pc += *(unsigned char*)pc * 2 + 1;
diff --git a/tests/extmod/ure1.py b/tests/extmod/ure1.py
index 577c8f61e7..1501a5264e 100644
--- a/tests/extmod/ure1.py
+++ b/tests/extmod/ure1.py
@@ -20,13 +20,27 @@ try:
except IndexError:
print("IndexError")
-r = re.compile("[a-c]")
+r = re.compile("[a-cu-z]")
m = r.match("a")
print(m.group(0))
+m = r.match("z")
+print(m.group(0))
m = r.match("d")
print(m)
m = r.match("A")
print(m)
+print("===")
+
+r = re.compile("[^a-cu-z]")
+m = r.match("a")
+print(m)
+m = r.match("z")
+print(m)
+m = r.match("d")
+print(m.group(0))
+m = r.match("A")
+print(m.group(0))
+
r = re.compile("o+")
m = r.search("foobar")