Rudimentary matching works

master
Aadhavan Srinivasan 2 months ago
parent 9f9de2234f
commit d191686168

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"os"
"slices" "slices"
) )
@ -157,13 +158,18 @@ func thompson(re string) State {
} }
func main() { func main() {
if len(os.Args) < 3 {
fmt.Println("ERROR: Missing cmdline args")
}
var re string var re string
// fmt.Scanln(&re) re = os.Args[1]
re = "abab|abbb"
re_postfix := shuntingYard(re) re_postfix := shuntingYard(re)
fmt.Println(re_postfix) fmt.Println(re_postfix)
start := thompson(re_postfix) start := thompson(re_postfix)
UNUSED(start) s, e, matched := match(&start, os.Args[2])
if matched {
fmt.Printf("Matched from %d to %d\n", s, e)
} else {
fmt.Printf("No match found.\n")
}
} }
func UNUSED[T any](val T) {}

@ -0,0 +1,52 @@
package main
// match tries to match the regex represented by given start-state, with
// the given string
func match(start *State, str string) (startIdx int, endIdx int, matched bool) {
currentStates := make([]*State, 0)
tempStates := make([]*State, 0) // Used to store states that should be used in next loop iteration
i := 0 // Index in string
// Increment until we hit a character matching the start state
if start.isEmpty == false {
for int(str[i]) != start.content {
i++
}
}
currentStates = append(currentStates, start)
startIdx = i
i++ // Advance to next character so that we can check for transitions
// Main loop
for i < len(str) {
// If there are any 0-transitions, take those
// TODO: Maybe I need to keep taking 0-transitions until I don't have anymore. Needs to be tested
for _, state := range currentStates {
if len(state.transitions[EPSILON]) > 0 {
tempStates = append(tempStates, state.transitions[EPSILON]...)
}
}
copy(currentStates, tempStates)
tempStates = nil
// Take any transitions corresponding to current character
for _, state := range currentStates {
if len(state.transitions[int(str[i])]) > 0 {
tempStates = append(tempStates, state.transitions[int(str[i])]...)
}
}
copy(currentStates, tempStates)
tempStates = nil
// If any of the current-states is a last state, return true.
for _, state := range currentStates {
if state.isLast {
endIdx = i
return startIdx, endIdx, true
}
}
i++
}
// We don't seem to have reached a last-state. Return fals
return -1, -1, false
}
Loading…
Cancel
Save