|
|
|
@@ -171,7 +171,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
}
|
|
|
|
|
re_runes = append(re_runes, []rune(regex)...)
|
|
|
|
|
} else if c == '(' && i < len(re_runes_orig)-2 && re_runes_orig[i+1] == '?' && re_runes_orig[i+2] == ':' {
|
|
|
|
|
re_runes = append(re_runes, NONCAPLPAREN_CHAR)
|
|
|
|
|
re_runes = append(re_runes, nonCapLparenRune)
|
|
|
|
|
i += 2
|
|
|
|
|
} else if c == '\\' && i < len(re_runes_orig)-1 && re_runes_orig[i+1] == '\\' { // Escaped backslash
|
|
|
|
|
re_runes = append(re_runes, escBackslashRune)
|
|
|
|
@@ -254,7 +254,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
re_postfix = append(re_postfix, re_runes[i]) // Append closing brace
|
|
|
|
|
}
|
|
|
|
|
if i < len(re_runes)-3 && string(re_runes[i+1:i+4]) == "(?:" { // Non-capturing lparen
|
|
|
|
|
re_postfix = append(re_postfix, NONCAPLPAREN_CHAR)
|
|
|
|
|
re_postfix = append(re_postfix, nonCapLparenRune)
|
|
|
|
|
i += 3
|
|
|
|
|
}
|
|
|
|
|
if i < len(re_runes) && re_runes[i] == '\\' { // Something is being escaped (I don't add the backslash to re_postfix, because it was already added earlier)
|
|
|
|
@@ -303,7 +303,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
if i >= len(re_runes) {
|
|
|
|
|
return nil, fmt.Errorf("unclosed lookaround")
|
|
|
|
|
}
|
|
|
|
|
if re_runes[i] == '(' || re_runes[i] == NONCAPLPAREN_CHAR {
|
|
|
|
|
if re_runes[i] == '(' || re_runes[i] == nonCapLparenRune {
|
|
|
|
|
numOpenParens++
|
|
|
|
|
}
|
|
|
|
|
if re_runes[i] == ')' {
|
|
|
|
@@ -317,7 +317,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if i < len(re_runes) && (re_runes[i] != '(' && re_runes[i] != NONCAPLPAREN_CHAR && re_runes[i] != '|' && re_runes[i] != '\\') || (i > 0 && re_runes[i-1] == '\\') { // Every character should be concatenated if it is escaped
|
|
|
|
|
if i < len(re_runes) && (re_runes[i] != '(' && re_runes[i] != nonCapLparenRune && re_runes[i] != '|' && re_runes[i] != '\\') || (i > 0 && re_runes[i-1] == '\\') { // Every character should be concatenated if it is escaped
|
|
|
|
|
if i < len(re_runes)-1 {
|
|
|
|
|
if re_runes[i+1] != '|' && re_runes[i+1] != '*' && re_runes[i+1] != '+' && re_runes[i+1] != '?' && re_runes[i+1] != ')' && re_runes[i+1] != '{' {
|
|
|
|
|
re_postfix = append(re_postfix, concatRune)
|
|
|
|
@@ -433,7 +433,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
if i >= len(re_postfix) {
|
|
|
|
|
return nil, fmt.Errorf("unclosed lookaround")
|
|
|
|
|
}
|
|
|
|
|
if re_postfix[i] == '(' || re_postfix[i] == NONCAPLPAREN_CHAR {
|
|
|
|
|
if re_postfix[i] == '(' || re_postfix[i] == nonCapLparenRune {
|
|
|
|
|
numOpenParens++
|
|
|
|
|
}
|
|
|
|
|
if re_postfix[i] == ')' {
|
|
|
|
@@ -757,7 +757,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
outQueue[idx].startReps = startRangeNum
|
|
|
|
|
outQueue[idx].endReps = endRangeNum
|
|
|
|
|
}
|
|
|
|
|
if c == '(' || c == NONCAPLPAREN_CHAR {
|
|
|
|
|
if c == '(' || c == nonCapLparenRune {
|
|
|
|
|
opStack = append(opStack, c)
|
|
|
|
|
if c == '(' { // We only push _capturing_ group parentheses to outQueue
|
|
|
|
|
outQueue = append(outQueue, newPostfixNode(c))
|
|
|
|
@@ -768,7 +768,7 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
|
|
|
|
|
// 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) {
|
|
|
|
|
for val, err = peek(opStack); val != '(' && val != nonCapLparenRune; val, err = peek(opStack) {
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("imbalanced parantheses")
|
|
|
|
|
}
|
|
|
|
|