Added support for detecting assertion characters; changed input so that newline isn't required
This commit is contained in:
28
main.go
28
main.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"slices"
|
||||
|
||||
@@ -128,6 +129,13 @@ func shuntingYard(re string) []postfixNode {
|
||||
outQueue = append(outQueue, newPostfixNode(dotChars()...))
|
||||
continue
|
||||
}
|
||||
if c == '^' { // Start-of-string assertion
|
||||
outQueue = append(outQueue, newPostfixNode(c))
|
||||
}
|
||||
if c == '$' { // End-of-string assertion
|
||||
outQueue = append(outQueue, newPostfixNode(c))
|
||||
}
|
||||
|
||||
if isOperator(c) {
|
||||
if len(opStack) == 0 {
|
||||
opStack = append(opStack, c)
|
||||
@@ -195,13 +203,27 @@ func shuntingYard(re string) []postfixNode {
|
||||
func thompson(re []postfixNode) *State {
|
||||
nfa := make([]*State, 0) // Stack of states
|
||||
for _, c := range re {
|
||||
if c.nodetype == CHARACTER {
|
||||
if c.nodetype == CHARACTER || c.nodetype == ASSERTION {
|
||||
state := State{}
|
||||
state.transitions = make(map[int][]*State)
|
||||
state.content = rune2Contents(c.contents)
|
||||
state.output = make([]*State, 0)
|
||||
state.output = append(state.output, &state)
|
||||
state.isEmpty = false
|
||||
if c.nodetype == ASSERTION {
|
||||
state.content = newContents(EPSILON) // Ideally, an assertion shouldn't have any content, since it doesn't say anything about the content of string
|
||||
state.isEmpty = true
|
||||
switch c.contents[0] {
|
||||
case '^':
|
||||
state.assert = SOS
|
||||
case '$':
|
||||
state.assert = EOS
|
||||
case 'b':
|
||||
state.assert = WBOUND
|
||||
case 'B':
|
||||
state.assert = NONWBOUND
|
||||
}
|
||||
}
|
||||
nfa = append(nfa, &state)
|
||||
}
|
||||
// Must be an operator if it isn't a character
|
||||
@@ -262,14 +284,14 @@ func main() {
|
||||
// Read test string from stdin
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
test_str, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
if err != nil && err != io.EOF {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Scanln(&test_str)
|
||||
re_postfix := shuntingYard(re)
|
||||
// fmt.Println(re_postfix)
|
||||
startState := thompson(re_postfix)
|
||||
matchIndices := findAllMatches(startState, test_str)
|
||||
|
||||
inColor := false
|
||||
if len(matchIndices) > 0 {
|
||||
for i, c := range test_str {
|
||||
|
Reference in New Issue
Block a user