Add linter, fix linting issue

This commit is contained in:
David Stotijn
2021-04-25 16:23:53 +02:00
parent ad3dc0da70
commit ca3a729c36
18 changed files with 442 additions and 231 deletions

View File

@ -11,7 +11,6 @@ type PrefixExpression struct {
Right Expression
}
func (pe *PrefixExpression) expressionNode() {}
func (pe *PrefixExpression) String() string {
b := strings.Builder{}
b.WriteString("(")
@ -29,7 +28,6 @@ type InfixExpression struct {
Right Expression
}
func (ie *InfixExpression) expressionNode() {}
func (ie *InfixExpression) String() string {
b := strings.Builder{}
b.WriteString("(")
@ -47,7 +45,6 @@ type StringLiteral struct {
Value string
}
func (sl *StringLiteral) expressionNode() {}
func (sl *StringLiteral) String() string {
return sl.Value
}

View File

@ -17,21 +17,21 @@ const eof = 0
// Token types.
const (
// Flow
// Flow.
TokInvalid TokenType = iota
TokEOF
TokParenOpen
TokParenClose
// Literals
// Literals.
TokString
// Boolean operators
// Boolean operators.
TokOpNot
TokOpAnd
TokOpOr
// Comparison operators
// Comparison operators.
TokOpEq
TokOpNotEq
TokOpGt
@ -98,6 +98,7 @@ func (tt TokenType) String() string {
if typeString, ok := tokenTypeStrings[tt]; ok {
return typeString
}
return "<unknown>"
}
@ -113,6 +114,7 @@ func (l *Lexer) read() (r rune) {
l.width = 0
return eof
}
r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
l.pos += l.width
@ -124,6 +126,7 @@ func (l *Lexer) emit(tokenType TokenType) {
Type: tokenType,
Literal: l.input[l.start:l.pos],
}
l.start = l.pos
}
@ -159,6 +162,7 @@ func begin(l *Lexer) stateFn {
l.backup()
l.emit(TokOpEq)
}
return begin
case '!':
switch next := l.read(); next {
@ -169,6 +173,7 @@ func begin(l *Lexer) stateFn {
default:
return l.errorf("invalid rune %v", r)
}
return begin
case '<':
if next := l.read(); next == '=' {
@ -177,6 +182,7 @@ func begin(l *Lexer) stateFn {
l.backup()
l.emit(TokOpLt)
}
return begin
case '>':
if next := l.read(); next == '=' {
@ -185,6 +191,7 @@ func begin(l *Lexer) stateFn {
l.backup()
l.emit(TokOpGt)
}
return begin
case '(':
l.emit(TokParenOpen)
@ -231,15 +238,18 @@ func unquotedString(l *Lexer) stateFn {
case r == eof:
l.backup()
l.emitUnquotedString()
return begin
case unicode.IsSpace(r):
l.backup()
l.emitUnquotedString()
l.skip()
return begin
case isReserved(r):
l.backup()
l.emitUnquotedString()
return begin
}
}
@ -251,6 +261,7 @@ func (l *Lexer) emitUnquotedString() {
l.emit(tokType)
return
}
l.emit(TokString)
}
@ -260,5 +271,6 @@ func isReserved(r rune) bool {
return true
}
}
return false
}

View File

@ -3,6 +3,8 @@ package search
import "testing"
func TestNextToken(t *testing.T) {
t.Parallel()
tests := []struct {
name string
input string

View File

@ -18,8 +18,10 @@ const (
precGroup
)
type prefixParser func(*Parser) (Expression, error)
type infixParser func(*Parser, Expression) (Expression, error)
type (
prefixParser func(*Parser) (Expression, error)
infixParser func(*Parser, Expression) (Expression, error)
)
var (
prefixParsers = map[TokenType]prefixParser{}
@ -77,7 +79,6 @@ func NewParser(l *Lexer) *Parser {
p.nextToken()
return p
}
func ParseQuery(input string) (expr Expression, err error) {
@ -91,18 +92,20 @@ func ParseQuery(input string) (expr Expression, err error) {
for !p.curTokenIs(TokEOF) {
right, err := p.parseExpression(precLowest)
if err != nil {
return nil, fmt.Errorf("search: could not parse expression: %v", err)
}
if expr == nil {
switch {
case err != nil:
return nil, fmt.Errorf("search: could not parse expression: %w", err)
case expr == nil:
expr = right
} else {
default:
expr = &InfixExpression{
Operator: TokOpAnd,
Left: expr,
Right: right,
}
}
p.nextToken()
}
@ -122,18 +125,11 @@ func (p *Parser) peekTokenIs(t TokenType) bool {
return p.peek.Type == t
}
func (p *Parser) expectPeek(t TokenType) error {
if !p.peekTokenIs(t) {
return fmt.Errorf("expected next token to be %v, got %v", t, p.peek.Type)
}
p.nextToken()
return nil
}
func (p *Parser) curPrecedence() precedence {
if p, ok := tokenPrecedences[p.cur.Type]; ok {
return p
}
return precLowest
}
@ -141,6 +137,7 @@ func (p *Parser) peekPrecedence() precedence {
if p, ok := tokenPrecedences[p.peek.Type]; ok {
return p
}
return precLowest
}
@ -152,7 +149,7 @@ func (p *Parser) parseExpression(prec precedence) (Expression, error) {
expr, err := prefixParser(p)
if err != nil {
return nil, fmt.Errorf("could not parse expression prefix: %v", err)
return nil, fmt.Errorf("could not parse expression prefix: %w", err)
}
for !p.peekTokenIs(eof) && prec < p.peekPrecedence() {
@ -165,7 +162,7 @@ func (p *Parser) parseExpression(prec precedence) (Expression, error) {
expr, err = infixParser(p, expr)
if err != nil {
return nil, fmt.Errorf("could not parse infix expression: %v", err)
return nil, fmt.Errorf("could not parse infix expression: %w", err)
}
}
@ -181,8 +178,9 @@ func parsePrefixExpression(p *Parser) (Expression, error) {
right, err := p.parseExpression(precPrefix)
if err != nil {
return nil, fmt.Errorf("could not parse expression for right operand: %v", err)
return nil, fmt.Errorf("could not parse expression for right operand: %w", err)
}
expr.Right = right
return expr, nil
@ -199,8 +197,9 @@ func parseInfixExpression(p *Parser, left Expression) (Expression, error) {
right, err := p.parseExpression(prec)
if err != nil {
return nil, fmt.Errorf("could not parse expression for right operand: %v", err)
return nil, fmt.Errorf("could not parse expression for right operand: %w", err)
}
expr.Right = right
return expr, nil
@ -215,17 +214,19 @@ func parseGroupedExpression(p *Parser) (Expression, error) {
expr, err := p.parseExpression(precLowest)
if err != nil {
return nil, fmt.Errorf("could not parse grouped expression: %v", err)
return nil, fmt.Errorf("could not parse grouped expression: %w", err)
}
for p.nextToken(); !p.curTokenIs(TokParenClose); p.nextToken() {
if p.curTokenIs(TokEOF) {
return nil, fmt.Errorf("unexpected EOF: unmatched parentheses")
}
right, err := p.parseExpression(precLowest)
if err != nil {
return nil, fmt.Errorf("could not parse expression: %v", err)
return nil, fmt.Errorf("could not parse expression: %w", err)
}
expr = &InfixExpression{
Operator: TokOpAnd,
Left: expr,

View File

@ -7,6 +7,8 @@ import (
)
func TestParseQuery(t *testing.T) {
t.Parallel()
tests := []struct {
name string
input string
@ -233,6 +235,8 @@ func TestParseQuery(t *testing.T) {
}
func assertError(t *testing.T, exp, got error) {
t.Helper()
switch {
case exp == nil && got != nil:
t.Fatalf("expected: nil, got: %v", got)