From 001b1e3cf01aa4befe011b7f17bcd22c12d4c8c4 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 6 Apr 2018 12:43:49 -0400 Subject: Improve location of error messages around identifiers. Lexer::ReadIdent() now sets last_token_ before returning, like Lexer::ReadEvalString() does. So all "expected identifiers" and things that call ReadIdent (pool parser, rule parser, let parser, code parsing the rule name after a : in a build line) now point the "^ near here" at what was there instead of the previous last_token According to manifest_parser_perftest, this is perf-neutral. --- src/lexer.cc | 9 +++++++-- src/lexer.in.cc | 9 +++++++-- src/manifest_parser_test.cc | 18 +++++++++++++----- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/lexer.cc b/src/lexer.cc index 37b8678..49c69aa 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -537,8 +537,9 @@ yy92: bool Lexer::ReadIdent(string* out) { const char* p = ofs_; + const char* start; for (;;) { - const char* start = p; + start = p; { unsigned char yych; @@ -604,7 +605,10 @@ yy96: } yy97: ++p; - { return false; } + { + last_token_ = start; + return false; + } yy99: ++p; yych = *p; @@ -616,6 +620,7 @@ yy100: } } + last_token_ = start; ofs_ = p; EatWhitespace(); return true; diff --git a/src/lexer.in.cc b/src/lexer.in.cc index f861239..20ed442 100644 --- a/src/lexer.in.cc +++ b/src/lexer.in.cc @@ -182,16 +182,21 @@ void Lexer::EatWhitespace() { bool Lexer::ReadIdent(string* out) { const char* p = ofs_; + const char* start; for (;;) { - const char* start = p; + start = p; /*!re2c varname { out->assign(start, p - start); break; } - [^] { return false; } + [^] { + last_token_ = start; + return false; + } */ } + last_token_ = start; ofs_ = p; EatWhitespace(); return true; diff --git a/src/manifest_parser_test.cc b/src/manifest_parser_test.cc index 39ed810..c91d8d1 100644 --- a/src/manifest_parser_test.cc +++ b/src/manifest_parser_test.cc @@ -523,7 +523,7 @@ TEST_F(ParserTest, Errors) { EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err)); EXPECT_EQ("input:1: unknown build rule 'y'\n" "build x: y z\n" - " ^ near here" + " ^ near here" , err); } @@ -534,7 +534,7 @@ TEST_F(ParserTest, Errors) { EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err)); EXPECT_EQ("input:1: expected build command name\n" "build x:: y z\n" - " ^ near here" + " ^ near here" , err); } @@ -636,7 +636,10 @@ TEST_F(ParserTest, Errors) { string err; EXPECT_FALSE(parser.ParseTest("rule %foo\n", &err)); - EXPECT_EQ("input:1: expected rule name\n", err); + EXPECT_EQ("input:1: expected rule name\n" + "rule %foo\n" + " ^ near here", + err); } { @@ -672,7 +675,10 @@ TEST_F(ParserTest, Errors) { string err; EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n && bar", &err)); - EXPECT_EQ("input:3: expected variable name\n", err); + EXPECT_EQ("input:3: expected variable name\n" + " && bar\n" + " ^ near here", + err); } { @@ -767,7 +773,9 @@ TEST_F(ParserTest, Errors) { ManifestParser parser(&local_state, NULL); string err; EXPECT_FALSE(parser.ParseTest("pool\n", &err)); - EXPECT_EQ("input:1: expected pool name\n", err); + EXPECT_EQ("input:1: expected pool name\n" + "pool\n" + " ^ near here", err); } { -- cgit v0.12