Added strict flag to parser:

Have added a new bool strict flag to the parsing functions, if the
strict flag is set to false the parser will just skip lines with unknwon
keywords, including pure garbage in the input. I.e. for a deck like:

TABDIMS
  1 1 1 /

Crap - not a keyword at all

-- Correctly formatted - unknown keyword
IGNORED
  0 1 /

The parser will load the TABDIMS keyword correctly, and skip the rest.
This commit is contained in:
Joakim Hove
2015-06-12 10:54:25 +02:00
parent c38b892876
commit 875fd86c3c
5 changed files with 126 additions and 42 deletions

View File

@@ -6,7 +6,8 @@ foreach(tapp CheckDeckValidity IntegrationTests ParseWellProbe
ParseTVDP ParseDENSITY ParseVFPPROD ScheduleCreateFromDeck
CompletionsFromDeck ParseEND IncludeTest ParseEQUIL
ParseRSVD ParsePVTG ParsePVTO ParseSWOF BoxTest
ParseMULTREGT ParseSGOF EclipseGridCreateFromDeck NNCTests)
ParseMULTREGT ParseSGOF EclipseGridCreateFromDeck NNCTests
ResinsightTest )
opm_add_test(run${tapp} SOURCES ${tapp}.cpp
LIBRARIES opmparser ${Boost_LIBRARIES})
endforeach()

View File

@@ -0,0 +1,52 @@
/*
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/>.
*/
#define BOOST_TEST_MODULE BoxTest
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
using namespace Opm;
BOOST_AUTO_TEST_CASE( test_parse ) {
Parser parser(false);
parser.addKeyword<ParserKeywords::SPECGRID>();
parser.addKeyword<ParserKeywords::FAULTS>();
auto deck = parser.parseFile("testdata/integration_tests/Resinsight/DECK1.DATA" , false);
BOOST_CHECK( deck->hasKeyword<ParserKeywords::SPECGRID>() );
BOOST_CHECK( deck->hasKeyword<ParserKeywords::FAULTS>() );
}
BOOST_AUTO_TEST_CASE( test_state ) {
Parser parser(false);
parser.addKeyword<ParserKeywords::SPECGRID>();
parser.addKeyword<ParserKeywords::FAULTS>();
auto deck = parser.parseFile("testdata/integration_tests/Resinsight/DECK1.DATA" , false);
auto grid = std::make_shared<EclipseGrid>( deck );
auto faults = std::make_shared<FaultCollection>( deck , grid );
}

View File

