diff --git a/compile.go b/compile.go index 4c8b463..7a6669b 100644 --- a/compile.go +++ b/compile.go @@ -344,7 +344,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { } if c == '\\' { // Escape character - invert special and non-special characters eg. \( is treated as a literal parentheses, \b is treated as word boundary - if i == len(re_postfix)-1 { // End of string - panic, because backslash is an escape character (something needs to come after it) + if i == len(re_postfix)-1 { // End of string - throw error, because backslash is an escape character (something needs to come after it) return nil, fmt.Errorf("backslash with no escape character") } i++ @@ -426,7 +426,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { regex += string(re_postfix[i]) i++ } - if len(regex) <= 1 { // Nothing in regex - panic + if len(regex) <= 1 { // Nothing in regex - throw error return nil, fmt.Errorf("invalid lookaround. (too short?)") } // 'regex' should now contain the lookaround regex, plus the characters at the start (which indicate pos/neg, ahead/behind) @@ -660,7 +660,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { endOfRange = false // Reset the flag } } - if i == len(re_postfix) { // We have reached the end of the string, so we didn't encounter a closing brakcet. Panic. + if i == len(re_postfix) { // We have reached the end of the string, so we didn't encounter a closing brakcet. Throw error. return nil, fmt.Errorf("opening bracket without closing bracket") } @@ -690,7 +690,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { startRangeNum, err := strconv.Atoi(string(startRange)) if err != nil { - panic(err) + return nil, fmt.Errorf("invalid numeric range") } if re_postfix[i] == '}' { // Case 1 above @@ -708,7 +708,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { return nil, fmt.Errorf("brace not closed") } if re_postfix[i] != '}' { - return nil, fmt.Errorf("invalid numeric specifier") + return nil, fmt.Errorf("invalid start range for numeric specifier") } if len(endRange) == 0 { // Case 3 above endRangeNum = INFINITE_REPS @@ -716,7 +716,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { var err error endRangeNum, err = strconv.Atoi(string(endRange)) if err != nil { - panic(err) + return nil, fmt.Errorf("invalid end range for numeric specifier") } } } @@ -737,7 +737,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { numOpenParens++ } if c == ')' { - // Keep popping from opStack until we encounter an opening parantheses or a NONCAPLPAREN_CHAR. Panic if we reach the end of the stack. + // Keep popping from opStack until we encounter an opening parantheses or a NONCAPLPAREN_CHAR. Throw error if we reach the end of the stack. var val rune var err error for val, err = peek(opStack); val != '(' && val != NONCAPLPAREN_CHAR; val, err = peek(opStack) { @@ -951,7 +951,10 @@ func thompson(re []postfixNode) (Reg, error) { nfa = append(nfa, s1) } case KLEENE: // Create a 0-state, concat the popped state after it, concat the 0-state after the popped state - s1 := mustPop(&nfa) + s1, err := pop(&nfa) + if err != nil { + return Reg{}, fmt.Errorf("error applying kleene star") + } stateToAdd := kleene(*s1) nfa = append(nfa, stateToAdd) case PLUS: // a+ is equivalent to aa*