From 8abec0190168b7749c0e7e6a390056bc1b390318 Mon Sep 17 00:00:00 2001 From: ysugimoto Date: Sat, 19 Oct 2024 16:40:07 +0900 Subject: [PATCH] improve underlying lexer performance --- lexer/lexer.go | 107 ++------------------------------------------- lexer/pool.go | 12 ----- lexer/reader.go | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 116 deletions(-) delete mode 100644 lexer/pool.go create mode 100644 lexer/reader.go diff --git a/lexer/lexer.go b/lexer/lexer.go index 80a2278f..206cc250 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -29,6 +29,8 @@ func New(r io.Reader, opts ...OptionFunc) *Lexer { r: bufio.NewReader(r), line: 1, buffer: new(bytes.Buffer), + stack: make([]string, 0, 512), + peeks: make([]token.Token, 0, 8), file: o.Filename, customs: o.Customs, } @@ -416,111 +418,8 @@ func (l *Lexer) skipWhitespace() { } } -func (l *Lexer) readString() string { - buf := pool.Get().(*bytes.Buffer) // notlint:errcheck - defer pool.Put(buf) - buf.Reset() - - l.readChar() - for { - if l.char == '"' || l.char == 0x00 { - break - } - buf.WriteRune(l.char) - l.readChar() - } - - return buf.String() -} - -func (l *Lexer) readBracketString() string { - buf := pool.Get().(*bytes.Buffer) // notlint:errcheck - defer pool.Put(buf) - buf.Reset() - - l.readChar() - for { - if l.char == 0x00 { - break - } - if l.char == '"' { - if l.peekChar() == '}' { - l.readChar() - break - } - } - buf.WriteRune(l.char) - l.readChar() - } - - return buf.String() -} - -func (l *Lexer) readNumber() string { - buf := pool.Get().(*bytes.Buffer) // notlint:errcheck - defer pool.Put(buf) - buf.Reset() - - for isDigit(l.char) { - buf.WriteRune(l.char) - l.readChar() - } - return buf.String() -} - -func (l *Lexer) readEOL() string { - buf := pool.Get().(*bytes.Buffer) // notlint:errcheck - defer pool.Put(buf) - buf.Reset() - - for { - buf.WriteRune(l.char) - if l.peekChar() == 0x00 || l.peekChar() == '\n' { - break - } - l.readChar() - } - return buf.String() -} - -func (l *Lexer) readMultiComment() string { - buf := pool.Get().(*bytes.Buffer) // notlint:errcheck - defer pool.Put(buf) - buf.Reset() - - for { - if l.char == 0x00 { - break - } - if l.char == '*' && l.peekChar() == '/' { - buf.WriteRune(l.char) - l.readChar() - buf.WriteRune(l.char) - break - } - buf.WriteRune(l.char) - l.readChar() - } - - return buf.String() -} - -func (l *Lexer) readIdentifier() string { - buf := pool.Get().(*bytes.Buffer) // notlint:errcheck - defer pool.Put(buf) - buf.Reset() - - for l.isLetter(l.char) { - buf.WriteRune(l.char) - l.readChar() - } - return buf.String() -} - func (l *Lexer) isLetter(r rune) bool { - // Letter allows "-", "." and ":" character to parse ident http header name like `req.http.X-Forwarded-For` - // but in some name definitions (e.g. acl name, backend name), parser must check "-" IS NOT included. - // return 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || r == '_' || r == '-' || r == '.' || r == ':' + // Letter allows [a-zA-Z_] character to parse ident of http header name like `req`, `http`, `X-Forwarded-For`. return r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r == '_' } diff --git a/lexer/pool.go b/lexer/pool.go deleted file mode 100644 index d72c5320..00000000 --- a/lexer/pool.go +++ /dev/null @@ -1,12 +0,0 @@ -package lexer - -import ( - "bytes" - "sync" -) - -var pool = sync.Pool{ - New: func() any { - return new(bytes.Buffer) - }, -} diff --git a/lexer/reader.go b/lexer/reader.go new file mode 100644 index 00000000..44610961 --- /dev/null +++ b/lexer/reader.go @@ -0,0 +1,113 @@ +package lexer + +import ( + "bytes" + "sync" +) + +var pool = sync.Pool{ + New: func() any { + return new(bytes.Buffer) + }, +} + +func (l *Lexer) readString() string { + buf := pool.Get().(*bytes.Buffer) // notlint:errcheck + defer pool.Put(buf) + buf.Reset() + + l.readChar() + for { + if l.char == '"' || l.char == 0x00 { + break + } + buf.WriteRune(l.char) + l.readChar() + } + + return buf.String() +} + +func (l *Lexer) readBracketString() string { + buf := pool.Get().(*bytes.Buffer) // notlint:errcheck + defer pool.Put(buf) + buf.Reset() + + l.readChar() + for { + if l.char == 0x00 { + break + } + if l.char == '"' { + if l.peekChar() == '}' { + l.readChar() + break + } + } + buf.WriteRune(l.char) + l.readChar() + } + + return buf.String() +} + +func (l *Lexer) readNumber() string { + buf := pool.Get().(*bytes.Buffer) // notlint:errcheck + defer pool.Put(buf) + buf.Reset() + + for isDigit(l.char) { + buf.WriteRune(l.char) + l.readChar() + } + return buf.String() +} + +func (l *Lexer) readEOL() string { + buf := pool.Get().(*bytes.Buffer) // notlint:errcheck + defer pool.Put(buf) + buf.Reset() + + for { + buf.WriteRune(l.char) + if l.peekChar() == 0x00 || l.peekChar() == '\n' { + break + } + l.readChar() + } + return buf.String() +} + +func (l *Lexer) readMultiComment() string { + buf := pool.Get().(*bytes.Buffer) // notlint:errcheck + defer pool.Put(buf) + buf.Reset() + + for { + if l.char == 0x00 { + break + } + if l.char == '*' && l.peekChar() == '/' { + buf.WriteRune(l.char) + l.readChar() + buf.WriteRune(l.char) + break + } + buf.WriteRune(l.char) + l.readChar() + } + + return buf.String() +} + +func (l *Lexer) readIdentifier() string { + buf := pool.Get().(*bytes.Buffer) // notlint:errcheck + defer pool.Put(buf) + buf.Reset() + + for l.isLetter(l.char) { + buf.WriteRune(l.char) + l.readChar() + } + return buf.String() +}