Added parser error for 'random text'.

Previously random text in the input deck which was not formatted as a
valid keyword header was simply ignored; i.e. this

   DIMENS
     10 10 10 /

   Mohaha random gibbersih - not according to any Spec.

   GRID

Would suprisingly parse just fine. This will now be handled according
to the ParseMode::randomText setting. Observe that as a side effect of
this it turned out that many of the test datasets had additional
terminating slashes which were now detected as 'ranomdText'.
This commit is contained in:
Joakim Hove
2015-07-24 22:43:00 +02:00
parent 733af54777
commit 5e64d0f147
14 changed files with 199 additions and 84 deletions

View File

@@ -44,7 +44,6 @@ const std::string& deckStr = "RUNSPEC\n"
"\n"
"TSTEP\n"
" 1 2 3 4 5 /\n"
"\n"
"DATES\n"
" 1 JAN 1982 /\n"
" 1 JAN 1982 13:55:44 /\n"
@@ -52,8 +51,7 @@ const std::string& deckStr = "RUNSPEC\n"
"/\n"
"TSTEP\n"
" 9 10 /\n"
"\n"
"/\n";
"\n";
const std::string& deckStr3 = "RUNSPEC\n"

View File

@@ -31,60 +31,55 @@
using namespace Opm;
const std::string& deckStr =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5\n"
"/\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n"
"/\n";
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5\n"
"/\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n";
const std::string& deckStr2 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"/\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"/\n";
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n";
const std::string& deckStr3 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5 SAVE UNFORMATTED\n"
"/\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n"
"/\n";
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5 SAVE UNFORMATTED /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"SKIPREST \n";
const std::string& deckStr4 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5\n"
"/\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n"
"/\n";
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /\n"
"SOLUTION\n"
"RESTART\n"
"BASE 5 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
"SCHEDULE\n";
static DeckPtr createDeck(const std::string& input) {
Opm::Parser parser;

View File

@@ -824,7 +824,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTRST) {
"/\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"/\n";
const char *deckData2 =
@@ -846,7 +845,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTRST) {
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n"
"/\n";
const char *deckData3 =
@@ -868,7 +866,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTRST) {
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n"
"/\n";
@@ -929,7 +926,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTSCHED) {
"/\n"
"RPTSCHED\n"
"RESTART=0\n"
"/\n"
"/\n";
@@ -955,7 +951,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTSCHED) {
"/\n"
"RPTSCHED\n"
"NOTHING RUBBISH\n"
"/\n"
"/\n";
const char *deckData2 =
@@ -980,7 +975,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTSCHED) {
"/\n"
"RPTSCHED\n"
"0 0 0 0 0 0 0 0\n"
"/\n"
"/\n";
std::shared_ptr<const EclipseGrid> grid = std::make_shared<const EclipseGrid>( 10 , 10 , 10 );
@@ -1042,7 +1036,6 @@ BOOST_AUTO_TEST_CASE(createDeckWithRPTSCHEDandRPTRST) {
"/\n"
"RPTSCHED\n"
"RESTART=1\n"
"/\n"
"/\n";

View File

@@ -63,7 +63,6 @@ static DeckPtr createDeckTOP() {
"PERMX \n"
"100*0.25 /\n"
"EDIT\n"
"/\n"
"OIL\n"
"\n"
"GAS\n"
@@ -429,14 +428,12 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreation) {
" 10 OKT 2008 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=2\n"
"/\n"
"BASIC=3 FREQ=2 /\n"
"DATES -- 2\n"
" 20 JAN 2010 / \n"
"/\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n"
"/\n";
@@ -463,11 +460,9 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTRST) {
" 10 10 10 /\n"
"SOLUTION\n"
"RPTRST\n"
"BASIC=1\n"
"/\n"
"BASIC=1/\n"
"RPTRST\n"
"BASIC=3 FREQ=5\n"
"/\n"
"BASIC=3 FREQ=5 /\n"
"GRID\n"
"START -- 0 \n"
"19 JUN 2007 / \n"
@@ -479,11 +474,9 @@ BOOST_AUTO_TEST_CASE(TestIOConfigCreationWithSolutionRPTRST) {
" 20 JAN 2010 / \n"
"/\n"
"RPTRST\n"
"BASIC=3 FREQ=2\n"
"/\n"
"BASIC=3 FREQ=2 /\n"
"DATES -- 3\n"
" 20 JAN 2011 / \n"
"/\n"
"/\n";

View File

@@ -34,6 +34,7 @@ BOOST_AUTO_TEST_CASE( test_parse ) {
Parser parser(false);
ParseMode parseMode;
parseMode.unknownKeyword = InputError::IGNORE;
parseMode.randomText = InputError::IGNORE;
parser.addKeyword<ParserKeywords::SPECGRID>();
parser.addKeyword<ParserKeywords::FAULTS>();
@@ -49,6 +50,7 @@ BOOST_AUTO_TEST_CASE( test_state ) {
Parser parser(false);
ParseMode parseMode;
parseMode.unknownKeyword = InputError::IGNORE;
parseMode.randomText = InputError::IGNORE;
parser.addKeyword<ParserKeywords::SPECGRID>();
parser.addKeyword<ParserKeywords::FAULTS>();

View File

@@ -25,6 +25,7 @@ namespace Opm {
ParseMode::ParseMode() {
unknownKeyword = InputError::THROW_EXCEPTION;
randomText = InputError::THROW_EXCEPTION;
}
}

View File

@@ -48,7 +48,38 @@ namespace Opm {
struct ParseMode {
ParseMode();
/*
The unknownKeyword field regulates how the parser should
react when it encounters an unknwon keyword. Observe that
'keyword' in this context means:
o A string of 8 characters or less - starting in column
0.
o A string consisiting of UPPERCASE characters and
numerals, staring with an UPPERCASE character [Hmmm -
actually lowercase is also accepted?!]
Observe that unknownKeyword does *not* consult any global
collection of keywords to see if a particular string
corresponds to a known valid keyword which we just happen
to ignore for this particualar parse operation.
The 'unknownkeyword' and 'randomText' error situations are
not fully orthogonal, and in particualar if a unknown
keyword has been encountered - without halting the parser, a
subsequent piece of 'random text' might not be identified
correctly as such.
*/
InputError::Action unknownKeyword;
/*
With random text we mean a string in the input deck is not
correctly formatted as a keyword heading.
*/
InputError::Action randomText;
};
}

View File

@@ -98,6 +98,25 @@ namespace Opm {
rootPath = boost::filesystem::current_path() / inputFile.parent_path();
}
/*
We have encountered 'random' characters in the input file which
are not correctly formatted as a keyword heading, and not part
of the data section of any keyword.
*/
void handleRandomText(const std::string& keywordString ) const {
std::stringstream msg;
InputError::Action action = parseMode.randomText;
msg << "String \'" << keywordString << "\' not formatted/recognized as valid keyword at: " << dataFile << ":" << lineNR;
if (action == InputError::THROW_EXCEPTION)
throw std::invalid_argument( msg.str() );
else {
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , msg.str());
}
}
};
Parser::Parser(bool addDefault) {
@@ -385,18 +404,25 @@ namespace Opm {
return RawKeywordPtr(new RawKeyword(keywordString, parserState->dataFile.string() , parserState->lineNR , targetSize , parserKeyword->isTableCollection()));
}
} else {
InputError::Action action = parserState->parseMode.unknownKeyword;
if (action == InputError::THROW_EXCEPTION)
throw std::invalid_argument("Keyword " + keywordString + " not recognized ");
else {
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , "Keyword " + keywordString + " not recognized");
if (ParserKeyword::validDeckName(keywordString)) {
InputError::Action action = parserState->parseMode.unknownKeyword;
if (action == InputError::THROW_EXCEPTION)
throw std::invalid_argument("Keyword " + keywordString + " not recognized ");
else {
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , "Keyword " + keywordString + " not recognized");
return std::shared_ptr<RawKeyword>( );
}
} else {
parserState->handleRandomText( keywordString );
return std::shared_ptr<RawKeyword>( );
}
}
}
std::string Parser::doSpecialHandlingForTitleKeyword(std::string line, std::shared_ptr<ParserState> parserState) const {
if ((parserState->rawKeyword != NULL) && (parserState->rawKeyword->getKeywordName() == "TITLE"))
line = line.append("/");
@@ -432,7 +458,9 @@ namespace Opm {
if (parserState->rawKeyword == NULL) {
if (RawKeyword::isKeywordPrefix(line, keywordString)) {
parserState->rawKeyword = createRawKeyword(keywordString, parserState);
}
} else
/* We are looking at some random gibberish?! */
parserState->handleRandomText( line );
} else {
if (parserState->rawKeyword->getSizeType() == Raw::UNKNOWN) {
if (isRecognizedKeyword(line)) {

View File

@@ -1,5 +1,5 @@
foreach(tapp ParserTests ParserKeywordTests ParserRecordTests
ParserItemTests ParserEnumTests ParserIncludeTests)
ParserItemTests ParserEnumTests ParserIncludeTests ParseModeTests)
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
endforeach()

View File

@@ -0,0 +1,76 @@
/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE ParseModeTests
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords.hpp>
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp>
using namespace Opm;
BOOST_AUTO_TEST_CASE(TestUnkownKeyword) {
const char * deck1 =
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /n"
"\n";
const char * deck2 =
"1rdomTX\n"
"RUNSPEC\n"
"DIMENS\n"
" 10 10 10 /n"
"\n";
ParseMode parseMode;
Parser parser(false);
parser.addKeyword<ParserKeywords::DIMENS>();
parseMode.unknownKeyword = InputError::THROW_EXCEPTION;
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
parseMode.unknownKeyword = InputError::IGNORE;
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
parseMode.randomText = InputError::IGNORE;
parseMode.unknownKeyword = InputError::THROW_EXCEPTION;
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
parseMode.randomText = InputError::IGNORE;
parseMode.unknownKeyword = InputError::IGNORE;
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
parseMode.randomText = InputError::THROW_EXCEPTION;
parseMode.unknownKeyword = InputError::IGNORE;
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
parseMode.randomText = InputError::IGNORE;
parseMode.unknownKeyword = InputError::IGNORE;
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
}

View File

@@ -63,7 +63,7 @@ PERMZ
PORO
162*0.3 /
/
PROPS ===============================================================
@@ -429,7 +429,6 @@ WCONPROD
/
TSTEP
4*500.0
/
4*500.0 /
--
END

View File

@@ -7,4 +7,4 @@ PLYDHFLF
0.0 365.0
50.0 240.0
150.0 200.0 /
/

View File

@@ -6,4 +6,3 @@ TABDIMS
PLYVISC
0.0 1.0
1.25 30.0 /
/

View File

@@ -36,7 +36,7 @@ WELSPECS
TSTEP
14.0 /
/
WELSPECS
'INJ2' 'G1' 1 1 8335 'GAS' /
@@ -63,7 +63,7 @@ WCONPROD
TSTEP
3 /
/
END