Skip to content

Instantly share code, notes, and snippets.

@willhbr
Created March 4, 2015 02:02
Show Gist options
  • Save willhbr/19f78083e466de3898aa to your computer and use it in GitHub Desktop.
Save willhbr/19f78083e466de3898aa to your computer and use it in GitHub Desktop.
DFA Tester
package main
import (
"fmt"
"os"
"strings"
)
type State struct {
name string
actions map[string]*State
final bool
}
func (current State) test(input []string) bool {
if len(input) > 0 {
char := input[0]
input = input[1:]
if nextState, ok := current.actions[char]; ok {
return nextState.test(input)
} else {
return false
}
} else {
return current.final
}
}
func (current State) Test(input string) bool {
return current.test(strings.Split(input, ""))
}
func (node State) print(done *map[string]*State) {
(*done)[node.name] = &node
fmt.Print(node.name)
if node.final {
fmt.Println(".")
} else {
fmt.Println()
}
fmt.Println(node.actions)
for key, val := range node.actions {
if _, ok := (*done)[val.name]; !ok {
fmt.Println(key)
(*val).print(done)
}
}
}
func (node State) Print() {
m := make(map[string]*State)
node.print(&m)
}
// "final.(a:other b:other) other(a:final b:final)"
func parse(input string) *State {
inState := false
states := make(map[string]*State)
buffer := make([]string, 0)
var currentState *State
var initial *State
var key string
for _, char := range input {
if char <= 122 && char >= 97 || char >= 48 && char <= 57 {
buffer = append(buffer, string(char))
}
if (string(char) == "." || string(char) == "(") && len(buffer) > 0 {
name := strings.Join(buffer, "")
buffer = make([]string, 0)
inState = true
if val, ok := states[name]; ok {
currentState = val
currentState.final = string(char) == "."
} else {
currentState = &State{name, make(map[string]*State), string(char) == "."}
states[name] = currentState
}
if initial == nil {
initial = currentState
}
}
if string(char) == ":" {
key = strings.Join(buffer, "")
buffer = make([]string, 0)
}
if string(char) == "," && inState || string(char) == ")" {
if string(char) == ")" {
inState = false
}
name := strings.Join(buffer, "")
buffer = make([]string, 0)
var state *State
if val, ok := states[name]; ok {
state = val
} else {
state = &State{name, make(map[string]*State), false}
states[name] = state
}
currentState.actions[key] = state
}
}
return initial
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Useage: tester \"DFA\" testStrings...")
fmt.Println("DFA format: \"0.(a:1,b:1)1(a:0,b:0)\"")
} else {
stringDFA := os.Args[1]
tests := os.Args[2:]
init := parse(stringDFA)
for _, test := range tests {
fmt.Print(test + ": ")
fmt.Println(init.Test(test))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment