2013-03-20 16:29:51 +01:00
/*
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/>.
*/
2013-12-06 14:18:05 +01:00
# include <memory>
2013-08-14 08:40:07 +02:00
2013-05-27 14:28:23 +02:00
# include <opm/parser/eclipse/Parser/Parser.hpp>
2013-06-20 15:30:37 +02:00
# include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
2013-08-13 14:51:33 +02:00
# include <opm/parser/eclipse/RawDeck/RawConsts.hpp>
2013-12-05 08:26:29 +01:00
# include <opm/parser/eclipse/RawDeck/RawEnums.hpp>
2013-05-27 14:28:23 +02:00
# include <opm/parser/eclipse/Deck/Deck.hpp>
2013-08-11 12:36:16 +02:00
# include <opm/parser/eclipse/Deck/DeckIntItem.hpp>
2013-05-27 14:28:23 +02:00
2013-03-20 16:29:51 +01:00
namespace Opm {
2013-09-14 22:39:43 +02:00
Parser : : Parser ( bool addDefault ) {
if ( addDefault )
addDefaultKeywords ( ) ;
2013-07-31 11:30:21 +02:00
}
2013-08-26 15:17:52 +02:00
DeckPtr Parser : : parse ( const std : : string & dataFile ) const {
2013-08-21 14:54:38 +02:00
return parse ( dataFile , true ) ;
}
2013-08-11 12:36:16 +02:00
2013-09-02 10:08:37 +02:00
/*
About INCLUDE : Observe that the ECLIPSE parser is slightly unlogical
when it comes to nested includes ; the path to an included file is always
interpreted relative to the filesystem location of the DATA file , and
not the location of the file issuing the INCLUDE command . That behaviour
is retained in the current implementation .
*/
DeckPtr Parser : : parse ( const std : : string & dataFileName , bool strictParsing ) const {
2013-12-06 14:18:05 +01:00
std : : shared_ptr < ParserState > parserState ( new ParserState ( ) ) ;
parserState - > strictParsing = strictParsing ;
parserState - > dataFile = boost : : filesystem : : path ( dataFileName ) ; ;
if ( parserState - > dataFile . is_absolute ( ) )
parserState - > rootPath = parserState - > dataFile . parent_path ( ) ;
2013-09-02 10:08:37 +02:00
else
2013-12-06 14:18:05 +01:00
parserState - > rootPath = boost : : filesystem : : current_path ( ) / parserState - > dataFile . parent_path ( ) ;
parserState - > deck = DeckPtr ( new Deck ( ) ) ;
2013-09-02 10:08:37 +02:00
2013-12-06 14:18:05 +01:00
parseFile ( parserState ) ;
return parserState - > deck ;
2013-08-11 12:36:16 +02:00
}
2013-09-02 10:08:37 +02:00
2013-08-19 22:37:48 +02:00
size_t Parser : : size ( ) const {
return m_parserKeywords . size ( ) ;
}
2013-12-01 09:28:14 +01:00
2013-08-26 15:17:52 +02:00
void Parser : : addKeyword ( ParserKeywordConstPtr parserKeyword ) {
2013-12-01 09:28:14 +01:00
const std : : string & name = parserKeyword - > getName ( ) ;
dropKeyword ( name ) ;
m_parserKeywords . insert ( std : : make_pair ( name , parserKeyword ) ) ;
if ( ParserKeyword : : wildCardName ( name ) )
m_wildCardKeywords . insert ( std : : make_pair ( name , parserKeyword ) ) ;
2013-08-26 15:17:52 +02:00
}
2013-08-27 10:00:36 +02:00
2013-12-01 09:28:14 +01:00
ParserKeywordConstPtr Parser : : matchingKeyword ( const std : : string & name ) const {
std : : map < std : : string , ParserKeywordConstPtr > : : const_iterator iter = m_wildCardKeywords . begin ( ) ;
ParserKeywordConstPtr keyword ;
while ( true ) {
if ( iter = = m_wildCardKeywords . end ( ) )
break ;
if ( ( * iter ) . second - > matches ( name ) ) {
keyword = ( * iter ) . second ;
break ;
}
+ + iter ;
}
return keyword ;
}
2013-08-26 15:17:52 +02:00
bool Parser : : hasKeyword ( const std : : string & keyword ) const {
2013-12-01 09:28:14 +01:00
return ( m_parserKeywords . find ( keyword ) ! = m_parserKeywords . end ( ) ) ;
2013-08-26 15:17:52 +02:00
}
2013-08-19 22:37:48 +02:00
2013-12-01 09:28:14 +01:00
bool Parser : : hasWildCardKeyword ( const std : : string & keyword ) const {
return ( m_wildCardKeywords . find ( keyword ) ! = m_parserKeywords . end ( ) ) ;
}
bool Parser : : canParseKeyword ( const std : : string & keyword ) const {
if ( hasKeyword ( keyword ) )
2013-10-09 08:22:43 +02:00
return true ;
2013-12-01 09:28:14 +01:00
else {
ParserKeywordConstPtr wildCardKeyword = matchingKeyword ( keyword ) ;
if ( wildCardKeyword )
return true ;
else
return false ;
}
}
bool Parser : : dropKeyword ( const std : : string & keyword ) {
bool erase = ( m_parserKeywords . erase ( keyword ) = = 1 ) ;
if ( erase )
m_wildCardKeywords . erase ( keyword ) ;
return erase ;
2013-10-09 08:22:43 +02:00
}
2013-12-01 09:28:14 +01:00
2013-08-27 10:00:36 +02:00
ParserKeywordConstPtr Parser : : getKeyword ( const std : : string & keyword ) const {
if ( hasKeyword ( keyword ) ) {
return m_parserKeywords . at ( keyword ) ;
2013-12-01 09:28:14 +01:00
} else {
ParserKeywordConstPtr wildCardKeyword = matchingKeyword ( keyword ) ;
if ( wildCardKeyword )
return wildCardKeyword ;
else
throw std : : invalid_argument ( " Do not have parser keyword for parsing: " + keyword ) ;
2013-08-27 10:00:36 +02:00
}
}
2013-08-26 15:17:52 +02:00
2013-09-02 10:08:37 +02:00
2013-12-06 14:18:05 +01:00
void Parser : : parseFile ( std : : shared_ptr < ParserState > parserState ) const {
2013-10-01 16:05:01 +02:00
bool verbose = false ;
2013-12-06 14:18:05 +01:00
parserState - > lineNR = 0 ;
parserState - > inputstream . open ( parserState - > dataFile . string ( ) . c_str ( ) ) ;
2013-08-21 10:41:18 +02:00
2013-12-06 14:18:05 +01:00
if ( parserState - > inputstream ) {
2013-12-05 08:26:29 +01:00
while ( true ) {
2013-12-06 14:18:05 +01:00
bool streamOK = tryParseKeyword ( parserState ) ;
if ( parserState - > rawKeyword ) {
if ( parserState - > rawKeyword - > getKeywordName ( ) = = Opm : : RawConsts : : include ) {
RawRecordConstPtr firstRecord = parserState - > rawKeyword - > getRecord ( 0 ) ;
2013-12-05 08:26:29 +01:00
std : : string includeFileString = firstRecord - > getItem ( 0 ) ;
boost : : filesystem : : path includeFile ( includeFileString ) ;
if ( includeFile . is_relative ( ) )
2013-12-06 14:18:05 +01:00
includeFile = parserState - > rootPath / includeFile ;
2013-12-05 08:26:29 +01:00
if ( verbose )
2013-12-06 14:18:05 +01:00
std : : cout < < parserState - > rawKeyword - > getKeywordName ( ) < < " " < < includeFile < < std : : endl ;
2013-12-05 08:26:29 +01:00
2013-12-06 14:18:05 +01:00
std : : shared_ptr < ParserState > newParserState ( new ParserState ( ) ) ;
newParserState - > copyFrom ( parserState ) ;
newParserState - > dataFile = includeFile ;
parseFile ( newParserState ) ;
2013-08-22 15:53:57 +02:00
} else {
2013-12-05 08:26:29 +01:00
if ( verbose )
2013-12-06 14:18:05 +01:00
std : : cout < < parserState - > rawKeyword - > getKeywordName ( ) < < std : : endl ;
2013-12-05 08:26:29 +01:00
2013-12-06 14:18:05 +01:00
if ( canParseKeyword ( parserState - > rawKeyword - > getKeywordName ( ) ) ) {
ParserKeywordConstPtr parserKeyword = getKeyword ( parserState - > rawKeyword - > getKeywordName ( ) ) ;
2013-12-05 08:26:29 +01:00
ParserKeywordActionEnum action = parserKeyword - > getAction ( ) ;
if ( action = = INTERNALIZE ) {
2013-12-06 14:18:05 +01:00
DeckKeywordPtr deckKeyword = parserKeyword - > parse ( parserState - > rawKeyword ) ;
parserState - > deck - > addKeyword ( deckKeyword ) ;
2013-12-05 08:26:29 +01:00
} else if ( action = = IGNORE_WARNING )
2013-12-06 14:18:05 +01:00
parserState - > deck - > addWarning ( " The keyword " + parserState - > rawKeyword - > getKeywordName ( ) + " is ignored - this might potentially affect the results " , parserState - > dataFile . string ( ) , parserState - > rawKeyword - > getLineNR ( ) ) ;
2013-12-05 08:26:29 +01:00
} else {
2013-12-06 14:18:05 +01:00
DeckKeywordPtr deckKeyword ( new DeckKeyword ( parserState - > rawKeyword - > getKeywordName ( ) , false ) ) ;
parserState - > deck - > addKeyword ( deckKeyword ) ;
parserState - > deck - > addWarning ( " The keyword " + parserState - > rawKeyword - > getKeywordName ( ) + " is not recognized " , parserState - > dataFile . string ( ) , parserState - > lineNR ) ;
2013-12-05 08:26:29 +01:00
}
2013-08-21 10:41:18 +02:00
}
2013-12-06 14:18:05 +01:00
parserState - > rawKeyword . reset ( ) ;
2013-08-21 10:41:18 +02:00
}
2013-12-05 08:26:29 +01:00
if ( ! streamOK )
break ;
2013-08-11 12:36:16 +02:00
}
2013-12-05 08:26:29 +01:00
2013-12-06 14:18:05 +01:00
parserState - > inputstream . close ( ) ;
2013-08-13 14:51:33 +02:00
} else
2013-12-06 14:18:05 +01:00
throw std : : invalid_argument ( " Failed to open file: " + parserState - > dataFile . string ( ) ) ;
2013-05-06 12:13:49 +02:00
}
2013-05-30 10:11:12 +02:00
2013-07-31 11:30:21 +02:00
void Parser : : loadKeywords ( const Json : : JsonObject & jsonKeywords ) {
2013-07-30 14:10:07 +02:00
if ( jsonKeywords . is_array ( ) ) {
for ( size_t index = 0 ; index < jsonKeywords . size ( ) ; index + + ) {
2013-08-21 10:41:18 +02:00
Json : : JsonObject jsonKeyword = jsonKeywords . get_array_item ( index ) ;
ParserKeywordConstPtr parserKeyword ( new ParserKeyword ( jsonKeyword ) ) ;
addKeyword ( parserKeyword ) ;
2013-07-30 14:10:07 +02:00
}
} else
throw std : : invalid_argument ( " Input JSON object is not an array " ) ;
}
2013-12-06 14:18:05 +01:00
RawKeywordPtr Parser : : createRawKeyword ( const std : : string & keywordString , std : : shared_ptr < ParserState > parserState ) const {
2013-12-01 09:28:14 +01:00
if ( canParseKeyword ( keywordString ) ) {
ParserKeywordConstPtr parserKeyword = getKeyword ( keywordString ) ;
2013-10-08 16:54:41 +02:00
ParserKeywordActionEnum action = parserKeyword - > getAction ( ) ;
if ( action = = THROW_EXCEPTION )
throw std : : invalid_argument ( " Parsing terminated by fatal keyword: " + keywordString ) ;
2013-12-05 08:26:29 +01:00
if ( parserKeyword - > getSizeType ( ) = = SLASH_TERMINATED | | parserKeyword - > getSizeType ( ) = = UNKNOWN ) {
Raw : : KeywordSizeEnum rawSizeType ;
if ( parserKeyword - > getSizeType ( ) = = SLASH_TERMINATED )
rawSizeType = Raw : : SLASH_TERMINATED ;
else
rawSizeType = Raw : : UNKNOWN ;
2013-12-06 14:18:05 +01:00
return RawKeywordPtr ( new RawKeyword ( keywordString , rawSizeType , parserState - > dataFile . string ( ) , parserState - > lineNR ) ) ;
2013-12-05 08:26:29 +01:00
} else {
2013-08-11 12:36:16 +02:00
size_t targetSize ;
2013-08-21 10:41:18 +02:00
2013-08-11 12:36:16 +02:00
if ( parserKeyword - > hasFixedSize ( ) )
targetSize = parserKeyword - > getFixedSize ( ) ;
else {
2013-08-21 10:41:18 +02:00
const std : : pair < std : : string , std : : string > sizeKeyword = parserKeyword - > getSizeDefinitionPair ( ) ;
2013-12-06 14:18:05 +01:00
DeckKeywordConstPtr sizeDefinitionKeyword = parserState - > deck - > getKeyword ( sizeKeyword . first ) ;
2013-08-14 08:43:54 +02:00
DeckItemConstPtr sizeDefinitionItem ;
{
DeckRecordConstPtr record = sizeDefinitionKeyword - > getRecord ( 0 ) ;
sizeDefinitionItem = record - > getItem ( sizeKeyword . second ) ;
}
targetSize = sizeDefinitionItem - > getInt ( 0 ) ;
2013-08-11 12:36:16 +02:00
}
2013-12-06 14:18:05 +01:00
return RawKeywordPtr ( new RawKeyword ( keywordString , parserState - > dataFile . string ( ) , parserState - > lineNR , targetSize , parserKeyword - > isTableCollection ( ) ) ) ;
2013-08-11 12:36:16 +02:00
}
2013-08-21 10:41:18 +02:00
} else {
2013-12-06 14:18:05 +01:00
if ( parserState - > strictParsing ) {
2013-08-21 10:41:18 +02:00
throw std : : invalid_argument ( " Keyword " + keywordString + " not recognized " ) ;
} else {
2013-12-06 14:18:05 +01:00
return RawKeywordPtr ( new RawKeyword ( keywordString , parserState - > dataFile . string ( ) , parserState - > lineNR , 0 ) ) ;
2013-08-21 10:41:18 +02:00
}
}
2013-08-11 12:36:16 +02:00
}
2013-10-08 16:54:41 +02:00
2013-12-06 14:18:05 +01:00
bool Parser : : tryParseKeyword ( std : : shared_ptr < ParserState > parserState ) const {
2013-08-11 12:36:16 +02:00
std : : string line ;
2013-12-05 08:26:29 +01:00
2013-12-06 14:18:05 +01:00
if ( parserState - > nextKeyword . length ( ) > 0 ) {
parserState - > rawKeyword = createRawKeyword ( parserState - > nextKeyword , parserState ) ;
parserState - > nextKeyword = " " ;
2013-12-05 08:26:29 +01:00
}
2013-12-02 16:17:57 +01:00
2013-12-06 14:18:05 +01:00
while ( std : : getline ( parserState - > inputstream , line ) ) {
2013-12-02 16:17:57 +01:00
boost : : algorithm : : trim_right ( line ) ; // Removing garbage (eg. \r)
2013-08-11 12:36:16 +02:00
std : : string keywordString ;
2013-12-06 14:18:05 +01:00
parserState - > lineNR + + ;
if ( parserState - > rawKeyword = = NULL ) {
2013-08-21 08:44:46 +02:00
if ( RawKeyword : : tryParseKeyword ( line , keywordString ) ) {
2013-12-06 14:18:05 +01:00
parserState - > rawKeyword = createRawKeyword ( keywordString , parserState ) ;
2013-08-21 08:44:46 +02:00
}
2013-08-11 12:36:16 +02:00
} else {
2013-12-06 14:18:05 +01:00
if ( parserState - > rawKeyword - > getSizeType ( ) = = Raw : : UNKNOWN ) {
2013-12-05 08:26:29 +01:00
if ( canParseKeyword ( line ) ) {
2013-12-06 14:18:05 +01:00
parserState - > nextKeyword = line ;
2013-12-05 08:26:29 +01:00
return true ;
}
}
2013-08-21 08:44:46 +02:00
if ( RawKeyword : : useLine ( line ) ) {
2013-12-06 14:18:05 +01:00
parserState - > rawKeyword - > addRawRecordString ( line ) ;
2013-08-21 08:44:46 +02:00
}
2013-08-21 10:41:18 +02:00
}
2013-12-06 14:18:05 +01:00
if ( parserState - > rawKeyword ! = NULL & & parserState - > rawKeyword - > isFinished ( ) )
2013-08-11 12:36:16 +02:00
return true ;
}
2013-08-21 10:41:18 +02:00
2013-08-11 12:36:16 +02:00
return false ;
}
2013-08-19 22:37:48 +02:00
bool Parser : : loadKeywordFromFile ( const boost : : filesystem : : path & configFile ) {
try {
2013-09-16 15:53:56 +02:00
Json : : JsonObject jsonKeyword ( configFile ) ;
ParserKeywordConstPtr parserKeyword ( new ParserKeyword ( jsonKeyword ) ) ;
addKeyword ( parserKeyword ) ;
return true ;
}
catch ( . . . ) {
return false ;
}
2013-08-19 22:37:48 +02:00
}
2013-09-13 22:23:12 +02:00
2013-08-21 12:50:21 +02:00
void Parser : : loadKeywordsFromDirectory ( const boost : : filesystem : : path & directory , bool recursive , bool onlyALLCAPS8 ) {
2013-08-23 00:16:50 +02:00
if ( ! boost : : filesystem : : exists ( directory ) )
throw std : : invalid_argument ( " Directory: " + directory . string ( ) + " does not exist. " ) ;
else {
boost : : filesystem : : directory_iterator end ;
2013-08-27 10:00:36 +02:00
for ( boost : : filesystem : : directory_iterator iter ( directory ) ; iter ! = end ; iter + + ) {
if ( boost : : filesystem : : is_directory ( * iter ) ) {
2013-08-23 00:16:50 +02:00
if ( recursive )
2013-08-27 10:00:36 +02:00
loadKeywordsFromDirectory ( * iter , recursive , onlyALLCAPS8 ) ;
2013-08-23 00:16:50 +02:00
} else {
2013-08-27 10:00:36 +02:00
if ( ParserKeyword : : validName ( iter - > path ( ) . filename ( ) . string ( ) ) | | ! onlyALLCAPS8 ) {
2013-08-23 00:16:50 +02:00
if ( ! loadKeywordFromFile ( * iter ) )
std : : cerr < < " ** Warning: failed to load keyword from file: " < < iter - > path ( ) < < std : : endl ;
}
}
}
}
}
2013-08-19 22:37:48 +02:00
2013-12-06 14:18:05 +01:00
2013-03-20 16:29:51 +01:00
} // namespace Opm