From 93903fc5572ed81dabcc05332d39b0b712515433 Mon Sep 17 00:00:00 2001 From: Aadhavan Srinivasan Date: Sat, 25 Jan 2025 13:04:36 -0500 Subject: [PATCH] Allowed creation of empty non-capturing groups --- compile.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compile.go b/compile.go index 0566133..252d3b7 100644 --- a/compile.go +++ b/compile.go @@ -658,6 +658,21 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { func thompson(re []postfixNode) (Reg, error) { nfa := make([]*State, 0) // Stack of states numGroups := 0 // Number of capturing groups + + // If thompson() receives an empty regex, then whatever was given to shuntingYard() + // was parsed away. This doesn't mean that the regex itself is empty. + // For example, it could have been '(?:)'. This is an empty non-capturing group. Since + // shuntingYard() doesn't include non-capturing groups in its output (and the group contains + // nothing), the output of shuntingYard() (and the input to thompson()) ends up being empty. + // In these cases, we will return an NFA with 1 state, with an assertion that is always true. + if len(re) == 0 { + start := newState() + start.content = newContents(EPSILON) + start.isEmpty = true + start.assert = ALWAYS_TRUE + nfa = append(nfa, &start) + } + for _, c := range re { if c.nodetype == CHARACTER || c.nodetype == ASSERTION { state := State{}