parser.go (2109B)
1 package parser 2 3 import ( 4 "bytes" 5 "strconv" 6 7 "github.com/uptrace/bun/internal" 8 ) 9 10 type Parser struct { 11 b []byte 12 i int 13 } 14 15 func New(b []byte) *Parser { 16 return &Parser{ 17 b: b, 18 } 19 } 20 21 func NewString(s string) *Parser { 22 return New(internal.Bytes(s)) 23 } 24 25 func (p *Parser) Valid() bool { 26 return p.i < len(p.b) 27 } 28 29 func (p *Parser) Bytes() []byte { 30 return p.b[p.i:] 31 } 32 33 func (p *Parser) Read() byte { 34 if p.Valid() { 35 c := p.b[p.i] 36 p.Advance() 37 return c 38 } 39 return 0 40 } 41 42 func (p *Parser) Peek() byte { 43 if p.Valid() { 44 return p.b[p.i] 45 } 46 return 0 47 } 48 49 func (p *Parser) Advance() { 50 p.i++ 51 } 52 53 func (p *Parser) Skip(skip byte) bool { 54 if p.Peek() == skip { 55 p.Advance() 56 return true 57 } 58 return false 59 } 60 61 func (p *Parser) SkipBytes(skip []byte) bool { 62 if len(skip) > len(p.b[p.i:]) { 63 return false 64 } 65 if !bytes.Equal(p.b[p.i:p.i+len(skip)], skip) { 66 return false 67 } 68 p.i += len(skip) 69 return true 70 } 71 72 func (p *Parser) ReadSep(sep byte) ([]byte, bool) { 73 ind := bytes.IndexByte(p.b[p.i:], sep) 74 if ind == -1 { 75 b := p.b[p.i:] 76 p.i = len(p.b) 77 return b, false 78 } 79 80 b := p.b[p.i : p.i+ind] 81 p.i += ind + 1 82 return b, true 83 } 84 85 func (p *Parser) ReadIdentifier() (string, bool) { 86 if p.i < len(p.b) && p.b[p.i] == '(' { 87 s := p.i + 1 88 if ind := bytes.IndexByte(p.b[s:], ')'); ind != -1 { 89 b := p.b[s : s+ind] 90 p.i = s + ind + 1 91 return internal.String(b), false 92 } 93 } 94 95 ind := len(p.b) - p.i 96 var alpha bool 97 for i, c := range p.b[p.i:] { 98 if isNum(c) { 99 continue 100 } 101 if isAlpha(c) || (i > 0 && alpha && c == '_') { 102 alpha = true 103 continue 104 } 105 ind = i 106 break 107 } 108 if ind == 0 { 109 return "", false 110 } 111 b := p.b[p.i : p.i+ind] 112 p.i += ind 113 return internal.String(b), !alpha 114 } 115 116 func (p *Parser) ReadNumber() int { 117 ind := len(p.b) - p.i 118 for i, c := range p.b[p.i:] { 119 if !isNum(c) { 120 ind = i 121 break 122 } 123 } 124 if ind == 0 { 125 return 0 126 } 127 n, err := strconv.Atoi(string(p.b[p.i : p.i+ind])) 128 if err != nil { 129 panic(err) 130 } 131 p.i += ind 132 return n 133 } 134 135 func isNum(c byte) bool { 136 return c >= '0' && c <= '9' 137 } 138 139 func isAlpha(c byte) bool { 140 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') 141 }