From 6c508518ffd95d9badac7a017e528ce6b64354f9 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 14 Oct 2008 16:32:43 -0700 Subject: implement matching clean up interface equality hack still needs more tests; checking in for gccgo testing R=rsc DELTA=304 (261 added, 14 deleted, 29 changed) OCL=17128 CL=17135 --- usr/r/regexp/main.go | 129 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 6 deletions(-) (limited to 'usr/r/regexp/main.go') diff --git a/usr/r/regexp/main.go b/usr/r/regexp/main.go index d723d87a9..25ec07ade 100644 --- a/usr/r/regexp/main.go +++ b/usr/r/regexp/main.go @@ -9,14 +9,131 @@ import ( "regexp"; ) +var good_re = []string{ + `` +, `.` +, `^.$` +, `a` +, `a*` +, `a+` +, `a?` +, `a|b` +, `a*|b*` +, `(a*|b)(c*|d)` +, `[a-z]` +, `[a-abc-c\-\]\[]` +, `[a-z]+` +, `[]` +, `[abc]` +, `[^1234]` +} + +// TODO: nice to do this with a map but we don't have an iterator +type StringError struct { + re string; + err *os.Error; +} +var bad_re = []StringError{ + StringError{ `*`, regexp.ErrBareClosure }, + StringError{ `(abc`, regexp.ErrUnmatchedLpar }, + StringError{ `abc)`, regexp.ErrUnmatchedRpar }, + StringError{ `x[a-z`, regexp.ErrUnmatchedLbkt }, + StringError{ `abc]`, regexp.ErrUnmatchedRbkt }, + StringError{ `[z-a]`, regexp.ErrBadRange }, + StringError{ `abc\`, regexp.ErrExtraneousBackslash }, + StringError{ `a**`, regexp.ErrBadClosure }, + StringError{ `a*+`, regexp.ErrBadClosure }, + StringError{ `a??`, regexp.ErrBadClosure }, + StringError{ `*`, regexp.ErrBareClosure }, + StringError{ `\x`, regexp.ErrBadBackslash } +} + +type Vec [20]int; + +type Tester struct { + re string; + text string; + match Vec; +} + +var matches = []Tester { + Tester{ ``, "", Vec{0,0, -1,-1} }, + Tester{ `a`, "a", Vec{0,1, -1,-1} }, + Tester{ `b`, "abc", Vec{1,2, -1,-1} }, + Tester{ `.`, "a", Vec{0,1, -1,-1} }, + Tester{ `.*`, "abcdef", Vec{0,6, -1,-1} }, + Tester{ `^abcd$`, "abcd", Vec{0,4, -1,-1} }, + Tester{ `^bcd'`, "abcdef", Vec{-1,-1} }, + Tester{ `^abcd$`, "abcde", Vec{-1,-1} }, + Tester{ `a+`, "baaab", Vec{1, 4, -1,-1} }, + Tester{ `a*`, "baaab", Vec{0, 0, -1,-1} } +} + +func Compile(expr string, error *os.Error) regexp.Regexp { + re, err := regexp.Compile(expr); + if err != error { + print("compiling `", expr, "`; unexpected error: ", err.String(), "\n"); + sys.exit(1); + } + return re +} + +func MarkedLen(m *[] int) int { + if m == nil { + return 0 + } + var i int; + for i = 0; i < len(m) && m[i] >= 0; i = i+2 { + } + return i +} + +func PrintVec(m *[] int) { + l := MarkedLen(m); + for i := 0; i < l && m[i] >= 0; i = i+2 { + print(m[i], ",", m[i+1], " ") + } +} + +func Equal(m1, m2 *[]int) bool { + l := MarkedLen(m1); + if l != MarkedLen(m2) { + return false + } + for i := 0; i < l; i++ { + if m1[i] != m2[i] { + return false + } + } + return true +} + +func Match(expr string, str string, match *[]int) { + re := Compile(expr, nil); + m := re.Execute(str); + if !Equal(m, match) { + print("failure on `", expr, "` matching `", str, "`:\n"); + PrintVec(m); + print("\nshould be:\n"); + PrintVec(match); + print("\n"); + sys.exit(1); + } +} + func main() { - str := "a*b*c*"; if sys.argc() > 1 { - str = sys.argv(1); + Compile(sys.argv(1), nil); + sys.exit(0); } - re, err := regexp.Compile(str); - if err != nil { - print("error: ", err.String(), "\n"); - sys.exit(1); + for i := 0; i < len(good_re); i++ { + Compile(good_re[i], nil); + } + for i := 0; i < len(bad_re); i++ { + Compile(bad_re[i].re, bad_re[i].err) + } + for i := 0; i < len(matches); i++ { + t := &matches[i]; + Match(t.re, t.text, &t.match) } } -- cgit v1.2.3