github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/parse/parse.go (about) 1 package parse 2 3 import ( 4 "io" 5 "errors" 6 "github.com/v2pro/plz/countlog/loglog" 7 "unicode/utf8" 8 "reflect" 9 ) 10 11 func String(input string, lexer Lexer) (interface{}, error) { 12 src := NewSourceString(input) 13 left := Parse(src, lexer, 0) 14 if src.Error() != nil { 15 if src.Error() == io.EOF { 16 return left, nil 17 } 18 return nil, src.Error() 19 } 20 return left, nil 21 } 22 23 func Parse(src *Source, lexer Lexer, precedence int) interface{} { 24 token := lexer.PrefixToken(src) 25 if token == nil { 26 src.ReportError(errors.New("can not parse")) 27 return nil 28 } 29 loglog.Message("prefix", ">>>", reflect.TypeOf(token)) 30 left := token.PrefixParse(src) 31 loglog.Message("prefix", "<<<", reflect.TypeOf(token)) 32 for { 33 if src.Error() != nil { 34 return left 35 } 36 token, infixPrecedence := lexer.InfixToken(src) 37 if token == nil { 38 return left 39 } 40 if precedence >= infixPrecedence { 41 loglog.Message("precedence skip ", reflect.TypeOf(token), precedence, infixPrecedence) 42 return left 43 } 44 loglog.Message("infix ", ">>>", reflect.TypeOf(token)) 45 left = token.InfixParse(src, left) 46 loglog.Message("infix ", "<<<", reflect.TypeOf(token)) 47 } 48 return left 49 } 50 51 type Source struct { 52 err error 53 reader io.Reader 54 current []byte 55 nextList [][]byte 56 buf []byte 57 Attachment interface{} 58 } 59 60 func NewSource(reader io.Reader, buf []byte) (*Source, error) { 61 n, err := reader.Read(buf) 62 if n == 0 { 63 return nil, err 64 } 65 return &Source{ 66 reader: reader, 67 current: buf[:n], 68 buf: buf, 69 }, nil 70 } 71 72 func NewSourceString(src string) *Source { 73 return &Source{ 74 current: []byte(src), 75 } 76 } 77 78 func (src *Source) SetBuffer(buf []byte) { 79 src.buf = buf 80 } 81 82 func (src *Source) Peek() []byte { 83 return src.current 84 } 85 86 func (src *Source) Peek1() byte { 87 return src.current[0] 88 } 89 90 func (src *Source) PeekN(n int) ([]byte, error) { 91 if n <= len(src.current) { 92 return src.current[:n], nil 93 } 94 if src.reader == nil { 95 return src.current, io.EOF 96 } 97 peeked := src.current 98 for _, next := range src.nextList { 99 peeked = append(peeked, next...) 100 if len(peeked) >= n { 101 return peeked[:n], nil 102 } 103 } 104 for { 105 buf := make([]byte, len(src.buf)) 106 read, err := src.reader.Read(buf) 107 next := buf[:read] 108 peeked = append(peeked, next...) 109 src.nextList = append(src.nextList, next) 110 if len(peeked) >= n { 111 return peeked[:n], nil 112 } 113 if err != nil { 114 return peeked, err 115 } 116 } 117 } 118 119 func (src *Source) ConsumeN(n int) { 120 for n != 0 && n >= len(src.current) { 121 n -= len(src.current) 122 src.Consume() 123 } 124 src.current = src.current[n:] 125 } 126 127 func (src *Source) Consume1(b1 byte) { 128 if b1 != src.current[0] { 129 src.ReportError(errors.New( 130 "expect " + string([]byte{b1}) + 131 " but found " + string([]byte{src.current[0]}))) 132 } 133 src.ConsumeN(1) 134 } 135 136 func (src *Source) Consume() { 137 if src.reader == nil { 138 src.current = nil 139 src.ReportError(io.EOF) 140 return 141 } 142 if len(src.nextList) != 0 { 143 src.current = src.nextList[0] 144 src.nextList = src.nextList[1:] 145 return 146 } 147 n, err := src.reader.Read(src.buf) 148 if err != nil { 149 src.ReportError(err) 150 } 151 src.current = src.buf[:n] 152 } 153 154 func (src *Source) PeekRune() (rune, int) { 155 n := len(src.current) 156 if n < 1 { 157 return utf8.RuneError, 1 158 } 159 p0 := src.current[0] 160 x := first[p0] 161 if x >= as { 162 return utf8.DecodeRune(src.current) 163 } 164 sz := x & 7 165 fullBuf, _ := src.PeekN(int(sz)) 166 return utf8.DecodeRune(fullBuf) 167 } 168 169 func (src *Source) ReportError(err error) { 170 if src.err == nil { 171 src.err = err 172 } 173 } 174 175 func (src *Source) Error() error { 176 return src.err 177 } 178 179 const DefaultPrecedence = 1 180 181 type PrefixToken interface { 182 PrefixParse(src *Source) interface{} 183 } 184 185 type InfixToken interface { 186 InfixParse(src *Source, left interface{}) interface{} 187 } 188 189 type Lexer interface { 190 PrefixToken(src *Source) PrefixToken 191 InfixToken(src *Source) (InfixToken, int) 192 }