From 355a9f0d000f2732c7e00ec68ba69f3153c1e612 Mon Sep 17 00:00:00 2001
From: Boming Zhang <bomingzh@sjtu.edu.cn>
Date: Sat, 6 Apr 2024 16:41:53 -0400
Subject: [PATCH 1/2] feat: keyword parser

---
 internal/parsers/all.go            |  1 +
 internal/parsers/keyword/meta.go   |  9 ++++
 internal/parsers/keyword/parser.go | 67 ++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 internal/parsers/keyword/meta.go
 create mode 100644 internal/parsers/keyword/parser.go

diff --git a/internal/parsers/all.go b/internal/parsers/all.go
index d305bd6..c687743 100644
--- a/internal/parsers/all.go
+++ b/internal/parsers/all.go
@@ -4,6 +4,7 @@ import (
 	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/cpplint"
 	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/diff"
 	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/dummy"
+	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/keyword"
 	_ "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/parsers/resultstatus"
 )
 
diff --git a/internal/parsers/keyword/meta.go b/internal/parsers/keyword/meta.go
new file mode 100644
index 0000000..fd2dccd
--- /dev/null
+++ b/internal/parsers/keyword/meta.go
@@ -0,0 +1,9 @@
+package keyword
+
+import "focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
+
+var name = "keyword"
+
+func init() {
+	stage.RegisterParser(name, &Keyword{})
+}
diff --git a/internal/parsers/keyword/parser.go b/internal/parsers/keyword/parser.go
new file mode 100644
index 0000000..f11fb4a
--- /dev/null
+++ b/internal/parsers/keyword/parser.go
@@ -0,0 +1,67 @@
+package keyword
+
+import (
+	"fmt"
+	"strings"
+
+	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage"
+)
+
+type Match struct {
+	Keyword string
+	Score   int
+}
+
+type Conf struct {
+	FullScore  int
+	MinScore   int
+	Files      []string
+	EndOnMatch bool
+	Matches    []Match
+}
+
+type Keyword struct{}
+
+func Parse(executorResult stage.ExecutorResult, conf Conf) (
+	stage.ParserResult, bool,
+) {
+	score := conf.FullScore
+	comment := ""
+	matched := false
+	for _, file := range conf.Files {
+		content := executorResult.Files[file]
+		for _, match := range conf.Matches {
+			count := strings.Count(content, match.Keyword)
+			if count > 0 {
+				matched = true
+				score -= count * match.Score
+				comment += fmt.Sprintf(
+					"Matched keyword %d time(s): %s\n",
+					count, match.Keyword)
+			}
+		}
+	}
+	return stage.ParserResult{
+		Score:   min(score, conf.MinScore),
+		Comment: comment,
+	}, matched
+}
+
+func (*Keyword) Run(results []stage.ExecutorResult, confAny any) (
+	[]stage.ParserResult, bool, error,
+) {
+	conf, err := stage.DecodeConf[Conf](confAny)
+	if err != nil {
+		return nil, true, err
+	}
+	var res []stage.ParserResult
+	end := false
+	for _, result := range results {
+		tmp, matched := Parse(result, *conf)
+		if matched && conf.EndOnMatch {
+			end = true
+		}
+		res = append(res, tmp)
+	}
+	return res, end, nil
+}
-- 
2.30.2


From 83085ed38ab87ee458a33139973e6bbb7872ac9c Mon Sep 17 00:00:00 2001
From: Boming Zhang <bomingzh@sjtu.edu.cn>
Date: Sat, 27 Apr 2024 15:45:47 -0400
Subject: [PATCH 2/2] feat: test

---
 .gitmodules                        | 4 ++++
 examples/cpplint/sillycode         | 2 +-
 examples/keyword/sillycode         | 1 +
 internal/parsers/keyword/parser.go | 2 +-
 4 files changed, 7 insertions(+), 2 deletions(-)
 create mode 160000 examples/keyword/sillycode

diff --git a/.gitmodules b/.gitmodules
index 2d32453..5691987 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -18,3 +18,7 @@
 	path = examples/dummy/error
 	url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
 	branch = dummy/error
+[submodule "examples/keyword/sillycode"]
+	path = examples/keyword/sillycode
+	url = ssh://git@focs.ji.sjtu.edu.cn:2222/FOCS-dev/JOJ3-examples.git
+	branch = keyword/sillycode
diff --git a/examples/cpplint/sillycode b/examples/cpplint/sillycode
index e650457..a700156 160000
--- a/examples/cpplint/sillycode
+++ b/examples/cpplint/sillycode
@@ -1 +1 @@
-Subproject commit e6504575379ef49c1495dc635f7aba36f57dddc8
+Subproject commit a7001564a22f9807119efb7b8f4cf6f74d4c12fc
diff --git a/examples/keyword/sillycode b/examples/keyword/sillycode
new file mode 160000
index 0000000..09cfded
--- /dev/null
+++ b/examples/keyword/sillycode
@@ -0,0 +1 @@
+Subproject commit 09cfdedda32061a03b4335e9a0f162c7891301c9
diff --git a/internal/parsers/keyword/parser.go b/internal/parsers/keyword/parser.go
index f11fb4a..ccf0c0f 100644
--- a/internal/parsers/keyword/parser.go
+++ b/internal/parsers/keyword/parser.go
@@ -42,7 +42,7 @@ func Parse(executorResult stage.ExecutorResult, conf Conf) (
 		}
 	}
 	return stage.ParserResult{
-		Score:   min(score, conf.MinScore),
+		Score:   max(score, conf.MinScore),
 		Comment: comment,
 	}, matched
 }
-- 
2.30.2