Implements required and prohibited keywords.

This commit is contained in:
Williham Williham Totland
2020-10-05 13:34:35 +02:00
parent bd3242fe05
commit 7aba0cd976
6 changed files with 121 additions and 0 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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";

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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