Skip to content

Commit

Permalink
Better error messages.
Browse files Browse the repository at this point in the history
Signed-off-by: Tom Wilkie <[email protected]>
  • Loading branch information
tomwilkie committed May 8, 2019
1 parent 80bbd04 commit d1b8731
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 81 deletions.
128 changes: 72 additions & 56 deletions pkg/logql/expr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 24 additions & 10 deletions pkg/logql/expr.y
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (

%union{
Expr Expr
Filter labels.MatchType
Selector []*labels.Matcher
Matchers []*labels.Matcher
Matcher *labels.Matcher
str string
Expand All @@ -16,9 +18,11 @@ import (

%start root

%type <Expr> expr
%type <Matchers> matchers
%type <Matcher> matcher
%type <Expr> expr
%type <Filter> filter
%type <Selector> selector
%type <Matchers> matchers
%type <Matcher> matcher

%token <str> IDENTIFIER STRING
%token <val> MATCHERS LABELS EQ NEQ RE NRE OPEN_BRACE CLOSE_BRACE COMMA DOT PIPE_MATCH PIPE_EXACT
Expand All @@ -28,13 +32,23 @@ import (
root: expr { exprlex.(*lexer).expr = $1 };

expr:
OPEN_BRACE matchers CLOSE_BRACE { $$ = &matchersExpr{ matchers: $2 } }
| expr PIPE_MATCH STRING { $$ = NewFilterExpr( $1, labels.MatchRegexp, $3 ) }
| expr PIPE_EXACT STRING { $$ = NewFilterExpr( $1, labels.MatchEqual, $3 ) }
| expr NRE STRING { $$ = NewFilterExpr( $1, labels.MatchNotRegexp, $3 ) }
| expr NEQ STRING { $$ = NewFilterExpr( $1, labels.MatchNotEqual, $3 ) }
| expr PIPE_MATCH { exprlex.(*lexer).Error("unexpected end of query, expected string") }
| expr STRING { exprlex.(*lexer).Error("unexpected string, expected pipe") }
selector { $$ = &matchersExpr{ matchers: $1 } }
| expr filter STRING { $$ = NewFilterExpr( $1, $2, $3 ) }
| expr filter error
| expr error
;

filter:
PIPE_MATCH { $$ = labels.MatchRegexp }
| PIPE_EXACT { $$ = labels.MatchEqual }
| NRE { $$ = labels.MatchNotRegexp }
| NEQ { $$ = labels.MatchNotEqual }
;

selector:
OPEN_BRACE matchers CLOSE_BRACE { $$ = $2 }
| OPEN_BRACE matchers error { $$ = $2 }
| OPEN_BRACE error CLOSE_BRACE { }
;

matchers:
Expand Down
32 changes: 19 additions & 13 deletions pkg/logql/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@ import (
"text/scanner"
)

func init() {
// Improve the error messages coming out of yacc.
exprErrorVerbose = true
for str, tok := range tokens {
exprToknames[tok-exprPrivate+1] = str
}
}

// ParseExpr parses a string and returns an Expr.
func ParseExpr(input string) (Expr, error) {
var l lexer
var l = lexer{
parser: exprNewParser().(*exprParserImpl),
}
l.Init(strings.NewReader(input))
//l.Scanner.Mode = scanner.SkipComments | scanner.ScanStrings | scanner.ScanInts
l.Scanner.Error = func(_ *scanner.Scanner, msg string) {
l.Error(msg)
}

e := exprParse(&l)
if e != 0 || l.err != nil {
return nil, l.err
e := l.parser.Parse(&l)
if e != 0 || len(l.errs) > 0 {
return nil, l.errs[0]
}
return l.expr, nil
}
Expand All @@ -38,8 +48,9 @@ var tokens = map[string]int{

type lexer struct {
scanner.Scanner
err error
expr Expr
errs []ParseError
expr Expr
parser *exprParserImpl
}

func (l *lexer) Lex(lval *exprSymType) int {
Expand Down Expand Up @@ -73,16 +84,11 @@ func (l *lexer) Lex(lval *exprSymType) int {
}

func (l *lexer) Error(msg string) {
// We want to return the first error (from the lexer), and ignore subsequent ones.
if l.err != nil {
return
}

l.err = ParseError{
l.errs = append(l.errs, ParseError{
msg: msg,
line: l.Line,
col: l.Column,
}
})
}

// ParseError is what is returned when we failed to parse.
Expand Down
22 changes: 20 additions & 2 deletions pkg/logql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,36 @@ func TestParse(t *testing.T) {
col: 6,
},
},
{
in: `{foo="bar"`,
err: ParseError{
msg: "syntax error: unexpected $end, expecting } or ,",
line: 1,
col: 11,
},
},

{
in: `{foo="bar"} |~`,
err: ParseError{
msg: "unexpected end of query, expected string",
msg: "syntax error: unexpected $end, expecting STRING",
line: 1,
col: 15,
},
},

{
in: `{foo="bar"} "foo"`,
err: ParseError{
msg: "unexpected string, expected pipe",
msg: "syntax error: unexpected STRING, expecting != or !~ or |~ or |=",
line: 1,
col: 13,
},
},
{
in: `{foo="bar"} foo`,
err: ParseError{
msg: "syntax error: unexpected IDENTIFIER, expecting != or !~ or |~ or |=",
line: 1,
col: 13,
},
Expand Down

0 comments on commit d1b8731

Please sign in to comment.