parser: improve printing of unexpected tokens (#8654)

pull/8664/head
Nick Treleaven 2021-02-09 15:07:30 +00:00 committed by GitHub
parent 0f92485698
commit d37fb5641f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 29 additions and 18 deletions

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/trailing_comma_struct_attr.vv:3:31: error: unexpected `]`, expecting `name`
vlib/v/checker/tests/trailing_comma_struct_attr.vv:3:31: error: unexpected token `]`, expecting name
1 | struct User {
2 | name string
3 | jobs []string [json:jobss;]

View File

@ -527,7 +527,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
no_body := p.tok.kind != .lcbr
same_line = p.tok.line_nr == p.prev_tok.line_nr
if no_body && same_line {
p.error_with_pos('unexpected `$p.tok.kind` after anonymous function signature, expecting `{`',
p.error_with_pos('unexpected $p.tok after anonymous function signature, expecting `{`',
p.tok.position())
}
mut label_names := []string{}

View File

@ -15,7 +15,7 @@ fn (mut p Parser) lock_expr() ast.LockExpr {
}
is_rlock := p.tok.kind == .key_rlock
if !is_rlock && p.tok.kind != .key_lock {
p.error_with_pos('unexpected `$p.tok.lit`; `lock` or `rlock` expected', p.tok.position())
p.error_with_pos('unexpected $p.tok, expected `lock` or `rlock`', p.tok.position())
}
p.next()
for p.tok.kind == .name {

View File

@ -424,14 +424,16 @@ fn (mut p Parser) check(expected token.Kind) {
// }
if p.tok.kind == expected {
p.next()
} else if p.tok.kind == .name {
p.error('unexpected name `$p.tok.lit`, expecting `$expected.str()`')
} else {
if expected == .name {
p.name_error = true
}
label := if token.is_key(p.tok.lit) { 'keyword ' } else { '' }
p.error('unexpected $label`$p.tok.kind.str()`, expecting `$expected.str()`')
mut s := expected.str()
// quote keywords, punctuation, operators
if token.is_key(s) || (s.len > 0 && !s[0].is_letter()) {
s = '`$s`'
}
p.error('unexpected $p.tok, expecting $s')
}
}
@ -841,7 +843,7 @@ fn (mut p Parser) attributes() {
p.next()
break
}
p.error('unexpected `$p.tok.kind.str()`, expecting `;`')
p.error('unexpected $p.tok, expecting `;`')
return
}
p.next()

View File

@ -297,8 +297,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
else {
if p.tok.kind != .eof {
// eof should be handled where it happens
p.error_with_pos('invalid expression: unexpected `$p.tok.kind.str()` token',
p.tok.position())
p.error_with_pos('invalid expression: unexpected $p.tok', p.tok.position())
return ast.Expr{}
}
}

View File

@ -1,4 +1,4 @@
vlib/v/parser/tests/postfix_inc.vv:3:1: error: `++` must be on the same line as the previous token
vlib/v/parser/tests/postfix_inc.vv:3:1: error: token `++` must be on the same line as the previous token
1 | mut v := 4
2 | _ = v
3 | ++v

View File

@ -1,4 +1,4 @@
vlib/v/parser/tests/struct_field_expected.vv:6:2: error: unexpected `.`, expecting struct field name
vlib/v/parser/tests/struct_field_expected.vv:6:2: error: unexpected token `.`, expecting struct field name
4 |
5 | x = {
6 | .a : 'Alpha'

View File

@ -1,4 +1,4 @@
vlib/v/parser/tests/struct_update_err.vv:15:3: error: unexpected `...`, expecting `name`
vlib/v/parser/tests/struct_update_err.vv:15:3: error: unexpected token `...`, expecting name
13 | f2 := Foo{
14 | name: 'f2'
15 | ...f

View File

@ -1,4 +1,4 @@
vlib/v/parser/tests/uncomplete_module_call_err.vv:7:1: error: unexpected `}`, expecting `name`
vlib/v/parser/tests/uncomplete_module_call_err.vv:7:1: error: unexpected token `}`, expecting name
5 | fn main() {
6 | os.
7 | }

View File

@ -0,0 +1,3 @@
vlib/v/parser/tests/unexpected_expr.vv:1:5: error: invalid expression: unexpected keyword `break`
1 | _ = break
| ~~~~~

View File

@ -0,0 +1 @@
_ = break

View File

@ -319,6 +319,7 @@ pub fn (t Kind) is_assign() bool {
return t in token.assign_tokens
}
// note: used for some code generation, so no quoting
pub fn (t Kind) str() string {
return token.token_str[int(t)]
}
@ -327,12 +328,17 @@ pub fn (t Token) str() string {
mut s := t.kind.str()
if s.len == 0 {
eprintln('missing token kind string')
} else if !s[0].is_letter() {
} else if !s[0].is_letter() {
// punctuation, operators
return '`$s`'
return 'token `$s`'
}
if is_key(t.lit) {
s = 'keyword'
}
if t.lit != '' {
// string contents etc
s += ' `$t.lit`'
}
// string contents etc
if t.lit != '' { s += ' `$t.lit`' }
return s
}