main.go raw
1 // Command regexp_ref prints the same case table tests/data/regexp/main.mx
2 // prints, using Go's regexp. Legacy's -print-allocs matches with Go's regexp,
3 // so this is the reference for the stage4 matcher in pkg/mxregexp: the two
4 // outputs must be byte identical.
5 package main
6
7 import (
8 "fmt"
9 "os"
10 "regexp"
11 "strings"
12 )
13
14 func unescape(s string) string {
15 if !strings.Contains(s, `\`) {
16 return s
17 }
18 var b strings.Builder
19 for i := 0; i < len(s); {
20 if s[i] == '\\' && i+1 < len(s) {
21 switch s[i+1] {
22 case 'n':
23 b.WriteByte('\n')
24 i += 2
25 continue
26 case 't':
27 b.WriteByte('\t')
28 i += 2
29 continue
30 case 'r':
31 b.WriteByte('\r')
32 i += 2
33 continue
34 case '\\':
35 b.WriteByte('\\')
36 i += 2
37 continue
38 }
39 }
40 b.WriteByte(s[i])
41 i++
42 }
43 return b.String()
44 }
45
46 func main() {
47 if len(os.Args) < 2 {
48 fmt.Fprintln(os.Stderr, "usage: regexp_ref <cases-file>")
49 os.Exit(2)
50 }
51 data, err := os.ReadFile(os.Args[1])
52 if err != nil {
53 fmt.Fprintln(os.Stderr, err)
54 os.Exit(2)
55 }
56 for i, line := range strings.Split(string(data), "\n") {
57 if line == "" {
58 continue
59 }
60 tab := strings.IndexByte(line, '\t')
61 if tab < 0 {
62 fmt.Printf("case %d: missing tab\n", i)
63 os.Exit(1)
64 }
65 pattern, text := line[:tab], unescape(line[tab+1:])
66 re, cerr := regexp.Compile(pattern)
67 if cerr != nil {
68 fmt.Printf("%d error\n", i)
69 continue
70 }
71 fmt.Printf("%d %t\n", i, re.MatchString(text))
72 }
73 }
74