Implements required and prohibited keywords.
This commit is contained in:
@@ -198,6 +198,14 @@ class KeywordLocation;
|
||||
*/
|
||||
const static std::string PARSE_MISSING_INCLUDE;
|
||||
|
||||
/*
|
||||
For certain keywords, other, specific keywords are either
|
||||
required or prohibited. When such keywords are found in an
|
||||
invalid combination (missing required or present prohibited
|
||||
keyword), this error situation occurs.
|
||||
*/
|
||||
const static std::string PARSE_INVALID_KEYWORD_COMBINATION;
|
||||
|
||||
/// Dynamic number of wells exceeds maximum declared in
|
||||
/// RUNSPEC keyword WELLDIMS (item 1).
|
||||
const static std::string RUNSPEC_NUMWELLS_TOO_LARGE;
|
||||
|
||||
@@ -171,6 +171,8 @@ namespace Opm {
|
||||
void initMatchRegex( const Json::JsonObject& jsonObject );
|
||||
void initCode( const Json::JsonObject& jsonConfig );
|
||||
void initData( const Json::JsonObject& jsonConfig );
|
||||
void initProhibitedKeywords(const Json::JsonObject& keywordList);
|
||||
void initRequiredKeywords(const Json::JsonObject& keywordList);
|
||||
void initSize( const Json::JsonObject& jsonConfig );
|
||||
void initSizeKeyword(const Json::JsonObject& sizeObject);
|
||||
void commonInit(const std::string& name, ParserKeywordSizeEnum sizeType);
|
||||
|
||||
@@ -81,6 +81,7 @@ namespace Opm {
|
||||
addKey(PARSE_MISSING_INCLUDE, InputError::EXIT1);
|
||||
addKey(PARSE_LONG_KEYWORD, InputError::WARN);
|
||||
addKey(PARSE_WGNAME_SPACE, InputError::THROW_EXCEPTION);
|
||||
addKey(PARSE_INVALID_KEYWORD_COMBINATION, InputError::THROW_EXCEPTION);
|
||||
|
||||
addKey(UNIT_SYSTEM_MISMATCH, InputError::THROW_EXCEPTION);
|
||||
|
||||
@@ -325,6 +326,7 @@ namespace Opm {
|
||||
const std::string ParseContext::PARSE_MISSING_INCLUDE = "PARSE_MISSING_INCLUDE";
|
||||
const std::string ParseContext::PARSE_LONG_KEYWORD = "PARSE_LONG_KEYWORD";
|
||||
const std::string ParseContext::PARSE_WGNAME_SPACE = "PARSE_WGNAME_SPACE";
|
||||
const std::string ParseContext::PARSE_INVALID_KEYWORD_COMBINATION = "PARSE_INVALID_KEYWORD_COMBINATION";
|
||||
|
||||
const std::string ParseContext::UNIT_SYSTEM_MISMATCH = "UNIT_SYSTEM_MISMATCH";
|
||||
|
||||
|
||||
@@ -581,6 +581,32 @@ void ParserState::addPathAlias( const std::string& alias, const std::string& pat
|
||||
|
||||
|
||||
RawKeyword * newRawKeyword(const ParserKeyword& parserKeyword, const std::string& keywordString, ParserState& parserState, const Parser& parser) {
|
||||
for (const auto& keyword : parserKeyword.prohibitedKeywords()) {
|
||||
if (parserState.deck.hasKeyword(keyword)) {
|
||||
parserState
|
||||
.parseContext
|
||||
.handleError(
|
||||
ParseContext::PARSE_INVALID_KEYWORD_COMBINATION,
|
||||
fmt::format("Incompatible keyword combination: {} declared when {} is already present.", keywordString, keyword),
|
||||
KeywordLocation { keywordString, parserState.current_path(), parserState.line() } ,
|
||||
parserState.errors
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& keyword : parserKeyword.requiredKeywords()) {
|
||||
if (!parserState.deck.hasKeyword(keyword)) {
|
||||
parserState
|
||||
.parseContext
|
||||
.handleError(
|
||||
ParseContext::PARSE_INVALID_KEYWORD_COMBINATION,
|
||||
fmt::format("Incompatible keyword combination: {} declared, but {} is missing.", keywordString, keyword),
|
||||
KeywordLocation { keywordString, parserState.current_path(), parserState.line() } ,
|
||||
parserState.errors
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool raw_string_keyword = parserKeyword.rawStringKeyword();
|
||||
|
||||
if( parserKeyword.getSizeType() == SLASH_TERMINATED || parserKeyword.getSizeType() == UNKNOWN || parserKeyword.getSizeType() == DOUBLE_SLASH_TERMINATED) {
|
||||
|
||||
@@ -189,6 +189,14 @@ namespace Opm {
|
||||
initSectionNames(jsonConfig);
|
||||
initMatchRegex(jsonConfig);
|
||||
|
||||
if (jsonConfig.has_item("prohibits")) {
|
||||
initProhibitedKeywords(jsonConfig.get_item("prohibits"));
|
||||
}
|
||||
|
||||
if (jsonConfig.has_item("requires")) {
|
||||
initRequiredKeywords(jsonConfig.get_item("requires"));
|
||||
}
|
||||
|
||||
if (jsonConfig.has_item("items") && (jsonConfig.has_item("records") ||
|
||||
jsonConfig.has_item("alternating_records") ||
|
||||
jsonConfig.has_item("records_set") ))
|
||||
@@ -227,7 +235,33 @@ namespace Opm {
|
||||
|
||||
}
|
||||
|
||||
void ParserKeyword::initProhibitedKeywords(const Json::JsonObject& keywordList) {
|
||||
if (!keywordList.is_array())
|
||||
throw std::invalid_argument("The 'prohibits' JSON item of keyword "+m_name+" needs to be a list");
|
||||
|
||||
for (std::size_t keywordIndex { 0 } ; keywordIndex != keywordList.size() ; ++keywordIndex) {
|
||||
const auto keywordObject { keywordList.get_array_item(keywordIndex) } ;
|
||||
|
||||
if (!keywordObject.is_string())
|
||||
throw std::invalid_argument("The sub-items of 'prohibits' of keyword "+m_name+" need to be strings");
|
||||
|
||||
m_prohibits.emplace_back(keywordObject.as_string());
|
||||
}
|
||||
}
|
||||
|
||||
void ParserKeyword::initRequiredKeywords(const Json::JsonObject& keywordList) {
|
||||
if (!keywordList.is_array())
|
||||
throw std::invalid_argument("The 'requires' JSON item of keyword "+m_name+" needs to be a list");
|
||||
|
||||
for (std::size_t keywordIndex { 0 } ; keywordIndex != keywordList.size() ; ++keywordIndex) {
|
||||
const auto keywordObject { keywordList.get_array_item(keywordIndex) } ;
|
||||
|
||||
if (!keywordObject.is_string())
|
||||
throw std::invalid_argument("The sub-items of 'requires' of keyword "+m_name+" need to be strings");
|
||||
|
||||
m_requires.emplace_back(keywordObject.as_string());
|
||||
}
|
||||
}
|
||||
|
||||
void ParserKeyword::initSizeKeyword(const std::string& sizeKeyword, const std::string& sizeItem, int size_shift) {
|
||||
keyword_size = KeywordSize(sizeKeyword, sizeItem, size_shift);
|
||||
@@ -742,6 +776,23 @@ void set_dimensions( ParserItem& item,
|
||||
ss << indent << "addValidSectionName(\"" << *sectionNameIt << "\");" << '\n';
|
||||
}
|
||||
|
||||
// set required and prohibited keywords
|
||||
if (!m_prohibits.empty()) {
|
||||
ss << indent << "setProhibitedKeywords({" << '\n';
|
||||
for (const auto& keyword : m_prohibits) {
|
||||
ss << indent << indent << '"' << keyword << '"' << "," << '\n';
|
||||
}
|
||||
ss << indent << "});" << '\n';
|
||||
}
|
||||
|
||||
if (!m_requires.empty()) {
|
||||
ss << indent << "setRequiredKeywords({" << '\n';
|
||||
for (const auto& keyword : m_requires) {
|
||||
ss << indent << indent << '"' << keyword << '"' << "," << '\n';
|
||||
}
|
||||
ss << indent << "});" << '\n';
|
||||
}
|
||||
|
||||
// add the deck names
|
||||
ss << indent << "clearDeckNames();\n";
|
||||
for (auto deckNameIt = m_deckNames.begin();
|
||||
|
||||
@@ -514,6 +514,38 @@ BOOST_AUTO_TEST_CASE(test_1arg_constructor) {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_invalid_keyword_combination_required ) {
|
||||
const std::string deckString = R"(
|
||||
AQUCT
|
||||
1 2000.0 1.5 100 .3 3.0e-5 330 10 360.0 1 2 /
|
||||
)";
|
||||
|
||||
ParseContext parseContext;
|
||||
Parser parser;
|
||||
ErrorGuard errors;
|
||||
|
||||
BOOST_CHECK_THROW(parser.parseString(deckString, parseContext, errors), OpmInputError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_invalid_keyword_combination_prohibited ) {
|
||||
const std::string deckString = R"(
|
||||
EQLDIMS
|
||||
/
|
||||
|
||||
TEMPVD
|
||||
0.5 0 /
|
||||
|
||||
RTEMPVD
|
||||
0.5 0 /
|
||||
)";
|
||||
|
||||
ParseContext parseContext;
|
||||
Parser parser;
|
||||
ErrorGuard errors;
|
||||
|
||||
BOOST_CHECK_THROW(parser.parseString(deckString, parseContext, errors), OpmInputError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_invalid_wtemplate_config ) {
|
||||
const std::string defDeckString = R"(
|
||||
START -- 0
|
||||
|
||||
Reference in New Issue
Block a user