<- Back to shtanton's homepage
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2022-12-23 15:53:24 +0000
committerCharlie Stanton <charlie@shtanton.xyz>2022-12-23 15:53:24 +0000
commitc19df3ff75e7693e38940f20a5f3b40931be424a (patch)
tree5af34ca9683f3b66f3506a5e53df5e0cfd541b81
parentfb1f51d1da22f34509cf3fe1d174296d36a0f0ad (diff)
downloadsubex-c19df3ff75e7693e38940f20a5f3b40931be424a.tar
Changes main to read input from stdin. Prunes states that won't wouldn't ever reach the front of the state priority queue.
-rw-r--r--main/main.go34
-rw-r--r--main/subexast.go20
2 files changed, 38 insertions, 16 deletions
diff --git a/main/main.go b/main/main.go
index 0466371..cc671ee 100644
--- a/main/main.go
+++ b/main/main.go
@@ -3,6 +3,7 @@ package main
import (
"os"
"fmt"
+ "io"
)
type TransducerOutput interface {
@@ -53,6 +54,23 @@ func (pair SubexBranch) accepting() []string {
return pair.state.accepting(pair.store)
}
+func equalStates(left SubexBranch, right SubexBranch) bool {
+ // Only care about if they are the same pointer
+ return left.state == right.state
+}
+
+func pruneStates(states []SubexBranch) (newStates []SubexBranch) {
+ outer: for _, state := range states {
+ for _, newState := range newStates {
+ if equalStates(state, newState) {
+ continue outer
+ }
+ }
+ newStates = append(newStates, state)
+ }
+ return newStates
+}
+
func runTransducer(transducer SubexState, input string) (output string, err bool) {
states := []SubexBranch{{
state: transducer,
@@ -64,7 +82,7 @@ func runTransducer(transducer SubexState, input string) (output string, err bool
for _, state := range states {
newStates = append(newStates, state.eat(char)...)
}
- states = newStates
+ states = pruneStates(newStates)
}
for _, state := range states {
outputEnds := state.accepting()
@@ -76,16 +94,20 @@ func runTransducer(transducer SubexState, input string) (output string, err bool
}
func main() {
- if len(os.Args) != 3 {
- panic("Expected: program [input] [subex]")
+ if len(os.Args) != 2 {
+ panic("Expected: program [subex]")
+ }
+ inputBytes, inputErr := io.ReadAll(os.Stdin)
+ input := string(inputBytes)
+ if inputErr != nil {
+ fmt.Println("Error reading")
}
- input := os.Args[1]
- program := os.Args[2]
+ program := os.Args[1]
ast := parse(program)
transducer := compileTransducer(ast)
output, err := runTransducer(transducer, input)
if err {
output = input
}
- fmt.Println(output)
+ fmt.Print(output)
}
diff --git a/main/subexast.go b/main/subexast.go
index 510335f..040bc9d 100644
--- a/main/subexast.go
+++ b/main/subexast.go
@@ -23,8 +23,8 @@ type SubexASTStore struct {
slot rune
}
func (ast SubexASTStore) compileWith(next SubexState) SubexState {
- return SubexStoreState {
- match: ast.match.compileWith(SubexNoneState{}),
+ return &SubexStoreState {
+ match: ast.match.compileWith(&SubexNoneState{}),
slot: ast.slot,
next: next,
}
@@ -37,7 +37,7 @@ type SubexASTOr struct {
first, second SubexAST
}
func (ast SubexASTOr) compileWith(next SubexState) SubexState {
- return SubexGroupState {
+ return &SubexGroupState {
ast.first.compileWith(next),
ast.second.compileWith(next),
}
@@ -79,7 +79,7 @@ type SubexASTRepeat struct {
}
func (ast SubexASTRepeat) compileWith(next SubexState) SubexState {
for i := ast.min; i < ast.max; i += 1 {
- next = SubexGroupState {
+ next = &SubexGroupState {
ast.content.compileWith(next),
next,
}
@@ -92,7 +92,7 @@ func (ast SubexASTRepeat) compileWith(next SubexState) SubexState {
type SubexASTCopyRune rune
func (ast SubexASTCopyRune) compileWith(next SubexState) SubexState {
- return SubexCopyRuneState{
+ return &SubexCopyRuneState{
rune: rune(ast),
next: next,
}
@@ -100,7 +100,7 @@ func (ast SubexASTCopyRune) compileWith(next SubexState) SubexState {
type SubexASTCopyAny struct {}
func (ast SubexASTCopyAny) compileWith(next SubexState) SubexState {
- return SubexCopyAnyState{next}
+ return &SubexCopyAnyState{next}
}
func (ast SubexASTCopyAny) String() string {
return "."
@@ -110,7 +110,7 @@ type SubexASTOutput struct {
replacement []TransducerOutput
}
func (ast SubexASTOutput) compileWith(next SubexState) SubexState {
- return SubexOutputState{
+ return &SubexOutputState{
content: ast.replacement,
next: next,
}
@@ -120,7 +120,7 @@ type SubexASTTry struct {
content SubexAST
}
func (ast SubexASTTry) compileWith(next SubexState) SubexState {
- return SubexGroupState {
+ return &SubexGroupState {
ast.content.compileWith(next),
next,
}
@@ -130,7 +130,7 @@ type SubexASTMaybe struct {
content SubexAST
}
func (ast SubexASTMaybe) compileWith(next SubexState) SubexState {
- return SubexGroupState {
+ return &SubexGroupState {
next,
ast.content.compileWith(next),
}
@@ -146,7 +146,7 @@ func (ast SubexASTJoin) compileWith(next SubexState) SubexState {
}
manyContentsState := ast.content.compileWith(afterContentState)
afterContentState.first = ast.delimiter.compileWith(manyContentsState)
- return SubexGroupState {
+ return &SubexGroupState {
manyContentsState,
next,
}