| |
| 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); |
| } |
| ( COMMA |
| lp=labelled_argument |
| { |
| sep::ParserUtil::appendRoutineParameters(routine, $lp.label, |
| labelledParams, positionalParams, $lp.arg); |
| } |
| )* |
| )? |
| RPAREN |
| |
| ( ( '-->' | 'returns:' ) |
| ( LPAREN |
| lp=labelled_argument |
| { |
| sep::ParserUtil::appendRoutineReturns(routine, $lp.label, |
| labelledReturns, positionalReturns, $lp.arg); |
| } |
| ( COMMA |
| lp=labelled_argument |
| { |
| sep::ParserUtil::appendRoutineReturns(routine, $lp.label, |
| labelledReturns, positionalReturns, $lp.arg); |
| } |
| )* |
| RPAREN |
| |
| | lp=labelled_argument |
| { |
| sep::ParserUtil::appendRoutineReturns(routine, $lp.label, |
| labelledReturns, positionalReturns, $lp.arg); |
| } |
| ) |
| )? |
| |
| // | 'ctx:' LCURLY ( sa=statement_assign { $ac->append($sa.ac); } )+ RCURLY |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration COMMUNCATION POINT : PORT |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| decl_port |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::IComPoint::ENUM_IO_NATURE nature = sep::IComPoint::IO_UNDEFINED_NATURE; |
| } |
| : 'port' { nature = sep::IComPoint::IO_PORT_NATURE; } |
| |
| decl_port_impl[ declProperty , mdfr, nature ] |
| ; |
| |
| decl_port_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr , |
| sep::IComPoint::ENUM_IO_NATURE nature ] |
| @init{ |
| sep::Port * port; |
| sep::BF TPort; |
| bool isaType = true; |
| } |
| : ( ID ) => id=ID |
| { |
| declProperty.appendPort( sep::BF( |
| port = new sep::Port(declProperty, |
| STR($id.text->chars), nature, |
| mdfr.setDirectionInoutElse() ) ) ); |
| } |
| ( type_param_com[ port ] )? SEMI |
| |
| | modifier_set_direction_strict_text[ mdfr ] |
| ( id=ID |
| { |
| declProperty.appendPort( sep::BF( |
| port = new sep::Port(declProperty, |
| STR($id.text->chars), nature, mdfr ) ) ); |
| } |
| ( type_param_com[ port ] )? SEMI |
| |
| | LCURLY |
| ( id=ID |
| { |
| declProperty.appendPort( sep::BF( |
| port = new sep::Port(declProperty, |
| STR($id.text->chars), nature, mdfr) ) ); |
| } |
| ( type_param_com[ port ] )? SEMI |
| )+ |
| RCURLY |
| ) |
| | LCURLY |
| ( ( ID ) => id=ID |
| { |
| declProperty.appendPort( sep::BF( |
| port = new sep::Port(declProperty, |
| STR($id.text->chars), nature, |
| mdfr.setDirectionInoutElse() ) ) ); |
| port->setModifier( mdfr ); |
| } |
| ( type_param_com[ port ] )? SEMI |
| |
| | modifier_set_direction_strict_text[ mdfr ] id=ID |
| { |
| declProperty.appendPort( sep::BF( |
| port = new sep::Port(declProperty, |
| STR($id.text->chars), nature, mdfr) ) ); |
| } |
| ( type_param_com[ port ] )? SEMI |
| )+ |
| RCURLY |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration COMMUNCATION POINT : MESSAGE | SIGNAL |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| decl_signal |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::IComPoint::ENUM_IO_NATURE nature = sep::IComPoint::IO_UNDEFINED_NATURE; |
| } |
| : ( 'signal' { nature = sep::IComPoint::IO_SIGNAL_NATURE; } |
| | 'message' { nature = sep::IComPoint::IO_MESSAGE_NATURE; } |
| ) |
| decl_signal_impl[ declProperty , mdfr, nature ] |
| ; |
| |
| decl_signal_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr , |
| sep::IComPoint::ENUM_IO_NATURE nature ] |
| @init{ |
| sep::Port * signal; |
| sep::BF TPort; |
| bool isaType = true; |
| } |
| : ( ID ) => id=ID |
| { |
| declProperty.appendSignal( sep::BF( |
| signal = new sep::Signal(declProperty, |
| STR($id.text->chars), nature, |
| mdfr.setDirectionInoutElse() ) ) ); |
| } |
| ( type_param_com[ signal ] )? SEMI |
| |
| | modifier_set_direction_strict_text[ mdfr ] |
| ( id=ID |
| { |
| declProperty.appendSignal( sep::BF( |
| signal = new sep::Signal(declProperty, |
| STR($id.text->chars), nature, mdfr ) ) ); |
| } |
| ( type_param_com[ signal ] )? SEMI |
| |
| | LCURLY |
| ( id=ID |
| { |
| declProperty.appendSignal( sep::BF( |
| signal = new sep::Signal(declProperty, |
| STR($id.text->chars), nature, mdfr) ) ); |
| } |
| ( type_param_com[ signal ] )? SEMI |
| )+ |
| RCURLY |
| ) |
| | LCURLY |
| ( ( ID ) => id=ID |
| { |
| declProperty.appendSignal( sep::BF( |
| signal = new sep::Signal(declProperty, |
| STR($id.text->chars), nature, |
| mdfr.setDirectionInoutElse() ) ) ); |
| signal->setModifier( mdfr ); |
| } |
| ( type_param_com[ signal ] )? SEMI |
| |
| | modifier_set_direction_strict_text[ mdfr ] id=ID |
| { |
| declProperty.appendSignal( sep::BF( |
| signal = new sep::Signal(declProperty, |
| STR($id.text->chars), nature, mdfr) ) ); |
| } |
| ( type_param_com[ signal ] )? SEMI |
| )+ |
| RCURLY |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration COMMUNCATION PARAMETER |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| type_param_com [ sep::Port * port ] |
| @init{ |
| sep::avm_offset_t offset = 0; |
| } |
| : LPAREN |
| param_com_atom[ port , offset] |
| ( COMMA param_com_atom[ port , ++offset ] )* |
| RPAREN |
| ; |
| |
| param_com_atom |
| /* in */[ sep::Port * port , sep::avm_offset_t offset ] |
| @init{ |
| sep::Variable * variable; |
| sep::BF paramT = sep::TypeManager::UNIVERSAL; |
| std::string paramID; |
| sep::BF value; |
| } |
| : tv=type_var { paramT = $tv.type; } |
| ( id=ID { paramID = STR($id.text->chars); } |
| ( iv=initial_value { value = $iv.bf; } )? |
| )? |
| { |
| port->saveParameter( variable = new sep::Variable(port, |
| sep::Modifier::PROPERTY_PARAMETER_MODIFIER, |
| 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; |
| port->saveParameter( variable = new sep::Variable(port, |
| sep::Modifier::PROPERTY_PARAMETER_BIND_MODIFIER, |
| paramT, paramID, value) ); |
| variable->setOffset( offset ); |
| } |
| ; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration BUFFER |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| decl_buffer |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'buffer' decl_buffer_impl[ declProperty , mdfr ] |
| ; |
| |
| decl_buffer_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::Buffer * buffer; |
| |
| sep::BF TBuffer; |
| bool isaType = true; |
| } |
| : db=def_buffer id=ID |
| { |
| declProperty.appendBuffer( sep::BF( |
| buffer = new sep::Buffer( declProperty, |
| STR($id.text->chars), $db.kind, $db.size)) ); |
| buffer->setModifier( mdfr ); |
| } |
| ( initial_buffer_contents[ buffer ] )? SEMI |
| |
| | LCURLY |
| ( |
| db=def_buffer id=ID |
| { |
| declProperty.appendBuffer( sep::BF( |
| buffer = new sep::Buffer(declProperty, |
| STR($id.text->chars), $db.kind, $db.size)) ); |
| buffer->setModifier( mdfr ); |
| } |
| )+ |
| RCURLY |
| ; |
| |
| |
| def_buffer |
| returns [ sep::avm_type_specifier_kind_t kind , int size = -1 ] |
| : pb=policy_buffer { $kind = $pb.kind; } |
| ( LT_ |
| ( n=integer_constant { $size = $n.val; } |
| | STAR { $size = -1; } |
| ) |
| GT )? |
| |
| | 'ram' { $kind = sep::TYPE_RAM_SPECIFIER; $size = 1; } |
| ; |
| |
| |
| policy_buffer |
| returns [ sep::avm_type_specifier_kind_t kind ] |
| : 'fifo' { $kind = sep::TYPE_FIFO_SPECIFIER; } |
| | 'lifo' { $kind = sep::TYPE_LIFO_SPECIFIER; } |
| | 'multififo' { $kind = sep::TYPE_MULTI_FIFO_SPECIFIER; } |
| | 'multilifo' { $kind = sep::TYPE_MULTI_LIFO_SPECIFIER; } |
| | 'set' { $kind = sep::TYPE_SET_SPECIFIER; } |
| | 'multiset' { $kind = sep::TYPE_MULTISET_SPECIFIER; } |
| | 'vector' { $kind = sep::TYPE_VECTOR_SPECIFIER; } |
| | 'rvector' { $kind = sep::TYPE_REVERSE_VECTOR_SPECIFIER; } |
| ; |
| |
| ref_buffer[ sep::Machine * machine ] |
| returns [ sep::BF buf ] |
| : id=qualifiedNameID |
| { $buf = sep::ParserUtil::getBuffer(machine, $id.s, $id.nb); } |
| ; |
| |
| |
| initial_buffer_contents[ const sep::Buffer * buffer ] |
| @init{ |
| sep::BF msg; |
| } |
| : ASSIGN LBRACKET |
| mid=qualifiedNameID |
| {/* msg = sep::ParserUtil::getMessage($mid.s, $mid.nb); |
| buffer->appendMessage(msg); */} |
| ( COMMA mid=qualifiedNameID |
| )* |
| RBRACKET |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration CHANNEL |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| decl_channel |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'channel' decl_channel_port[ declProperty , mdfr ] |
| /* ( ID LCURLY => decl_channel_port[ declProperty , mdfr ] |
| | decl_channel_var[ declProperty , mdfr ] |
| ) |
| */ ; |
| |
| |
| decl_channel_port |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::Channel * aChannel; |
| |
| declProperty.appendChannel( sep::BF( aChannel = |
| new sep::Channel( declProperty, |
| "#channel#", mdfr.setDirectionInoutElse() ) )); |
| |
| } |
| : ( LT_ |
| com_protocol[ declProperty.getContainer()->as< sep::Machine >(), aChannel ] |
| ( COMMA com_cast[ aChannel ] )? |
| GT |
| )? |
| |
| ( modifier_set_direction_strict_text[ aChannel->getwModifier() ] ) ? |
| id=ID { aChannel->fullyUpdateAllNameID( STR($id.text->chars) ); } |
| |
| LCURLY |
| ( |
| m=modifier_direction uid=qualifiedNameID SEMI |
| { |
| sep::BF comSignal = sep::ParserUtil::getComSignal($uid.s, $uid.nb); |
| if( comSignal.valid() ) |
| { |
| aChannel->appendSignal($m.mdfr, comSignal); |
| } |
| } |
| |
| | decl_port[ *(aChannel->getContents()) , |
| sep::Modifier::PROPERTY_PUBLIC_MODIFIER ] |
| |
| | decl_signal[ *(aChannel->getContents()) , |
| sep::Modifier::PROPERTY_PUBLIC_MODIFIER ] |
| )+ |
| RCURLY |
| ; |
| |
| |
| decl_channel_var |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::Variable * var; |
| } |
| : tv=type_var id=ID |
| { |
| declProperty.saveOwnedVariable( var = new sep::Variable( |
| declProperty, mdfr, $tv.type, STR($id.text->chars)) ); |
| } |
| ( iv=initial_value { var->setValue($iv.bf); } )? |
| ( SEMI | on_write_var_routine_def[ var ] ) |
| |
| | LCURLY ( |
| tv=type_var id=ID |
| { |
| declProperty.saveOwnedVariable( var = new sep::Variable( |
| declProperty, mdfr, $tv.type, STR($id.text->chars)) ); |
| } |
| ( iv=initial_value { var->setValue($iv.bf); } )? |
| ( SEMI | on_write_var_routine_def[ var ] ) |
| )+ RCURLY |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration VAR |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| decl_variable |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : ( 'var' { mdfr.setNatureVariable(); } |
| | 'val' { mdfr.setFeatureConst(); } |
| | ( 'const' { mdfr.setFeatureConst(); } |
| | 'macro' { mdfr.setNatureMacro(); } |
| )+ |
| ( 'var' )? |
| ) |
| decl_variable_impl[ declProperty , mdfr ] |
| |
| | decl_variable_time_clock_impl[ declProperty , mdfr ] |
| ; |
| |
| |
| decl_variable_time_clock_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| mdfr.override_ifdef( sep::Modifier::PROPERTY_PUBLIC_VOLATILE_MODIFIER ); |
| } |
| : ctv=time_clock_type |
| decl_typed_variable_atom_impl[ declProperty , mdfr , $ctv.bts ] |
| ; |
| |
| |
| decl_variable_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : decl_variable_atom_impl[ declProperty , mdfr ] |
| |
| | LCURLY |
| ( decl_variable_atom_impl[ declProperty , mdfr ] )+ |
| RCURLY |
| ; |
| |
| decl_variable_atom_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : tv=type_var |
| decl_typed_variable_atom_impl[ declProperty , mdfr , $tv.type ] |
| ; |
| |
| decl_typed_variable_atom_impl |
| /* in */[ sep::PropertyPart & declProperty , |
| sep::Modifier mdfr , const sep::BF & type ] |
| @init{ |
| sep::Variable * var; |
| } |
| : id=ID |
| { |
| declProperty.saveOwnedVariable( var = new sep::Variable( |
| declProperty, mdfr, type, STR($id.text->chars)) ); |
| } |
| |
| ( StringLiteral |
| { var->setUnrestrictedName(STR($StringLiteral.text->chars)); } |
| )? |
| |
| ( iv=initial_value { var->setValue($iv.bf); } )? |
| ( SEMI | on_write_var_routine_def[ var ] ) |
| ; |
| |
| |
| initial_value |
| returns [ sep::BF bf ] |
| : ASSIGN e=expression { $bf = $e.bf; } |
| | LPAREN e=expression RPAREN { $bf = $e.bf; } |
| ; |
| |
| |
| type_var |
| returns [ sep::BF type ] |
| : btv=base_type_var { $type = $btv.type; } |
| ( dta=def_type_array[ type , "" ] { $type = $dta.type; } )? |
| |
| | dtc=def_type_container[ "" ] { $type = $dtc.type; } |
| |
| | dti=def_type_interval [ "" ] { $type = $dti.type; } |
| ; |
| |
| |
| def_type_array |
| /* in */[ sep::BF baseT , const std::string & tid ] |
| returns [ sep::BF type ] |
| @init{ |
| sep::ListOfInt listOfSize; |
| } |
| : ( dta=def_type_array_size { listOfSize.push_back($dta.size); } )+ |
| { |
| int szT = listOfSize.front(); |
| listOfSize.pop_front(); |
| |
| while( listOfSize.nonempty() ) |
| { |
| baseT = sep::BF( sep::DataType::newContainer(_CPM_, |
| sep::DataType::strContainerId(sep::TYPE_ARRAY_SPECIFIER, |
| baseT, listOfSize.back()), |
| sep::TYPE_ARRAY_SPECIFIER, baseT, listOfSize.back()) ); |
| listOfSize.pop_back(); |
| } |
| type = sep::BF( sep::DataType::newContainer(_CPM_, |
| sep::DataType::strContainerId( |
| tid, sep::TYPE_ARRAY_SPECIFIER, baseT, szT), |
| sep::TYPE_ARRAY_SPECIFIER, baseT, szT) ); |
| } |
| ; |
| |
| def_type_array_size |
| returns [ int size ] |
| : LBRACKET |
| ( sz=IntegerLiteral { size = NUM_INT($sz.text->chars); } |
| // ( sz=integer_constant { size = $sz.val; } |
| |
| | id=qualifiedNameID |
| { |
| const sep::BF & constVar = |
| sep::ParserUtil::getConstant($id.s, $id.nb); |
| if( constVar.valid() && |
| constVar.to_ptr< sep::Variable >()->hasValue() && |
| constVar.to_ptr< sep::Variable >()->getValue().isInteger() ) |
| { |
| size = constVar.to_ptr< sep::Variable >()->getValue().toInteger(); |
| } |
| else |
| { |
| sep::BF aType = sep::ParserUtil::getDataType($id.s, $id.nb); |
| |
| if( aType.valid() && aType.is< sep::DataType >() ) |
| { |
| if( aType.to_ptr< sep::DataType >()->isTypedInterval() ) |
| { |
| size = aType.to_ptr< sep::DataType >()->getIntervalLength(); |
| |
| if( size < 0 ) |
| { |
| sep::ParserUtil::avm_syntax_error( |
| "def_type_array_size(...)" ) |
| << "unexpected << interval: " << $id.s |
| << " >> as size (i.e. " << size |
| << ") in an array typedef" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| |
| size = 0; |
| } |
| } |
| else if( aType.to_ptr< sep::DataType >()->isTypedEnum() ) |
| { |
| size = aType.to_ptr< sep::DataType >()->getEnumSize(); |
| |
| if( size == 0 ) |
| { |
| sep::ParserUtil::avm_syntax_error( |
| "def_type_array_size(...)" ) |
| << "unexpected << enum: " << $id.s |
| << " >> as size in an array typedef" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| else |
| { |
| size = 0; |
| |
| sep::ParserUtil::avm_syntax_error( |
| "def_type_array_size(...)" ) |
| << "unexpected << [Qualified]NameID: " << $id.s |
| << " >> as size in an array typedef" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| else |
| { |
| size = 0; |
| |
| sep::ParserUtil::avm_syntax_error( |
| "def_type_array_size(...)" ) |
| << "unexpected << [Qualified]NameID: " << $id.s |
| << " >> as size in an array typedef" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| } |
| ) |
| RBRACKET |
| ; |
| |
| |
| def_type_container [ const std::string & tid ] |
| returns [ sep::BF type ] |
| @init{ |
| sep::BF baseT = sep::TypeManager::UNIVERSAL; |
| int szT = -1; |
| } |
| : sb=specifier_buffer |
| ( LT_ |
| ( ( btv=base_type_var { baseT = $btv.type; } |
| ( COMMA ( 'size:' )? |
| ( sz=integer_constant { szT = $sz.val; } |
| | STAR { szT = -1; } |
| ) |
| )? |
| ) |
| | ( 'size:' )? sz=integer_constant { szT = $sz.val; } |
| ) |
| GT |
| )? |
| { |
| $type = sep::BF( sep::DataType::newContainer(_CPM_, |
| sep::DataType::strContainerId(tid, $sb.kind, baseT, szT), |
| $sb.kind, baseT, szT) ); |
| } |
| ; |
| |
| |
| specifier_buffer |
| returns [ sep::avm_type_specifier_kind_t kind ] |
| : 'array' { $kind = sep::TYPE_ARRAY_SPECIFIER; } |
| | 'vector' { $kind = sep::TYPE_VECTOR_SPECIFIER; } |
| | 'rvector' { $kind = sep::TYPE_REVERSE_VECTOR_SPECIFIER; } |
| | 'list' { $kind = sep::TYPE_LIST_SPECIFIER; } |
| | 'fifo' { $kind = sep::TYPE_FIFO_SPECIFIER; } |
| | 'lifo' { $kind = sep::TYPE_LIFO_SPECIFIER; } |
| | 'multififo' { $kind = sep::TYPE_MULTI_FIFO_SPECIFIER; } |
| | 'multilifo' { $kind = sep::TYPE_MULTI_LIFO_SPECIFIER; } |
| | 'set' { $kind = sep::TYPE_SET_SPECIFIER; } |
| | 'multiset' { $kind = sep::TYPE_MULTISET_SPECIFIER; } |
| ; |
| |
| |
| def_type_interval [ const std::string & tid ] |
| returns [ sep::BF type ] |
| @init{ |
| sep::BF baseT = sep::TypeManager::INTEGER; |
| } |
| : 'interval' { $type = sep::TypeManager::INTEGER; } |
| LT_ |
| ( pt=primitive_type { baseT = $pt.bts; } )? |
| (ll=LBRACKET | ll=RBRACKET | ll=LPAREN) |
| min=expression COMMA max=expression |
| (rr=LBRACKET | rr=RBRACKET | rr=RPAREN) |
| GT |
| { |
| $type = sep::BF( sep::DataType::newInterval(_CPM_, tid, baseT, |
| sep::IIntervalKind::computeKind(CHAR($ll), CHAR($rr)), |
| $min.bf, $max.bf) ); |
| } |
| ; |
| |
| |
| base_type_var |
| returns [ sep::BF type ] |
| : pt=primitive_type |
| { $type = $pt.bts; } |
| | id=qualifiedNameID |
| { $type = sep::ParserUtil::getDataType($id.s, $id.nb); } |
| ; |
| |
| |
| primitive_type |
| returns [ sep::TypeSpecifier bts ] |
| @init{ |
| sep::avm_size_t arity = 1; |
| } |
| : ( 'boolean' | 'bool' ) { $bts = sep::TypeManager::BOOLEAN; } |
| |
| | ( 'integer' | 'int' ) { $bts = sep::TypeManager::INTEGER; } |
| ( bfs=bit_field_size |
| { $bts = sep::TypeManager::getTypeInteger( $bfs.size ); } |
| )? |
| |
| | ( 'uinteger' | 'uint' ) { $bts = sep::TypeManager::UINTEGER; } |
| ( bfs=bit_field_size |
| { $bts = sep::TypeManager::getTypeUInteger( $bfs.size ); } |
| )? |
| |
| | ( 'pos_integer' | 'pos_int' ) { $bts = sep::TypeManager::POS_INTEGER; } |
| ( bfs=bit_field_size |
| { $bts = sep::TypeManager::getTypePosInteger( $bfs.size ); } |
| )? |
| |
| |
| | ( ( 'rational' | 'rat' ) { $bts = sep::TypeManager::RATIONAL; } |
| | ( 'urational' | 'urat' ) { $bts = sep::TypeManager::URATIONAL; } |
| |
| | 'float' { $bts = sep::TypeManager::FLOAT; } |
| | 'ufloat' { $bts = sep::TypeManager::UFLOAT; } |
| |
| | 'double' { $bts = sep::TypeManager::DOUBLE; } |
| | 'udouble' { $bts = sep::TypeManager::UDOUBLE; } |
| |
| | 'real' { $bts = sep::TypeManager::REAL; } |
| | 'ureal' { $bts = sep::TypeManager::UREAL; } |
| ) |
| ( bfs=bit_field_size |
| { |
| $bts = sep::TypeManager::newNumericTypeSpecifier( |
| $bts, $bfs.size, sep::ExpressionConstant::INTEGER_ZERO); |
| } |
| )? |
| |
| |
| | ct=time_clock_type { $bts = $ct.bts; } |
| |
| | tt=time_type { $bts = $tt.bts; } |
| |
| | 'char' { $bts = sep::TypeManager::CHAR; } |
| ( bfs=bit_field_size |
| { $bts = sep::TypeManager::newCharacter( "char", $bfs.size ); } |
| )? |
| |
| | 'character' { $bts = sep::TypeManager::CHARACTER; } |
| ( bfs=bit_field_size |
| { $bts = sep::TypeManager::newCharacter( "character", $bfs.size ); } |
| )? |
| |
| | 'string' { $bts = sep::TypeManager::STRING; } |
| ( sfs=string_field_size |
| { $bts = sep::TypeManager::newString( $sfs.min , $sfs.max ); } |
| )? |
| |
| |
| | 'operator' { $bts = sep::TypeManager::OPERATOR; } |
| | 'avmcode' { $bts = sep::TypeManager::AVMCODE; } |
| |
| | 'port' { $bts = sep::TypeManager::PORT; } |
| | 'buffer' { $bts = sep::TypeManager::BUFFER; } |
| | 'message' { $bts = sep::TypeManager::MESSAGE; } |
| | 'signal' { $bts = sep::TypeManager::SIGNAL; } |
| | 'connector' { $bts = sep::TypeManager::CONNECTOR; } |
| |
| | 'machine' { $bts = sep::TypeManager::MACHINE; } |
| ( LT_ id=qualifiedNameID GT |
| { |
| sep::BF machineT = |
| sep::ParserUtil::getExecutableMachine($id.s, $id.nb); |
| } |
| )? |
| |
| | 'universal' { $bts = sep::TypeManager::UNIVERSAL; } |
| ; |
| |
| |
| bit_field_size |
| returns [ int size ] |
| : COLON n=integer_constant { size = $n.val; } |
| | LT_ ( 'size:' )? n=integer_constant GT { size = $n.val; } |
| ; |
| |
| |
| string_field_size |
| returns [ int min=0 , int max=-1 ] |
| : COLON rc=range_constant |
| { $min = $rc.min; $max = $rc.max; } |
| |
| | LT_ ( 'size:' )? rc=range_constant GT |
| { $min = $rc.min; $max = $rc.max; } |
| ; |
| |
| range_constant |
| returns [ int min=0 , int max=-1 ] |
| : n=integer_constant { $max = $n.val; } |
| ( ( COMMA | DOTDOT ) |
| n=integer_constant { $min = $max; $max = $n.val; } |
| )? |
| ; |
| |
| on_write_var_routine_def [ sep::Variable * var ] |
| : LCURLY ( var_routine_def[ var ] )+ RCURLY |
| ; |
| |
| |
| var_routine_def [ sep::Variable * var ] |
| @init{ |
| sep::Routine * onWriteRoutine = NULL; |
| |
| sep::BehavioralPart * aBehavioralpart = var->getUniqContainerOfRoutines(); |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION( onWriteRoutine ); |
| } |
| : '@on_write' |
| { |
| onWriteRoutine = new sep::Routine(var, "on_write"); |
| var->setOnWriteRoutine(onWriteRoutine); |
| if( aBehavioralpart != NULL ) |
| { |
| aBehavioralpart->saveAnonymousInnerRoutine(onWriteRoutine); |
| } |
| } |
| ( routine_single_param[*onWriteRoutine, var->getType()] )? |
| ( bs=block_statement { onWriteRoutine->setCode($bs.ac); } |
| | '|=>' ce=conditionalExpression SEMI |
| { onWriteRoutine->setCode( NEW_STMT1(OP(GUARD), $ce.bf) ); } |
| ) |
| ; |
| |
| routine_single_param |
| /* in */[ sep::Routine & routine , const sep::BF & dftType ] |
| @init{ |
| sep::BF paramT = dftType; |
| sep::BF value; |
| } |
| : LPAREN |
| ( ( type_var ID ) => tv=type_var { paramT = $tv.type; } id=ID |
| | id=ID |
| ) |
| ( iv=initial_value { value = $iv.bf; } )? |
| { |
| sep::Variable * variable; |
| routine.saveParameter( variable = new sep::Variable( &routine, |
| sep::Modifier::PROPERTY_INPUT_PARAMETER_MODIFIER, |
| paramT, STR($id.text->chars), value) ); |
| } |
| RPAREN |
| ; |
| |
| |
| def_enum |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::Variable * var = NULL; |
| } |
| : 'enum' id=ID |
| def_enum_impl[declProperty, mdfr, STR($id.text->chars)] |
| ; |
| |
| def_enum_impl |
| /* in */[ sep::PropertyPart & declProperty , |
| sep::Modifier mdfr , const std::string & tid ] |
| @init{ |
| sep::Variable * var = NULL; |
| sep::DataType * enumT; |
| |
| sep::BF td( enumT = sep::DataType::newEnum(declProperty, tid) ); |
| enumT->setModifier( mdfr ); |
| declProperty.appendDataType( td ); |
| } |
| : LCURLY |
| id=ID |
| { |
| enumT->saveVariable( var = new sep::Variable( enumT, |
| sep::Modifier::PROPERTY_UNDEFINED_MODIFIER, |
| sep::TypeManager::INTEGER, STR($id.text->chars) ) ); |
| } |
| ( ASSIGN e=expression { var->setValue($e.bf); } )? |
| |
| ( COMMA id=ID |
| { |
| enumT->saveVariable( var = new sep::Variable( enumT, |
| sep::Modifier::PROPERTY_UNDEFINED_MODIFIER, |
| sep::TypeManager::INTEGER, STR($id.text->chars) ) ); |
| } |
| ( ASSIGN e=expression { var->setValue($e.bf); } )? |
| )* |
| /*TODO#ADD |
| ( COMMA )? |
| */ |
| RCURLY |
| ; |
| |
| |
| def_struct |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : ( 'struct' | 'class' ) id=ID |
| def_class_structure_impl[declProperty, mdfr, STR($id.text->chars)] |
| ; |
| |
| def_class_structure_impl |
| /* in */[ sep::PropertyPart & declProperty , |
| sep::Modifier mdfr , const std::string & tid ] |
| @init{ |
| sep::DataType * structT; |
| |
| sep::BF td( structT = sep::DataType::newStructure(declProperty, tid) ); |
| structT->setModifier( mdfr ); |
| declProperty.appendDataType( td ); |
| } |
| : LCURLY |
| ( { mdfr = sep::Modifier::PROPERTY_UNDEFINED_MODIFIER; } |
| |
| ( m=modifier_declaration { mdfr = $m.mdfr; } )? |
| |
| ( decl_variable[ *(structT->getPropertyPart()) , mdfr ] |
| | def_method[ declProperty ] |
| ) |
| )+ |
| RCURLY |
| ; |
| |
| |
| def_choice |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'choice' id=ID |
| def_choice_impl[declProperty, mdfr, STR($id.text->chars)] |
| ; |
| |
| def_choice_impl |
| /* in */[ sep::PropertyPart & declProperty , |
| sep::Modifier mdfr , const std::string & tid ] |
| @init{ |
| sep::DataType * choiceT; |
| |
| sep::BF td( choiceT = sep::DataType::newChoice(declProperty, tid) ); |
| choiceT->setModifier( mdfr ); |
| declProperty.appendDataType( td ); |
| } |
| : LCURLY |
| ( { mdfr = sep::Modifier::PROPERTY_UNDEFINED_MODIFIER; } |
| |
| ( m=modifier_declaration { mdfr = $m.mdfr; } )? |
| |
| ( decl_variable[ *(choiceT->getPropertyPart()) , mdfr ] |
| | def_method[ declProperty ] |
| ) |
| )+ |
| RCURLY |
| ; |
| |
| |
| def_union |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'union' id=ID |
| def_union_impl[declProperty , mdfr, STR($id.text->chars)] |
| ; |
| |
| |
| def_union_impl |
| /* in */[ sep::PropertyPart & declProperty , |
| sep::Modifier mdfr , const std::string & tid ] |
| @init{ |
| sep::DataType * unionT; |
| |
| sep::BF td( unionT = sep::DataType::newUnion(declProperty, tid) ); |
| unionT->setModifier( mdfr ); |
| declProperty.appendDataType( td ); |
| } |
| : LCURLY |
| ( { mdfr = sep::Modifier::PROPERTY_UNDEFINED_MODIFIER; } |
| |
| ( m=modifier_declaration { mdfr = $m.mdfr; } )? |
| |
| decl_variable[ *(unionT->getPropertyPart()) , mdfr ] |
| )+ |
| RCURLY |
| ; |
| |
| |
| def_method[ sep::PropertyPart & declProperty ] |
| : 'fun' ID LPAREN decl_parameters ? RPAREN ( type_var )? |
| ; |
| |
| decl_parameters |
| : type_var ID ( COMMA type_var ID )* |
| ; |
| |
| |
| def_type |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'type' def_type_impl[ declProperty , mdfr ] |
| ; |
| |
| def_type_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : def_type_atom_impl[ declProperty , mdfr ] |
| |
| | LCURLY |
| ( def_type_atom_impl[ declProperty , mdfr ] )+ |
| RCURLY |
| ; |
| |
| |
| def_type_atom_impl |
| /* in */[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| @init{ |
| sep::DataType * aliasT; |
| sep::BF type; |
| bool isTypedArray = false; |
| } |
| : id=ID |
| ( btv=base_type_var { type = $btv.type; } |
| ( dta=def_type_array[ type , STR($id.text->chars) ] |
| { type = $dta.type; isTypedArray = true; } |
| )? |
| { |
| if( isTypedArray ) |
| { |
| aliasT = type.to_ptr< sep::DataType >(); |
| aliasT->setModifier( mdfr ); |
| declProperty.appendDataType( type ); |
| } |
| else |
| { |
| sep::BF td( aliasT = sep::DataType::newAlias( |
| declProperty, STR($id.text->chars), type) ); |
| aliasT->setModifier( mdfr ); |
| declProperty.appendDataType( td ); |
| } |
| } |
| ( def_typedef_constraint[ aliasT ] | SEMI )? |
| |
| | dtc=def_type_container[ STR($id.text->chars) ] |
| { |
| aliasT = $dtc.type.to_ptr< sep::DataType >(); |
| aliasT->setModifier( mdfr ); |
| declProperty.appendDataType( $dtc.type ); |
| } |
| ( def_typedef_constraint[ aliasT ] | SEMI )? |
| |
| | dti=def_type_interval[ STR($id.text->chars) ] SEMI |
| { |
| aliasT = $dti.type.to_ptr< sep::DataType >(); |
| aliasT->setModifier( mdfr ); |
| declProperty.appendDataType( $dti.type ); |
| } |
| |
| | 'enum' |
| def_enum_impl[declProperty, mdfr, STR($id.text->chars)] |
| |
| | 'union' |
| def_union_impl[declProperty, mdfr, STR($id.text->chars)] |
| |
| | 'choice' |
| def_choice_impl[declProperty, mdfr, STR($id.text->chars)] |
| |
| | ( 'struct' | 'class' ) |
| def_class_structure_impl[declProperty, mdfr, STR($id.text->chars)] |
| ) |
| |
| | def_enum [ declProperty , mdfr ] |
| | def_union [ declProperty , mdfr ] |
| | def_choice[ declProperty , mdfr ] |
| | def_struct[ declProperty , mdfr ] |
| ; |
| |
| |
| def_typedef_constraint[ sep::DataType * aliasT ] |
| @init{ |
| sep::Routine * onConstraintRoutine = NULL; |
| |
| sep::BehavioralPart * aBehavioralpart = aliasT->getUniqBehaviorPart(); |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION( onConstraintRoutine ); |
| } |
| : LCURLY |
| '@constraint' |
| { |
| onConstraintRoutine = new sep::Routine(aliasT, "constraint"); |
| aliasT->setConstraintRoutine(onConstraintRoutine); |
| aBehavioralpart->saveAnonymousInnerRoutine(onConstraintRoutine); |
| } |
| ( routine_single_param[*onConstraintRoutine, aliasT->getTypeSpecifier()] )? |
| ( bs=block_statement { onConstraintRoutine->setCode( $bs.ac ); } |
| | '|=>' ce=conditionalExpression SEMI |
| { onConstraintRoutine->setCode( NEW_STMT1(OP(GUARD), $ce.bf) ); } |
| ) |
| RCURLY |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // TYPEDEF TIME |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| time_type |
| returns [ sep::TypeSpecifier bts ] |
| @init{ |
| int szT = 1; |
| sep::avm_type_specifier_kind_t tsk = sep::TYPE_TIME_SPECIFIER; |
| } |
| : ( 'time' { $bts = sep::TypeManager::TIME; } |
| | 'ctime' { $bts = sep::TypeManager::CONTINUOUS_TIME; } |
| | 'dtime' { $bts = sep::TypeManager::DISCRETE_TIME; } |
| ) |
| ( LT_ { tsk = $bts.getTypeSpecifierKind(); } |
| pt=time_type_domain { $bts = $pt.type; } |
| ( COMMA sz=integer_constant { szT = $sz.val; } )? |
| GT |
| { $bts = sep::TypeManager::newClockTime(tsk, $bts, szT); } |
| |
| | pt=time_type_domain |
| { $bts = sep::TypeManager::newClockTime(tsk, $pt.type, szT); } |
| )? |
| ; |
| |
| |
| time_clock_type |
| returns [ sep::TypeSpecifier bts ] |
| @init{ |
| int szT = 1; |
| } |
| : 'clock' { $bts = sep::TypeManager::CLOCK; } |
| ( LT_ |
| ( 'time' { $bts = sep::TypeManager::TIME; } |
| | 'ctime' { $bts = sep::TypeManager::CONTINUOUS_TIME; } |
| | 'dtime' { $bts = sep::TypeManager::DISCRETE_TIME; } |
| | pt=time_type_domain { $bts = $pt.type; } |
| ) |
| ( COMMA sz=integer_constant { szT = $sz.val; } )? |
| GT |
| { $bts = sep::TypeManager::newClockTime(sep::TYPE_CLOCK_SPECIFIER, $bts, szT); } |
| |
| | ( 'time' { $bts = sep::TypeManager::TIME; } |
| | 'ctime' { $bts = sep::TypeManager::CONTINUOUS_TIME; } |
| | 'dtime' { $bts = sep::TypeManager::DISCRETE_TIME; } |
| | pt=time_type_domain { $bts = $pt.type; } |
| ) |
| ( COMMA sz=integer_constant { szT = $sz.val; } )? |
| { $bts = sep::TypeManager::newClockTime(sep::TYPE_CLOCK_SPECIFIER, $bts, szT); } |
| )? |
| ; |
| |
| |
| time_type_domain |
| returns [ sep::TypeSpecifier type ] |
| : ( 'integer' | 'int' ) { $type = sep::TypeManager::INTEGER; } |
| ( LT_ |
| n=integer_constant |
| { $type = sep::TypeManager::getTypeInteger( $n.val ); } |
| GT )? |
| |
| | ( 'uinteger' | 'uint' ) { $type = sep::TypeManager::UINTEGER; } |
| ( LT_ |
| n=integer_constant |
| { $type = sep::TypeManager::getTypeUInteger( $n.val); } |
| GT )? |
| |
| | ( 'rational' | 'rat' ) { $type = sep::TypeManager::RATIONAL; } |
| | ( 'urational' | 'urat' ) { $type = sep::TypeManager::URATIONAL; } |
| |
| | 'float' { $type = sep::TypeManager::FLOAT; } |
| | 'ufloat' { $type = sep::TypeManager::UFLOAT; } |
| |
| | 'double' { $type = sep::TypeManager::DOUBLE; } |
| | 'udouble' { $type = sep::TypeManager::UDOUBLE; } |
| |
| | 'real' { $type = sep::TypeManager::REAL; } |
| | 'ureal' { $type = sep::TypeManager::UREAL; } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // declaration FUNCTION , PROCEDURE , LAMBDA |
| //////////////////////////////////////////////////////////////////////////////// |
| /* |
| decl_func [ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'func' ID func_signature |
| block_statement |
| ; |
| |
| func_signature |
| : LPAREN decl_call_param ? RPAREN |
| '-->' |
| LPAREN decl_ret_value RPAREN |
| |
| | COLON decl_call_param |
| '-->' decl_ret_value |
| ; |
| |
| decl_proc |
| /* in /[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'proc' ID decl_call_param |
| block_statement |
| ; |
| |
| decl_lambda |
| /* in /[ sep::PropertyPart & declProperty , sep::Modifier mdfr ] |
| : 'lambda' ID |
| COLON decl_call_param |
| '-->' decl_ret_value |
| block_statement |
| ; |
| |
| |
| decl_call_param |
| : decl_call_one_param ( COMMA decl_call_one_param )* |
| ; |
| |
| decl_call_one_param |
| : param_modifier ? type_var ID |
| ; |
| |
| param_modifier |
| : 'in' | 'ref' | 'out' |
| ; |
| |
| decl_ret_value |
| : type_var ( ID )? ( COMMA type_var ( ID )? )* |
| ; |
| |
| |
| decl_one_ret_value |
| : type_var ( ID )? |
| ; |
| */ |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // section MOC |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| section_model_of_computation [ sep::Machine * container ] |
| : '@moc:' |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // section ROUTINE & MACRO |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| section_routine [ sep::Machine * container ] |
| @init{ |
| sep::Modifier mdfr; |
| |
| sep::Specifier spcfr( sep::Specifier::DESIGN_MODEL_KIND ); |
| } |
| : ( '@routine:' |
| | '@macro:' { mdfr.setNatureMacro(); } |
| ) |
| ( def_routine_model[ container , mdfr , spcfr ] )* |
| ; |
| |
| def_routine_model |
| /* in */[ sep::Machine * container , |
| sep::Modifier mdfr , sep::Specifier spcfr ] |
| : ('routine' |
| | 'macro' { mdfr.setNatureMacro(); } |
| ( 'routine' ) ? |
| ) |
| def_routine_model_impl[ container , mdfr , spcfr ] |
| ; |
| |
| |
| def_routine_model_impl |
| /* in */[ sep::Machine * container , |
| sep::Modifier mdfr , sep::Specifier spcfr ] |
| @init{ |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION( _CPR_ ); |
| |
| POP_CTX; |
| } |
| : ID |
| { |
| PUSH_CTX_CPR( sep::Routine::newDefine( |
| container, mdfr, spcfr, STR($ID.text->chars)) ); |
| |
| container->saveOwnedElement( _CPR_ ); |
| } |
| |
| ( def_routine_parameters[ *_CPR_ ] )? |
| ( ( '-->' | 'returns:' ) def_routine_returns[ *_CPR_ ] )? |
| |
| bs=block_statement { _CPR_->setCode($bs.ac); } |
| ; |
| |
| |
| def_routine_parameters [ sep::Routine & routine ] |
| @init{ |
| sep::avm_size_t offset = 0; |
| } |
| : LPAREN |
| ( def_routine_param_atom[ routine , offset++ ] |
| |
| ( COMMA def_routine_param_atom[ routine , offset++ ] )* )? |
| RPAREN |
| ; |
| |
| def_routine_param_atom |
| /* in */[ sep::Routine & routine , sep::avm_size_t offset ] |
| @init{ |
| sep::BF variable; |
| sep::Variable * param; |
| sep::Machine * machine = routine.getContainerMachine(); |
| sep::BF paramT = sep::TypeManager::UNIVERSAL; |
| sep::Modifier mdfr = sep::Modifier::PROPERTY_PARAMETER_MODIFIER; |
| mdfr.addFeatureKind( sep::Modifier::FEATURE_TRANSIENT_KIND ); |
| } |
| : ( ( modifier_param ? type_var ID ) => |
| ( m=modifier_param { mdfr.override_ifdef( $m.mdfr ); } )? |
| tv=type_var { paramT = $tv.type; } id=ID |
| |
| | id=ID |
| { |
| variable = sep::ParserUtil::getVariable(STR($id.text->chars) , 1); |
| if( variable.invalid() ) |
| { |
| sep::ParserUtil::avm_syntax_error( |
| "def_routine_param_atom:> " + routine.str(), $id.line ) |
| << "Unfound machine param's variable < " |
| << STR($id.text->chars) |
| << " > in routine header < " << " >" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| ) |
| { |
| if( variable.valid() ) |
| { |
| routine.saveParameter( param = new sep::Variable( &routine, |
| sep::Modifier::PROPERTY_MACRO_MODIFIER, |
| variable.to_ptr< sep::Variable >()->getType(), |
| STR($id.text->chars)) ); |
| param->setOffset( offset ); |
| param->setBinding( variable ); |
| } |
| else |
| { |
| param = new sep::Variable(&routine, |
| mdfr, $tv.type, STR($id.text->chars)); |
| param->setOffset( offset ); |
| |
| // Only for Routine design as PROTOTYPE a.k.a. primitive routine |
| if( routine.getSpecifier().isDesignPrototypeStatic() ) |
| { |
| routine.appendParameter( |
| machine->getPropertyPart().saveOwnedVariable( param ) ); |
| } |
| else |
| { |
| routine.saveParameter( param ); |
| } |
| } |
| } |
| ( iv=initial_value { param->setValue($iv.bf); } )? |
| ; |
| |
| |
| def_routine_returns [ sep::Routine & routine ] |
| @init{ |
| sep::BF value; |
| sep::avm_size_t offset = 0; |
| } |
| : LPAREN |
| def_routine_returns_atom[ routine , offset++ ] |
| |
| ( COMMA def_routine_returns_atom[ routine , offset++ ] )* |
| RPAREN |
| |
| | tv=type_var ( iv=initial_value { value = $iv.bf; } )? |
| { |
| sep::Variable * variable; |
| routine.saveReturn( variable = new sep::Variable( &routine, |
| sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER, |
| $tv.type, "#0", value) ); |
| variable->setOffset( offset ); |
| } |
| ; |
| |
| |
| def_routine_returns_atom |
| /* in */[ sep::Routine & routine , sep::avm_size_t offset ] |
| @init{ |
| sep::BF variable; |
| sep::Variable * param; |
| sep::Machine * machine = routine.getContainerMachine(); |
| sep::BF paramT = sep::TypeManager::UNIVERSAL; |
| sep::Modifier mdfr = sep::Modifier::PROPERTY_RETURN_PARAMETER_MODIFIER; |
| } |
| : ( ( modifier_param ? type_var ID ) => |
| ( m=modifier_param { mdfr.override_ifdef( $m.mdfr ); } )? |
| tv=type_var { paramT = $tv.type; } id=ID |
| |
| | id=ID |
| { |
| variable = sep::ParserUtil::getVariable(STR($id.text->chars) , 1); |
| if( variable.invalid() ) |
| { |
| sep::ParserUtil::avm_syntax_error( |
| "def_routine_returns_atom:> " + routine.str(), $id.line ) |
| << "Unfound machine return's variable < " |
| << STR($id.text->chars) |
| << " > in routine header < " << " >" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| ) |
| |
| { |
| if( variable.valid() ) |
| { |
| routine.saveReturn( param = new sep::Variable( &routine, |
| sep::Modifier::PROPERTY_MACRO_MODIFIER, |
| variable.to_ptr< sep::Variable >()->getType(), |
| STR($id.text->chars)) ); |
| |
| param->setOffset( offset ); |
| param->setBinding( variable ); |
| } |
| else |
| { |
| param = new sep::Variable(&routine, |
| mdfr, $tv.type, STR($id.text->chars)); |
| param->setOffset( offset ); |
| |
| // Only for Routine design as PROTOTYPE a.k.a. primitive routine |
| if( routine.getSpecifier().isDesignPrototypeStatic() ) |
| { |
| routine.appendReturn( |
| machine->getPropertyPart().saveOwnedVariable( param )); |
| } |
| else |
| { |
| routine.saveReturn( param ); |
| } |
| } |
| } |
| |
| ( iv=initial_value { param->setValue($iv.bf); } )? |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // section MOE |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| section_model_of_execution [ sep::Machine * container ] |
| : '@moe:' ( def_moe_primitive[ container ] )* |
| ; |
| |
| def_moe_primitive [ sep::Machine * container ] |
| @init{ |
| sep::BehavioralPart * theBehavior = container->getUniqBehaviorPart(); |
| |
| sep::Modifier mdfr; |
| |
| sep::Specifier spcfr( sep::Specifier::DESIGN_MODEL_KIND ); |
| } |
| : '@create' def_routine_seq[ theBehavior->getOnCreateRoutine() ] |
| | '@init' def_routine_seq[ theBehavior->getOnInitRoutine() ] |
| | '@final' def_routine_seq[ theBehavior->getOnFinalRoutine() ] |
| |
| | '@start' def_routine_seq[ theBehavior->getOnStartRoutine() ] |
| | '@stop' def_routine_seq[ theBehavior->getOnStopRoutine() ] |
| |
| | '@ienable' def_routine_seq[ theBehavior->getOnIEnableRoutine() ] |
| | '@enable' def_routine_seq[ theBehavior->getOnEnableRoutine() ] |
| |
| | '@idisable' def_routine_seq[ theBehavior->getOnIDisableRoutine() ] |
| | '@disable' def_routine_seq[ theBehavior->getOnDisableRoutine() ] |
| |
| | '@iabort' def_routine_seq[ theBehavior->getOnIAbortRoutine() ] |
| | '@abort' def_routine_seq[ theBehavior->getOnAbortRoutine() ] |
| |
| | '@irun' def_routine_seq[ theBehavior->getOnIRunRoutine() ] |
| | '@run' def_routine_seq[ theBehavior->getOnRunRoutine() ] |
| | '@rtc' def_routine_seq[ theBehavior->getOnRtcRoutine() ] |
| |
| | '@return' def_routine_seq[ theBehavior->getOnFinalRoutine() ] |
| |
| | '@concurrency' def_routine_seq[ theBehavior->getOnConcurrencyRoutine() ] |
| | '@schedule' def_routine_seq[ theBehavior->getOnScheduleRoutine() ] |
| |
| |
| | 'routine' |
| def_routine_model_impl[ container , mdfr , spcfr ] |
| ; |
| |
| |
| def_routine_seq [ sep::Routine & routine ] |
| @init{ |
| PUSH_CTX_CPR( & routine ); |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION( _CPR_ ); |
| |
| POP_CTX;; |
| } |
| : ( def_routine_parameters[ routine ] )? |
| ( ( '-->' | 'returns:' ) def_routine_returns[ routine ] )? |
| |
| bs=block_statement { routine.seqCode($bs.ac); } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // section COM |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| section_model_of_interaction [ sep::Machine * machine ] |
| @init{ |
| sep::InteractionPart * theInteraction = machine->getUniqInteraction(); |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION(theInteraction); |
| } |
| |
| : ( '@interaction:' | '@com:' ) |
| ( com_connect[ machine, theInteraction ] )* |
| ; |
| |
| com_protocol |
| /* in */[ sep::Machine * machine , sep::ComProtocol * cp ] |
| : 'env' { $cp->setProtocol(sep::ComProtocol::PROTOCOL_ENVIRONMENT_KIND); } |
| |
| | 'rdv' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_RDV_KIND, sep::ComProtocol::PROTOCOL_UNICAST_KIND); } |
| | 'multirdv' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_MULTIRDV_KIND, sep::ComProtocol::PROTOCOL_MULTICAST_KIND); } |
| |
| | 'flow' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_FLOW_KIND, sep::ComProtocol::PROTOCOL_MULTICAST_KIND); } |
| |
| |
| | 'anycast' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_ANYCAST_KIND, sep::ComProtocol::PROTOCOL_ANYCAST_KIND); } |
| |
| | 'unicast' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_UNICAST_KIND, sep::ComProtocol::PROTOCOL_UNICAST_KIND); } |
| |
| | 'multicast' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_MULTICAST_KIND, sep::ComProtocol::PROTOCOL_MULTICAST_KIND); } |
| |
| | 'broadcast' { $cp->setProtocolCast(sep::ComProtocol::PROTOCOL_BROADCAST_KIND, sep::ComProtocol::PROTOCOL_BROADCAST_KIND); } |
| |
| | bc=buffer_com [ machine ] |
| { |
| $cp->setProtocol(sep::ComProtocol::PROTOCOL_BUFFER_KIND); |
| $cp->setBuffer($bc.buf); |
| } |
| ; |
| |
| com_cast[ sep::ComProtocol * cp ] |
| : 'anycast' { $cp->setCast(sep::ComProtocol::PROTOCOL_ANYCAST_KIND); } |
| | 'unicast' { $cp->setCast(sep::ComProtocol::PROTOCOL_UNICAST_KIND); } |
| | 'multicast' { $cp->setCast(sep::ComProtocol::PROTOCOL_MULTICAST_KIND); } |
| | 'broadcast' { $cp->setCast(sep::ComProtocol::PROTOCOL_BROADCAST_KIND); } |
| ; |
| |
| buffer_com [ sep::Machine * machine ] |
| returns [ sep::BF buf ] |
| : 'buffer' |
| ( COLON |
| ( rb=ref_buffer[machine] { $buf = $rb.buf; } |
| | db=def_buffer |
| { |
| $buf = sep::BF( new sep::Buffer(machine, |
| newBufferID(), $db.kind, $db.size) ); |
| } |
| ) |
| |
| | LT_ |
| ( rb=ref_buffer[machine] { $buf = $rb.buf; } |
| | db=def_buffer |
| { |
| $buf = sep::BF( new sep::Buffer(machine, |
| newBufferID(), $db.kind, $db.size) ); |
| } |
| ) |
| GT |
| ) |
| | db=def_buffer |
| { |
| $buf = sep::BF( new sep::Buffer(machine, |
| newBufferID(), $db.kind, $db.size) ); |
| } |
| ; |
| |
| |
| com_connect |
| /* in */[ sep::Machine * machine , sep::InteractionPart * anInteraction ] |
| @init{ |
| sep::Connector * aConnector; |
| anInteraction->saveConnector( aConnector = new sep::Connector(*anInteraction) ); |
| aConnector->update(anInteraction); |
| std::string c_id; |
| |
| sep::ComRoute * comRoute = NULL; |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION(aConnector); |
| } |
| : ( 'connector' | 'connect' ) |
| ( LT_ |
| com_protocol[ machine, aConnector ] |
| ( COMMA com_cast[ aConnector ] )? |
| GT |
| )? |
| ( ID { c_id = STR($ID.text->chars); } )? |
| { aConnector->fullyUpdateAllNameID(newConnectID(c_id, "_#connector")); } |
| LCURLY |
| ( com_route[ machine, aConnector ] )+ |
| RCURLY |
| |
| |
| | ( 'route' ) |
| { |
| aConnector->setNature( sep::IComPoint::IO_SIGNAL_NATURE ); |
| aConnector->fullyUpdateAllNameID(newConnectID("", "_#route")); |
| } |
| ( LT_ |
| com_protocol[ machine, aConnector ] |
| ( COMMA com_cast[ aConnector ] )? |
| GT |
| )? |
| |
| ( com_route[ machine, aConnector ] |
| |
| | LCURLY |
| ( com_route[ machine, aConnector ] )+ |
| RCURLY |
| |
| | LBRACKET |
| { |
| comRoute = new sep::ComRoute(aConnector, |
| sep::Modifier::PROPERTY_INOUT_DIRECTION); |
| aConnector->appendComRoute(comRoute); |
| } |
| ( com_port[ machine , comRoute ] |
| ( COMMA com_port[ machine , comRoute ] )* |
| |
| | STAR |
| { |
| sep::ComPoint * comPoint = new sep::ComPoint(); |
| comPoint->setMachineAllSignal(machine); |
| comRoute->setComPoint(comPoint, sep::Modifier::DIRECTION_INOUT_KIND); |
| |
| SET_RULE_LOCATION(comPoint); |
| } |
| ) |
| RBRACKET |
| SEMI |
| ) |
| ; |
| |
| |
| com_route |
| /* in */[ sep::Machine * machine , sep::Connector * aConnector ] |
| @init{ |
| sep::ComRoute * comRoute = new sep::ComRoute(aConnector); |
| aConnector->appendComRoute(comRoute); |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION(comRoute); |
| } |
| : modifier_set_direction_strict_text[ comRoute->getwModifier() ] |
| ( LT_ ( |
| bc=buffer_com[ machine ] |
| { |
| comRoute->setProtocol(sep::ComProtocol::PROTOCOL_BUFFER_KIND); |
| comRoute->setBuffer($bc.buf); |
| } |
| | com_cast[ comRoute ] |
| ) GT )? |
| |
| ( com_port[ machine , comRoute ] SEMI |
| |
| | LCURLY |
| ( com_port[ machine , comRoute ] SEMI )+ |
| RCURLY |
| |
| | LBRACKET |
| ( com_port[ machine , comRoute ] |
| ( COMMA com_port[ machine , comRoute ] )* |
| |
| | STAR |
| { |
| sep::ComPoint * comPoint = new sep::ComPoint(); |
| comPoint->setMachineAllSignal(machine); |
| comRoute->setComPoint(comPoint, sep::Modifier::DIRECTION_INOUT_KIND); |
| |
| SET_RULE_LOCATION(comPoint); |
| } |
| ) |
| RBRACKET |
| SEMI |
| ) |
| |
| | com_port[ machine , comRoute ] SEMI |
| ; |
| |
| |
| com_port |
| /* in */[ sep::Machine * machine , sep::ComRoute * comRoute] |
| @init{ |
| sep::Machine * comMachine = machine; |
| while( comMachine != NULL ) |
| { |
| if( comMachine->hasPortSignal() || (! comMachine->hasContainer()) ) |
| { |
| break; |
| } |
| comMachine = comMachine->getContainerMachine(); |
| } |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| : ( qualifiedNameID '->' ) => |
| m=qualifiedNameID |
| { comMachine = sep::ParserUtil::getMachine(machine, $m.s, $m.nb); } |
| |
| '->' |
| |
| ( cp=com_port_id[ machine , comMachine ] |
| { comRoute->appendComPoint($cp.comPoint); } |
| |
| | LBRACKET |
| ( cp=com_port_id[ machine , comMachine ] |
| { comRoute->appendComPoint($cp.comPoint); } |
| |
| ( COMMA cp=com_port_id[ machine , comMachine ] |
| { comRoute->appendComPoint($cp.comPoint); } )* |
| |
| | STAR |
| { |
| sep::ComPoint * comPoint = new sep::ComPoint(); |
| comPoint->setMachineAllSignal(comMachine); |
| comRoute->setComPoint(comPoint, sep::Modifier::DIRECTION_INOUT_KIND); |
| |
| SET_RULE_LOCATION(comPoint); |
| } |
| ) |
| RBRACKET |
| ) |
| |
| |
| | cp=com_port_id[ machine , comMachine ] |
| { comRoute->appendComPoint($cp.comPoint); } |
| ; |
| |
| |
| com_port_id |
| /* in */[ sep::Machine * machine , sep::Machine * comMachine ] |
| returns [ sep::BF comPoint ] |
| @init{ |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| : id=qualifiedNameID |
| { |
| sep::ComPoint * aComPoint; |
| $comPoint = sep::BF( aComPoint = new sep::ComPoint() ); |
| |
| SET_RULE_LOCATION(aComPoint); |
| |
| const sep::BF & comPort = sep::ParserUtil::getComPortSignal( |
| comMachine, $id.s, $id.nb); |
| if( comPort.valid() ) |
| { |
| aComPoint->setMachinePort(comMachine, comPort.to_ptr< sep::Port >()); |
| } |
| else |
| { |
| aComPoint->setMachine(comMachine); |
| aComPoint->setMachinePort(NEW_QNID($id.s, $id.nb)); |
| } |
| } |
| ; |
| |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement |
| returns [ sep::BFCode ac ] |
| : s=statement_assign { $ac = $s.ac; } |
| // | s=statement_buffer { $ac = $s.ac; } |
| | s=statement_com { $ac = $s.ac; } |
| | s=statement_constraint { $ac = $s.ac; } |
| | s=statement_jump { $ac = $s.ac; } |
| // | s=statement_time { $ac = $s.ac; } |
| |
| | s=statement_activity { $ac = $s.ac; } |
| | s=statement_invoke_routine { $ac = $s.ac; } |
| |
| | s=statement_moc { $ac = $s.ac; } |
| |
| | s=statement_invoke { $ac = $s.ac; } |
| | s=statement_invoke_method { $ac = $s.ac; } |
| |
| | s=statement_activity_new { $ac = $s.ac; } |
| |
| | s=statement_ite { $ac = $s.ac; } |
| | s=statement_iteration { $ac = $s.ac; } |
| |
| // | s=statement_lem { $ac = $s.ac; } |
| |
| | s=block_statement { $ac = $s.ac; } |
| |
| | s=prefix_statement { $ac = $s.ac; } |
| |
| | s=statement_prompt { $ac = $s.ac; } |
| |
| | s=meta_statement { $ac = $s.ac; } |
| |
| // | s=quote_statement { $ac = $s.ac; } |
| ; |
| |
| |
| block_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); } )* |
| RCURLY |
| ; |
| |
| op_block |
| returns [ sep::Operator * op ] |
| : o=op_sequence { $op = $o.op; } |
| | o=op_scheduling { $op = $o.op; } |
| | o=op_concurrency { $op = $o.op; } |
| |
| | OP_FORK { $op = OP(FORK); } |
| | OP_JOIN { $op = OP(JOIN); } |
| ; |
| |
| op_sequence |
| returns [ sep::Operator * op ] |
| : OP_SEQUENCE { $op = OP(SEQUENCE); } |
| | OP_SEQUENCE_SIDE { $op = OP(SEQUENCE_SIDE); } |
| | OP_SEQUENCE_WEAK { $op = OP(SEQUENCE_WEAK); } |
| |
| | OP_ATOMIC_SEQUENCE { $op = OP(ATOMIC_SEQUENCE); } |
| ; |
| |
| op_scheduling |
| returns [ sep::Operator * op ] |
| : OP_SCHEDULE_GT { $op = OP(PRIOR_GT); } |
| | OP_SCHEDULE_LT { $op = OP(PRIOR_LT); } |
| | OP_SCHEDULE_XOR { $op = OP(EXCLUSIVE); } |
| |
| | OP_SCHEDULE_AND_THEN { $op = OP(SCHEDULE_AND_THEN); } |
| | OP_SCHEDULE_OR_ELSE { $op = OP(SCHEDULE_OR_ELSE); } |
| |
| | OP_NON_DETERMINISM { $op = OP(NONDETERMINISM); } |
| ; |
| |
| op_concurrency |
| returns [ sep::Operator * op ] |
| : OP_CONCURRENCY_ASYNC { $op = OP(ASYNCHRONOUS); } |
| | OP_CONCURRENCY_AND { $op = OP(STRONG_SYNCHRONOUS); } |
| | OP_CONCURRENCY_OR { $op = OP(WEAK_SYNCHRONOUS); } |
| | OP_CONCURRENCY_INTERLEAVING { $op = OP(INTERLEAVING); } |
| | OP_CONCURRENCY_PARALLEL { $op = OP(PARALLEL); } |
| |
| | OP_CONCURRENCY_RDV_ASYNC { $op = OP(RDV_ASYNCHRONOUS); } |
| | OP_CONCURRENCY_RDV_AND { $op = OP(RDV_STRONG_SYNCHRONOUS); } |
| | OP_CONCURRENCY_RDV_OR { $op = OP(RDV_WEAK_SYNCHRONOUS); } |
| | OP_CONCURRENCY_RDV_INTERLEAVING { $op = OP(RDV_INTERLEAVING); } |
| | OP_CONCURRENCY_RDV_PARALLEL { $op = OP(RDV_PARALLEL); } |
| ; |
| |
| |
| |
| op_invokable |
| returns [ sep::Operator * op ] |
| : PLUS { $op = OP(PLUS); } |
| |
| | MINUS { $op = OP(MINUS); } |
| |
| | STAR { $op = OP(MULT); } |
| | DIV { $op = OP(DIV); } |
| | MOD { $op = OP(MOD); } |
| |
| // | POW { $op = OP(POW); } |
| |
| | EQUAL { $op = OP(EQ); } |
| | NEQUAL { $op = OP(NEQ); } |
| |
| | SEQUAL { $op = OP(SEQ); } |
| | NSEQUAL { $op = OP(NSEQ); } |
| |
| | GT { $op = OP(GT); } |
| | GTE { $op = OP(GTE); } |
| | LT_ { $op = OP(LT); } |
| | LTE { $op = OP(LTE); } |
| |
| | LNOT { $op = OP(NOT); } |
| | LAND { $op = OP(AND); } |
| | LAND_THEN { $op = OP(AND_THEN); } |
| | LOR { $op = OP(OR); } |
| | LOR_ELSE { $op = OP(OR_ELSE); } |
| |
| | BNOT { $op = OP(BNOT); } |
| | BAND { $op = OP(BAND); } |
| | BOR { $op = OP(BOR); } |
| | BXOR { $op = OP(BXOR); } |
| |
| | LSHIFT { $op = OP(LSHIFT); } |
| | RSHIFT { $op = OP(RSHIFT); } |
| |
| | ASSIGN { $op = OP(ASSIGN); } |
| | ASSIGN_AFTER { $op = OP(ASSIGN_AFTER); } |
| | ASSIGN_REF { $op = OP(ASSIGN_REF); } |
| | ASSIGN_MACRO { $op = OP(ASSIGN_MACRO); } |
| |
| | OP_PUSH { $op = OP(PUSH); } |
| | OP_ASSIGN_TOP { $op = OP(ASSIGN_TOP); } |
| | OP_TOP { $op = OP(TOP); } |
| | OP_POP { $op = OP(POP); } |
| ; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // AVM STATEMENT |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| prefix_statement |
| returns [ sep::BFCode ac ] |
| : DOLLAR_LCURLY op=avm_operator { $ac = NEW_STMT(op); } |
| ( ps=prefix_statement { $ac->append($ps.ac); } |
| | e=unaryExpression { $ac->append($e.bf); } |
| )* |
| RCURLY |
| ; |
| |
| prefix_expression |
| returns [ sep::BFCode ac ] |
| : DOLLAR_LCURLY op=avm_operator { $ac = NEW_STMT(op); } |
| ( ps=prefix_expression { $ac->append($ps.ac); } |
| | e=unaryExpression { $ac->append($e.bf); } |
| )* |
| RCURLY |
| ; |
| |
| avm_operator |
| returns [ sep::Operator * op ] |
| : o=op_invokable { $op = $o.op; } |
| |
| | o=op_activity { $op = $o.op; } |
| |
| | { (op = sep::OperatorManager::getOp(STR(LT(1)->getText(LT(1))->chars))) != NULL }? ID |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // AVM STATEMENT INVOKE |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_invoke_method |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BF modelProcedure; |
| sep::Machine * callProcedure; |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after |
| { |
| SET_RULE_LOCATION(callProcedure); |
| } |
| : 'call' id=ID |
| { |
| modelProcedure = sep::ParserUtil::getvarProcedure(STR($id.text->chars)); |
| |
| callProcedure = sep::Machine::newProcedureInstance(_CPM_, |
| sep::OSS() << "call_" << ++mProcedureCallCount |
| << '#' << STR($id.text->chars), modelProcedure); |
| |
| callProcedure->getwSpecifier().setDesignInstanceStatic(); |
| |
| $ac = NEW_STMT1(OP(INVOKE_METHOD), sep::BF(callProcedure)); |
| } |
| |
| decl_instance_machine_params [ callProcedure ] ? |
| decl_instance_machine_returns[ callProcedure ] ? |
| |
| SEMI |
| ; |
| |
| |
| statement_invoke |
| returns [ sep::BFCode ac ] |
| : LPAREN_INVOKE |
| ue=unaryExpression { $ac = NEW_STMT1(OP(INVOKE_METHOD), $ue.bf); } |
| ( id=ID { $ac->append(sep::ParserUtil::getInvokable($ue.bf, STR($id.text->chars))); } |
| | 'in' { $ac->append( INCR_BF(OP(IN)) ); } |
| | op=op_invokable { $ac->append( INCR_BF($op.op) ); } |
| ) |
| ( e=expression { $ac->append($e.bf); } )* |
| ( 'provided:' e=expression |
| | 'from:' ue=unaryExpression |
| | 'to:' ue=unaryExpression |
| | 'activity:' o=op_activity |
| )? |
| RPAREN |
| SEMI |
| ; |
| |
| expression_invoke |
| returns [ sep::BFCode ac ] |
| : LPAREN_INVOKE |
| e=unaryExpression { $ac = NEW_STMT1(OP(INVOKE_METHOD), $e.bf); } |
| ( id=ID { $ac->append(sep::ParserUtil::getInvokable($e.bf, STR($id.text->chars))); } |
| | 'in' { $ac->append( INCR_BF(OP(IN)) ); } |
| | op=op_invokable { $ac->append( INCR_BF($op.op) ); } |
| ) |
| ( e=expression { $ac->append($e.bf); } )* |
| ( 'provided:' e=expression |
| | 'from:' ue=unaryExpression |
| | 'to:' ue=unaryExpression |
| | 'activity:' o=op_activity |
| )? |
| RPAREN |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT NEW |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_activity_new |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::Machine * ptrInstance = NULL; |
| sep::BF aModel; |
| |
| sep::Machine * container = _CPM_; |
| } |
| @after{ |
| if( aModel.is< sep::Machine >() ) |
| { |
| POP_CTX; |
| } |
| } |
| : 'new' { $ac = NEW_STMT(OP(INVOKE_NEW)); } |
| id=qualifiedNameID |
| { |
| aModel = sep::ParserUtil::getvarMachine($id.s, $id.nb); |
| |
| if( aModel.is< sep::Machine >() ) |
| { |
| PUSH_CTX_NEW( aModel.to_ptr< sep::Machine >() ); |
| } |
| |
| ptrInstance = sep::Machine::newInstance(container, |
| newInvokeNewInstanceNameID(container, $id.s), aModel, 1, 1); |
| |
| ptrInstance->getwSpecifier().override_ifdef( |
| sep::Specifier::DESIGN_INSTANCE_DYNAMIC_SPECIFIER ); |
| |
| $ac->append( container->saveOwnedElement( ptrInstance ) ); |
| } |
| |
| //activity_machine_param_return[ aModel , ac ] |
| decl_instance_dynamic_impl[ _CPM_ , ptrInstance ] |
| |
| ( ( '-->' | 'returns:' ) e=expression )? |
| |
| SEMI |
| ; |
| |
| |
| decl_instance_dynamic_impl |
| /* in */[ sep::Machine * container , sep::Machine * ptrInstance ] |
| @init{ |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after{ |
| SET_RULE_LOCATION(ptrInstance); |
| } |
| : ( ( LPAREN ) => LPAREN |
| ( def_instance_on_new_activity[ ptrInstance ] ) ? |
| RPAREN |
| )? |
| |
| ( ( LCURLY ) => LCURLY |
| ( s=statement { ptrInstance->getUniqBehaviorPart()->seqOnCreate($s.ac); } )* |
| |
| ( def_instance_activity[ ptrInstance ] )* |
| RCURLY |
| )? |
| ; |
| |
| |
| |
| expression_activity_new |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::Machine * ptrInstance = NULL; |
| sep::BF aModel; |
| |
| sep::Machine * container = _CPM_; |
| } |
| @after{ |
| if( aModel.is< sep::Machine >() ) |
| { |
| POP_CTX; |
| } |
| } |
| : 'new' { $ac = NEW_STMT(OP(INVOKE_NEW)); } |
| id=qualifiedNameID |
| { |
| sep::BF aModel = sep::ParserUtil::getvarMachine($id.s, $id.nb); |
| |
| if( aModel.is< sep::Machine >() ) |
| { |
| PUSH_CTX_NEW( aModel.to_ptr< sep::Machine >() ); |
| } |
| |
| ptrInstance = sep::Machine::newInstance(container, |
| newInvokeNewInstanceNameID(container, $id.s), aModel, 1, 1); |
| |
| ptrInstance->getwSpecifier().override_ifdef( |
| sep::Specifier::DESIGN_INSTANCE_DYNAMIC_SPECIFIER ); |
| |
| $ac->append( container->saveOwnedElement( ptrInstance ) ); |
| } |
| |
| activity_machine_param_return[ aModel , ac ] |
| // decl_instance_dynamic_expr_impl[ _CPM_ , ptrInstance , ac ] |
| |
| // { $ac->toStream(sep::AVM_OS_DEBUG); } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT PROMPT |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_prompt |
| returns [ sep::BFCode ac ] |
| : STATEMENT_PROMPT spi=statement_prompt_impl { $ac = $spi.ac; } |
| ; |
| |
| statement_prompt_impl |
| returns [ sep::BFCode ac ] |
| : spo=statement_prompt_obs { $ac = $spo.ac; } |
| ; |
| |
| |
| statement_prompt_obs |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BF varMachine = INCR_BF(_SYSTEM_); |
| } |
| : { IS_KEYWORD( "obs" ) }? ID |
| |
| ( 'ctx:' id=qualifiedNameID |
| { varMachine = sep::ParserUtil::getvarMachine($id.s, $id.nb); } |
| )? |
| |
| LCURLY |
| bs=statement_prompt_obs_com[ varMachine ] |
| RCURLY |
| |
| ( 'provided:' e=expression |
| | LBRACKET e=expression RBRACKET |
| ) |
| SEMI |
| |
| { $ac = NEW_STMT3(OP(OBS), varMachine, $bs.ac, $e.bf); } |
| ; |
| |
| |
| statement_prompt_obs_com [ const sep::BF & varMachine ] |
| returns [ sep::BFCode ac ] |
| : sc=statement_com { $ac = $sc.ac; } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // META STATEMENT |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| meta_statement |
| returns [ sep::BFCode ac ] |
| : '$:informal' bs=block_statement { $ac = NEW_STMT1(OP(INFORMAL), $bs.ac); } |
| | '$:trace' bs=block_statement { $ac = NEW_STMT1(OP(TRACE) , $bs.ac); } |
| | '$:debug' bs=block_statement { $ac = NEW_STMT1(OP(DEBUG) , $bs.ac); } |
| | '$:comment' bs=block_statement { $ac = NEW_STMT1(OP(COMMENT) , $bs.ac); } |
| /* TODO#ADD |
| // meta_eval |
| | LBRACKET_BAR |
| e=expression { $ac = NEW_STMT1(OP(META_EVAL), $e.bf); } |
| BAR_RBRACKET |
| |
| // meta_run |
| | LBRACKET_LCURLY |
| s=statement { $ac = NEW_STMT1(OP(META_RUN), $s.ac); } |
| RCURLY_RBRACKET |
| */ |
| ; |
| |
| /* TODO#ADD |
| quote_statement |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::Operator * op = OP(SEQUENCE); |
| } |
| : PERCENT_LCURLY ( o=op_block { op = $o.op; } ) ? { $ac = NEW_STMT(op); } |
| ( s=statement { $ac->append($s.ac); } )+ |
| RCURLY_PERCENT |
| { $ac = NEW_STMT1(OP(QUOTE), $ac); } |
| ; |
| */ |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT ASSIGN |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_assign |
| returns [ sep::BFCode ac ] |
| // lvalue := expression |
| : lv=lvalue |
| ( ( ASSIGN | ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT2(OP(ASSIGN), $lv.bf, $e.bf); } |
| |
| | ASSIGN_REF e=lvalue SEMI |
| { $ac = NEW_STMT2(OP(ASSIGN_REF), $lv.bf, $e.bf); } |
| |
| | ASSIGN_MACRO e=expression SEMI |
| { $ac = NEW_STMT2(OP(ASSIGN_MACRO), $lv.bf, $e.bf); } |
| |
| |
| | ( PLUS_ASSIGN | PLUS_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, $e.bf); } |
| |
| | ( MINUS_ASSIGN | MINUS_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(MINUS), $lv.bf, $e.bf); } |
| |
| | ( STAR_ASSIGN | STAR_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(MULT), $lv.bf, $e.bf); } |
| |
| | ( DIV_ASSIGN | DIV_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(DIV), $lv.bf, $e.bf); } |
| |
| | ( MOD_ASSIGN | MOD_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(MOD), $lv.bf, $e.bf); } |
| |
| |
| | ( LAND_ASSIGN | LAND_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(AND), $lv.bf, $e.bf); } |
| |
| | ( LOR_ASSIGN | LOR_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(OR), $lv.bf, $e.bf); } |
| |
| |
| | ( BAND_ASSIGN | BAND_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(BAND), $lv.bf, $e.bf); } |
| |
| | ( BOR_ASSIGN | BOR_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(BOR), $lv.bf, $e.bf); } |
| |
| | ( BXOR_ASSIGN | BXOR_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(BXOR), $lv.bf, $e.bf); } |
| |
| |
| | ( LSHIFT_ASSIGN | LSHIFT_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(LSHIFT), $lv.bf, $e.bf); } |
| |
| | ( RSHIFT_ASSIGN | RSHIFT_ASSIGN_AFTER ) e=expression SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(RSHIFT), $lv.bf, $e.bf); } |
| |
| |
| // queue <=< expression ( <=< expression )* |
| // fifo <=< a <=< b <=< c |
| // soit :> fifo:a:b:c |
| | OP_PUSH e=expression |
| { $ac = NEW_STMT2(OP(PUSH), $lv.bf, $e.bf); } |
| ( OP_PUSH e=expression { $ac->append($e.bf); } )* |
| SEMI |
| |
| // queue ^=< expression |
| // fifo:a ^=< b |
| // soit :> fifo:b |
| | OP_ASSIGN_TOP e=expression SEMI |
| { $ac = NEW_STMT2(OP(ASSIGN_TOP), $lv.bf, $e.bf); } |
| |
| // queue ^=> lvalue |
| // fifo:a ^=> b |
| // soit :> fifo:a et lvalue = a |
| | OP_TOP v=lvalue SEMI |
| { $ac = NEW_STMT2(OP(TOP), $lv.bf, $v.bf); } |
| |
| // queue >=> lvalue ( >=> lvalue )* |
| // fifo::a::b::c >=> lvalue1 >=> lvalue2 >=> lvalue3 |
| // soit :> fifo et lvalue1 = c , lvalue2 = b , lvalue3 = a |
| | OP_POP { $ac = NEW_STMT1(OP(POP), $lv.bf); } |
| ( v=lvalue { $ac->append($v.bf); } )* |
| SEMI |
| |
| // lvalue ++ |
| | INCR SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_ONE); } |
| |
| // lvalue -- |
| | DECR SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_MINUS_ONE); } |
| ) |
| |
| // | 'pop' lv=lvalue SEMI |
| // { $ac = NEW_STMT1(OP(POP), $lv.bf); } |
| |
| // | 'newfresh' lv=lvalue SEMI |
| // { $ac = NEW_STMT1(OP(ASSIGN_NEWFRESH), $lv.bf); } |
| |
| // ++ lvalue |
| | INCR lv=lvalue SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_ONE); } |
| |
| // -- lvalue |
| | DECR lv=lvalue SEMI |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_MINUS_ONE); } |
| ; |
| |
| |
| lvalue |
| returns [ sep::BF bf ] |
| @init{ |
| sep::UniFormIdentifier * ufi; |
| sep::BF bfUfi; // for automatic destruction of << UFI >> if need |
| |
| sep::avm_size_t countID = 1; |
| bool isnotEXPR = true; |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| : ( COLONx2 { ufi->setAbsolute(); } )? |
| id=ID |
| { |
| ufi = new sep::UniFormIdentifier(false); |
| bfUfi = ufi; |
| |
| if( ($bf = sep::ParserUtil::getvar(STR($id.text->chars), 1)).valid() ) |
| { |
| ufi->appendFieldVariable($bf); |
| } |
| else if( ($bf = sep::ParserUtil::getvarMachine( |
| STR($id.text->chars), 1)).valid() ) |
| { |
| ufi->appendFieldMachine($bf); |
| } |
| else |
| { |
| ufi->appendField(STR($id.text->chars)); |
| } |
| |
| $bf = bfUfi; |
| } |
| |
| ( ( DOT id=ID |
| { ufi->appendField(STR($id.text->chars)); ++countID; } ) |
| |
| | ( LBRACKET e=expression RBRACKET |
| { ufi->appendIndex($e.bf); isnotEXPR = false; } ) |
| )* |
| { |
| if( isnotEXPR ) |
| { |
| if( countID == 1 ) |
| { |
| $bf = ufi->first(); |
| } |
| else if( ($bf = sep::ParserUtil::getvar( |
| ufi->str(), countID)).invalid() ) |
| { |
| $bf = bfUfi; |
| SET_RULE_LOCATION(ufi); |
| } |
| } |
| } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT BUFFER |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| //statement_buffer |
| //returns [ sep::BFCode ac ] |
| // : 'clear' id=qualifiedNameID SEMI |
| // { $ac = NEW_STMT1(OP(CLEAR), getvarBuffer($id.s, $id.nb)); } |
| // |
| // | 'push' id=qualifiedNameID |
| // { $ac = NEW_STMT1(OP(PUSH), getvarBuffer($id.s, $id.nb)); } |
| // parameters[ ac ] ? SEMI |
| // |
| // | 'pop' id=qualifiedNameID |
| // { $ac = NEW_STMT1(OP(POP), getvarBuffer($id.s, $id.nb)); } |
| // parameters[ ac ] ? SEMI |
| // |
| // | 'top' id=qualifiedNameID |
| // { $ac = NEW_STMT1(OP(TOP), getvarBuffer($id.s, $id.nb)); } |
| // parameters[ ac ] ? SEMI |
| // ; |
| |
| //expression_buffer |
| //returns [ sep::BFCode ac ] |
| // : 'empty' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(EMPTY), $e.bf); } |
| // |
| // | 'nonempty' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(NONEMPTY), $e.bf); } |
| // |
| // | 'singleton' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(SINGLETON), $e.bf); } |
| // |
| // | 'populated' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(POPULATED), $e.bf); } |
| // |
| // | 'full' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(FULL), $e.bf); } |
| // |
| // | 'size' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(SIZE), $e.bf); } |
| // |
| // | 'pop' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(POP), $e.bf); } |
| // |
| // | 'top' e=unaryExpression |
| // { $ac = NEW_STMT1(OP(TOP), $e.bf); } |
| // ; |
| |
| parameters [ const sep::BFCode & ac ] |
| : LPAREN e=expression { $ac->append($e.bf); } |
| ( COMMA e=expression { $ac->append($e.bf); } )* |
| RPAREN |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT COM |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_com |
| returns [ sep::BFCode ac ] |
| : s=statement_com_input { $ac = $s.ac; } |
| | s=statement_com_output { $ac = $s.ac; } |
| ; |
| |
| statement_com_input |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BF varPortSignal; |
| sep::Port * port = NULL; |
| sep::Operator * op = NULL; |
| } |
| : ( tok='input' { op = OP(INPUT); } |
| | tok='input#save' { op = OP(INPUT_SAVE); } |
| | tok='input#var' { op = OP(INPUT_VAR); } |
| | tok='input#flow' { op = OP(INPUT_FLOW); } |
| | tok='input#env' { op = OP(INPUT_ENV); } |
| | tok='input#buffer' { op = OP(INPUT_BUFFER); } |
| | tok='input#rdv' { op = OP(INPUT_RDV); } |
| ) id=qualifiedNameID |
| { |
| $ac = NEW_STMT1( op, |
| varPortSignal = sep::ParserUtil::getvarPortSignal($id.s, $id.nb) ); |
| if( varPortSignal.is< sep::Port >() ) |
| { port = varPortSignal.to_ptr< sep::Port >(); } |
| else if( varPortSignal.invalid() ) |
| { |
| sep::ParserUtil::avm_syntax_error( |
| "statement_com_input:> ", $tok.line ) |
| << "Unfound port/signal or variable < " << $id.s |
| << " > in machine < " << str_header( _CPM_ ) << " >" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| parameters_port[ port , ac ] ? |
| ( '<--' |
| ( 'env' { $ac->setOperator( OP(INPUT_ENV) ); } |
| | me=expression |
| { |
| sep::BFCode inputFrom = NEW_STMT2(OP(INPUT_FROM), $ac->first(), $me.bf); |
| |
| inputFrom->insert(inputFrom->end(), ++($ac->begin()), $ac->end()); |
| $ac = inputFrom; |
| } |
| ) |
| ( '<-' id=qualifiedNameID |
| { $ac->append(sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| )? |
| )? |
| ( ( '<==' | 'via' ) id=qualifiedNameID |
| { sep::ParserUtil::updateSignalRoutingChannel( |
| sep::Modifier::DIRECTION_INPUT_KIND, $ac, $id.s, $id.nb); } |
| )? |
| SEMI |
| ; |
| |
| statement_com_output |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BF varPortSignal; |
| sep::Port * port = NULL; |
| sep::Operator * op = NULL; |
| } |
| : ( tok='output' { op = OP(OUTPUT); } |
| | tok='output#var' { op = OP(OUTPUT_VAR); } |
| | tok='output#flow' { op = OP(OUTPUT_FLOW); } |
| | tok='output#env' { op = OP(OUTPUT_ENV); } |
| | tok='output#buffer' { op = OP(OUTPUT_BUFFER); } |
| | tok='output#rdv' { op = OP(OUTPUT_RDV); } |
| ) id=qualifiedNameID |
| { |
| $ac = NEW_STMT1( op, |
| varPortSignal = sep::ParserUtil::getvarPortSignal($id.s, $id.nb) ); |
| if( varPortSignal.is< sep::Port >() ) |
| { port = varPortSignal.to_ptr< sep::Port >(); } |
| else if( varPortSignal.invalid() ) |
| { |
| sep::ParserUtil::avm_syntax_error( |
| "statement_com_output:>", $tok.line ) |
| << "Unfound port/signal or variable < " << $id.s |
| << " > in machine < " << str_header( _CPM_ ) << " >" |
| << sep::ParserUtil::SYNTAX_ERROR_EOL; |
| } |
| } |
| parameters_port[ port , ac ] ? |
| ( '-->' |
| ( 'env' { $ac->setOperator( OP(OUTPUT_ENV) ); } |
| | me=expression |
| { |
| sep::BFCode outputTo = NEW_STMT2(OP(OUTPUT_TO), $ac->first(), $me.bf); |
| |
| outputTo->insert(outputTo->end(), ++($ac->begin()), $ac->end()); |
| $ac = outputTo; |
| } |
| ) |
| ( '->' id=qualifiedNameID |
| { $ac->append(sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| )? |
| )? |
| ( ( '==>' | 'via' ) id=qualifiedNameID |
| { sep::ParserUtil::updateSignalRoutingChannel( |
| sep::Modifier::DIRECTION_OUTPUT_KIND, $ac, $id.s, $id.nb); } |
| )? |
| SEMI |
| ; |
| |
| |
| parameters_port |
| /* in */[ sep::Port * port , const sep::BFCode & ac ] |
| @init{ |
| sep::BFVector labelledParams( |
| (port != NULL) ? port->getParametersCount() : 0 ); |
| |
| sep::BFList positionalParams; |
| } |
| @after{ |
| sep::ParserUtil::computePortParameter( |
| port, $ac, labelledParams, positionalParams); |
| } |
| : LPAREN |
| lp=labelled_argument |
| { |
| sep::ParserUtil::appendPortParameter(port, $lp.label, |
| labelledParams, positionalParams, $lp.arg); |
| } |
| ( COMMA lp=labelled_argument |
| { |
| sep::ParserUtil::appendPortParameter(port, $lp.label, |
| labelledParams, positionalParams, $lp.arg); |
| } |
| )* |
| RPAREN |
| ; |
| |
| |
| |
| expression_com |
| returns [ sep::BFCode ac ] |
| : 'present' id=qualifiedNameID |
| { $ac = NEW_STMT1(OP(PRESENT), |
| sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| |
| | 'absent' id=qualifiedNameID |
| { $ac = NEW_STMT1(OP(ABSENT), |
| sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| ; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT GUARD |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_constraint |
| returns [ sep::BFCode ac ] |
| : s=statement_guard { $ac = $s.ac; } |
| | s=statement_timed_guard { $ac = $s.ac; } |
| | s=statement_checksat { $ac = $s.ac; } |
| ; |
| |
| |
| statement_guard |
| returns [ sep::BFCode ac ] |
| : 'guard' e=expression SEMI |
| { $ac = NEW_STMT1(OP(GUARD), $e.bf); } |
| |
| | 'event' e=expression SEMI |
| { $ac = NEW_STMT1(OP(EVENT), $e.bf); } |
| ; |
| |
| statement_timed_guard |
| returns [ sep::BFCode ac ] |
| : 'tguard' e=expression SEMI |
| { $ac = NEW_STMT1(OP(TIMED_GUARD), $e.bf); } |
| ; |
| |
| statement_checksat |
| returns [ sep::BFCode ac ] |
| @init{ |
| std::string solverID; |
| } |
| : 'checksat' |
| ( LT_ ( id=StringLiteral | id=ID ) GT { solverID = STR($id.text->chars); } |
| | 'solver:' ( id=StringLiteral | id=ID ) { solverID = STR($id.text->chars); } |
| )? |
| e=expression SEMI |
| { |
| if( solverID.empty() ) |
| { |
| $ac = NEW_STMT1( OP(CHECK_SAT), $e.bf ); |
| } |
| else |
| { |
| $ac = NEW_STMT2( OP(CHECK_SAT), NEW_STRING(solverID), $e.bf ); |
| } |
| } |
| ; |
| |
| |
| expression_guard |
| returns [ sep::BFCode ac ] |
| @init{ |
| std::string solverID; |
| } |
| : 'checksat' |
| ( LT_ ( id=StringLiteral | id=ID ) GT { solverID = STR($id.text->chars); } |
| | 'solver:' ( id=StringLiteral | id=ID ) { solverID = STR($id.text->chars); } |
| )? |
| e=expression |
| { |
| if( solverID.empty() ) |
| { |
| $ac = NEW_STMT1( OP(CHECK_SAT), $e.bf); |
| } |
| else |
| { |
| $ac = NEW_STMT2( OP(CHECK_SAT), NEW_STRING(solverID), $e.bf ); |
| } |
| } |
| ; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT IF THEN [ ELSEIF ] [ ELSE ] |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_ite |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BFCode elseifCode; |
| sep::BFCode code; |
| } |
| : 'if' e=expression bs=block_statement |
| { code = $ac = NEW_STMT2(OP(IF), $e.bf, $bs.ac); } |
| ( ( 'elseif' | 'else' 'if' ) e=expression bs=block_statement |
| { |
| code->setOperator(OP(IFE)); |
| code->append(elseifCode = NEW_STMT2(OP(IF), $e.bf, $bs.ac)); |
| code = elseifCode; |
| } |
| )* |
| ( 'else' bs=block_statement |
| { |
| if( $bs.ac->nonempty() ) |
| { |
| code->setOperator(OP(IFE)); code->append($bs.ac); |
| } |
| } |
| )? |
| ; |
| |
| expression_ite |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BFCode elseifExpr; |
| sep::BFCode expr; |
| } |
| : 'if' c=expression LCURLY e=expression RCURLY |
| { expr = $ac = NEW_STMT2(OP(IF), $c.bf, $e.bf); } |
| ( ( 'elseif' | 'else' 'if' ) c=expression LCURLY e=expression RCURLY |
| { |
| expr->setOperator(OP(IFE)); |
| expr->append(elseifExpr = NEW_STMT2(OP(IF), $c.bf, $e.bf)); |
| expr = elseifExpr; |
| } |
| )* |
| ( 'else' LCURLY e=expression RCURLY |
| { expr->setOperator(OP(IFE)); expr->append($e.bf); } |
| )? |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT WHERE PROVIDED |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| //statement_where |
| //returns [ sep::BFCode ac ] |
| // : 'where' e=expression bs=block_statement |
| // { $ac = NEW_STMT2(OP(WHERE), $e.bf, $bs.ac); } |
| // ( 'provided' e=expression { $ac->append($e.bf); } )? |
| // ( 'else' bs=block_statement { $ac->append($bs.ac); } |
| // )? |
| // ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT ITERATION |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_iteration |
| returns [ sep::BFCode ac ] |
| : 'for' |
| ( isa=for_assign_header SEMI e=expression SEMI sai=for_assign_header |
| { $ac = NEW_STMT3(OP(FOR), $isa.ac, $e.bf, $sai.ac); } |
| | |
| LPAREN |
| isa=for_assign_header SEMI e=expression SEMI sai=for_assign_header |
| RPAREN |
| { $ac = NEW_STMT3(OP(FOR), $isa.ac, $e.bf, $sai.ac); } |
| | |
| lv=lvalue COLON e=expression |
| { $ac = NEW_STMT2(OP(FOREACH), $lv.bf, $e.bf); } |
| | |
| LPAREN lv=lvalue COLON e=expression RPAREN |
| { $ac = NEW_STMT2(OP(FOREACH), $lv.bf, $e.bf); } |
| ) |
| sa=block_statement { $ac->append($sa.ac); } |
| |
| | 'while' e=expression bs=block_statement |
| { $ac = NEW_STMT2(OP(WHILE_DO), $e.bf, $bs.ac); } |
| |
| | 'do' bs=block_statement 'while' e=expression SEMI |
| { $ac = NEW_STMT2(OP(DO_WHILE), $bs.ac, $e.bf); } |
| ; |
| |
| |
| for_assign_header |
| returns [ sep::BFCode ac ] |
| // lvalue := expression |
| : lv=lvalue |
| ( ASSIGN e=expression |
| { $ac = NEW_STMT2(OP(ASSIGN), $lv.bf, $e.bf); } |
| |
| // ++ lvalue |
| // lvalue ++ |
| | INCR |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_ONE); } |
| |
| // lvalue -- |
| | DECR |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_MINUS_ONE); } |
| ) |
| |
| | INCR lv=lvalue |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_ONE); } |
| |
| // -- lvalue |
| | DECR lv=lvalue |
| { $ac = NEW_STMT_ASSIGN_OP(OP(PLUS), $lv.bf, |
| sep::ExpressionConstant::INTEGER_MINUS_ONE); } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT JUMP |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_jump |
| returns [ sep::BFCode ac ] |
| : 'break' { $ac = NEW_STMT(OP(BREAK)); } |
| ( e=expression { $ac->append( $e.bf ); } )? |
| SEMI |
| |
| | 'continue' { $ac = NEW_STMT(OP(CONTINUE)); } |
| ( e=expression { $ac->append( $e.bf ); } )? |
| SEMI |
| |
| | 'return' { $ac = NEW_STMT(OP(RETURN)); } |
| ( e=expression { $ac->append( $e.bf ); } |
| ( COMMA e=expression { $ac->append( $e.bf ); } )* |
| )? |
| SEMI |
| |
| | 'exit' { $ac = NEW_STMT(OP(EXIT)); } |
| ( e=expression { $ac->append( $e.bf ); } )? |
| SEMI |
| ; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT LAMBDA |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| expression_lambda |
| returns [ sep::BFCode ac ] |
| : 'lambda' { $ac = NEW_CODE( OP(LAMBDA) ); } |
| ( id=ID { $ac->append( NEW_ID(STR($id.text->chars)) ); } )* |
| '->' e=expression { $ac->append( $e.bf ); } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT STATUS |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| expression_status |
| returns [ sep::BFCode ac ] |
| : 'status#was' o=op_activity id=qualifiedNameID |
| { $ac = NEW_STMT2(OP(STATUS_WAS), INCR_BF($o.op), |
| sep::ParserUtil::getvarMachine($id.s, $id.nb)); } |
| |
| | 'status#is' o=op_activity id=qualifiedNameID |
| { $ac = NEW_STMT2(OP(STATUS_IS), INCR_BF($o.op), |
| sep::ParserUtil::getvarMachine($id.s, $id.nb)); } |
| |
| | 'status#being' o=op_activity id=qualifiedNameID |
| { $ac = NEW_STMT2(OP(STATUS_BEING), INCR_BF($o.op), |
| sep::ParserUtil::getvarMachine($id.s, $id.nb)); } |
| |
| | 'status#will' o=op_activity id=qualifiedNameID |
| { $ac = NEW_STMT2(OP(STATUS_WILL), INCR_BF($o.op), |
| sep::ParserUtil::getvarMachine($id.s, $id.nb)); } |
| |
| | 'changed' lv=lvalue |
| { $ac = NEW_STMT1(OP(CHANGED), $lv.bf); } |
| |
| | 'changed#to' lv=lvalue |
| { $ac = NEW_STMT1(OP(CHANGED_TO), $lv.bf); } |
| ; |
| |
| op_activity |
| returns [ sep::Operator * op ] |
| : 'init' { $op = OP(INIT); } |
| | 'final' { $op = OP(FINAL); } |
| | 'destroy' { $op = OP(DESTROY); } |
| | 'start' { $op = OP(START); } |
| | 'restart' { $op = OP(RESTART); } |
| | 'stop' { $op = OP(STOP); } |
| | 'ienable' { $op = OP(IENABLE_INVOKE); } |
| | 'enable' { $op = OP(ENABLE_INVOKE); } |
| | 'idisable' { $op = OP(IDISABLE_INVOKE); } |
| | 'disable' { $op = OP(DISABLE_INVOKE); } |
| | 'iabort' { $op = OP(IABORT_INVOKE); } |
| | 'abort' { $op = OP(ABORT_INVOKE); } |
| | 'run' { $op = OP(RUN); } |
| | 'rtc' { $op = OP(RTC); } |
| | 'schedule' { $op = OP(SCHEDULE_INVOKE); } |
| | 'suspend' { $op = OP(SUSPEND); } |
| | 'resume' { $op = OP(RESUME); } |
| | 'wait' { $op = OP(WAIT); } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT ACTIVITY |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_activity |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::BF flowTarget; |
| sep::BF machine; |
| } |
| : o=op_activity { $ac = NEW_STMT($o.op); } |
| ( id=qualifiedNameID |
| { $ac->append(machine = |
| sep::ParserUtil::getvarMachine($id.s, $id.nb)); } |
| )? |
| |
| activity_machine_param_return[ machine , ac ] ? |
| SEMI |
| /* |
| | 'wait' expression SEMI |
| { $ac = NEW_STMT(OP(WAIT)); } |
| */ |
| |
| | 'goto' id=qualifiedNameID |
| { $ac = NEW_STMT1(OP(GOTO), |
| flowTarget = sep::ParserUtil::getvarMachine($id.s, $id.nb)); } |
| ( fs=statement_init_flow[flowTarget] { $ac->append($fs.ac); } |
| | SEMI |
| ) |
| |
| | 'join' e=expression SEMI |
| { $ac = NEW_STMT1(OP(JOIN), $e.bf); } |
| |
| ; |
| |
| |
| statement_init_flow [ const sep::BF & flowTarget ] |
| returns [ sep::BFCode ac ] |
| @init{ |
| if( flowTarget.is< sep::Machine >() ) |
| { |
| PUSH_CTX_CPM( flowTarget.to_ptr< sep::Machine >() ); |
| } |
| } |
| @after{ |
| if( flowTarget.is< sep::Machine >() ) |
| { |
| POP_CTX; |
| } |
| } |
| : 'flow' bs=block_statement { $ac = $bs.ac; } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT ROUTINE INVOKATION |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_invoke_routine |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::Routine * invokeRoutine = NULL; |
| } |
| : id=ID |
| { |
| invokeRoutine = sep::Routine::newInvoke( _CPRMS_, STR($id.text->chars)); |
| |
| invokeRoutine->setModel( |
| sep::ParserUtil::getvarRoutine(STR($id.text->chars)) ); |
| } |
| |
| invoke_routine_params[ invokeRoutine ] |
| ( invoke_routine_returns[ invokeRoutine ] )? |
| SEMI |
| |
| { $ac = sep::ParserUtil::invokeRoutineStatement(invokeRoutine); } |
| ; |
| |
| |
| invoke_routine_params [ sep::Routine * invokeRoutine ] |
| : LPAREN |
| ( lp=labelled_argument |
| { |
| invokeRoutine->appendParameter($lp.label, $lp.arg); |
| } |
| ( COMMA |
| lp=labelled_argument |
| { |
| invokeRoutine->appendParameter($lp.label, $lp.arg); |
| } |
| )* |
| )? |
| RPAREN |
| ; |
| |
| |
| invoke_routine_returns [ sep::Routine * invokeRoutine ] |
| : ( '-->' | 'returns:' ) |
| ( LPAREN |
| lp=labelled_argument |
| { |
| invokeRoutine->appendReturn($lp.label, $lp.arg); |
| } |
| ( COMMA |
| lp=labelled_argument |
| { |
| invokeRoutine->appendReturn($lp.label, $lp.arg); |
| } |
| )* |
| RPAREN |
| |
| | lp=labelled_argument |
| { |
| invokeRoutine->appendReturn($lp.label, $lp.arg); |
| } |
| ) |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT LEM |
| //////////////////////////////////////////////////////////////////////////////// |
| /* |
| statement_lem |
| returns [ sep::BFCode ac ] |
| : 'when' { $ac = NEW_STMT(OP(LEM_WHEN)); } |
| ( e=expression { $ac->append($e.bf); } )? |
| bs=block_statement { $ac->append($bs.ac); } |
| ( e=expression { $ac->append($e.bf); } )? |
| SEMI |
| |
| | 'in' id=qualifiedNameID |
| { $ac = NEW_STMT1(OP(LEM_INPUT), |
| sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| ( 'provided' e=expression { $ac->append($e.bf); } )? |
| SEMI |
| |
| | id=qualifiedNameID LEM_TRANSFERT id2=qualifiedNameID SEMI |
| { $ac = NEW_STMT2(OP(LEM_OUTPUT), |
| sep::ParserUtil::getvarPortSignal($id.s, $id.nb), |
| sep::ParserUtil::getvarPortSignal($id2.s, $id2.nb)); } |
| ; |
| |
| expression_lem |
| returns [ sep::BFCode ac ] |
| : 'touch' id=qualifiedNameID |
| { $ac = NEW_STMT1(OP(LEM_TOUCH), |
| sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| |
| | 'in' id=qualifiedNameID |
| { $ac = NEW_STMT1(OP(LEM_INPUT), |
| sep::ParserUtil::getvarPortSignal($id.s, $id.nb)); } |
| ( 'provided' e=expression { $ac->append($e.bf); } )? |
| ; |
| */ |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // STATEMENT MOC |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| statement_moc |
| returns [ sep::BFCode ac ] |
| : 'step_mark' StringLiteral SEMI |
| { |
| $ac = NEW_STMT1(OP(STEP_MARK), |
| NEW_STRING(STR($StringLiteral.text->chars))); |
| } |
| ; |
| |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| // EXPRESSION |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| expression |
| returns [ sep::BF bf ] |
| : e=conditionalExpression { $bf = $e.bf; } |
| |
| ( ASSIGN e=expression |
| { $bf = NEW_CODE2(OP(ASSIGN), $bf, $e.bf); } |
| |
| | ASSIGN_MACRO e=expression |
| { $bf = NEW_CODE2(OP(ASSIGN_MACRO), $bf, $e.bf); } |
| |
| | ASSIGN_AFTER e=expression |
| { $bf = NEW_CODE2(OP(ASSIGN_AFTER), $bf, $e.bf); } |
| |
| | PLUS_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(PLUS), $bf, $e.bf); } |
| |
| | PLUS_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(PLUS), $bf, $e.bf); } |
| |
| | MINUS_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(MINUS), $bf, $e.bf); } |
| |
| | MINUS_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(MINUS), $bf, $e.bf); } |
| |
| | STAR_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(MULT), $bf, $e.bf); } |
| |
| | STAR_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(MULT), $bf, $e.bf); } |
| |
| | DIV_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(DIV), $bf, $e.bf); } |
| |
| | DIV_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(DIV), $bf, $e.bf); } |
| |
| | MOD_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(MOD), $bf, $e.bf); } |
| |
| | MOD_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(MOD), $bf, $e.bf); } |
| |
| | LAND_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(AND), $bf, $e.bf); } |
| |
| | LAND_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(AND), $bf, $e.bf); } |
| |
| | LOR_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(OR), $bf, $e.bf); } |
| |
| | LOR_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(OR), $bf, $e.bf); } |
| |
| | BAND_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(BAND), $bf, $e.bf); } |
| |
| | BAND_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(BAND), $bf, $e.bf); } |
| |
| | BOR_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(BOR), $bf, $e.bf); } |
| |
| | BOR_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(BOR), $bf, $e.bf); } |
| |
| | BXOR_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(BXOR), $bf, $e.bf); } |
| |
| | BXOR_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(BXOR), $bf, $e.bf); } |
| |
| | LSHIFT_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(LSHIFT), $bf, $e.bf); } |
| |
| | LSHIFT_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(LSHIFT), $bf, $e.bf); } |
| |
| | RSHIFT_ASSIGN e=expression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(RSHIFT), $bf, $e.bf); } |
| |
| | RSHIFT_ASSIGN_AFTER e=expression |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(RSHIFT), $bf, $e.bf); } |
| |
| | OP_PUSH e=expression |
| { $bf = NEW_CODE2(OP(PUSH), $bf, $e.bf); } |
| |
| | OP_ASSIGN_TOP e=expression |
| { $bf = NEW_CODE2(OP(ASSIGN_TOP), $bf, $e.bf); } |
| |
| | OP_POP e=expression |
| { $bf = NEW_CODE2(OP(POP), $bf, $e.bf); } |
| |
| // | LEM_TRANSFERT e=expression |
| // { $bf = NEW_CODE2(OP(LEM_OUTPUT), $bf, $e.bf); } |
| )? |
| ; |
| |
| |
| conditionalExpression |
| returns [ sep::BF bf ] |
| : e=scheduleExpression { $bf = $e.bf; } |
| ( QUESTION th=expression COLON el=expression |
| { $bf = NEW_CODE3(OP(IFE), $bf, $th.bf, $el.bf); } |
| )? |
| ; |
| |
| scheduleExpression |
| returns [ sep::BF bf ] |
| : e=conditionalOrExpression { $bf = $e.bf; } |
| ( ( op=op_sequence | op=op_scheduling | op=op_concurrency ) |
| e=conditionalOrExpression { $bf = NEW_CODE_FLAT(op, $bf, $e.bf); } |
| )* |
| ; |
| |
| conditionalOrExpression |
| returns [ sep::BF bf ] |
| : e=conditionalAndExpression { $bf = $e.bf; } |
| ( LOR e=conditionalAndExpression |
| { $bf = NEW_CODE_FLAT(OP(OR), $bf, $e.bf); } |
| )* |
| ; |
| |
| conditionalAndExpression |
| returns [ sep::BF bf ] |
| : e=bitwiseOrExpression { $bf = $e.bf; } |
| ( LAND e=bitwiseOrExpression |
| { $bf = NEW_CODE_FLAT(OP(AND), $bf, $e.bf); } |
| )* |
| ; |
| |
| bitwiseOrExpression |
| returns [ sep::BF bf ] |
| : e=bitwiseXorExpression { $bf = $e.bf; } |
| ( BOR e=bitwiseXorExpression |
| { $bf = NEW_CODE_FLAT(OP(BOR), $bf, $e.bf); } |
| )* |
| ; |
| |
| bitwiseXorExpression |
| returns [ sep::BF bf ] |
| : e=bitwiseAndExpression { $bf = $e.bf; } |
| ( BXOR e=bitwiseAndExpression |
| { $bf = NEW_CODE_FLAT(OP(BXOR), $bf, $e.bf); } |
| )* |
| ; |
| |
| bitwiseAndExpression |
| returns [ sep::BF bf ] |
| : e=equalityExpression { $bf = $e.bf; } |
| ( BAND e=equalityExpression |
| { $bf = NEW_CODE_FLAT(OP(BAND), $bf, $e.bf); } |
| )* |
| ; |
| |
| equalityExpression |
| returns [ sep::BF bf ] |
| @init{ |
| sep::BFCode eqExpr; |
| sep::BF rhs; |
| } |
| : e=relationalExpression { $bf = $e.bf; } |
| ( op=equalOp e=relationalExpression |
| { eqExpr = NEW_CODE2(op, $bf, $e.bf); } |
| ( op=equalOp e=relationalExpression |
| { |
| /*if( eqExpr.getOperator() == op ) |
| { |
| eqExpr.append( $e.bf ); |
| } |
| else*/ if( eqExpr.getOperator() == OP(AND) ) |
| { |
| eqExpr.append( NEW_CODE2(op, rhs, $e.bf) ); |
| } |
| else |
| { |
| eqExpr = NEW_CODE2(OP(AND), eqExpr, NEW_CODE2(op, rhs, $e.bf)); |
| } |
| |
| rhs = $e.bf; |
| } |
| )* |
| { $bf = eqExpr; } |
| )? |
| ; |
| |
| equalOp |
| returns [ sep::Operator * op ] |
| : EQUAL { op = OP(EQ); } |
| | NEQUAL { op = OP(NEQ); } |
| | SEQUAL { op = OP(SEQ); } |
| | NSEQUAL { op = OP(NSEQ); } |
| ; |
| |
| |
| relationalExpression |
| returns [ sep::BF bf ] |
| @init{ |
| sep::BFCode relExpr; |
| sep::BF rhs; |
| } |
| : e=shiftExpression { $bf = $e.bf; } |
| ( op=relationalOp e=shiftExpression |
| { relExpr = NEW_CODE2(op, $bf, rhs = $e.bf); } |
| ( op=relationalOp e=shiftExpression |
| { |
| /*if( relExpr.getOperator() == op ) |
| { |
| relExpr.append( $e.bf ); |
| } |
| else*/ if( relExpr.getOperator() == OP(AND) ) |
| { |
| relExpr.append( NEW_CODE2(op, rhs, $e.bf) ); |
| } |
| else |
| { |
| relExpr = NEW_CODE2(OP(AND), relExpr, NEW_CODE2(op, rhs, $e.bf)); |
| } |
| |
| rhs = $e.bf; |
| } |
| )* |
| { $bf = relExpr; } |
| )? |
| ; |
| |
| relationalOp |
| returns [ sep::Operator * op ] |
| : LTE { $op = OP(LTE); } |
| | GTE { $op = OP(GTE); } |
| | LT_ { $op = OP(LT); } |
| | GT { $op = OP(GT); } |
| |
| | 'in' { $op = OP(IN); } |
| // | 'notin' { $op = OP(NOTIN); } |
| // | 'contains' { $op = OP(CONTAINS); } |
| // |
| // | 'subset' { $op = OP(SUBSET); } |
| // |
| // | 'starts_with' { $op = OP(STARTS_WITH); } |
| // | 'ends_with' { $op = OP(ENDS_WITH); } |
| ; |
| |
| shiftExpression |
| returns [ sep::BF bf ] |
| : e=additiveExpression { $bf = $e.bf; } |
| ( op=shiftOp e=additiveExpression |
| { $bf = NEW_CODE2(op, $bf, $e.bf); } |
| )* |
| ; |
| |
| |
| shiftOp |
| returns [ sep::Operator * op ] |
| : LSHIFT { $op = OP(LSHIFT); } |
| | RSHIFT { $op = OP(RSHIFT); } |
| ; |
| |
| |
| additiveExpression |
| returns [ sep::BF bf ] |
| @init{ |
| sep::Operator * op = NULL; |
| } |
| : e=multiplicativeExpression { $bf = $e.bf; } |
| ( ( PLUS { op = OP(PLUS); } |
| | MINUS { op = OP(MINUS); } |
| ) |
| e=multiplicativeExpression |
| { $bf = NEW_CODE_FLAT(op, $bf, $e.bf); } |
| )* |
| ; |
| |
| multiplicativeExpression |
| returns [ sep::BF bf ] |
| @init{ |
| sep::Operator * op = NULL; |
| } |
| : e=unaryExpression { $bf = $e.bf; } |
| ( ( STAR { op = OP(MULT); } |
| | DIV { op = OP(DIV); } |
| | MOD { op = OP(MOD); } |
| ) |
| e=unaryExpression |
| { $bf = NEW_CODE_FLAT(op, $bf, $e.bf); } |
| )* |
| ; |
| |
| /** |
| * NOTE: for '+' and '-', if the next token is int or long interal, then it's not a unary expression. |
| * it's a literal with signed value. INTLTERAL AND LONG LITERAL are added here for this. |
| */ |
| unaryExpression |
| returns [ sep::BF bf ] |
| : PLUS e=unaryExpression |
| { $bf = $e.bf; } |
| |
| | MINUS e=unaryExpression |
| { $bf = new_uminus_expr($e.bf); } |
| |
| | INCR e=unaryExpression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(PLUS), |
| $e.bf, sep::ExpressionConstant::INTEGER_ONE); } |
| | DECR e=unaryExpression |
| { $bf = NEW_STMT_ASSIGN_OP(OP(PLUS), $e.bf, |
| sep::ExpressionConstant::INTEGER_MINUS_ONE); } |
| |
| | LNOT e=unaryExpression |
| { $bf = new_not_expr($e.bf); } |
| |
| | BNOT e=unaryExpression |
| { $bf = NEW_CODE1(OP(BNOT), $e.bf); } |
| |
| | OP_POP e=unaryExpression |
| { $bf = NEW_CODE1(OP(POP), $e.bf); } |
| |
| | OP_TOP e=unaryExpression |
| { $bf = NEW_CODE1(OP(TOP), $e.bf); } |
| |
| // | 'newfresh' e=unaryExpression |
| // { $bf = NEW_CODE1(OP(ASSIGN_NEWFRESH), $e.bf); } |
| |
| |
| | c=prefix_expression { $bf = $c.ac; } |
| |
| | c=expression_invoke { $bf = $c.ac; } |
| |
| | c=expression_activity_new { $bf = $c.ac; } |
| |
| // | c=expression_buffer { $bf = $c.ac; } |
| | c=expression_com { $bf = $c.ac; } |
| | c=expression_guard { $bf = $c.ac; } |
| | c=expression_ite { $bf = $c.ac; } |
| | c=expression_lambda { $bf = $c.ac; } |
| // | c=expression_status { $bf = $c.ac; } |
| // | c=expression_time { $bf = $c.ac; } |
| |
| // | c=expression_lem { $bf = $c.ac; } |
| |
| | e=ctorExpression { $bf = $e.bf; } |
| |
| | e=primary { $bf = $e.bf; } |
| ( INCR |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(PLUS), $e.bf, |
| sep::ExpressionConstant::INTEGER_ONE); } |
| | DECR |
| { $bf = NEW_STMT_ASSIGN_OP_AFTER(OP(PLUS), $e.bf, |
| sep::ExpressionConstant::INTEGER_MINUS_ONE); } |
| )? |
| |
| | l=literal { $bf = $l.bf; } |
| |
| | q=quote_expression { $bf = $q.ac; } |
| |
| | q=meta_eval_expression { $bf = $q.ac; } |
| |
| | LPAREN e=expression RPAREN { $bf = $e.bf; } |
| |
| | e=collection_of_expression { $bf = $e.bf; } |
| ; |
| |
| |
| ctorExpression |
| returns [ sep::BFCode ctor ] |
| : 'ctor' LT_ tv=type_var GT LPAREN e=expression RPAREN |
| { $ctor = NEW_CODE2(OP(CTOR), $tv.type, $e.bf); } |
| ; |
| |
| |
| /* |
| quote_expression |
| returns [ sep::BFCode ac ] |
| @init{ |
| sep::Operator * op = OP(SEQUENCE); |
| } |
| : PERCENT_LCURLY ( o=op_block { op = $o.op; } ) ? { $ac = NEW_STMT(op); } |
| ( s=statement { $ac->append($s.ac); } )* |
| ( e=expression { $ac->append($e.bf); } ) |
| RCURLY_PERCENT |
| { $ac = NEW_STMT1(OP(QUOTE), $ac); } |
| ; |
| */ |
| |
| |
| quote_expression |
| returns [ sep::BFCode ac ] |
| : PERCENT_LCURLY e=expression RCURLY_PERCENT |
| { $ac = NEW_STMT1(OP(QUOTE), $e.bf); } |
| ; |
| |
| meta_eval_expression |
| returns [ sep::BFCode ac ] |
| : LBRACKET_BAR e=expression BAR_RBRACKET |
| { $ac = NEW_STMT1(OP(META_EVAL), $e.bf); } |
| ; |
| |
| |
| |
| /** |
| * have to use scope here, parameter passing isn't well supported in antlr. |
| * |
| primary |
| returns [ sep::BF bf ] |
| @init{ |
| sep::UniFormIdentifier * ufi; |
| sep::BF bfUfi;// for automatic destruction of << UFI >> if need |
| |
| sep::avm_size_t countID = 1; |
| bool isnotEXPR = true; |
| bool hasntPARAM = true; |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| : //( ( id=ID { ufi->setLocator(STR($id.text->chars)); } )? |
| // COLONx2 { ufi->setAbsolute(); } )? |
| id=ID |
| { |
| ufi = new sep::UniFormIdentifier(false); |
| bfUfi = ufi; |
| |
| if( ($bf = sep::ParserUtil::getObjectByNameID(STR($id.text->chars))).valid() ) |
| { |
| ufi->appendField($bf); |
| } |
| else |
| { |
| ufi->appendField(STR($id.text->chars)); |
| } |
| |
| $bf = bfUfi; |
| } |
| |
| ( ( DOT id=ID |
| { ufi->appendField(STR($id.text->chars)); ++countID; } ) |
| |
| | ( LBRACKET e=expression RBRACKET |
| { ufi->appendIndex($e.bf); isnotEXPR = false; } |
| ) |
| |
| | LPAREN { ufi->last().addScheme(sep::UFI_SCHEME_INVOKABLE); } |
| ( e=expression { ufi->appendFieldParameter($e.bf); hasntPARAM = false; } |
| ( COMMA |
| e=expression { ufi->appendFieldParameter($e.bf); hasntPARAM = false; } |
| )* |
| )? |
| RPAREN |
| )* |
| { |
| if( countID == 1 ) |
| { |
| $bf = ufi->first(); |
| } |
| else if( isnotEXPR && hasntPARAM ) |
| { |
| if( ($bf = sep::ParserUtil::getvar( |
| ufi->str(), countID)).invalid() ) |
| { |
| $bf = bfUfi; |
| SET_RULE_LOCATION(ufi); |
| } |
| } |
| else if( ufi->singleton() ) |
| { |
| $bf = ufi->first(); |
| } |
| } |
| ; |
| */ |
| |
| |
| primary |
| returns [ sep::BF bf ] |
| : id=ID |
| ( ( LPAREN ) => p=primary_invoke[ STR($id.text->chars) ] |
| { $bf = $p.bf; } |
| |
| | ( DOT | LBRACKET ) => p=primary_ufid[ STR($id.text->chars) ] |
| { $bf = $p.bf; } |
| | ( COLONx2 ) => p=primary_ufi[ STR($id.text->chars) ] |
| { $bf = $p.bf; } |
| )? |
| { |
| if( $bf.invalid() ) |
| { |
| if( ($bf = sep::ParserUtil::getObjectByNameID( |
| STR($id.text->chars))).invalid() ) |
| { |
| $bf = NEW_ID( STR($id.text->chars)); |
| } |
| } |
| } |
| |
| | p=primary_ufi[ "" ] { $bf = $p.bf; } |
| ; |
| |
| |
| primary_ufid [ const std::string & mainId ] |
| returns [ sep::BF bf ] |
| @init{ |
| sep::UniFormIdentifier * ufi = new sep::UniFormIdentifier(false); |
| sep::BF bfUfi( ufi );// for automatic destruction of << UFI >> if need |
| |
| if( ($bf = sep::ParserUtil::getObjectByNameID(mainId)).valid() ) |
| { |
| ufi->appendField( $bf ); |
| } |
| else |
| { |
| ufi->appendField( mainId ); |
| } |
| |
| $bf = bfUfi; |
| |
| sep::avm_size_t countID = 1; |
| bool isnotEXPR = true; |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| : ( ( DOT id=ID |
| { ufi->appendField( STR($id.text->chars) ); ++countID; } ) |
| |
| | ( LBRACKET e=expression RBRACKET |
| { ufi->appendIndex( $e.bf ); isnotEXPR = false; } |
| ) |
| )+ |
| { |
| if( isnotEXPR ) |
| { |
| if( ($bf = sep::ParserUtil::getvar(ufi->str(), countID)).invalid() ) |
| { |
| $bf = bfUfi; |
| SET_RULE_LOCATION( ufi ); |
| } |
| } |
| } |
| ; |
| |
| |
| |
| primary_ufi [ const std::string & locatorId ] |
| returns [ sep::BF bf ] |
| @init{ |
| sep::UniFormIdentifier * ufi = |
| new sep::UniFormIdentifier(not locatorId.empty()); |
| sep::BF bfUfi( ufi );// for automatic destruction of << UFI >> if need |
| |
| if( not locatorId.empty() ) |
| { |
| ufi->setLocator( locatorId ); |
| } |
| |
| $bf = bfUfi; |
| |
| sep::avm_size_t countID = 1; |
| bool isnotEXPR = true; |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| : COLONx2 id=ID |
| { |
| if( ($bf = sep::ParserUtil::getObjectByNameID(STR($id.text->chars))).valid() ) |
| { |
| ufi->appendField( $bf ); |
| } |
| else |
| { |
| ufi->appendField( STR($id.text->chars) ); |
| } |
| } |
| |
| ( ( DOT id=ID |
| { ufi->appendField( STR($id.text->chars) ); ++countID; } ) |
| |
| | ( LBRACKET e=expression RBRACKET |
| { ufi->appendIndex( $e.bf ); isnotEXPR = false; } |
| ) |
| )+ |
| { |
| if( isnotEXPR ) |
| { |
| if( ($bf = sep::ParserUtil::getvar(ufi->str(), countID)).invalid() ) |
| { |
| $bf = bfUfi; |
| SET_RULE_LOCATION( ufi ); |
| } |
| } |
| } |
| ; |
| |
| |
| primary_invoke [ const std::string & mainId ] |
| returns [ sep::BF bf ] |
| @init{ |
| sep::Routine * invokeRoutine = sep::Routine::newInvoke( _CPRMS_, mainId); |
| |
| invokeRoutine->setModel( sep::ParserUtil::getvarRoutine(mainId) ); |
| |
| SAVE_RULE_BEGIN_LOCATION; |
| } |
| @after |
| { |
| SET_RULE_LOCATION( invokeRoutine ); |
| } |
| : LPAREN |
| ( lp=labelled_argument |
| { |
| invokeRoutine->appendParameter($lp.label, $lp.arg); |
| } |
| ( COMMA |
| lp=labelled_argument |
| { |
| invokeRoutine->appendParameter($lp.label, $lp.arg); |
| } |
| )* |
| )? |
| RPAREN |
| |
| { $bf = sep::ParserUtil::invokeRoutineExpression(invokeRoutine); } |
| ; |
| |
| |
| literal |
| returns [ sep::BF bf ] |
| : IntegerLiteral { $bf = NEW_INTEGER(STR($IntegerLiteral.text->chars)); } |
| | RationalLiteral { $bf = NEW_RATIONAL(STR($RationalLiteral.text->chars)); } |
| | FloatLiteral { $bf = NEW_FLOAT(STR($FloatLiteral.text->chars)); } |
| |
| | CharLiteral { $bf = NEW_CHAR(STR($CharLiteral.text->chars)); } |
| | StringLiteral { $bf = NEW_STRING(STR($StringLiteral.text->chars)); } |
| |
| | 'true' { $bf = NEW_BOOL(true); } |
| | 'false' { $bf = NEW_BOOL(false); } |
| |
| | 'self' { $bf = sep::ExecutableLib::MACHINE_SELF; } |
| | 'parent' { $bf = sep::ExecutableLib::MACHINE_PARENT; } |
| | 'env' { $bf = sep::ExecutableLib::MACHINE_ENVIRONMENT; } |
| |
| | '$this' { $bf = sep::ExecutableLib::MACHINE_SELF; } |
| | '$self' { $bf = sep::ExecutableLib::MACHINE_SELF; } |
| | '$parent' { $bf = sep::ExecutableLib::MACHINE_PARENT; } |
| | '$super' { $bf = sep::ExecutableLib::MACHINE_PARENT; } |
| | '$env' { $bf = sep::ExecutableLib::MACHINE_ENVIRONMENT; } |
| |
| | 'null<' |
| ( 'machine' { $bf = sep::ExecutableLib::MACHINE_NULL; } |
| | 'channel' { $bf = sep::ExecutableLib::CHANNEL_NIL; } |
| | 'port' { $bf = sep::ExecutableLib::PORT_NIL; } |
| | 'signal' { $bf = sep::ExecutableLib::PORT_NIL; } |
| | 'message' { $bf = sep::ExecutableLib::PORT_NIL; } |
| | 'buffer' { $bf = sep::ExecutableLib::BUFFER_NIL; } |
| ) GT |
| | 'null' { $bf = sep::BF::REF_NULL; } |
| ; |
| |
| |
| |
| collection_of_expression |
| returns [ sep::BF bf ] |
| @init{ |
| sep::BFVector values; |
| } |
| : LCURLY |
| e=expression { values.append($e.bf); } |
| ( COMMA e=expression { values.append($e.bf); } )* |
| RCURLY |
| { $bf = sep::BuiltinArray::create(values); } |
| |
| | LBRACKET |
| e=expression { values.append($e.bf); } |
| ( COMMA e=expression { values.append($e.bf); } )* |
| RBRACKET |
| { $bf = sep::BuiltinArray::create(values); } |
| ; |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| ///// KEYWORD XLIA or XFSP |
| //////////////////////////////////////////////////////////////////////////////// |
| /* |
| kw_start : { IS_KEYWORD( "start" ) }? ID; |
| |
| kw_in : { IS_KEYWORD( "in" ) }? ID; |
| |
| kw_input : { IS_KEYWORD( "input" ) }? ID; |
| kw_output : { IS_KEYWORD( "output" ) }? ID; |
| |
| kw_wait : { IS_KEYWORD( "wait" ) }? ID; |
| */ |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| // LEXER |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| |
| OP_ATOMIC_SEQUENCE : '|§|' ; |
| |
| OP_SEQUENCE : '|;|' ; |
| OP_SEQUENCE_SIDE : '|.|' | '|/;|' ; |
| OP_SEQUENCE_WEAK : '|;;|' ; |
| |
| OP_SCHEDULE_GT : '|>|' ; |
| OP_SCHEDULE_LT : '|<|' ; |
| OP_SCHEDULE_XOR : '|xor|' ; |
| |
| OP_SCHEDULE_AND_THEN : '|and#then|' ; |
| OP_SCHEDULE_OR_ELSE : '|or#else|' ; |
| |
| |
| OP_NON_DETERMINISM : '|/\|' | '|indet|' ; |
| |
| OP_CONCURRENCY_ASYNC : '|a|' ; |
| OP_CONCURRENCY_AND : '|and|' ; |
| OP_CONCURRENCY_OR : '|or|' ; |
| OP_CONCURRENCY_INTERLEAVING : '|i|' ; |
| OP_CONCURRENCY_PARALLEL : '|,|' ; |
| |
| OP_FORK : '|fork|' ; |
| OP_JOIN : '|join|' ; |
| |
| |
| OP_CONCURRENCY_RDV_ASYNC : '||a||' ; |
| OP_CONCURRENCY_RDV_AND : '||and||' ; |
| OP_CONCURRENCY_RDV_OR : '||or||' ; |
| OP_CONCURRENCY_RDV_INTERLEAVING : '||i||' ; |
| OP_CONCURRENCY_RDV_PARALLEL : '||,||' ; |
| |
| //LEM_TRANSFERT : '->' ; |
| |
| ASSIGN : '=' | ':=' ; |
| ASSIGN_AFTER : '=:' ; |
| ASSIGN_REF : '<-' ; |
| ASSIGN_MACRO : '::=' ; |
| |
| OP_PUSH : '<=<' ; |
| OP_ASSIGN_TOP : '^=<' ; |
| OP_TOP : '^=>' ; |
| OP_POP : '>=>' ; |
| |
| LPAREN : '(' ; |
| RPAREN : ')' ; |
| LCURLY : '{' ; |
| RCURLY : '}' ; |
| LBRACKET : '[' ; |
| RBRACKET : ']' ; |
| |
| LBRACKET_EXCEPT : '[^' ; |
| |
| LPAREN_INVOKE : '(:' ; |
| LCURLY_INVOKE : '{:' ; |
| |
| PERCENT_LPAREN_INVOKE : '%(:' ; |
| |
| PERCENT_LPAREN : '%(' ; |
| RPAREN_PERCENT : ')%' ; |
| |
| |
| STATEMENT_PROMPT: ':>' ; |
| |
| DOLLAR_LCURLY : '${' ; |
| RCURLY_DOLLAR : '}$' ; |
| |
| PERCENT_LCURLY : '%{' ; |
| RCURLY_PERCENT : '}%' ; |
| |
| LBRACKET_BAR : '[|' ; |
| BAR_RBRACKET : '|]' ; |
| |
| LBRACKET_LCURLY : '[{' ; |
| RCURLY_RBRACKET : '}]' ; |
| |
| COLON : ':' ; |
| COMMA : ',' ; |
| QUESTION : '?' ; |
| SEMI : ';' ; |
| |
| DIESE : '#' ; |
| DOLLAR : '$' ; |
| |
| DOT : '.' ; |
| DOTDOT : '..' ; |
| COLONx2 : '::' ; |
| |
| |
| LAND : '&&' | 'and' ; |
| LAND_THEN : 'and#then' ; |
| LAND_ASSIGN : '&&=' | '&&:='; |
| LAND_ASSIGN_AFTER : '&&=:'; |
| |
| LNOT : '!' | 'not' ; |
| |
| LOR : '||' | 'or' ; |
| LOR_ELSE : 'or#else' ; |
| LOR_ASSIGN : '||=' | '||:='; |
| LOR_ASSIGN_AFTER : '||=:'; |
| LXOR : 'xor' ; |
| |
| EQUAL : '==' ; |
| NEQUAL : '!=' ; |
| |
| SEQUAL : '===' ; |
| NSEQUAL : '=!=' | '=/=' ; |
| |
| LTE : '<=' ; |
| LT_ : '<' ; |
| GTE : '>=' ; |
| GT : '>' ; |
| |
| |
| PLUS : '+' ; |
| PLUS_ASSIGN : '+=' | '+:=' ; |
| PLUS_ASSIGN_AFTER : '+=:' ; |
| INCR : '++' ; |
| |
| MINUS : '-' ; |
| MINUS_ASSIGN : '-=' | '-:=' ; |
| MINUS_ASSIGN_AFTER : '-=:' ; |
| DECR : '--' ; |
| |
| STAR : '*' ; |
| STAR_ASSIGN : '*=' | '*:=' ; |
| STAR_ASSIGN_AFTER : '*=:' ; |
| DIV : '/' ; |
| DIV_ASSIGN : '/=' | '/:=' ; |
| DIV_ASSIGN_AFTER : '/=:' ; |
| MOD : '%' ; |
| MOD_ASSIGN : '%=' | '%:=' ; |
| MOD_ASSIGN_AFTER : '%=:' ; |
| |
| //POW : "**" ; |
| |
| RSHIFT : '>>' ; |
| RSHIFT_ASSIGN : '>>=' | '>>:='; |
| RSHIFT_ASSIGN_AFTER : '>>=:'; |
| LSHIFT : '<<' ; |
| LSHIFT_ASSIGN : '<<=' | '<<:='; |
| LSHIFT_ASSIGN_AFTER : '<<=:'; |
| |
| BAND : '&' ; |
| BAND_ASSIGN : '&=' | '&:=' ; |
| BAND_ASSIGN_AFTER : '&=:' ; |
| BNOT : '~' ; |
| BOR : '|' ; |
| BOR_ASSIGN : '|=' | '|:=' ; |
| BOR_ASSIGN_AFTER : '|=:' ; |
| BXOR : '^' ; |
| BXOR_ASSIGN : '^=' | '^:=' ; |
| BXOR_ASSIGN_AFTER : '^=:' ; |
| |
| |
| |
| ID |
| : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'#')* |
| ; |
| |
| |
| AT_ID |
| @init{ |
| ANTLR3_MARKER theStart = $start; |
| //sep::AVM_OS_DEBUG << "AT_ID:> start = " << theStart; |
| } |
| : '@' |
| { |
| theStart = GETCHARINDEX(); |
| //sep::AVM_OS_DEBUG << " GETCHARINDEX() = " << theStart << std::endl; |
| } |
| ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'#'|'$')* |
| { $start = theStart; EMIT(); } |
| ; |
| |
| |
| StringLiteral |
| @init{ |
| ANTLR3_MARKER theStart = $start; |
| } |
| : '"' |
| { theStart = GETCHARINDEX(); } |
| ( ESC_SEQ | ~('\\'|'"') )* |
| { $start = theStart; EMIT(); } |
| '"' |
| ; |
| |
| CharLiteral |
| @init{ |
| ANTLR3_MARKER theStart = $start; |
| } |
| : '\'' |
| { theStart = GETCHARINDEX(); } |
| ( ESC_SEQ | ~('\''|'\\') ) |
| { $start = theStart; EMIT(); } |
| '\'' |
| ; |
| |
| |
| NumberLiteral |
| : ( IntegerLiteral DOTDOT ) => IntegerLiteral { $type=IntegerLiteral; } |
| // | ( RationalLiteral ) => RationalLiteral { $type=RationalLiteral; } |
| | ( FloatLiteral ) => FloatLiteral { $type=FloatLiteral; } |
| | IntegerLiteral { $type=IntegerLiteral; } |
| ; |
| |
| // fragments |
| fragment FloatLiteral : Float ImaginarySuffix?; |
| |
| fragment RationalLiteral : IntegerLiteral DIV Integer; |
| |
| fragment IntegerLiteral : Integer IntSuffix?; |
| |
| fragment FloatTypeSuffix : 'f' | 'F' | 'L'; |
| fragment ImaginarySuffix : 'i'; |
| fragment IntSuffix : 'L'|'u'|'U'|'Lu'|'LU'|'uL'|'UL' ; |
| |
| fragment Integer : Decimal | Binary | Octal | Hexadecimal ; |
| fragment Decimal : '0' | '1'..'9' (DecimalDigit | '_')* ; |
| |
| fragment Binary : ('0b' | '0B') ('0' | '1' | '_')+ ; |
| fragment Octal : '0' (OctalDigit | '_')+ ; |
| fragment Hexadecimal : ('0x' | '0X') (HexDigit | '_')+; |
| |
| fragment DecimalDigit : '0'..'9' ; |
| fragment OctalDigit : '0'..'7' ; |
| fragment HexDigit : ('0'..'9'|'a'..'f'|'A'..'F') ; |
| |
| fragment DecimalExponent : 'e' | 'E' | 'e+' | 'E+' | 'e-' | 'E-' DecimalDigits; |
| fragment DecimalDigits : ( '0'..'9' | '_')+ ; |
| |
| fragment |
| Float |
| : d=DecimalDigits |
| ( options {greedy = true; } : FloatTypeSuffix |
| | '.' DecimalDigits DecimalExponent? |
| ) |
| | '.' DecimalDigits DecimalExponent? |
| ; |
| |
| |
| |
| fragment |
| EXPONENT |
| : ('e'|'E') ('+'|'-')? ('0'..'9')+ |
| ; |
| |
| fragment |
| HEX_DIGIT |
| : ('0'..'9' | 'a'..'f' | 'A'..'F') |
| ; |
| |
| fragment |
| ESC_SEQ |
| : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') |
| | UNICODE_ESC |
| | OCTAL_ESC |
| ; |
| |
| fragment |
| OCTAL_ESC |
| : '\\' ('0'..'3') ('0'..'7') ('0'..'7') |
| | '\\' ('0'..'7') ('0'..'7') |
| | '\\' ('0'..'7') |
| ; |
| |
| fragment |
| UNICODE_ESC |
| : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT |
| ; |
| |
| |
| COMMENT |
| : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} |
| | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} |
| ; |
| |
| WS |
| : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;} |
| ; |
| |
| |