Commit 7e711f80 authored by Vladimir Glavnyy's avatar Vladimir Glavnyy Committed by Wouter van Oortmerssen

Parser error message reports both the line number and the cursor position. (#4954)

parent bf871ffd
...@@ -477,10 +477,28 @@ struct IDLOptions { ...@@ -477,10 +477,28 @@ struct IDLOptions {
// This encapsulates where the parser is in the current source file. // This encapsulates where the parser is in the current source file.
struct ParserState { struct ParserState {
ParserState() : cursor_(nullptr), line_(1), token_(-1) {} ParserState()
: cursor_(nullptr), line_start_(nullptr), line_(0), token_(-1) {}
protected: protected:
void ResetState(const char *source) {
cursor_ = source;
line_ = 0;
MarkNewLine();
}
void MarkNewLine() {
line_start_ = cursor_;
line_ += 1;
}
int64_t CursorPosition() const {
FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_);
return static_cast<int64_t>(cursor_ - line_start_);
}
const char *cursor_; const char *cursor_;
const char *line_start_;
int line_; // the current line being parsed int line_; // the current line being parsed
int token_; int token_;
......
...@@ -94,11 +94,12 @@ std::string MakeCamel(const std::string &in, bool first) { ...@@ -94,11 +94,12 @@ std::string MakeCamel(const std::string &in, bool first) {
void Parser::Message(const std::string &msg) { void Parser::Message(const std::string &msg) {
error_ = file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : ""; error_ = file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : "";
// clang-format off // clang-format off
#ifdef _WIN32 #ifdef _WIN32 // MSVC alike
error_ += "(" + NumToString(line_) + ")"; // MSVC alike error_ +=
#else "(" + NumToString(line_) + ", " + NumToString(CursorPosition()) + ")";
#else // gcc alike
if (file_being_parsed_.length()) error_ += ":"; if (file_being_parsed_.length()) error_ += ":";
error_ += NumToString(line_) + ":0"; // gcc alike error_ += NumToString(line_) + ": " + NumToString(CursorPosition());
#endif #endif
// clang-format on // clang-format on
error_ += ": " + msg; error_ += ": " + msg;
...@@ -280,7 +281,7 @@ CheckedError Parser::Next() { ...@@ -280,7 +281,7 @@ CheckedError Parser::Next() {
case '\r': case '\r':
case '\t': break; case '\t': break;
case '\n': case '\n':
line_++; MarkNewLine();
seen_newline = true; seen_newline = true;
break; break;
case '{': case '{':
...@@ -420,7 +421,7 @@ CheckedError Parser::Next() { ...@@ -420,7 +421,7 @@ CheckedError Parser::Next() {
cursor_++; cursor_++;
// TODO: make nested. // TODO: make nested.
while (*cursor_ != '*' || cursor_[1] != '/') { while (*cursor_ != '*' || cursor_[1] != '/') {
if (*cursor_ == '\n') line_++; if (*cursor_ == '\n') MarkNewLine();
if (!*cursor_) return Error("end of file in comment"); if (!*cursor_) return Error("end of file in comment");
cursor_++; cursor_++;
} }
...@@ -2259,8 +2260,8 @@ bool Parser::Parse(const char *source, const char **include_paths, ...@@ -2259,8 +2260,8 @@ bool Parser::Parse(const char *source, const char **include_paths,
CheckedError Parser::StartParseFile(const char *source, CheckedError Parser::StartParseFile(const char *source,
const char *source_filename) { const char *source_filename) {
file_being_parsed_ = source_filename ? source_filename : ""; file_being_parsed_ = source_filename ? source_filename : "";
source_ = cursor_ = source; source_ = source;
line_ = 1; ResetState(source_);
error_.clear(); error_.clear();
ECHECK(SkipByteOrderMark()); ECHECK(SkipByteOrderMark());
NEXT(); NEXT();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment