cmd/watchflakes/internal/script: lex !~ as a single token
Even though both ~ and !~ operators are documented as supported at
https://go.dev/wiki/Watchflakes, it seems only the former was ever
supported in practice. As it was uncovered when I tried the latter
in https://go.dev/issue/66337#issuecomment-2569872000, it fails to
parse with an "unexpected !" error.
The problem is that lex doesn't find the !~ token, it reports that
sequence as separate tokens ! and ~. Fix its logic.
Fixes golang/go#71119.
Change-Id: I08dd845a59e976a5eb2687924dce972680c90077
Reviewed-on: https://go-review.googlesource.com/c/build/+/640275
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/cmd/watchflakes/internal/script/script.go b/cmd/watchflakes/internal/script/script.go
index 499f2e7..6159251 100644
--- a/cmd/watchflakes/internal/script/script.go
+++ b/cmd/watchflakes/internal/script/script.go
@@ -454,7 +454,7 @@
p.i++
p.tok = p.s[p.pos:p.i]
return
- case '<': // <-, <=
+ case '<': // < <- <=
p.pos = p.i
p.i++
if p.i < len(p.s) && (p.s[p.i] == '-' || p.s[p.i] == '=') {
@@ -462,7 +462,15 @@
}
p.tok = p.s[p.pos:p.i]
return
- case '!', '>': // ! != > >=
+ case '!': // ! !~ !=
+ p.pos = p.i
+ p.i++
+ if p.i < len(p.s) && (p.s[p.i] == '~' || p.s[p.i] == '=') {
+ p.i++
+ }
+ p.tok = p.s[p.pos:p.i]
+ return
+ case '>': // > >=
p.pos = p.i
p.i++
if p.i < len(p.s) && p.s[p.i] == '=' {
diff --git a/cmd/watchflakes/internal/script/script_test.go b/cmd/watchflakes/internal/script/script_test.go
index 073de57..71cc09d 100644
--- a/cmd/watchflakes/internal/script/script_test.go
+++ b/cmd/watchflakes/internal/script/script_test.go
@@ -25,7 +25,7 @@
{"x ~", "a ~"},
{"x &", "a err: :1.3: invalid syntax at &"},
{"x &y", "a err: :1.3: invalid syntax at &"},
- {"output !~ `content`", "a ! ~ `"},
+ {"output !~ `content`", "a !~ `"},
}
func TestLex(t *testing.T) {
diff --git a/cmd/watchflakes/script_test.go b/cmd/watchflakes/script_test.go
index deb5d8d..79f2709 100644
--- a/cmd/watchflakes/script_test.go
+++ b/cmd/watchflakes/script_test.go
@@ -96,8 +96,17 @@
{
`default <- pkg == "cmd/go" && test == "TestScript" &&
output !~ ` + "`" + `The process cannot access the file because it is being used by another process.` + "`" + ` # tracked in go.dev/issue/71112`,
- nil,
- "script:2.22: unexpected !",
+ []*script.Rule{{
+ Action: "default",
+ Pattern: &script.AndExpr{
+ X: &script.AndExpr{
+ X: &script.CmpExpr{Field: "pkg", Op: "==", Literal: "cmd/go"},
+ Y: &script.CmpExpr{Field: "test", Op: "==", Literal: "TestScript"},
+ },
+ Y: &script.RegExpr{Field: "output", Not: true, Regexp: regexp.MustCompile(`(?m)The process cannot access the file because it is being used by another process.`)},
+ },
+ }},
+ "",
},
{
`post <- pkg ~ "^cmd/go"`,