diff --git a/main.go b/main.go index 76661f8..a2920d8 100644 --- a/main.go +++ b/main.go @@ -69,12 +69,17 @@ func shuntingYard(re string) string { if len(opStack) == 0 { opStack = append(opStack, c) } else { - if priority(c) > priority(peek(opStack)) { // 2a + topStack, err := peek(opStack) + if err != nil { + panic("ERROR: Operator without operand.") + } + if priority(c) > priority(topStack) { // 2a opStack = append(opStack, c) } else { - for len(opStack) > 0 && priority(c) <= priority(peek(opStack)) { // 2b - to_append := pop(&opStack) + for priority(c) <= priority(topStack) { // 2b + to_append := mustPop(&opStack) outQueue = append(outQueue, to_append) + topStack, _ = peek(opStack) } opStack = append(opStack, c) } @@ -84,17 +89,21 @@ func shuntingYard(re string) string { opStack = append(opStack, c) } if c == ')' { - for peek(opStack) != '(' { - to_append := pop(&opStack) + // Keep popping from opStack until we encounter an opening parantheses. Panic if we reach the end of the stack. + for val, err := peek(opStack); val != '('; val, err = peek(opStack) { + if err != nil { + panic("ERROR: Imbalanced parantheses.") + } + to_append := mustPop(&opStack) outQueue = append(outQueue, to_append) } - _ = pop(&opStack) // Get rid of opening parantheses + _ = mustPop(&opStack) // Get rid of opening parantheses } } // Pop all remaining operators (and append to outQueue) for len(opStack) > 0 { - to_append := pop(&opStack) + to_append := mustPop(&opStack) outQueue = append(outQueue, to_append) } @@ -118,15 +127,15 @@ func thompson(re string) *State { // Must be an operator if it isn't alphanumeric switch c { case CONCAT: - s2 := pop(&nfa) - s1 := pop(&nfa) + s2 := mustPop(&nfa) + s1 := mustPop(&nfa) for i := range s1.output { s1.output[i].transitions[s2.content] = append(s1.output[i].transitions[s2.content], s2) } s1.output = s2.output nfa = append(nfa, s1) case '*': // Create a 0-state, concat the popped state after it, concat the 0-state after the popped state - s1 := pop(&nfa) + s1 := mustPop(&nfa) stateToAdd := &State{} stateToAdd.transitions = make(map[int][]*State) stateToAdd.content = EPSILON @@ -139,7 +148,7 @@ func thompson(re string) *State { stateToAdd.transitions[s1.content] = append(stateToAdd.transitions[s1.content], s1) nfa = append(nfa, stateToAdd) case '+': - s1 := pop(&nfa) + s1 := mustPop(&nfa) for i := range s1.output { s1.output[i].transitions[s1.content] = append(s1.output[i].transitions[s1.content], s1) } @@ -148,8 +157,8 @@ func thompson(re string) *State { s1.output = append(s1.output, s1) nfa = append(nfa, s1) case '|': - s1 := pop(&nfa) - s2 := pop(&nfa) + s1 := mustPop(&nfa) + s2 := mustPop(&nfa) s3 := State{} s3.transitions = make(map[int][]*State) s3.output = append(s3.output, s1.output...)