From d191686168e6b8012369a31abb686d680fecf8e6 Mon Sep 17 00:00:00 2001 From: Aadhavan Srinivasan Date: Tue, 22 Oct 2024 16:25:49 -0400 Subject: [PATCH] Rudimentary matching works --- main.go | 16 +++++++++++----- matching.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 matching.go diff --git a/main.go b/main.go index cc62206..e885475 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "slices" ) @@ -157,13 +158,18 @@ func thompson(re string) State { } func main() { + if len(os.Args) < 3 { + fmt.Println("ERROR: Missing cmdline args") + } var re string - // fmt.Scanln(&re) - re = "abab|abbb" + re = os.Args[1] re_postfix := shuntingYard(re) fmt.Println(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) {} diff --git a/matching.go b/matching.go new file mode 100644 index 0000000..4678cdf --- /dev/null +++ b/matching.go @@ -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 + +}