github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/lib/stringlib/pattern/pattern.go (about) 1 package pattern 2 3 import "errors" 4 5 // A Pattern is a data structure able to interpret a Lua "pattern" (see e.g. 6 // https://www.lua.org/manual/5.3/manual.html#6.4.1). 7 type Pattern struct { 8 items []patternItem 9 captureCount int 10 startAnchor, endAnchor bool 11 } 12 13 // New returns a new Pattern built from the given string (or an error if it is 14 // not a valid pattern string). 15 func New(ptn string) (*Pattern, error) { 16 pb := &patternBuilder{ptn: ptn} 17 return pb.getPattern() 18 } 19 20 // MatchFromStart returns a slice of Capture instances that match the given 21 // string, starting from the `init` index. 22 func (p *Pattern) MatchFromStart(s string, init int, budget uint64) (captures []Capture, used uint64) { 23 defer func() { 24 if r := recover(); r == budgetConsumed { 25 captures = nil 26 used = budget + 1 27 } 28 }() 29 matcher := patternMatcher{ 30 Pattern: *p, 31 s: s, 32 si: init, 33 budget: budget, 34 } 35 captures = matcher.findFromStart() 36 return captures, budget - matcher.budget 37 } 38 39 // Match returns a slice of Capture instances that match the given 40 // string, starting from the `init` index. 41 func (p *Pattern) Match(s string, init int, budget uint64) (captures []Capture, used uint64) { 42 defer func() { 43 if r := recover(); r == budgetConsumed { 44 captures = nil 45 used = budget + 1 46 } 47 }() 48 matcher := patternMatcher{ 49 Pattern: *p, 50 s: s, 51 si: init, 52 budget: budget, 53 } 54 captures = matcher.find() 55 return captures, budget - matcher.budget 56 } 57 58 // A Capture represents a matching substring. 59 type Capture struct { 60 start, end int 61 } 62 63 // Start index of the capture. 64 func (c Capture) Start() int { 65 return c.start 66 } 67 68 // End index of the capture. 69 func (c Capture) End() int { 70 return c.end 71 } 72 73 // IsEmpty is trye if the Capture is empty. 74 func (c Capture) IsEmpty() bool { 75 return c.end == -1 76 } 77 78 type patternItemType byte 79 80 const ( 81 ptnOnce patternItemType = iota 82 ptnGreedyRepeat 83 ptnGreedyRepeatOnce 84 ptnRepeat 85 ptnOptional 86 ptnCapture 87 ptnBalanced 88 ptnFrontier 89 ptnStartCapture 90 ptnEndCapture 91 ) 92 93 type patternItem struct { 94 bytes byteSet 95 ptnType patternItemType 96 } 97 98 var errInvalidPattern = errors.New("malformed pattern") 99 var errUnfinishedCapture = errors.New("unfinished capture") 100 var errInvalidPatternCapture = errors.New("invalid pattern capture") 101 var errPatternTooComplex = errors.New("pattern too complex")