diff --git a/framework/contrib/hit/lex.cc b/framework/contrib/hit/lex.cc index e3c5e82bc7ae..5f226d224bf6 100644 --- a/framework/contrib/hit/lex.cc +++ b/framework/contrib/hit/lex.cc @@ -69,8 +69,8 @@ tokTypeName(TokType t) // clang-format on } -Token::Token(TokType t, const std::string & val, size_t offset, int line) - : type(t), val(val), offset(offset), line(line) +Token::Token(TokType t, const std::string & val, const std::string & name, size_t offset, int line) + : type(t), val(val), name(name), offset(offset), line(line) { } @@ -120,7 +120,7 @@ void Lexer::emit(TokType type) { auto substr = _input.substr(_start, _pos - _start); - _tokens.push_back(Token(type, substr, _start, _line_count)); + _tokens.push_back(Token(type, substr, _name, _start, _line_count)); _line_count += lineCount(substr); _start = _pos; } @@ -142,7 +142,7 @@ Lexer::ignore() LexFunc Lexer::error(const std::string & msg) { - _tokens.push_back(Token(TokType::Error, msg, _start, _line_count)); + _tokens.push_back(Token(TokType::Error, msg, _name, _start, _line_count)); return nullptr; } @@ -471,7 +471,8 @@ lexHit(Lexer * l) l->emit(TokType::EOF); return NULL; } - return l->error("invalid character '" + std::string(1, c) + "' - did you leave a field value blank after a previous '='?"); + return l->error("invalid character '" + std::string(1, c) + + "' - did you leave a field value blank after a previous '='?"); } std::vector diff --git a/framework/contrib/hit/lex.h b/framework/contrib/hit/lex.h index 99959f47928b..1999584841b1 100644 --- a/framework/contrib/hit/lex.h +++ b/framework/contrib/hit/lex.h @@ -32,7 +32,11 @@ enum class TokType /// Token represents an (atomic) token/quantum of input text. struct Token { - Token(TokType t, const std::string & val, size_t offset = 0, int line = 0); + Token(TokType t, + const std::string & val, + const std::string & name, + size_t offset = 0, + int line = 0); /// str returns a human-friendly string representation of the token. std::string str(); @@ -40,6 +44,8 @@ struct Token TokType type; /// val is the actual text from the input that makes this token. std::string val; + /// name of the original input file + std::string name; /// offset is the byte offset into the original input identifying the start position where this /// token was found. This can be used to determine line numbers, column offsets, etc. useful for /// error messages among other things. diff --git a/framework/contrib/hit/parse.cc b/framework/contrib/hit/parse.cc index 6a14a0ce01c8..1dc7e32d4500 100644 --- a/framework/contrib/hit/parse.cc +++ b/framework/contrib/hit/parse.cc @@ -1,12 +1,12 @@ -#include -#include #include -#include -#include #include #include #include +#include +#include +#include +#include #include "parse.h" @@ -188,6 +188,15 @@ Node::remove() delete this; } +const std::string & +Node::name() +{ + if (_toks.size() > 0) + return _toks[0].name; + static std::string unknown_name = "[unknown]"; + return unknown_name; +} + int Node::line() { @@ -690,7 +699,7 @@ class Parser if (_pos >= _tokens.size()) { _pos++; - return Token{TokType::EOF, "", _input.size()}; + return Token{TokType::EOF, "", _name, _input.size()}; } auto tok = _tokens[_pos]; _pos++; diff --git a/framework/contrib/hit/parse.h b/framework/contrib/hit/parse.h index 761e59af23fc..a693ac93d0ea 100644 --- a/framework/contrib/hit/parse.h +++ b/framework/contrib/hit/parse.h @@ -1,13 +1,13 @@ #ifndef HIT_PARSE #define HIT_PARSE -#include -#include -#include #include -#include #include #include +#include +#include +#include +#include #include "lex.h" @@ -147,6 +147,9 @@ class Node /// line returns the line number of the original parsed input (file) that contained the start of /// the content that this node was built from. int line(); + /// name returns the file name of the original parsed input (file) that contained the start of + /// the content that this node was built from. + const std::string & name(); /// the following functions return the stored value of the node (if any exists) of the type /// indicated in the function name. If the node holds a value of a different type or doesn't hold @@ -266,6 +269,9 @@ template <> inline unsigned int Node::paramInner(Node * n) { + if (n->intVal() < 0) + throw Error("negative value read from file '" + n->name() + "' on line " + + std::to_string(n->line())); return n->intVal(); } template <> @@ -299,7 +305,12 @@ Node::paramInner(Node * n) auto tmp = n->vecIntVal(); std::vector vec; for (auto val : tmp) + { + if (val < 0) + throw Error("negative value read from file '" + n->name() + "' on line " + + std::to_string(n->line())); vec.push_back(val); + } return vec; } template <>