<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/subex/subexast.go
diff options
context:
space:
mode:
Diffstat (limited to 'subex/subexast.go')
-rw-r--r--subex/subexast.go163
1 files changed, 163 insertions, 0 deletions
diff --git a/subex/subexast.go b/subex/subexast.go
new file mode 100644
index 0000000..c583245
--- /dev/null
+++ b/subex/subexast.go
@@ -0,0 +1,163 @@
+package subex
+
+import (
+ "fmt"
+)
+
+type SubexAST interface {
+ compileWith(next SubexState) SubexState
+}
+
+type SubexASTConcat struct {
+ first, second SubexAST
+}
+func (ast SubexASTConcat) compileWith(next SubexState) SubexState {
+ return ast.first.compileWith(ast.second.compileWith(next))
+}
+func (ast SubexASTConcat) String() string {
+ return fmt.Sprintf("(%v)(%v)", ast.first, ast.second)
+}
+
+type SubexASTStore struct {
+ match SubexAST
+ slot rune
+}
+func (ast SubexASTStore) compileWith(next SubexState) SubexState {
+ return &SubexStoreState {
+ match: ast.match.compileWith(&SubexNoneState{}),
+ slot: ast.slot,
+ next: next,
+ }
+}
+func (ast SubexASTStore) String() string {
+ return fmt.Sprintf("$%c(%v)", ast.slot, ast.match)
+}
+
+type SubexASTOr struct {
+ first, second SubexAST
+}
+func (ast SubexASTOr) compileWith(next SubexState) SubexState {
+ return &SubexGroupState {
+ ast.first.compileWith(next),
+ ast.second.compileWith(next),
+ }
+}
+
+type SubexASTMaximise struct {
+ content SubexAST
+}
+func (ast SubexASTMaximise) compileWith(next SubexState) SubexState {
+ state := &SubexGroupState {
+ nil,
+ next,
+ }
+ state.first = ast.content.compileWith(state)
+ return state
+}
+func (ast SubexASTMaximise) String() string {
+ return fmt.Sprintf("(%v)*", ast.content)
+}
+
+type SubexASTMinimise struct {
+ content SubexAST
+}
+func (ast SubexASTMinimise) compileWith(next SubexState) SubexState {
+ state := &SubexGroupState {
+ next,
+ nil,
+ }
+ state.second = ast.content.compileWith(state)
+ return state
+}
+func (ast SubexASTMinimise) String() string {
+ return fmt.Sprintf("(%v)-", ast.content)
+}
+
+type SubexASTRepeat struct {
+ content SubexAST
+ min, max int
+}
+func (ast SubexASTRepeat) compileWith(next SubexState) SubexState {
+ for i := ast.min; i < ast.max; i += 1 {
+ next = &SubexGroupState {
+ ast.content.compileWith(next),
+ next,
+ }
+ }
+ for i := 0; i < ast.min; i += 1 {
+ next = ast.content.compileWith(next)
+ }
+ return next
+}
+
+type SubexASTCopyRune rune
+func (ast SubexASTCopyRune) compileWith(next SubexState) SubexState {
+ return &SubexCopyRuneState{
+ rune: rune(ast),
+ next: next,
+ }
+}
+
+type SubexASTCopyAny struct {}
+func (ast SubexASTCopyAny) compileWith(next SubexState) SubexState {
+ return &SubexCopyAnyState{next}
+}
+func (ast SubexASTCopyAny) String() string {
+ return "."
+}
+
+type SubexASTOutput struct {
+ replacement []TransducerOutput
+}
+func (ast SubexASTOutput) compileWith(next SubexState) SubexState {
+ return &SubexOutputState{
+ content: ast.replacement,
+ 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,
+ }
+}
+
+type SubexASTRange struct {
+ parts map[rune]rune
+}
+func (ast SubexASTRange) compileWith(next SubexState) SubexState {
+ return &SubexRangeState {
+ parts: ast.parts,
+ next: next,
+ }
+}