blob: 0b4aab9cf2d7e84ab1c70d010078ee86e6d7282d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 CEA LIST.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "ParserManager.h"
#include <antlr/ANTLRException.hpp>
#include <fml/infrastructure/System.h>
#include <fml/workflow/WObject.h>
#include <parser/workflow/WorkflowLexer.hpp>
#include <parser/workflow/WorkflowParser.hpp>
#include <parser/model/fmlLexer.h>
#include <parser/model/fmlParser.h>
#include <parser/model/ParserUtil.h>
#include <printer/OutStream.h>
#include <util/avm_vfs.h>
namespace sep
{
/**
* CONSTRUCTOR
* Default
*/
ParserManager::ParserManager(const std::string & fileLocation)
: mFileLocation( fileLocation ),
mFilename( VFS::filename( fileLocation ) ),
mErrorCount( 0 ),
mWarningCount( 0 ),
mExceptionMessage( )
{
//!! NOTHING
}
/**
* ParserManager::start
*
*/
System * ParserManager::parseFML(WObjectManager & aWObjectManager)
{
System * theParseSpec = NULL;
mErrorCount = 0;
if( mFileLocation.empty() )
{
AVM_OS_WARN << _SEW_
<< "< error > Unexpected an empty specification file location !"
<< std::endl;
return( NULL );
}
std::ifstream anInputStream( mFileLocation.c_str() );
if( anInputStream.fail() )
{
AVM_OS_WARN << _SEW_
<< "< error > Cannot open file '"
<< mFileLocation << "'." << std::endl;
avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE );
return( NULL );
}
try
{
if( (mFileLocation.rfind(".xfml") != std::string::npos) ||
(mFileLocation.rfind(".fml" ) != std::string::npos) ||
(mFileLocation.rfind(".xlia") != std::string::npos) ||
(mFileLocation.rfind(".xfsp") != std::string::npos) ||
(mFileLocation.rfind(".lia" ) != std::string::npos) )
{
theParseSpec = parseFML(aWObjectManager, anInputStream);
}
if( theParseSpec == NULL )
{
AVM_OS_WARN << _SEW_
<< "< error > NO PARSING RESULT !" << std::endl;
avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE );
return( NULL );
}
}
catch( antlr::ANTLRException & e )
{
AVM_OS_WARN << _SEW_ << e.toString() << std::endl;
avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE );
return( NULL );
}
return( theParseSpec );
}
/**
* ParserManager::parseXLIA
*
*/
System * ParserManager::parseFML(
WObjectManager & aWObjectManager, std::ifstream & anInputStream)
{
///!!! The Return Variable Value *!*
System * theParseSpec = NULL;
mErrorCount = 0;
ParserUtil::XLIA_SYNTAX_ERROR_COUNT = 0;
pANTLR3_UINT8 path;
pANTLR3_INPUT_STREAM input;
pfmlLexer lexer;
pANTLR3_COMMON_TOKEN_STREAM tstream;
//
pfmlParser parser;
path = (pANTLR3_UINT8) mFileLocation.c_str();
input = antlr3FileStreamNew(path, ANTLR3_ENC_8BIT);
//input = antlr3AsciiFileStreamNew(path);
if( input == NULL)
{
AVM_OS_WARN << _SEW_
<< "< error > Failed to open file '"
<< mFileLocation << "'" << std::endl;
++mErrorCount;
avm_set_exit_code( AVM_EXIT_FAILED_CODE );
}
// CLexerNew is generated by ANTLR
lexer = fmlLexerNew(input);
// Need to check for errors ANTLR3_ERR_NOMEM
AVM_OS_ASSERT_OUT_OF_MEMORY_EXIT( lexer )
<< "Unable to create the lexer due to malloc() failure"
<< SEND_EXIT;
// CStreamNew is generated by ANTLR3
tstream = antlr3CommonTokenStreamSourceNew(
ANTLR3_SIZE_HINT, TOKENSOURCE(lexer));
// Need to check for errors ANTLR3_ERR_NOMEM
AVM_OS_ASSERT_OUT_OF_MEMORY_EXIT( tstream )
<< "Out of memory trying to allocate token stream"
<< SEND_EXIT;
// CParserNew is generated by ANTLR3
parser = fmlParserNew(tstream);
// Need to check for errors ANTLR3_ERR_NOMEM
AVM_OS_ASSERT_OUT_OF_MEMORY_EXIT( parser )
<< "Out of memory trying to allocate parser\n"
<< SEND_EXIT;
AVM_OS_VERBOSITY_MINIMUM( AVM_OS_CLOG ) << _SEW_
<< "Parsing: " << mFilename << " ..." << std::endl;
theParseSpec = parser->formalML(parser, aWObjectManager);
mErrorCount = parser->pParser->rec->state->errorCount +
ParserUtil::XLIA_SYNTAX_ERROR_COUNT;
AVM_OS_VERBOSITY_MINIMUM( AVM_OS_CLOG ) << _SEW_
<< "Done ==> " << mErrorCount << " syntax error"
<< ((mErrorCount > 1)? "s" : "") << " found."
<< std::endl;
// We did not return anything from this parser rule, so we can finish.
// It only remains to close down our open objects, in the reverse order
// we created them
//
parser->free(parser);
parser = NULL;
tstream ->free(tstream);
tstream = NULL;
lexer->free(lexer);
lexer = NULL;
input->close(input);
input = NULL;
if( mErrorCount > 0 )
{
avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE );
}
return( theParseSpec );
}
/**
* parse Symbolic Execution Workflow
*
*/
WObject * ParserManager::parseSEW(
WObjectManager & aWObjectManager, std::ifstream & anInputStream)
{
WObject * theParseParam = WObject::_NULL_;
mErrorCount = 0;
try
{
WorkflowLexer lexer( anInputStream );
WorkflowParser parser( lexer );
lexer.setFilename( mFilename );
parser.setFilename( mFilename );
lexer.resetErrors();
parser.resetErrors();
// AVM_OS_VERBOSITY_MINIMUM( AVM_OS_CLOG ) << _SEW_
// << "Parsing: " << mFilename << " ..." << std::endl;
theParseParam = parser.form_grammar( aWObjectManager );
mErrorCount = lexer.numberOfErrors() + parser.numberOfErrors();
// AVM_OS_VERBOSITY_MINIMUM( AVM_OS_CLOG ) << _SEW_
// << "Done ==> " << mErrorCount << " syntax error"
// << ((mErrorCount > 1)? "s" : "") << " found."
// << std::endl;
if( mErrorCount > 0 )
{
avm_set_exit_code( AVM_EXIT_PARSING_ERROR_CODE );
}
}
catch( antlr::ANTLRException & e )
{
mExceptionMessage = e.toString();
if( mErrorCount == 0 )
{
++mErrorCount;
}
avm_set_exit_code( AVM_EXIT_PARSING_EXCEPTION_CODE );
}
return( theParseParam );
}
}