libexpr/parser: Use readable tokens in error messages instead of internal token names

Very low-hanging fruit for improving parser error messages.
This commit is contained in:
Sergei Zimmerman
2026-01-27 01:57:53 +03:00
parent ed9d8af93d
commit 68cf0a7f8a
53 changed files with 192 additions and 13 deletions

View File

@@ -3,7 +3,7 @@
%define api.namespace { ::nix::parser }
%define api.parser.class { BisonParser }
%locations
%define parse.error verbose
%define parse.error detailed
%defines
/* %no-lines */
%parse-param { void * scanner }
@@ -140,18 +140,41 @@ static Expr * makeCall(Exprs & exprs, PosIdx pos, Expr * fn, Expr * arg) {
%type <Expr *> path_start
%type <ToBeStringyExpr> string_parts string_attr
%type <StringToken> attr
%token <StringToken> ID
%token <StringToken> STR IND_STR
%token <NixInt> INT_LIT
%token <NixFloat> FLOAT_LIT
%token <StringToken> PATH HPATH SPATH PATH_END
%token <StringToken> URI
%token IF THEN ELSE ASSERT WITH LET IN_KW REC INHERIT EQ NEQ AND OR IMPL OR_KW
%token PIPE_FROM PIPE_INTO /* <| and |> */
%token DOLLAR_CURLY /* == ${ */
%token IND_STRING_OPEN IND_STRING_CLOSE
%token ELLIPSIS
%token <StringToken> ID "identifier"
%token <StringToken> STR "string"
%token <StringToken> IND_STR "indented string"
%token <NixInt> INT_LIT "integer"
%token <NixFloat> FLOAT_LIT "floating-point literal"
%token <StringToken> PATH "path"
%token <StringToken> HPATH "'~/…' path"
%token <StringToken> SPATH "'<…>' path"
%token <StringToken> PATH_END "end of path"
%token <StringToken> URI "URI"
%token IF "'if'"
%token THEN "'then'"
%token ELSE "'else'"
%token ASSERT "'assert'"
%token WITH "'with'"
%token LET "'let'"
%token IN_KW "'in'"
%token REC "'rec'"
%token INHERIT "'inherit'"
%token EQ "'=='"
%token NEQ "'!='"
%token LEQ "'<='"
%token GEQ "'>='"
%token UPDATE "'//'"
%token CONCAT "'++'"
%token AND "'&&'"
%token OR "'||'"
%token IMPL "'->'"
%token OR_KW "'or'"
%token PIPE_FROM "'<|'"
%token PIPE_INTO "'|>'"
%token DOLLAR_CURLY "'${'"
%token IND_STRING_OPEN "start of an indented string"
%token IND_STRING_CLOSE "end of an indented string"
%token ELLIPSIS "'...'"
%right IMPL
%left OR

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '&&'
at «stdin»:1:1:
1| && true
| ^
2|

View File

@@ -0,0 +1 @@
&& true

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'assert', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.assert
| ^
2|

View File

@@ -0,0 +1 @@
a.assert

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '++'
at «stdin»:1:1:
1| ++ []
| ^
2|

View File

@@ -0,0 +1 @@
++ []

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '...', expecting '.' or '='
at «stdin»:1:5:
1| { a ... }
| ^
2|

View File

@@ -0,0 +1 @@
{ a ... }

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'else', expecting 'then'
at «stdin»:1:6:
1| if 1 else
| ^
2|

View File

@@ -0,0 +1 @@
if 1 else

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '=='
at «stdin»:1:1:
1| == 1
| ^
2|

View File

@@ -0,0 +1 @@
== 1

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected floating-point literal, expecting 'inherit'
at «stdin»:1:3:
1| { 1.5 = x; }
| ^
2|

View File

@@ -0,0 +1 @@
{ 1.5 = x; }

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '>='
at «stdin»:1:1:
1| >= 1
| ^
2|

View File

@@ -0,0 +1 @@
>= 1

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '~/…' path, expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.~/foo
| ^
2|

View File

@@ -0,0 +1 @@
a.~/foo

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'if', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.if
| ^
2|

View File

@@ -0,0 +1 @@
a.if

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '->'
at «stdin»:1:1:
1| -> x
| ^
2|

View File

@@ -0,0 +1 @@
-> x

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'in', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.in
| ^
2|

View File

@@ -0,0 +1 @@
a.in

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected start of an indented string, expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.''
| ^
2|

View File

@@ -0,0 +1 @@
a.''

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'inherit', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.inherit
| ^
2|

View File

@@ -0,0 +1 @@
a.inherit

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected integer, expecting 'inherit'
at «stdin»:1:3:
1| { 1 = x; }
| ^
2|

View File

@@ -0,0 +1 @@
{ 1 = x; }

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '<='
at «stdin»:1:1:
1| <= 1
| ^
2|

View File

@@ -0,0 +1 @@
<= 1

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'let', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.let
| ^
2|

View File

@@ -0,0 +1 @@
a.let

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '!='
at «stdin»:1:6:
1| 1 != != 2
| ^
2|

View File

@@ -0,0 +1 @@
1 != != 2

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '||'
at «stdin»:1:1:
1| || true
| ^
2|

View File

@@ -0,0 +1 @@
|| true

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected path, expecting identifier or 'or' or '${' or '"'
at «stdin»:1:7:
1| { } ? ./foo
| ^
2|

View File

@@ -0,0 +1 @@
{ } ? ./foo

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'rec', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.rec
| ^
2|

View File

@@ -0,0 +1 @@
a.rec

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '<…>' path, expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.<nixpkgs>
| ^
2|

View File

@@ -0,0 +1 @@
a.<nixpkgs>

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'then'
at «stdin»:1:4:
1| if then
| ^
2|

View File

@@ -0,0 +1 @@
if then

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected '//'
at «stdin»:1:1:
1| // 1
| ^
2|

View File

@@ -0,0 +1 @@
// 1

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected URI
at «stdin»:1:11:
1| { inherit http://x; }
| ^
2|

View File

@@ -0,0 +1 @@
{ inherit http://x; }

View File

@@ -0,0 +1,5 @@
error: syntax error, unexpected 'with', expecting identifier or 'or' or '${' or '"'
at «stdin»:1:3:
1| a.with
| ^
2|

View File

@@ -0,0 +1 @@
a.with