Added alternate function, removed relevant code from main; also started working on escape characters

master
Aadhavan Srinivasan 2 months ago
parent cda0dfb0cc
commit ae219f763a

@ -54,7 +54,7 @@ func shuntingYard(re string) string {
outQueue := make([]rune, 0) // Output queue outQueue := make([]rune, 0) // Output queue
// Actual algorithm // Actual algorithm
for _, c := range re_postfix { for i := 0; i < len(re_postfix); i++ {
/* Two cases: /* Two cases:
1. Current character is alphanumeric - send to output queue 1. Current character is alphanumeric - send to output queue
2. Current character is operator - do the following: 2. Current character is operator - do the following:
@ -65,9 +65,19 @@ func shuntingYard(re string) string {
3. If current character is '(', push to opStack 3. If current character is '(', push to opStack
4. If current character is ')', pop from opStack (and append to outQueue) until '(' is found. Discard parantheses. 4. If current character is ')', pop from opStack (and append to outQueue) until '(' is found. Discard parantheses.
*/ */
c := re_postfix[i]
if isAlphaNum(c) { if isAlphaNum(c) {
outQueue = append(outQueue, c) outQueue = append(outQueue, c)
continue
} }
// Escape character - NOT IMPLEMENTED YET - DO NOT USE
// if c == '\\' { // Escape character - next character is treated as alphanum
// if i == len(re_postfix)-1 { // End of string - panic, because backslash is an escape character (something needs to come after it)
// panic("ERROR: Backslash with no escape character.")
// }
// outQueue = append(outQueue, re_postfix[i+1])
// }
if isOperator(c) { if isOperator(c) {
if len(opStack) == 0 { if len(opStack) == 0 {
opStack = append(opStack, c) opStack = append(opStack, c)
@ -146,21 +156,8 @@ func thompson(re string) *State {
case '|': case '|':
s1 := mustPop(&nfa) s1 := mustPop(&nfa)
s2 := mustPop(&nfa) s2 := mustPop(&nfa)
s3 := State{} s3 := alternate(s1, s2)
s3.transitions = make(map[int][]*State) nfa = append(nfa, s3)
s3.output = append(s3.output, s1.output...)
s3.output = append(s3.output, s2.output...)
// Unique append is used here (and elsewhere) to ensure that,
// for any given transition, a state can only be mentioned once.
// For example, given the transition 'a', the state 's1' can only be mentioned once.
// This would lead to multiple instances of the same set of match indices, since both
// 's1' states would be considered to match.
s3.transitions[s1.content] = unique_append(s3.transitions[s1.content], s1)
s3.transitions[s2.content] = unique_append(s3.transitions[s2.content], s2)
s3.content = EPSILON
s3.isEmpty = true
nfa = append(nfa, &s3)
} }
} }
if len(nfa) != 1 { if len(nfa) != 1 {

@ -74,3 +74,21 @@ func kleene(s1 State) *State {
toReturn.transitions[s1.content] = unique_append(toReturn.transitions[s1.content], &s1) toReturn.transitions[s1.content] = unique_append(toReturn.transitions[s1.content], &s1)
return toReturn return toReturn
} }
func alternate(s1 *State, s2 *State) *State {
toReturn := &State{}
toReturn.transitions = make(map[int][]*State)
toReturn.output = append(toReturn.output, s1.output...)
toReturn.output = append(toReturn.output, s2.output...)
// Unique append is used here (and elsewhere) to ensure that,
// for any given transition, a state can only be mentioned once.
// For example, given the transition 'a', the state 's1' can only be mentioned once.
// This would lead to multiple instances of the same set of match indices, since both
// 's1' states would be considered to match.
toReturn.transitions[s1.content] = unique_append(toReturn.transitions[s1.content], s1)
toReturn.transitions[s2.content] = unique_append(toReturn.transitions[s2.content], s2)
toReturn.content = EPSILON
toReturn.isEmpty = true
return toReturn
}

Loading…
Cancel
Save