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  }