<- Back to shtanton's homepage
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2022-09-23 14:55:58 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2022-09-23 14:55:58 +0100
commitf3911888915f6aa96e6b28bd2a98a662faf20f47 (patch)
tree55373234480b057e1615c0d51316be256b1d6d29
parent0a8690993d572a50b95dd4f1c1903ed00ddb9c2b (diff)
downloadsubex-f3911888915f6aa96e6b28bd2a98a662faf20f47.tar
Adds try, maybe and join operators with !, ? and ; respectively
-rw-r--r--main/parse.go29
-rw-r--r--main/regexast.go20
-rw-r--r--main/subexast.go36
3 files changed, 79 insertions, 6 deletions
diff --git a/main/parse.go b/main/parse.go
index a9bd4b5..6cc20ea 100644
--- a/main/parse.go
+++ b/main/parse.go
@@ -27,7 +27,7 @@ func parseRegex(l *RuneReader, minPower int) RegexAST {
switch r {
case eof:
return nil
- case ')', '*', '-', '|':
+ case ')', '*', '-', '|', '?', '!':
l.rewind()
return nil
case '(':
@@ -54,6 +54,10 @@ func parseRegex(l *RuneReader, minPower int) RegexAST {
lhs = RegexASTMaximise{lhs}
case r == '-' && minPower <= 4:
lhs = RegexASTMinimise{lhs}
+ case r == '!' && minPower <= 4:
+ lhs = RegexASTTry{lhs}
+ case r == '?' && minPower <= 4:
+ lhs = RegexASTMaybe{lhs}
case r == '|' && minPower <= 2:
rhs := parseRegex(l, 3)
if rhs == nil {
@@ -79,7 +83,7 @@ func parseSubex(l *RuneReader, minPower int) SubexAST {
if !l.accept(")") {
panic("Missing matching )")
}
- case ')', '*', '-', '|':
+ case ')', '*', '-', '|', '!', '?', ';':
l.rewind()
return nil
case '$':
@@ -113,16 +117,29 @@ func parseSubex(l *RuneReader, minPower int) SubexAST {
}
r := l.next()
switch {
- case r == '*' && minPower <= 4:
+ case r == '*' && minPower <= 8:
lhs = SubexASTMaximise{lhs}
- case r == '-' && minPower <= 4:
+ case r == '-' && minPower <= 8:
lhs = SubexASTMinimise{lhs}
- case r == '|' && minPower <= 2:
- rhs := parseSubex(l, 3)
+ case r == '!' && minPower <= 8:
+ lhs = SubexASTTry{lhs}
+ case r == '?' && minPower <= 8:
+ lhs = SubexASTMaybe{lhs}
+ case r == '|' && minPower <= 4:
+ rhs := parseSubex(l, 5)
if rhs == nil {
panic("Missing subex after |")
}
lhs = SubexASTOr{lhs, rhs}
+ case r == ';' && minPower <= 2:
+ rhs := parseSubex(l, 3)
+ if rhs == nil {
+ panic("Missing subex after ;")
+ }
+ lhs = SubexASTJoin{
+ content: lhs,
+ delimiter: rhs,
+ }
default:
l.rewind()
break loop
diff --git a/main/regexast.go b/main/regexast.go
index 0aab053..a5a60c4 100644
--- a/main/regexast.go
+++ b/main/regexast.go
@@ -70,3 +70,23 @@ func (ast RegexASTMinimise) compileWith(next RegexState) RegexState {
state.second = ast.content.compileWith(state)
return state
}
+
+type RegexASTTry struct {
+ content RegexAST
+}
+func (ast RegexASTTry) compileWith(next RegexState) RegexState {
+ return RegexGroupState{
+ ast.content.compileWith(next),
+ next,
+ }
+}
+
+type RegexASTMaybe struct {
+ content RegexAST
+}
+func (ast RegexASTMaybe) compileWith(next RegexState) RegexState {
+ return RegexGroupState {
+ next,
+ ast.content.compileWith(next),
+ }
+}
diff --git a/main/subexast.go b/main/subexast.go
index 7e2f33c..54cc5fe 100644
--- a/main/subexast.go
+++ b/main/subexast.go
@@ -115,3 +115,39 @@ func (ast SubexASTOutput) compileWith(next SubexState) SubexState {
next: next,
}
}
+
+type SubexASTTry struct {
+ content SubexAST
+}
+func (ast SubexASTTry) compileWith(next SubexState) SubexState {
+ return SubexGroupState {
+ ast.content.compileWith(next),
+ next,
+ }
+}
+
+type SubexASTMaybe struct {
+ content SubexAST
+}
+func (ast SubexASTMaybe) compileWith(next SubexState) SubexState {
+ return SubexGroupState {
+ next,
+ ast.content.compileWith(next),
+ }
+}
+
+type SubexASTJoin struct {
+ content, delimiter SubexAST
+}
+func (ast SubexASTJoin) compileWith(next SubexState) SubexState {
+ afterContentState := &SubexGroupState {
+ nil,
+ next,
+ }
+ manyContentsState := ast.content.compileWith(afterContentState)
+ afterContentState.first = ast.delimiter.compileWith(manyContentsState)
+ return SubexGroupState {
+ manyContentsState,
+ next,
+ }
+}