blob: 3ffc5b514782f0f7797f73bc557b7fa82c923aab [file] [log] [blame]
grammar fml;
options {
backtrack=true;
memoize=true;
k=1;
language = C;
}
@lexer::header {
}
@parser::header {
#include <parser/model/ParserUtil.h>
#include <common/BF.h>
#include <collection/BFContainer.h>
#include <fml/common/BehavioralElement.h>
#include <fml/common/ModifierElement.h>
#include <fml/common/SpecifierElement.h>
#include <fml/executable/ExecutableLib.h>
#include <fml/expression/AvmCode.h>
#include <fml/expression/BuiltinArray.h>
#include <fml/expression/ExpressionConstant.h>
#include <fml/expression/ExpressionConstructor.h>
#include <fml/expression/StatementConstructor.h>
#include <fml/lib/IComPoint.h>
#include <fml/operator/Operator.h>
#include <fml/operator/OperatorManager.h>
#include <fml/template/TemplateFactory.h>
#include <fml/type/TypeSpecifier.h>
#include <fml/type/TypeManager.h>
#include <fml/infrastructure/Buffer.h>
#include <fml/infrastructure/Channel.h>
#include <fml/infrastructure/ComPoint.h>
#include <fml/infrastructure/ComProtocol.h>
#include <fml/infrastructure/ComRoute.h>
#include <fml/infrastructure/Connector.h>
// extern "C" and C++ template incompatibility !!!
//#include <fml/infrastructure/PropertyPart.h>
#include <fml/infrastructure/DataType.h>
#include <fml/infrastructure/Machine.h>
#include <fml/infrastructure/Package.h>
#include <fml/infrastructure/Port.h>
#include <fml/infrastructure/Routine.h>
#include <fml/infrastructure/System.h>
#include <fml/infrastructure/Transition.h>
#include <fml/infrastructure/Variable.h>
#include <fml/infrastructure/BehavioralPart.h>
#include <fml/infrastructure/CompositePart.h>
#include <fml/infrastructure/InstanceSpecifierPart.h>
#include <fml/infrastructure/InteractionPart.h>
#include <fml/infrastructure/ModelOfComputationPart.h>
// extern "C" and C++ template incompatibility !!!
//#include <fml/infrastructure/PropertyPart.h>
#include <fml/workflow/Query.h>
#include <fml/workflow/UniFormIdentifier.h>
#include <fml/workflow/WObject.h>
//void fmlDisplayRecognitionError(
// pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames);
}
@parser::members {
// extern "C" and C++ Template incompatibility !!!
#include <fml/infrastructure/PropertyPart.h>
////////////////////////////////////////////////////////////////////////////////
// SET LOCATION IN TRACEABLE FORM
////////////////////////////////////////////////////////////////////////////////
#define SAVE_RULE_BEGIN_LOCATION sep::avm_size_t bLine = LT(1)->getLine(LT(1))
#define SET_RULE_LOCATION(form) \
sep::ParserUtil::setLocation(form, bLine, LT(-1)->getLine(LT(-1)))
////////////////////////////////////////////////////////////////////////////////
// XLIA or XFSP MACRO
////////////////////////////////////////////////////////////////////////////////
#define OP(op) sep::OperatorManager::OPERATOR_##op
#define NEW_EXPR(e) sep::ExpressionConstructor::newExpr(e)
#define NEW_BOOL(b) sep::ExpressionConstructor::newBoolean((bool) b)
#define NEW_INTEGER(i) sep::ExpressionConstructor::newInteger(i)
#define NEW_RATIONAL(q) sep::ExpressionConstructor::newRational(q)
#define NEW_FLOAT(f) sep::ExpressionConstructor::newFloat(f)
#define NEW_CHAR(c) sep::ExpressionConstructor::newChar(c)
#define NEW_STRING(s) sep::ExpressionConstructor::newString(s)
#define NEW_ID(id) sep::ExpressionConstructor::newIdentifier(id)
#define NEW_QID(id) sep::ExpressionConstructor::newQualifiedIdentifier(id)
#define NEW_QNID(id, nb) ( (nb > 1)? NEW_QID(id) : NEW_ID(id) )
#define NEW_INSTANCE_UFID(machine, var) \
sep::ExpressionConstructor::newQualifiedIdentifier( \
sep::OSS() << machine->getNameID() << '.' << var->getNameID() )
#define NEW_CODE(op) sep::ExpressionConstructor::newCode(op)
#define NEW_CODE1(op, e) sep::ExpressionConstructor::newCode(op, e)
#define NEW_CODE2(op, e1, e2) sep::ExpressionConstructor::newCode(op, e1, e2)
#define NEW_CODE3(op, e1, e2, e3) sep::ExpressionConstructor::newCode(op, e1, e2, e3)
#define NEW_CODE_FLAT(op, e1, e2) sep::ExpressionConstructor::newCodeFlat(op, e1, e2)
#define NEW_STMT(op) sep::StatementConstructor::newCode(op)
#define NEW_STMT1(op, s) sep::StatementConstructor::newCode(op, s)
#define NEW_STMT2(op, s1, s2) sep::StatementConstructor::newCode(op, s1, s2)
#define NEW_STMT3(op, s1, s2, s3) sep::StatementConstructor::newCode(op, s1, s2, s3)
#define NEW_STMT_ASSIGN_OP(op, lv, e) \
NEW_STMT2(OP(ASSIGN_OP), lv, NEW_CODE1(op, e))
#define NEW_STMT_ASSIGN_OP_AFTER(op, lv, e) \
NEW_STMT2(OP(ASSIGN_OP_AFTER), lv, NEW_CODE1(op, e))
#define NUM_INT(s) std::atoi((const char*)(s))
#define NUM_FLOAT(s) std::atof((const char*)(s))
#define CHAR(s) ( *((const char*)(s)) )
#define STR(s) std::string((const char*)(s))
#define STR_ID(s) std::string((const char*)((s->getText(s))->chars))
sep::BF new_uminus_expr(sep::BF & arg)
{
if( arg.isNumeric() )
{
return( sep::ExpressionConstructor::uminusExpr(arg) );
}
return( NEW_CODE1(OP(UMINUS), arg) );
}
sep::BF new_not_expr(sep::BF & arg)
{
if( arg.isBoolean() )
{
return( sep::ExpressionConstructor::notExpr(arg) );
}
return( NEW_CODE1(OP(NOT), arg) );
}
////////////////////////////////////////////////////////////////////////////////
// PARSER GLOBAL VARIABLE
////////////////////////////////////////////////////////////////////////////////
// WObject Manager
sep::WObjectManager * mWObjectManager = NULL;
// Current Diversity prologue specification
sep::WObject * DIVERITY_PROLOG = sep::WObject::_NULL_;
// Current Parse System
static sep::System * _SYSTEM_ = NULL;
// Current Parse Machine
static sep::Machine * _CPM_ = NULL;
#define PUSH_CTX_CPM( cpm ) sep::ParserUtil::pushCTX( _CPM_ = cpm )
#define PUSH_CTX_NEW( cpm ) sep::ParserUtil::pushDynamicCTX( _CPM_ = cpm )
// Current Parse Routine
static sep::Routine * _CPR_ = NULL;
#define PUSH_CTX_CPR( cpr ) sep::ParserUtil::pushCTX( _CPR_ = cpr )
// Pop old local parse context & update current machine & routine
#define POP_CTX sep::ParserUtil::popCTX( _CPM_ , _CPR_ )
#define POP_CTX_IF( cpm ) \
if( _CPM_ == cpm ) { sep::ParserUtil::popCTX( _CPM_ , _CPR_ ); }
// Current Parse Routine | Machine | System
#define _CPRMS_ ( ( _CPR_ != NULL ) \
? static_cast< sep::BehavioralElement * >(_CPR_) \
: ( ( _CPM_ != NULL ) \
? static_cast< sep::BehavioralElement * >(_CPM_) \
: static_cast< sep::BehavioralElement * >(_SYSTEM_) ) )
// Current Parse [ [ Fully ] Qualified ] Name ID
std::string cpLOCATOR;
std::vector< std::string > cpQNID;
////////////////////////////////////////////////////////////////////////////////
// DEFAULT STATE #final, #terminal, #return
////////////////////////////////////////////////////////////////////////////////
static sep::ListOfMachine needDefaultStateFinal;
static sep::ListOfMachine needDefaultStateTerminal;
static sep::ListOfMachine needDefaultStateReturn;
////////////////////////////////////////////////////////////////////////////////
// TRANSITION ID
////////////////////////////////////////////////////////////////////////////////
static sep::avm_size_t transition_id = 0;
static void resetTransitionID()
{
transition_id = 0;
}
static std::string newTransitionID(
const std::string & id, const std::string & prefix = "t")
{
return( id.empty() ?
(sep::OSS() << prefix << '#' << transition_id++).str() : id );
}
static int mInvokeNewInstanceCount = 0;
static std::string newInvokeNewInstanceNameID(
sep::Machine * container, const std::string modelNameID)
{
return( sep::OSS() << modelNameID << '#' << mInvokeNewInstanceCount++ );
}
static int mProcedureCallCount = 0;
////////////////////////////////////////////////////////////////////////////////
// CONNECT ID
////////////////////////////////////////////////////////////////////////////////
static sep::avm_size_t buffer_id = 0;
static void resetBufferID()
{
buffer_id = 0;
}
static std::string newBufferID(const std::string & prefix = sep::Buffer::ANONYM_ID)
{
return( sep::OSS() << prefix << '#' << buffer_id++ );
}
////////////////////////////////////////////////////////////////////////////////
// CONNECT ID
////////////////////////////////////////////////////////////////////////////////
static sep::avm_size_t connector_id = 0;
static void resetConnectID()
{
connector_id = 0;
}
static std::string newConnectID(const std::string & id,
const std::string & prefix = sep::Connector::ANONYM_ID)
{
return( id.empty() ?
(sep::OSS() << prefix << '#' << connector_id++).str() : id );
}
////////////////////////////////////////////////////////////////////////////////
// PARSER MACRO FOR SEMANTIC PREDICATE FOR KEYWORD DETECTION
////////////////////////////////////////////////////////////////////////////////
#define IS_KEYWORD(kw) \
( (STR(LT(1)->getText(LT(1))->chars) == kw)? ANTLR3_TRUE : ANTLR3_FALSE )
void fmlDisplayRecognitionError(
pANTLR3_BASE_RECOGNIZER recognizer, pANTLR3_UINT8 * tokenNames)
{
pANTLR3_PARSER parser;
pANTLR3_TREE_PARSER tparser;
pANTLR3_INT_STREAM is;
pANTLR3_STRING ttext;
pANTLR3_STRING ftext;
pANTLR3_EXCEPTION ex;
pANTLR3_COMMON_TOKEN theToken;
pANTLR3_BASE_TREE theBaseTree;
pANTLR3_COMMON_TREE theCommonTree;
// Retrieve some info for easy reading.
//
ex = recognizer->state->exception;
ttext = NULL;
// See if there is a 'filename' we can use
//
if (ex->streamName == NULL)
{
if (((pANTLR3_COMMON_TOKEN)(ex->token))->type == ANTLR3_TOKEN_EOF)
{
ANTLR3_FPRINTF(stderr, "-end of input-(");
}
else
{
ANTLR3_FPRINTF(stderr, "-unknown source-(");
}
}
else
{
ftext = ex->streamName->to8(ex->streamName);
ANTLR3_FPRINTF(stderr, "\%s(", ftext->chars);
}
// Next comes the line number
//
ANTLR3_FPRINTF(stderr, "\%d) ", recognizer->state->exception->line);
ANTLR3_FPRINTF(stderr, " : error \%d : \%s",
recognizer->state->exception->type,
(pANTLR3_UINT8) (recognizer->state->exception->message));
// How we determine the next piece is dependent on which thing raised the
// error.
//
switch (recognizer->type)
{
case ANTLR3_TYPE_PARSER:
// Prepare the knowledge we know we have
//
parser = (pANTLR3_PARSER) (recognizer->super);
tparser = NULL;
is = parser->tstream->istream;
theToken = (pANTLR3_COMMON_TOKEN)(recognizer->state->exception->token);
ttext = theToken->toString(theToken);
ANTLR3_FPRINTF(stderr, ", at offset \%d", recognizer->state->exception->charPositionInLine);
if (theToken != NULL)
{
if (theToken->type == ANTLR3_TOKEN_EOF)
{
ANTLR3_FPRINTF(stderr, ", at <EOF>");
}
else
{
// Guard against null text in a token
//
ANTLR3_FPRINTF(stderr, "\n NEAR \%s\n ", ttext == NULL ? (pANTLR3_UINT8)"<no text for the token>" : ttext->chars);
}
}
break;
case ANTLR3_TYPE_TREE_PARSER:
tparser = (pANTLR3_TREE_PARSER) (recognizer->super);
parser = NULL;
is = tparser->ctnstream->tnstream->istream;
theBaseTree = (pANTLR3_BASE_TREE)(recognizer->state->exception->token);
ttext = theBaseTree->toStringTree(theBaseTree);
if (theBaseTree != NULL)
{
theCommonTree = (pANTLR3_COMMON_TREE) theBaseTree->super;
if (theCommonTree != NULL)
{
theToken = (pANTLR3_COMMON_TOKEN) theBaseTree->getToken(theBaseTree);
}
ANTLR3_FPRINTF(stderr, ", at offset \%d", theBaseTree->getCharPositionInLine(theBaseTree));
ANTLR3_FPRINTF(stderr, ", near \%s", ttext->chars);
}
break;
default:
ANTLR3_FPRINTF(stderr, "Base recognizer function displayRecognitionError called by unknown parser type - provide override for this function\n");
return;
break;
}
// Although this function should generally be provided by the implementation, this one
// should be as helpful as possible for grammar developers and serve as an example
// of what you can do with each exception type. In general, when you make up your
// 'real' handler, you should debug the routine with all possible errors you expect
// which will then let you be as specific as possible about all circumstances.
//
// Note that in the general case, errors thrown by tree parsers indicate a problem
// with the output of the parser or with the tree grammar itself. The job of the parser
// is to produce a perfect (in traversal terms) syntactically correct tree, so errors
// at that stage should really be semantic errors that your own code determines and handles
// in whatever way is appropriate.
//
switch (ex->type)
{
case ANTLR3_UNWANTED_TOKEN_EXCEPTION:
// Indicates that the recognizer was fed a token which seesm to be
// spurious input. We can detect this when the token that follows
// this unwanted token would normally be part of the syntactically
// correct stream. Then we can see that the token we are looking at
// is just something that should not be there and throw this exception.
//
if (tokenNames == NULL)
{
ANTLR3_FPRINTF(stderr, " : Extraneous input...");
}
else
{
if (ex->expecting == ANTLR3_TOKEN_EOF)
{
ANTLR3_FPRINTF(stderr, " : Extraneous input - expected <EOF>\n");
}
else
{
ANTLR3_FPRINTF(stderr, " : Extraneous input - expected \%s ...\n", tokenNames[ex->expecting]);
}
}
break;
case ANTLR3_MISSING_TOKEN_EXCEPTION:
// Indicates that the recognizer detected that the token we just
// hit would be valid syntactically if preceeded by a particular
// token. Perhaps a missing ';' at line end or a missing ',' in an
// expression list, and such like.
//
if (tokenNames == NULL)
{
ANTLR3_FPRINTF(stderr, " : Missing token (\%d)...\n", ex->expecting);
}
else
{
if (ex->expecting == ANTLR3_TOKEN_EOF)
{
ANTLR3_FPRINTF(stderr, " : Missing <EOF>\n");
}
else
{
ANTLR3_FPRINTF(stderr, " : Missing \%s \n", tokenNames[ex->expecting]);
}
}
break;
case ANTLR3_RECOGNITION_EXCEPTION:
// Indicates that the recognizer received a token
// in the input that was not predicted. This is the basic exception type
// from which all others are derived. So we assume it was a syntax error.
// You may get this if there are not more tokens and more are needed
// to complete a parse for instance.
//
ANTLR3_FPRINTF(stderr, " : syntax error...\n");
break;
case ANTLR3_MISMATCHED_TOKEN_EXCEPTION:
// We were expecting to see one thing and got another. This is the
// most common error if we coudl not detect a missing or unwanted token.
// Here you can spend your efforts to
// derive more useful error messages based on the expected
// token set and the last token and so on. The error following
// bitmaps do a good job of reducing the set that we were looking
// for down to something small. Knowing what you are parsing may be
// able to allow you to be even more specific about an error.
//
if (tokenNames == NULL)
{
ANTLR3_FPRINTF(stderr, " : syntax error...\n");
}
else
{
if (ex->expecting == ANTLR3_TOKEN_EOF)
{
ANTLR3_FPRINTF(stderr, " : expected <EOF>\n");
}
else
{
ANTLR3_FPRINTF(stderr, " : expected \%s ...\n", tokenNames[ex->expecting]);
}
}
break;
case ANTLR3_NO_VIABLE_ALT_EXCEPTION:
// We could not pick any alt decision from the input given
// so god knows what happened - however when you examine your grammar,
// you should. It means that at the point where the current token occurred
// that the DFA indicates nowhere to go from here.
//
ANTLR3_FPRINTF(stderr, " : cannot match to any predicted input...\n");
break;
case ANTLR3_MISMATCHED_SET_EXCEPTION:
{
ANTLR3_UINT32 count;
ANTLR3_UINT32 bit;
ANTLR3_UINT32 size;
ANTLR3_UINT32 numbits;
pANTLR3_BITSET errBits;
// This means we were able to deal with one of a set of
// possible tokens at this point, but we did not see any
// member of that set.
//
ANTLR3_FPRINTF(stderr, " : unexpected input...\n expected one of : ");
// What tokens could we have accepted at this point in the
// parse?
//
count = 0;
errBits = antlr3BitsetLoad (ex->expectingSet);
numbits = errBits->numBits (errBits);
size = errBits->size (errBits);
if (size > 0)
{
// However many tokens we could have dealt with here, it is usually
// not useful to print ALL of the set here. I arbitrarily chose 8
// here, but you should do whatever makes sense for you of course.
// No token number 0, so look for bit 1 and on.
//
for (bit = 1; bit < numbits && count < 8 && count < size; bit++)
{
// TODO: This doesn;t look right - should be asking if the bit is set!!
//
if (tokenNames[bit])
{
ANTLR3_FPRINTF(stderr, "\%s\%s", count > 0 ? ", " : "", tokenNames[bit]);
count++;
}
}
ANTLR3_FPRINTF(stderr, "\n");
}
else
{
ANTLR3_FPRINTF(stderr, "Actually dude, we didn't seem to be expecting anything here, or at least\n");
ANTLR3_FPRINTF(stderr, "I could not work out what I was expecting, like so many of us these days!\n");
}
}
break;
case ANTLR3_EARLY_EXIT_EXCEPTION:
// We entered a loop requiring a number of token sequences
// but found a token that ended that sequence earlier than
// we should have done.
//
ANTLR3_FPRINTF(stderr, " : missing elements...\n");
break;
default:
// We don't handle any other exceptions here, but you can
// if you wish. If we get an exception that hits this point
// then we are just going to report what we know about the
// token.
//
ANTLR3_FPRINTF(stderr, " : syntax not recognized...\n");
break;
}
// Here you have the token that was in error which if this is
// the standard implementation will tell you the line and offset
// and also record the address of the start of the line in the
// input stream. You could therefore print the source line and so on.
// Generally though, I would expect that your lexer/parser will keep
// its own map of lines and source pointers or whatever as there
// are a lot of specific things you need to know about the input
// to do something like that.
// Here is where you do it though :-).
//
}
}
/*
@parser::apifuncs
{
// Install custom error message display
//
RECOGNIZER->displayRecognitionError = fmlDisplayRecognitionError;
}
*/
// MAIN RULE
formalML[ sep::WObjectManager & aWObjectManager ]
returns [ sep::System * spec ]
@init{
mWObjectManager = &( aWObjectManager );
spec = NULL;
}
@after{
spec->setWObject(DIVERITY_PROLOG);
}
: prologue_fml
( s=def_system { $spec = $s.sys; }
// | p=def_package { $spec = $p.pack; }
)
;
////////////////////////////////////////////////////////////////////////////////
// section PROLOGUE
////////////////////////////////////////////////////////////////////////////////
prologue_fml
@init{
std::string attrID;
}
: ( '@formalml' { DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "formalml" ); }
| '@xfml' { DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "xfml" ); }
| '@fml' { DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "fml" ); }
| '@diversity' { DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "diversity"); }
| '@xlia' { DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "xlia" ); }
| '@xfsp' { DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "xfsp" ); }
) ?
{
if( DIVERITY_PROLOG == sep::WObject::_NULL_ )
{ DIVERITY_PROLOG = mWObjectManager->newWSequence(sep::WObject::_NULL_, "symbex"); }
}
LT_
( 'system' { attrID = "system"; }
| 'package' { attrID = "package"; }
| id=ID { attrID = STR($id.text->chars); }
)
( ASSIGN id=ID
{
DIVERITY_PROLOG->append( mWObjectManager->newWPropertyIdentifier(
DIVERITY_PROLOG, attrID, STR($id.text->chars) ) );
}
)?
( COMMA ( FloatLiteral | ID | StringLiteral ) )*
GT
COLON
( prologue_attribute )?
( prologue_options )?
;
prologue_attribute
: '@package' ASSIGN id=ID SEMI
{
DIVERITY_PROLOG->append( mWObjectManager->newWPropertyIdentifier(
DIVERITY_PROLOG, "package", STR($id.text->chars) ) );
}
| '@system' ASSIGN id=ID SEMI
{
DIVERITY_PROLOG->append( mWObjectManager->newWPropertyIdentifier(
DIVERITY_PROLOG, "system", STR($id.text->chars) ) );
}
;
prologue_options
: '@options' LCURLY
( id=ID ASSIGN e=expression SEMI
{ sep::ParserUtil::setPrologueOption(STR($id.text->chars), $e.bf); }
)*
RCURLY
;
////////////////////////////////////////////////////////////////////////////////
// form MODIFIER
////////////////////////////////////////////////////////////////////////////////
//modifier_property_specifier
modifier_declaration
returns [ sep::Modifier mdfr ]
: ( 'final' { mdfr.setFeatureFinal(); }
// | 'const' { mdfr.setFeatureConst(); }
| 'static' { mdfr.setFeatureStatic(); }
| 'volatile' { mdfr.setFeatureVolatile(); }
| 'transient' { mdfr.setFeatureTransient(); }
| 'unsafe' { mdfr.setFeatureUnsafe(); }
| 'ref' { mdfr.setNatureReference(); }
// | 'macro' { mdfr.setNatureMacro(); }
| 'bind' { mdfr.setNatureBind(); }
| 'public' { mdfr.setVisibilityPublic(); }
// | 'protected' { mdfr.setVisibilityProtected(); }
| 'private' { mdfr.setVisibilityPrivate(); }
| modifier_set_direction_strict_text[ mdfr ]
)+
;
//modifier_parameter_specifier
modifier_direction
returns [ sep::Modifier mdfr ]
: ( '->' | 'in' | 'input' ) { mdfr.setDirectionInput(); }
| ( '<-' | 'out' | 'output' ) { mdfr.setDirectionOutput(); }
| ( '<->' | 'inout' ) { mdfr.setDirectionInout(); }
| ( '<=' | 'return' ) { mdfr.setDirectionReturn(); }
;
modifier_direction_text
returns [ sep::Modifier mdfr ]
: ( 'in' | 'input' ) { mdfr.setDirectionInput(); }
| ( 'out' | 'output' ) { mdfr.setDirectionOutput(); }
| ( 'inout' ) { mdfr.setDirectionInout(); }
| ( 'return' ) { mdfr.setDirectionReturn(); }
;
modifier_set_direction_strict_text
/*inout*/[ sep::Modifier & mdfr ]
: 'input' { mdfr.setDirectionInput(); }
| 'output' { mdfr.setDirectionOutput(); }
| 'inout' { mdfr.setDirectionInout(); }
| 'return' { mdfr.setDirectionReturn(); }
;
modifier_direction_symbol
returns [ sep::Modifier mdfr ]
: '->' { mdfr.setDirectionInput(); }
| '<-' { mdfr.setDirectionOutput(); }
| '<->' { mdfr.setDirectionInout(); }
| '<=' { mdfr.setDirectionReturn(); }
;
//modifier_parameter_specifier
modifier_param
returns [ sep::Modifier mdfr ]
: m=modifier_direction { mdfr = $m.mdfr; }
| 'final' { mdfr.setFeatureFinal(); }
| 'const' { mdfr.setFeatureConst(); }
| ( '&' | 'ref' ) { mdfr.setNatureReference(); }
| 'macro' { mdfr.setNatureMacro(); }
| 'bind' { mdfr.setNatureBind(); }
;
//modifier_procedure_specifier
procedure_modifier_specifier
returns [ sep::Modifier mdfr , sep::Specifier spcfr ]
// : ( 'final' { $mdfr.setFeatureFinal(); }
// | 'volatile' { $mdfr.setFeatureVolatile(); }
// | 'transient' { $mdfr.setFeatureTransient(); }
// | 'model' { $mdfr.setDesignModel(); }
// | 'prototype' { $mdfr.setDesignPrototypeStatic(); }
// | 'instance' { $mdfr.setDesignInstanceStatic(); }
// | 'dynamic' { $mdfr.setDesignInstanceDynamic(); }
// | 'macro' { $mdfr.setNatureMacro(); }
// | 'public' { $mdfr.setVisibilityPublic(); }
// | 'protected' { $mdfr.setVisibilityProtected(); }
// | 'private' { $mdfr.setVisibilityPrivate(); }
: ( 'timed' { $spcfr.setFeatureTimed(); }
| 'input_enabled' { $spcfr.setFeatureInputEnabled(); }
// | 'lifeline' { $spcfr.setFeatureLifeline(); }
| 'unsafe' { $mdfr.setFeatureUnsafe(); }
)+
;
executable_modifier_specifier
returns [ sep::Modifier mdfr , sep::Specifier spcfr ]
// : ( 'final' { $mdfr.setFeatureFinal(); }
// | 'volatile' { $mdfr.setFeatureVolatile(); }
// | 'transient' { $mdfr.setFeatureTransient(); }
: ( 'model' { $spcfr.setDesignModel(); }
| 'prototype' { $spcfr.setDesignPrototypeStatic(); }
// | 'instance' { $spcfr.setDesignInstanceStatic(); }
| 'dynamic' { $spcfr.setDesignInstanceDynamic(); }
// | 'macro' { $mdfr.setNatureMacro(); }
// | 'bind' { $mdfr.setNatureBind(); }
// | 'public' { $mdfr.setVisibilityPublic(); }
// | 'protected' { $mdfr.setVisibilityProtected(); }
// | 'private' { $mdfr.setVisibilityPrivate(); }
| 'unsafe' { $mdfr.setFeatureUnsafe(); }
| 'timed' { $spcfr.setFeatureTimed(); }
| 'input_enabled' { $spcfr.setFeatureInputEnabled(); }
| 'lifeline' { $spcfr.setFeatureLifeline(); }
)+
;
instance_modifier_specifier
returns [ sep::Modifier mdfr , sep::Specifier spcfr ]
: ( 'final' { $mdfr.setFeatureFinal(); }
// | 'volatile' { $mdfr.setFeatureVolatile(); }
// | 'transient' { $mdfr.setFeatureTransient(); }
// | 'model' { $spcfr.setDesignModel(); }
// | 'prototype' { $spcfr.setDesignPrototypeStatic(); }
// | 'instance' { $spcfr.setDesignInstanceStatic(); }
| 'dynamic' { $spcfr.setDesignInstanceDynamic(); }
// | 'macro' { $mdfr.setNatureMacro(); }
// | 'bind' { $mdfr.setNatureBind(); }
| 'public' { $mdfr.setVisibilityPublic(); }
| 'protected' { $mdfr.setVisibilityProtected(); }
| 'private' { $mdfr.setVisibilityPrivate(); }
| 'unsafe' { $mdfr.setFeatureUnsafe(); }
| 'timed' { $spcfr.setFeatureTimed(); }
| 'input_enabled' { $spcfr.setFeatureInputEnabled(); }
| 'lifeline' { $spcfr.setFeatureLifeline(); }
)+
;
//modifier_transition_specifier
modifier_transition
returns [ sep::Modifier mdfr , sep::Specifier spcfr ]
// : ( 'final' { $mdfr.setFeatureFinal(); }
// | 'volatile' { $mdfr.setFeatureVolatile(); }
: ( 'transient' { $mdfr.setFeatureTransient(); }
// | 'unsafe' { $mdfr.setFeatureUnsafe(); }
| 'timed' { $spcfr.setFeatureTimed(); }
| 'input_enabled' { $spcfr.setFeatureInputEnabled(); }
)+
;
////////////////////////////////////////////////////////////////////////////////
// section PACKAGE
////////////////////////////////////////////////////////////////////////////////
def_package
returns [ sep::Package * pack ]
@after{
POP_CTX;
sep::ParserUtil::declareDefaultEndingStateIfNeed(needDefaultStateFinal,
needDefaultStateTerminal, needDefaultStateReturn);
}
: 'package' id=ID
{ PUSH_CTX_CPM( $pack = new sep::Package(STR($id.text->chars)) ); }
( StringLiteral
{ $pack->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
LCURLY
section_header[ pack ] ?
section_import[ pack ] ?
( section_property[ pack ] )*
( section_composite_structure[ pack ] )*
RCURLY
;
////////////////////////////////////////////////////////////////////////////////
// SYSTEM SPECIFCATION
////////////////////////////////////////////////////////////////////////////////
def_system
returns [ sep::System * sys ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr( sep::Specifier::COMPONENT_SYSTEM_KIND );
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
sep::ParserUtil::declareDefaultEndingStateIfNeed(needDefaultStateFinal,
needDefaultStateTerminal, needDefaultStateReturn);
SET_RULE_LOCATION(sys);
}
: ( ms=executable_modifier_specifier
{ mdfr = $ms.mdfr; spcfr.ifnot_define( $ms.spcfr ); }
)? 'system'
( LT_ ( 'moc:' )? executable_specifier[ spcfr ] GT )?
id=ID
{
PUSH_CTX_CPM( _SYSTEM_ = $sys = new sep::System(STR($id.text->chars)) );
$sys->getwModifier().override_ifdef( mdfr );
$sys->getwSpecifier().ifnot_define( spcfr );
}
( StringLiteral
{ $sys->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
LCURLY
// section_header_import_parameter_property[ sys ]
section_header[ sys ] ?
section_import[ sys ] ?
( section_parameter[ sys ] )*
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty(sys); }
( section_property[ sys ] )*
( section_composite_structure[ sys ] )*
( section_behavior[ sys ]
| section_statemachine[ sys ]
)?
// Conditional Template Code Generation for @moe
{ sep::TemplateFactory::genBehavior(sys); }
( section_model_of_computation[ sys ]
| section_model_of_interaction[ sys ]
| section_model_of_execution[ sys ]
)*
RCURLY
;
////////////////////////////////////////////////////////////////////////////////
// NEW [ [ FULLY ] QUALIFIED ] NAME ID
////////////////////////////////////////////////////////////////////////////////
qualifiedNameID
returns [ std::string s , sep::avm_size_t nb = 1 ]
@init{
cpLOCATOR.clear();
cpQNID.clear();
}
: id=ID { $s = STR($id.text->chars); }
( ( DOT { cpQNID.push_back($s); $s = $s + "." ; ++$nb; }
// | COLON { $s = $s + ":" ; }
| COLONx2 { cpLOCATOR = $s; cpQNID.clear(); $s = $s + "::"; }
)
id=ID { cpQNID.push_back(STR_ID($id)); $s = $s + STR_ID($id); }
)*
;
integer_constant
returns [ sep::avm_size_t val ]
: n=IntegerLiteral
{ $val = NUM_INT($n.text->chars); }
| cid=qualifiedNameID
{ $val = sep::ParserUtil::getIntegerConstant($cid.s, $cid.nb); }
;
float_constant
returns [ sep::avm_float_t val ]
: f=FloatLiteral
{ $val = NUM_FLOAT($f.text->chars); }
| cid=qualifiedNameID
{ $val = sep::ParserUtil::getFloatConstant($cid.s, $cid.nb); }
;
////////////////////////////////////////////////////////////////////////////////
// section HEADER
////////////////////////////////////////////////////////////////////////////////
section_header [ sep::Machine * container ]
: '@header:'
;
////////////////////////////////////////////////////////////////////////////////
// section IMPORT
////////////////////////////////////////////////////////////////////////////////
section_import [ sep::Machine * container ]
: '@import:' ( include_package )+
;
include_package
: '@include'
( StringLiteral SEMI
| LCURLY ( StringLiteral )+ RCURLY
)
;
////////////////////////////////////////////////////////////////////////////////
// EXECUTABLE SPECIFCATION
////////////////////////////////////////////////////////////////////////////////
/*
executable_specification
/* in * [ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * machine ]
@init{
sep::avm_size_t initialCount = 1;
sep::avm_size_t maximalCount = AVM_NUMERIC_MAX_SIZE_T;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
SET_RULE_LOCATION(machine);
}
: 'executable'
( LT_
( ( 'moc:' )? executable_specifier[ spcfr ]
( COMMA def_instance_count[ initialCount , maximalCount ] )?
| def_instance_count[ initialCount , maximalCount ]
)?
GT )?
id=ID
{
PUSH_CTX_CPM( $machine = sep::Machine::newExecutable(
container, STR($id.text->chars), spcfr) );
$machine->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $machine );
$machine->getUniqInstanceSpecifier()
->setInstanceCount(initialCount, maximalCount);
}
( StringLiteral
{ $machine->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
def_machine_parameters[ machine , sep::Modifier::PROPERTY_PARAMETER_MODIFIER ] ?
def_machine_returns[ machine , sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER ] ?
def_body_machine[ machine ]
;
////////////////////////////////////////////////////////////////////////////////
// FLATTENED SPECIFICATION
////////////////////////////////////////////////////////////////////////////////
executable_component [ ]
returns
:
;
*/
////////////////////////////////////////////////////////////////////////////////
// section PROCEDURE
////////////////////////////////////////////////////////////////////////////////
section_procedure [ sep::Machine * container ]
: '@procedure:'
( p=def_procedure[ container ] )*
;
def_procedure [ sep::Machine * container ]
returns [ sep::Machine * procedure ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr( sep::Specifier::EXECUTABLE_PROCEDURE_MODEL_SPECIFIER );
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
sep::ParserUtil::checkProcedureCompositeMocKind(procedure);
SET_RULE_LOCATION(procedure);
}
: ( ms=procedure_modifier_specifier
{ mdfr.override_ifdef( $ms.mdfr ); spcfr.override_ifdef( $ms.spcfr ); }
)?
'procedure'
( LT_ ( 'moc:' )? executable_specifier[ spcfr ] GT )?
id=ID
{
PUSH_CTX_CPM( $procedure = sep::Machine::newProcedure(
container, STR($id.text->chars), spcfr) );
$procedure->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $procedure );
}
( StringLiteral
{ $procedure->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
def_machine_parameters[ procedure ] ?
def_machine_returns[ procedure ,
sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER ] ?
def_body_procedure[ procedure ]
;
def_machine_parameters [ sep::Machine * machine ]
@init{
sep::avm_offset_t offset = 0;
sep::Modifier mdfr = sep::Modifier::PROPERTY_PARAMETER_MODIFIER;
sep::PropertyPart & declProperty = machine->getPropertyPart();
}
: LBRACKET def_machine_variable_parameter_atom[ declProperty , mdfr , offset ]
( COMMA def_machine_variable_parameter_atom[ declProperty , mdfr , ++offset ] )*
RBRACKET
| LPAREN def_machine_variable_parameter_atom[ declProperty , mdfr , offset ]
( COMMA def_machine_variable_parameter_atom[ declProperty , mdfr , ++offset ] )*
RPAREN
;
def_machine_variable_parameter_atom
/* in */[ sep::PropertyPart & paramDecl ,
sep::Modifier mdfr , sep::avm_offset_t offset ]
@init{
sep::Variable * variable;
sep::Machine * machine = paramDecl.getContainer()->as< sep::Machine >();
sep::BF paramT = sep::TypeManager::UNIVERSAL;
std::string paramID;
sep::BF value;
}
: ( m=modifier_param { mdfr.override_ifdef( $m.mdfr ); } )?
tv=type_var { paramT = $tv.type; }
( id=ID { paramID = STR($id.text->chars); }
( iv=initial_value { value = $iv.bf; } )?
)?
{
paramDecl.saveOwnedVariable( variable = new sep::Variable(
machine, mdfr, paramT, paramID, value ) );
}
| 'bind:'
( ( type_var COLON ) => tv=type_var COLON { paramT = $tv.type; }
e=expression { value = $e.bf; }
| vid=qualifiedNameID
{
value = sep::ParserUtil::getVariable($vid.s, $vid.nb);
if( value.valid() ) { paramT = value.to_ptr< sep::Variable >()->getType(); }
}
)
{
paramID = sep::OSS() << '#' << offset;
paramDecl.saveOwnedVariable( variable = new sep::Variable(machine,
mdfr.addNatureKind( sep::Modifier::NATURE_BIND_KIND ),
paramT, paramID, value ) );
variable->setOffset( offset );
}
;
def_machine_returns
/* in */[ sep::Machine * machine , sep::Modifier mdfr ]
@init{
sep::avm_offset_t offset = 0;
mdfr.setDirectionKind( sep::Modifier::DIRECTION_RETURN_KIND );
sep::BF value;
sep::PropertyPart & declProperty = machine->getPropertyPart();
}
: ( '-->' | 'returns:' )
( ( LBRACKET def_machine_variable_return_atom[ declProperty , mdfr , offset]
( COMMA def_machine_variable_return_atom[ declProperty , mdfr , ++offset ] )*
RBRACKET
)
| ( LPAREN def_machine_variable_return_atom[ declProperty , mdfr , offset]
( COMMA def_machine_variable_return_atom[ declProperty , mdfr , ++offset ] )*
RPAREN
)
| tv=type_var ( iv=initial_value { value = $iv.bf; } )?
{
sep::Variable * variable =
new sep::Variable(machine, mdfr, $tv.type, "#0", value);
declProperty.saveOwnedVariable( variable );
}
)
;
def_machine_variable_return_atom
/* in */[ sep::PropertyPart & paramDecl ,
sep::Modifier mdfr , sep::avm_offset_t offset ]
@init{
sep::Variable * variable;
sep::Machine * machine = paramDecl.getContainer()->as< sep::Machine >();
sep::BF paramT = sep::TypeManager::UNIVERSAL;
std::string paramID;
sep::BF value;
}
: ( m=modifier_param { mdfr.override_ifdef( $m.mdfr ); } )?
tv=type_var { paramT = $tv.type; }
( id=ID { paramID = STR($id.text->chars); }
( iv=initial_value { value = $iv.bf; } )?
)?
{
paramDecl.saveOwnedVariable( variable =
new sep::Variable(machine, mdfr, paramT, paramID, value) );
}
| 'bind:'
( ( type_var COLON ) => tv=type_var COLON { paramT = $tv.type; }
e=expression { value = $e.bf; }
| vid=qualifiedNameID
{
value = sep::ParserUtil::getVariable($vid.s, $vid.nb);
if( value.valid() ) { paramT = value.to_ptr< sep::Variable >()->getType(); }
}
)
{
paramID = sep::OSS() << '#' << offset;
variable = new sep::Variable(machine,
mdfr.addNatureKind( sep::Modifier::NATURE_BIND_KIND ),
paramT, paramID, value);
paramDecl.saveOwnedVariable( variable );
variable->setOffset( offset );
}
;
def_body_procedure [ sep::Machine * procedure ]
: LCURLY
( ( def_body_machine_using_section_predicat ) =>
def_body_procedure_section[ procedure ]
| def_body_procedure_simplif[ procedure ]
)
RCURLY
;
def_body_procedure_section [ sep::Machine * procedure ]
: section_header[ procedure ] ?
section_import[ procedure ] ?
( section_parameter[ procedure ] )*
( section_property [ procedure ] )*
( section_composite_structure[ procedure ] )*
( section_behavior[ procedure ]
| section_statemachine[ procedure ]
)?
( section_model_of_computation[ procedure ]
| section_model_of_execution[ procedure ]
| section_model_of_interaction[ procedure ]
)*
;
def_body_procedure_simplif [ sep::Machine * procedure ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr;
}
: ( { mdfr = sep::Modifier::PROPERTY_UNDEFINED_MODIFIER; }
( m=modifier_declaration { mdfr = $m.mdfr; } )?
( decl_variable[ procedure->getPropertyPart() , mdfr ]
| ads=any_def_statemachine[ procedure , mdfr , spcfr ]
| def_state_activity[ procedure ]
)
)+
;
////////////////////////////////////////////////////////////////////////////////
// section COMPOSITE STRUCTURE
////////////////////////////////////////////////////////////////////////////////
section_composite_structure [ sep::Machine * container ]
: section_routine[ container ]
| section_procedure[ container ]
| section_composite_generic[ container ]
| section_machine_model[ container ]
| section_machine_prototype[ container ]
| section_machine_instance[ container ]
;
section_composite_generic [ sep::Machine * container ]
: ( '@composite:' | '@executable:' | '@machine:' )
( m=executable_machine[ container ] )*
;
section_machine_model [ sep::Machine * container ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr( sep::Specifier::DESIGN_MODEL_SPECIFIER );
}
: '@model:'
( m=executable_model_definiton[ container , mdfr , spcfr ] )*
;
section_machine_prototype [ sep::Machine * container ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr( sep::Specifier::DESIGN_PROTOTYPE_STATIC_SPECIFIER );
}
: '@prototype:'
( m=executable_model_definiton[ container , mdfr , spcfr ] )*
;
section_machine_instance [ sep::Machine * container ]
: '@instance:'
( edi=executable_instance_definiton[ container ] )*
;
executable_machine [ sep::Machine * container ]
returns [ sep::Machine * machine ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr;
}
: ( ms=executable_modifier_specifier
{ mdfr = $ms.mdfr; spcfr = $ms.spcfr; }
)?
( dm=def_machine[ container , mdfr , spcfr ]
{ $machine = $dm.machine; }
| ads=any_def_statemachine[ container , mdfr , spcfr ]
{ $machine = $ads.machine; }
| emi=decl_instance[ container , mdfr , spcfr ]
{ $machine = $emi.instance; }
)
;
executable_model_definiton
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * machine ]
: ( ms=executable_modifier_specifier
{ mdfr.override_ifdef( $ms.mdfr ); spcfr.override_ifdef( $ms.spcfr ); }
)?
( dm=def_machine [ container , mdfr , spcfr ]
{ $machine = $dm.machine; }
| ads=def_statemachine[ container , mdfr , spcfr ]
{ $machine = $ads.machine; }
)
;
executable_instance_definiton [ sep::Machine * container ]
returns [ sep::Machine * instance ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr( sep::Specifier::DESIGN_INSTANCE_STATIC_SPECIFIER );
}
: ( ms=instance_modifier_specifier
{ mdfr = $ms.mdfr; spcfr = $ms.spcfr; }
)?
emi=decl_instance[ container , mdfr , spcfr ]
{ $instance = $emi.instance; }
;
////////////////////////////////////////////////////////////////////////////////
// INSTANCE MACHINE
////////////////////////////////////////////////////////////////////////////////
decl_instance
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * instance ]
@init{
sep::BF aModel;
sep::avm_size_t initialCount = 1;
sep::avm_size_t maximalCount = AVM_NUMERIC_MAX_SIZE_T;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
if( aModel.is< sep::Machine >() )
{
POP_CTX;
}
SET_RULE_LOCATION(instance);
}
: 'instance' ( 'machine' | 'statemachine' )?
LT_
( 'model:' )? mm=instance_machine_model { aModel = $mm.model; }
( COMMA def_instance_count[ initialCount , maximalCount ] )?
GT id=ID
{
if( aModel.is< sep::Machine >() )
{
PUSH_CTX_NEW( aModel.to_ptr< sep::Machine >() );
}
$instance = sep::Machine::newInstance(container,
STR($id.text->chars), aModel, initialCount, maximalCount);
$instance->getwModifier().override_ifdef( mdfr );
$instance->getwSpecifier().override_ifdef(
spcfr.isDesignInstanceDynamic() ?
spcfr : spcfr.setDesignInstanceStatic() );
container->saveOwnedElement( $instance );
}
( StringLiteral
{ $instance->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
/*
decl_instance_machine_params [ machine ] ?
decl_instance_machine_returns[ machine ] ?
( def_body_machine[ machine ] | SEMI )
*/
( LPAREN
( def_instance_on_new_activity[ $instance ] ) ?
RPAREN
)?
( SEMI
| LCURLY
( s=statement { instance->getUniqBehaviorPart()->seqOnCreate($s.ac); } )*
( def_instance_activity[ $instance ] )*
RCURLY
)
;
def_instance_on_new_activity [ sep::Machine * instance ]
@init{
sep::avm_size_t position = 0;
}
: def_instance_on_new_activity_parameter[ $instance , position++ ]
( COMMA def_instance_on_new_activity_parameter[ $instance , position++ ] )*
;
def_instance_on_new_activity_parameter
/* in */[ sep::Machine * instance , sep::avm_size_t position ]
: ( lvalue op_assign_param ) =>
lv=lvalue oap=op_assign_param e=expression
{ instance->getUniqBehaviorPart()->seqOnCreate( NEW_STMT2($oap.op, $lv.bf, $e.bf) ); }
| e=expression
{
sep::ParserUtil::appendInstanceDynamicPositionalParameter(
instance, $e.bf, position);
}
;
op_assign_param
returns [ sep::Operator * op ]
: ( ASSIGN | COLON ) { $op = OP(ASSIGN); }
| ASSIGN_REF { $op = OP(ASSIGN_REF); }
| ASSIGN_MACRO { $op = OP(ASSIGN_MACRO); }
;
def_instance_activity [ sep::Machine * instance ]
@init{
sep::BehavioralPart * theBehavior = instance->getUniqBehaviorPart();
}
: '@create' bs=block_statement { theBehavior->seqOnCreate($bs.ac); }
| '@start' bs=block_statement { theBehavior->seqOnStart($bs.ac); }
/*
| '@init' bs=block_statement { theBehavior->seqOnInit($bs.ac); }
| '@ienable' bs=block_statement { theBehavior->seqOnIEnable($bs.ac); }
| '@enable' bs=block_statement { theBehavior->seqOnEnable ($bs.ac); }
| '@idisable' bs=block_statement { theBehavior->seqOnIDisable($bs.ac); }
| '@disable' bs=block_statement { theBehavior->seqOnDisable ($bs.ac); }
| '@iabort' bs=block_statement { theBehavior->seqOnIAbort($bs.ac); }
| '@abort' bs=block_statement { theBehavior->seqOnAbort($bs.ac); }
| '@irun' bs=block_statement { theBehavior->seqOnIRun($bs.ac); }
| '@run' bs=block_statement { theBehavior->seqOnRun($bs.ac); }
| '@rtc' bs=block_statement { theBehavior->seqOnRtc($bs.ac); }
| '@final' bs=block_statement { theBehavior->seqOnFinal($bs.ac); }
*/ ;
////////////////////////////////////////////////////////////////////////////////
// section BEHAVIOR | STATEMACHINE
////////////////////////////////////////////////////////////////////////////////
section_behavior [ sep::Machine * container ]
: '@behavior:'
( m=executable_machine[ container ] )+
;
////////////////////////////////////////////////////////////////////////////////
// definition MACHINE
////////////////////////////////////////////////////////////////////////////////
def_instance_count
/* in */[ sep::avm_size_t & initial , sep::avm_size_t & maximal ]
@after{
if( $maximal < $initial )
{
$maximal = $initial;
}
}
: ( 'multiplicity:' | 'instance:' )?
( LBRACKET
( n=integer_constant { $initial = $n.val; }
COMMA
( n=integer_constant { $maximal = $n.val; }
| ( STAR | PLUS ) { $maximal = AVM_NUMERIC_MAX_SIZE_T; }
)
| STAR { $initial = 0; $maximal = AVM_NUMERIC_MAX_SIZE_T; }
| PLUS { $initial = 1; $maximal = AVM_NUMERIC_MAX_SIZE_T; }
)
RBRACKET
| LPAREN
def_instance_count_atom[ $initial , $maximal ]
( COMMA ? def_instance_count_atom[ $initial , $maximal ] )*
RPAREN
)
;
def_instance_count_atom
/* in */[ sep::avm_size_t & initial , sep::avm_size_t & maximal ]
: 'init:' n=integer_constant { $initial = $n.val; }
| 'max:' n=integer_constant { $maximal = $n.val; }
;
def_machine
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * machine ]
@init{
sep::avm_size_t initialCount = 1;
sep::avm_size_t maximalCount = AVM_NUMERIC_MAX_SIZE_T;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
SET_RULE_LOCATION(machine);
}
: 'machine'
( LT_
( ( 'moc:' )? executable_specifier[ spcfr ]
( COMMA def_instance_count[ initialCount , maximalCount ] )?
| def_instance_count[ initialCount , maximalCount ]
)?
GT )?
id=ID
{
PUSH_CTX_CPM( $machine = sep::Machine::newExecutable(
container, STR($id.text->chars), spcfr) );
$machine->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $machine );
$machine->getUniqInstanceSpecifier()->
setInstanceCount(initialCount, maximalCount);
}
( StringLiteral
{ $machine->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
def_machine_parameters[ machine ] ?
def_machine_returns[ machine , sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER ] ?
def_body_machine[ machine ]
;
def_body_machine_using_section_header_predicat
: '@header:'
;
def_body_machine_using_section_import_predicat
: '@import:'
;
def_body_machine_using_section_parameter_predicat
: '@parameter:' | '@param:' /* deprecated */
| '@input:' | '@inout:' | '@output:'
| '@returns:' | '@return:' /* deprecated */
;
def_body_machine_using_section_property_predicat
: '@property:' | '@public:' | '@protected:' | '@private:'
| '@declaration:' /* deprecated */
;
def_body_machine_using_section_predicat
: def_body_machine_using_section_header_predicat
| def_body_machine_using_section_import_predicat
| def_body_machine_using_section_parameter_predicat
| def_body_machine_using_section_property_predicat
| '@macro:' | '@routine' | '@procedure:'
| '@composite' | '@machine:'
| '@region:' | '@statemachine:'
| '@behavior:' | '@transition:'
// Model Of { Computation , Execution , Interaction }
| '@moc:' | '@moe:' | '@com:' | '@interaction:'
;
def_body_machine [ sep::Machine * machine ]
: LCURLY
//( def_body_machine_using_section_predicat ) =>
def_body_machine_section[ machine ]
//| def_body_machine_simplif[ machine ]
RCURLY
;
def_body_machine_section [ sep::Machine * machine ]
: section_header[ machine ] ?
section_import[ machine ] ?
( section_parameter[ machine ] )*
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty( machine ); }
( section_property [ machine ] )*
( section_composite_structure[ machine ] )*
( section_behavior[ machine ]
| section_statemachine[ machine ]
)?
// Conditional Template Code Generation for @moe
{ sep::TemplateFactory::genBehavior(machine); }
( section_model_of_computation[ machine ]
| section_model_of_execution[ machine ]
| section_model_of_interaction[ machine ]
)*
;
def_body_machine_simplif [ sep::Machine * machine ]
@init{
sep::PropertyPart & declProperty = machine->getPropertyPart();
}
: ( ( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_UNDEFINED_MODIFIER ]
)*
| ( def_moe_primitive[ machine ] )+
)
;
////////////////////////////////////////////////////////////////////////////////
// definition STATEMACHINE
////////////////////////////////////////////////////////////////////////////////
any_def_statemachine
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * machine ]
: ( ms=executable_modifier_specifier
{ mdfr.override_ifdef( $ms.mdfr ); spcfr.override_ifdef( $ms.spcfr ); }
)?
( st=def_state_singleton[ container , mdfr , spcfr ]
{ $machine = $st.state; }
| st=def_state[ container , mdfr , spcfr ]
{ $machine = $st.state; }
| sm=def_statemachine[ container , mdfr , spcfr ]
{ $machine = $sm.machine; }
)
;
def_statemachine
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * machine ]
@init{
// resetTransitionID();
resetConnectID();
resetBufferID();
sep::avm_size_t initialCount = 1;
sep::avm_size_t maximalCount = AVM_NUMERIC_MAX_SIZE_T;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
SET_RULE_LOCATION(machine);
}
: 'statemachine'
( LT_
( ( 'moc:' )? executable_specifier[ spcfr ]
( COMMA def_instance_count[ initialCount , maximalCount ] )?
| def_instance_count[ initialCount , maximalCount ]
)?
GT
)?
( id=ID
{
if( spcfr.isUndefined() )
{
spcfr.setComponentExecutable();
}
PUSH_CTX_CPM( $machine = sep::Machine::newStatemachine(
container, STR($id.text->chars), spcfr) );
$machine->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $machine );
$machine->getUniqInstanceSpecifier()->
setInstanceCount(initialCount, maximalCount);
}
| ( LBRACKET { spcfr.setGroupSome(); }
| LBRACKET_EXCEPT { spcfr.setGroupExcept(); }
)
{
PUSH_CTX_CPM( $machine = sep::Machine::newStatemachine(
container, "[]", spcfr/*, type*/) );
$machine->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $machine );
$machine->getUniqInstanceSpecifier()->
setInstanceCount(initialCount, maximalCount);
}
( id=ID { $machine->appendGroupId( STR($id.text->chars) ); }
( COMMA id=ID { $machine->appendGroupId( STR($id.text->chars) ); } )*
| STAR
{ $machine->getwSpecifier().setGroupEvery(); }
)
RBRACKET { $machine->setGroupId(); }
)
( StringLiteral
{ $machine->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
def_machine_parameters[ machine ] ?
def_machine_returns[ machine , sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER ] ?
def_body_statemachine[ machine ]
;
//!![MIGRATION]:INSTANCE
/*
decl_instance_statemachine [ sep::Machine * container ]
returns [ sep::Machine * machine ]
@init{
// resetTransitionID();
resetConnectID();
resetBufferID();
sep::Specifier spcfr;
sep::BF aModel;
sep::avm_size_t initialCount = 1;
sep::avm_size_t maximalCount = AVM_NUMERIC_MAX_SIZE_T;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
SET_RULE_LOCATION(machine);
}
: 'statemachine'
LT_
( ( 'moc:' )? executable_specifier[ spcfr ] COMMA )?
( 'model:' )? mm=instance_machine_model { aModel = $mm.model; }
( COMMA def_instance_count[ initialCount , maximalCount ] )?
GT id=ID
{
if( spcfr.isUndefined() )
{
spcfr.setComponentStatemachine();
}
PUSH_CTX_CPM( $machine = sep::Machine::newStatemachineInstance(
container, STR($id.text->chars), spcfr, aModel) );
$machine->getwSpecifier().setDesignInstanceStatic();
container->saveOwnedElement( $machine );
$machine->getUniqInstanceSpecifier()->
setInstanceCount(initialCount, maximalCount);
}
( StringLiteral
{ $machine->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
decl_instance_machine_params [ machine ] ?
decl_instance_machine_returns[ machine ] ?
( def_body_statemachine[ machine ] | SEMI )
;
*/
def_body_statemachine [ sep::Machine * machine ]
: LCURLY
section_header[ machine ] ?
section_import[ machine ] ?
( section_parameter[ machine ] )*
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty( machine ); }
( section_property [ machine ] )*
( section_composite_structure[ machine ] )*
section_region[ machine ] ?
section_transition[ machine ] ?
// Conditional Template Code Generation for @moe
{ sep::TemplateFactory::genBehavior(machine); }
( section_model_of_computation[ machine ]
| section_model_of_execution[ machine ]
| section_model_of_interaction[ machine ]
)*
RCURLY
;
section_region [ sep::Machine * container ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr;
}
: '@region:'
{ container->getwSpecifier().setMocStateTransitionSystem(); }
( m=any_def_statemachine[ container , mdfr , spcfr ] )+
;
section_statemachine [ sep::Machine * container ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr;
}
: '@statemachine:'
{ container->getwSpecifier().setMocStateTransitionSystem(); }
( m=any_def_statemachine[ container , mdfr , spcfr ] )+
;
def_state
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * state = NULL ]
@init{
std::string sid;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
POP_CTX;
SET_RULE_LOCATION(state);
}
: 'state'
( LT_ ( 'moc:' )? executable_specifier[ spcfr ] GT
{ sid = "$" + spcfr.strAnyStateMoc(""); }
)?
( id=state_id
{
if( spcfr.couldBeStateMocSIMPLE() )
{
spcfr.setStateMocSIMPLE();
}
PUSH_CTX_CPM(
$state = sep::Machine::newState(container, $id.s, spcfr) );
$state->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $state );
}
| ( LBRACKET { spcfr.setGroupSome(); }
| LBRACKET_EXCEPT { spcfr.setGroupExcept(); }
)
{
PUSH_CTX_CPM(
$state = sep::Machine::newState(container, "[]", spcfr) );
container->saveOwnedElement( $state );
$state->getwModifier().override_ifdef( mdfr );
}
( id=state_id { $state->appendGroupId( $id.s ); }
( COMMA id=state_id { $state->appendGroupId( $id.s ); } )*
| STAR
{ $state->getwSpecifier().setGroupEvery(); }
)
RBRACKET { $state->setGroupId(); }
)?
{
if( $state == NULL )
{
PUSH_CTX_CPM(
$state = sep::Machine::newState(container, sid, spcfr) );
$state->getwModifier().override_ifdef( mdfr );
container->saveOwnedElement( $state );
}
}
( StringLiteral
{ $state->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
( def_body_state[ state ] | SEMI )
;
state_kw_id
returns [ std::string s ]
: '#init' { $s = "#init" ; }
| '#initial' { $s = "#initial" ; }
| '#start' { $s = "#start" ; }
| '#dhistory' { $s = "#dhistory"; }
| '#shistory' { $s = "#shistory"; }
| '#final'
{ $s = "#final" ; needDefaultStateFinal.remove(_CPM_); }
| '#terminal'
{ $s = "#terminal"; needDefaultStateTerminal.remove(_CPM_); }
| '#return'
{ $s = "#return" ; needDefaultStateReturn.remove(_CPM_); }
;
state_id
returns [ std::string s ]
: kw=state_kw_id { $s = $kw.s; }
| id=ID { $s = STR($id.text->chars); }
| DOLLAR id=ID { $s = "$" + STR($id.text->chars); }
;
def_state_singleton
/* in */[ sep::Machine * container ,
sep::Modifier mdfr , sep::Specifier spcfr ]
returns [ sep::Machine * state ]
@init{
SAVE_RULE_BEGIN_LOCATION;
}
@after{
state->getwModifier().override_ifdef( mdfr );
POP_CTX;
SET_RULE_LOCATION(state);
}
: ( '#initial'
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#initial", spcfr.setPseudostateMocINITIAL()) );
container->saveOwnedElement( $state );
}
| '#start'
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#start", spcfr.setStateMocSTART()) );
container->saveOwnedElement( $state );
}
| '#dhistory'
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#dhistory",
spcfr.setPseudostateMocDEEP_HISTORY()) );
container->saveOwnedElement( $state );
}
| '#shistory'
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#shistory",
spcfr.setPseudostateMocSHALLOW_HISTORY()) );
container->saveOwnedElement( $state );
}
)
LCURLY def_body_state_simplif[ state ] RCURLY
| '#final' bs=block_statement
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#final", spcfr.setStateMocFINAL()) );
container->saveOwnedElement( $state );
$state->getUniqBehaviorPart()->seqOnFinal($bs.ac);
needDefaultStateFinal.remove(container);
}
| '#terminal' bs=block_statement
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#terminal", spcfr.setPseudostateMocTERMINAL()) );
container->saveOwnedElement( $state );
$state->getUniqBehaviorPart()->seqOnFinal($bs.ac);
needDefaultStateTerminal.remove(container);
}
| '#return' bs=block_statement
{
PUSH_CTX_CPM( $state = sep::Machine::newState(
container, "#return", spcfr.setPseudostateMocRETURN()) );
container->saveOwnedElement( $state );
$state->getUniqBehaviorPart()->seqOnFinal($bs.ac);
needDefaultStateReturn.remove(container);
}
;
executable_specifier [ sep::Specifier & spcfr ]
: ka=executable_specifier_atom[ spcfr ]
( BAND ka=executable_specifier_atom[ spcfr ] )*
;
executable_specifier_atom [ sep::Specifier & spcfr ]
: id=ID { spcfr.setMoc( STR($id.text->chars) ); }
// | 'simple' { spcfr.setStateMocSIMPLE(); }
| 'start' { spcfr.setStateMocSTART(); }
| 'final' { spcfr.setStateMocFINAL(); }
// | 'sync' { spcfr.setStateMocSYNC(); }
// | 'initial' { spcfr.setPseudostateMocINITIAL(); }
// | 'terminal' { spcfr.setPseudostateMocTERMINAL(); }
| 'return' { spcfr.setPseudostateMocRETURN(); }
// | 'junction' { spcfr.setPseudostateMocJUNCTION(); }
| 'choice' { spcfr.setPseudostateMocCHOICE(); }
| 'fork' { spcfr.setPseudostateMocFORK(); }
| 'join' { spcfr.setPseudostateMocJOIN(); }
// | 'dhistory' { spcfr.setPseudostateMocDEEP_HISTORY(); }
// | 'shistory' { spcfr.setPseudostateMocSHALLOW_HISTORY(); }
| 'and' { spcfr.setMocCompositeStructure(); }
| 'or' { spcfr.setMocStateTransitionSystem(); }
| '#sts' { spcfr.setMocStateTransitionSystem(); }
| '#stf' { spcfr.setMocStateTransitionFlow(); }
| 'flow' { spcfr.setCompositeMocDataFlow(); }
;
instance_machine_model
returns [ sep::BF model ]
: tid=qualifiedNameID
{
$model = sep::ParserUtil::getExecutableMachine($tid.s, $tid.nb);
if( $model.invalid() )
{
sep::ParserUtil::avm_syntax_error(
"instance_machine_model", LT(0)->getLine(LT(0)) )
<< "unexpected ID< " << $tid.s << " >"
<< sep::ParserUtil::SYNTAX_ERROR_EOL;
}
}
;
def_body_state [ sep::Machine * state ]
: LCURLY
( ( def_body_machine_using_section_predicat ) =>
def_body_state_section[ state ]
| def_body_state_simplif[ state ]
)
RCURLY
;
def_body_state_section [ sep::Machine * machine ]
: ( section_property[ machine ] )*
( section_composite_structure[ machine ] )*
section_region[ machine ] ?
section_transition[ machine ] ?
( section_model_of_computation[ machine ]
| section_model_of_execution[ machine ]
| section_model_of_interaction[ machine ]
)*
;
def_body_state_simplif [ sep::Machine * state ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr;
}
: ( { mdfr = sep::Modifier::PROPERTY_UNDEFINED_MODIFIER; }
( m=modifier_declaration { mdfr = $m.mdfr; } )?
( decl_variable[ state->getPropertyPart() , mdfr ]
| ads=any_def_statemachine[ state , mdfr , spcfr ]
| def_transition[ state , mdfr , spcfr ]
| def_state_activity[ state ]
)
)*
;
section_transition [ sep::Machine * state ]
@init{
sep::Modifier mdfr;
sep::Specifier spcfr;
}
: '@transition:'
( ( m=modifier_transition { mdfr = $m.mdfr; } )?
def_transition[ state , mdfr , spcfr ]
)*
;
def_transition
/* in */[ sep::Machine * state ,
sep::Modifier mdfr , sep::Specifier spcfr ]
@init{
sep::Transition * trans = NULL;
std::string t_id;
mProcedureCallCount = 0;
SAVE_RULE_BEGIN_LOCATION;
}
@after{
if( (mProcedureCallCount > 0) && (trans != NULL) )
{
sep::ParserUtil::inlineTransitionProcedureCall(trans, trans->getNameID());
}
SET_RULE_LOCATION(trans);
}
: ( tok='@'
| ( tok=AT_ID { t_id = STR($tok.text->chars); } )
)
{
state->getUniqBehaviorPart()->saveOutgoingTransition(
trans = new sep::Transition(state, newTransitionID(t_id)) );
trans->setModifier( mdfr );
trans->setSpecifier( spcfr );
}
( LT_ moc_transition[ trans ] GT )?
moe_transition[ trans ]
| 'transition'
{
state->getUniqBehaviorPart()->saveOutgoingTransition(
trans = new sep::Transition(state) );
trans->setModifier( mdfr );
trans->setSpecifier( spcfr );
}
( LT_ moc_transition[ trans ] GT )?
( id=ID { t_id = STR($id.text->chars); } )?
{ trans->fullyUpdateAllNameID( newTransitionID(t_id) ); }
( StringLiteral
{ trans->setUnrestrictedName(STR($StringLiteral.text->chars)); }
)?
moe_transition[ trans ]
;
kind_transition
returns [ sep::Transition::MOC_KIND kind ]
: id=ID
{
if( ($kind = sep::Transition::toMocKind(STR($id.text->chars))) ==
sep::Transition::MOC_UNDEFINED_KIND )
{
sep::ParserUtil::avm_syntax_error( "kind_transition", $id.line )
<< "unexpected ID< " << STR($id.text->chars) << " >"
<< sep::ParserUtil::SYNTAX_ERROR_EOL;
}
}
// | 'simple' { $kind = sep::Transition::MOC_SIMPLE_KIND; }
| 'abort' { $kind = sep::Transition::MOC_ABORT_KIND; }
| 'final' { $kind = sep::Transition::MOC_FINAL_KIND; }
| 'else' { $kind = sep::Transition::MOC_ELSE_KIND; }
// | 'internal' { $kind = sep::Transition::MOC_INTERNAL_KIND; }
// | 'auto' { $kind = sep::Transition::MOC_AUTO_KIND; }
| 'flow' { $kind = sep::Transition::MOC_FLOW_KIND; }
;
moc_transition_attribute
returns [ sep::Transition::moc_kind_t kind ]
@init{
$kind = sep::Transition::MOC_UNDEFINED_KIND;
}
: kt=kind_transition { $kind = $kt.kind; }
( BAND 'else' { $kind = $kind | sep::Transition::MOC_ELSE_KIND; } )?
;
moc_transition [ sep::Transition * trans ]
: moc_transition_atom[ trans ] ( COMMA moc_transition_atom[ trans ] )*
;
moc_transition_atom [ sep::Transition * trans ]
: ( 'moc:' )? kt=moc_transition_attribute
{ trans->setMocKind( $kt.kind ); }
| ( 'prior:' )? n=integer_constant
{ trans->setPriority( $n.val ); }
| ( 'proba:' )? p=float_constant
{ trans->setProbability( $p.val ); }
;
moe_transition [ sep::Transition * trans ]
: bs=transition_statement { trans->setStatement($bs.ac); }
( ( '-->' )?
tid=target_state_id { trans->setTarget($tid.target); }
// ( COMMA tid=target_state_id { trans->appendTarget($tid.target); } )*
SEMI )?
| '-->' tid=target_state_id { trans->setTarget($tid.target); }
// ( COMMA tid=target_state_id { trans->appendTarget($tid.target); } )*
( bs=transition_statement { trans->setStatement($bs.ac); }
| SEMI
)
;
transition_statement
returns [ sep::BFCode ac ]
@init{
sep::Operator * op = OP(SEQUENCE);
bool implicitSequenceOp = true;
}
@after{
if( implicitSequenceOp && $ac.valid() && $ac->singleton() &&
sep::OperatorManager::isSchedule(op) )
{
sep::BFCode singleCode = $ac->first().bfCode();
$ac = singleCode;
}
}
: LCURLY ( o=op_block { op = $o.op; implicitSequenceOp = false; } )?
{ $ac = NEW_STMT(op); }
( s=statement { $ac->append($s.ac); } )*
( transition_trigger[ ac ] )?
( transition_guard[ ac ] )?
( transition_timed_guard[ ac ] )?
( transition_effect[ ac ] )?
RCURLY
;
transition_trigger [ sep::BFCode & ac ]
: '@trigger:' ( s=statement_com_input { $ac->append( $s.ac ); } )*
;
transition_guard [ sep::BFCode & ac ]
: '@guard:'
( s=statement_guard
{ $ac->append( $s.ac ); }
| e=expression
{ $ac->append( NEW_STMT1(OP(GUARD), $e.bf) ); }
| LBRACKET e=expression RBRACKET
{ $ac->append( NEW_STMT1(OP(GUARD), $e.bf) ); }
)*
;
transition_timed_guard [ sep::BFCode & ac ]
: '@tguard:'
( s=statement_timed_guard
{ $ac->append( $s.ac ); }
| e=expression
{ $ac->append( NEW_STMT1(OP(TIMED_GUARD), $e.bf) ); }
| LCURLY e=expression RCURLY
{ $ac->append( NEW_STMT1(OP(TIMED_GUARD), $e.bf) ); }
)*
;
transition_effect [ sep::BFCode & ac ]
: '@effect:' ( s=statement { $ac->append( $s.ac ); } )*
;
target_state_id
returns [ sep::BF target ]
@init{
std::string tid;
sep::avm_size_t nb = 1;
}
@after{
if( (target = sep::ParserUtil::getvarMachine(tid, nb)).invalid() )
{
target = NEW_QNID(tid, nb);
}
}
: kw=target_state_kw_id { tid = $kw.s; }
| u=qualifiedNameID { tid = $u.s; nb = $u.nb; }
| DOLLAR id=ID { tid ="$" + STR($id.text->chars); }
;
target_state_kw_id
returns [ std::string s ]
: '#init' { $s = "#init" ; }
| '#initial' { $s = "#initial" ; }
| '#start' { $s = "#start" ; }
| '#dhistory' { $s = "#dhistory"; }
| '#shistory' { $s = "#shistory"; }
| '#final'
{ $s = "#final";
needDefaultStateFinal.push_back(_CPM_->getContainerMachine()); }
| '#terminal'
{ $s = "#terminal";
needDefaultStateTerminal.push_back(_CPM_->getContainerMachine()); }
| '#return'
{ $s = "#return";
needDefaultStateReturn.push_back(_CPM_->getContainerMachine()); }
;
def_state_activity [ sep::Machine * state ]
@init{
sep::BehavioralPart * theBehavior = state->getUniqBehaviorPart();
}
: '@create' bs=block_statement { theBehavior->seqOnCreate($bs.ac); }
| '@init' bs=block_statement { theBehavior->seqOnInit($bs.ac); }
| '@ienable' bs=block_statement { theBehavior->seqOnIEnable($bs.ac); }
| '@enable' bs=block_statement { theBehavior->seqOnEnable ($bs.ac); }
| '@idisable' bs=block_statement { theBehavior->seqOnIDisable($bs.ac); }
| '@disable' bs=block_statement { theBehavior->seqOnDisable ($bs.ac); }
| '@iabort' bs=block_statement { theBehavior->seqOnIAbort($bs.ac); }
| '@abort' bs=block_statement { theBehavior->seqOnAbort($bs.ac); }
| '@irun' bs=block_statement { theBehavior->seqOnIRun($bs.ac); }
| '@run' bs=block_statement { theBehavior->seqOnRun($bs.ac); }
| '@rtc' bs=block_statement { theBehavior->seqOnRtc($bs.ac); }
| '@final' bs=block_statement { theBehavior->seqOnFinal($bs.ac); }
;
////////////////////////////////////////////////////////////////////////////////
// SECTION HEADER IMPORT PARAMETER PROPERTY or DEFAULT DECLARATION
////////////////////////////////////////////////////////////////////////////////
section_header_import_parameter_property
/* in */[ sep::Machine * container ]
: ( def_body_machine_using_section_header_predicat ) =>
section_header[ container ]
( section_import[ container ] )?
( section_parameter[ container ] )?
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty( container ); }
( section_property[ container ] )*
| ( def_body_machine_using_section_import_predicat ) =>
section_import[ container ]
( section_parameter[ container ] )?
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty( container ); }
( section_property[ container ] )*
| ( def_body_machine_using_section_parameter_predicat ) =>
section_parameter[ container ]
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty( container ); }
( section_property[ container ] )*
| ( def_body_machine_using_section_property_predicat ) =>
// Conditional Template Code Generation for @declaration
{ sep::TemplateFactory::genProperty( container ); }
( section_property[ container ] )+
| { sep::TemplateFactory::genProperty( container ); }
section_property_free_declaration[ container ]
;
////////////////////////////////////////////////////////////////////////////////
// section PARAMETER DECLARATION
////////////////////////////////////////////////////////////////////////////////
section_parameter [ sep::Machine * container ]
@init{
sep::PropertyPart & declProperty = container->getPropertyPart();
SAVE_RULE_BEGIN_LOCATION;
}
@after{
SET_RULE_LOCATION(declProperty);
}
: ( '@parameter:' | '@param:' /* deprecated */ )
( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_INPUT_PARAMETER_MODIFIER ]
)*
| '@input:' ( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_INPUT_PARAMETER_MODIFIER ]
)*
| '@inout:' ( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_INOUT_PARAMETER_MODIFIER ]
)*
| '@output:' ( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_OUTPUT_PARAMETER_MODIFIER ]
)*
| ( '@returns:' | '@return:' /* deprecated */ )
( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER ]
)*
;
////////////////////////////////////////////////////////////////////////////////
// section PROPERTY DECLARATION
////////////////////////////////////////////////////////////////////////////////
section_property [ sep::Machine * container ]
@init{
sep::PropertyPart & declProperty = container->getPropertyPart();
SAVE_RULE_BEGIN_LOCATION;
}
@after{
SET_RULE_LOCATION(declProperty);
}
: ( '@property:' | '@declaration:' /* deprecated */ )
( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_UNDEFINED_MODIFIER ]
)*
| '@public:'
( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_PUBLIC_MODIFIER ]
)*
| '@protected:'
( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_PROTECTED_MODIFIER ]
)*
| '@private:'
( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_PRIVATE_MODIFIER ]
)*
;
section_property_free_declaration [ sep::Machine * container ]
@init{
sep::PropertyPart & declProperty = container->getPropertyPart();
SAVE_RULE_BEGIN_LOCATION;
}
@after{
SET_RULE_LOCATION(declProperty);
}
: ( property_declaration[ declProperty ,
sep::Modifier::PROPERTY_UNDEFINED_MODIFIER ]
)*
;
////////////////////////////////////////////////////////////////////////////////
// PROPERTY ELEMENT DECLARATION
////////////////////////////////////////////////////////////////////////////////
property_declaration
/* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ]
: ( m=modifier_declaration { mdfr.override_ifdef( $m.mdfr ); } )?
decl_property_element[ declProperty , mdfr ]
;
decl_property_element
/* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ]
: decl_variable[ declProperty , mdfr ]
| decl_port [ declProperty , mdfr ]
| decl_signal [ declProperty , mdfr ]
| decl_buffer [ declProperty , mdfr ]
| decl_channel[ declProperty , mdfr ]
| def_type [ declProperty , mdfr ]
| def_enum [ declProperty , mdfr ]
| def_union [ declProperty , mdfr ]
| def_choice[ declProperty , mdfr ]
| def_struct[ declProperty , mdfr ]
/*
| decl_func[ declProperty , mdfr ]
| decl_proc[ declProperty , mdfr ]
| decl_lambda[ declProperty , mdfr ]
*/
;
////////////////////////////////////////////////////////////////////////////////
// declaration MACHINE PRAMETERS
////////////////////////////////////////////////////////////////////////////////
labelled_argument
returns [ std::string label, sep::BF arg ]
: ( ID COLON ) => id=ID COLON { $label = STR($id.text->chars); }
e=expression { $arg = $e.bf; }
| e=expression { $arg = $e.bf; }
;
decl_instance_machine_params [ sep::Machine * machine ]
@init{
sep::BFVector labelledParams(
( machine->getType().is< sep::Machine >() ) ? machine->getType().
to_ptr< sep::Machine >()->getVariableParametersCount() : 0 );
sep::BFList positionalParams;
}
@after{
if( labelledParams.nonempty() )
{
sep::ParserUtil::computeInstanceMachineParameter(
machine, labelledParams, positionalParams);
}
}
: LPAREN
( lp=labelled_argument
{
sep::ParserUtil::appendInstanceMachineParameter(machine, $lp.label,
labelledParams, positionalParams, $lp.arg);
}
( COMMA
lp=labelled_argument
{
sep::ParserUtil::appendInstanceMachineParameter(machine, $lp.label,
labelledParams, positionalParams, $lp.arg);
}
)*
)?
RPAREN
;
decl_instance_machine_returns [ sep::Machine * machine ]
@init{
sep::BFVector labelledReturns(
( machine->getType().is< sep::Machine >() ) ? machine->getType().
to_ptr< sep::Machine >()->getVariableParametersCount() : 0 );
sep::BFList positionalReturns;
}
@after{
if( labelledReturns.nonempty() )
{
sep::ParserUtil::computeInstanceMachineReturn(
machine, labelledReturns, positionalReturns);
}
}
: ( '-->' | 'returns:' )
( LPAREN
lp=labelled_argument
{
sep::ParserUtil::appendInstanceMachineReturn(machine, $lp.label,
labelledReturns, positionalReturns, $lp.arg);
}
( COMMA
lp=labelled_argument
{
sep::ParserUtil::appendInstanceMachineReturn(machine, $lp.label,
labelledReturns, positionalReturns, $lp.arg);
}
)*
RPAREN
| lp=labelled_argument
{
sep::ParserUtil::appendInstanceMachineReturn(machine, $lp.label,
labelledReturns, positionalReturns, $lp.arg);
}
)
;
activity_machine_param_return
/* in */[ const sep::BF & argMachine , sep::BFCode & ac ]
@init{
sep::Machine * machine = argMachine.is< sep::Machine >() ?
argMachine.to_ptr< sep::Machine >() : NULL;
sep::Routine * routine = NULL;
sep::avm_size_t paramCount = 0;
sep::avm_size_t returnCount = 0;
if( machine == NULL )
{
routine = NULL;
}
else if( machine->getSpecifier().isDesignInstanceStatic()
&& machine->getType().is< sep::Machine >() )
{
routine = &( machine->getType().to_ptr< sep::Machine >()->
getBehavior()->getActivity( ac->getAvmOpCode() ) );
}
else if( ac->isnotOpCode( sep::AVM_OPCODE_INVOKE_NEW ) )
// if( machine->isDesignPrototypeStatic() )
{
routine = &( machine->getBehavior()->
getActivity( ac->getAvmOpCode() ) );
}
if( routine != NULL )
{
paramCount = routine->getParameters().size();
returnCount = routine->getReturns().size();
}
sep::BFVector labelledParams( paramCount );
sep::BFList positionalParams;
sep::BFVector labelledReturns( returnCount );
sep::BFList positionalReturns;
if( machine != NULL )
{
PUSH_CTX_CPM( machine );
}
}
@after{
if( BACKTRACKING==0 )
{
sep::ParserUtil::computeActivityRoutineParamReturn(argMachine, routine, $ac,
labelledParams , positionalParams, labelledReturns, positionalReturns);
}
if( machine != NULL )
{
POP_CTX;
}
}
: LPAREN // Parameters
( lp=labelled_argument
{
sep::ParserUtil::appendRoutineParameters(routine, $lp.label,
labelledParams, positionalParams, $lp.arg);