@@ -32,57 +32,70 @@
namespace Opm {
struct ParserState {
bool m_strict;
DeckPtr deck;
boost::filesystem::path dataFile;
boost::filesystem::path rootPath;
std::map<std::string, std::string> pathMap;
bool initSuccessful;
size_t lineNR;
std::shared_ptr<std::istream> inputstream;
RawKeywordPtr rawKeyword;
std::string nextKeyword;
ParserState(const boost::filesystem::path &inputDataFile, DeckPtr deckToFill, const boost::filesystem::path &commonRootPath) {
SetValues(inputDataFile, deckToFill, commonRootPath);
/*ParserState(bool strict) {
m_strict = strict;
deck = std::make_shared<Deck>();
}
*/
ParserState(bool strict , const boost::filesystem::path &inputDataFile, DeckPtr deckToFill, const boost::filesystem::path &commonRootPath) {
SetValues(strict , inputDataFile, deckToFill, commonRootPath);
}
ParserState(const std::string &inputData, DeckPtr deckToFill) {
ParserState(bool strict , const std::string &inputData, DeckPtr deckToFill) {
m_strict = strict;
lineNR = 0;
dataFile = "";
deck = deckToFill;
initSuccessful = true;
inputstream.reset(new std::istringstream(inputData));
}
ParserState(std::shared_ptr<std::istream> inputStream, DeckPtr deckToFill) {
ParserState(bool strict , std::shared_ptr<std::istream> inputStream, DeckPtr deckToFill) {
m_strict = strict;
lineNR = 0;
dataFile = "";
deck = deckToFill;
initSuccessful = true;
inputstream = inputStream;
}
void SetValues(const boost::filesystem::path &inputDataFile, DeckPtr deckToFill, const boost::filesystem::path &commonRootPath){
lineNR = 0;
dataFile = inputDataFile;
deck = deckToFill;
rootPath = commonRootPath;
std::ifstream *ifs = new std::ifstream(inputDataFile.string().c_str());
initSuccessful = ifs->is_open();
inputstream.reset(ifs);
ParserState(bool strict , const boost::filesystem::path &inputDataFile, DeckPtr deckToFill, const boost::filesystem::path &commonRootPath, std::map<std::string, std::string> &pathMapRef) {
SetValues(strict , inputDataFile, deckToFill, commonRootPath);
pathMap = pathMapRef;
}
void openFile(const boost::filesystem::path& inputFile) {
std::ifstream *ifs = new std::ifstream(inputFile.string().c_str());
// make sure the file we'd like to parse exists and is
// readable
if (!ifs->is_open()) {
throw std::runtime_error(std::string("Input file '") +
inputDataFile.string() +
inputFile.string() +
std::string("' does not exist or is not readable"));
}
}
ParserState(const boost::filesystem::path &inputDataFile, DeckPtr deckToFill, const boost::filesystem::path &commonRootPath, std::map<std::string, std::string> &pathMapRef) {
SetValues(inputDataFile, deckToFill, commonRootPath);
pathMap = pathMapRef;
inputstream.reset( ifs );
dataFile = inputFile;
}
void SetValues(bool strict, const boost::filesystem::path &inputDataFile, DeckPtr deckToFill, const boost::filesystem::path &commonRootPath){
m_strict = strict;
lineNR = 0;
deck = deckToFill;
rootPath = commonRootPath;
openFile( inputDataFile );
}
};
@@ -100,13 +113,8 @@ namespace Opm {
is retained in the current implementation.
*/
DeckPtr Parser::parseFile(const std::string &dataFileName) const {
std::shared_ptr<ParserState> parserState(new ParserState(dataFileName, DeckPtr(new Deck()), getRootPathFromFile(dataFileName)));
// warn if the file we'd like to parse does not exist or is not readable
if (!parserState->initSuccessful)
throw std::invalid_argument("Input file '" + dataFileName + "' does not exist or is not readable.");
DeckPtr Parser::parseFile(const std::string &dataFileName, bool strict) const {
std::shared_ptr<ParserState> parserState = std::make_shared<ParserState>(strict , dataFileName , DeckPtr(new Deck()) , getRootPathFromFile(dataFileName));
parseState(parserState);
applyUnitsToDeck(parserState->deck);
@@ -114,16 +122,16 @@ namespace Opm {
return parserState->deck;
}
DeckPtr Parser::parseString(const std::string &data) const {
DeckPtr Parser::parseString(const std::string &data, bool strict) const {
std::shared_ptr<ParserState> parserState(new ParserState(data, DeckPtr(new Deck())));
std::shared_ptr<ParserState> parserState(new ParserState(strict , data, DeckPtr(new Deck())));
parseState(parserState);
applyUnitsToDeck(parserState->deck);
return parserState->deck;
}
DeckPtr Parser::parseStream(std::shared_ptr<std::istream> inputStream) const {
std::shared_ptr<ParserState> parserState(new ParserState(inputStream, DeckPtr(new Deck())));
DeckPtr Parser::parseStream(std::shared_ptr<std::istream> inputStream, bool strict) const {
std::shared_ptr<ParserState> parserState(new ParserState(strict , inputStream, DeckPtr(new Deck())));
parseState(parserState);
applyUnitsToDeck(parserState->deck);
@@ -288,10 +296,7 @@ namespace Opm {
RawRecordConstPtr firstRecord = parserState->rawKeyword->getRecord(0);
std::string includeFileAsString = readValueToken<std::string>(firstRecord->getItem(0));
boost::filesystem::path includeFile = getIncludeFilePath(parserState, includeFileAsString);
std::shared_ptr<ParserState> newParserState (new ParserState(includeFile.string(), parserState->deck, parserState->rootPath, parserState->pathMap));
if (!newParserState->initSuccessful)
throw std::invalid_argument("Included file '" + includeFile.string() + "' does not exist or is not readable.");
std::shared_ptr<ParserState> newParserState (new ParserState(parserState->m_strict , includeFile.string(), parserState->deck, parserState->rootPath, parserState->pathMap));
stopParsing = parseState(newParserState);
if (stopParsing) break;
@@ -374,8 +379,12 @@ namespace Opm {
}
return RawKeywordPtr(new RawKeyword(keywordString, parserState->dataFile.string() , parserState->lineNR , targetSize , parserKeyword->isTableCollection()));
}
} else
throw std::invalid_argument("Keyword " + keywordString + " not recognized ");
} else {
if (parserState->m_strict)
throw std::invalid_argument("Keyword " + keywordString + " not recognized ");
else
return std::shared_ptr<RawKeyword>( );
}
}

View File

@@ -46,9 +46,9 @@ namespace Opm {
Parser(bool addDefault = true);
/// The starting point of the parsing process. The supplied file is parsed, and the resulting Deck is returned.
DeckPtr parseFile(const std::string &dataFile) const;
DeckPtr parseString(const std::string &data) const;
DeckPtr parseStream(std::shared_ptr<std::istream> inputStream) const;
DeckPtr parseFile(const std::string &dataFile, bool strict = true) const;
DeckPtr parseString(const std::string &data, bool strict = true) const;
DeckPtr parseStream(std::shared_ptr<std::istream> inputStream , bool strict = true) const;
/// Method to add ParserKeyword instances, these holding type and size information about the keywords and their data.
void addParserKeyword(ParserKeywordConstPtr parserKeyword);

View File

@@ -0,0 +1,22 @@
SPECGRID
20 20 10 /
IGNORED
Have no clue /
how to /
parse This keyword/
/
FAULTS
'F1' 1 1 1 4 1 4 'X' /
'F2' 5 5 1 4 1 4 'X-' /
/
And then comes more crap??!
-- And a valid keyword:
TABDIMS
1 2 3 /
And it ends with crap?!