/******************************************************* * * DESCRIPTION: Modelica parser classes * * AUTHOR: Mariana C. D'Abreu * * EMAIL: mdabreu@dc.uba.ar * ********************************************************/ #include #include "modparser.h" #include "modsynnode.h" #include "modgram.h" #include "modexcept.h" #include "bgmapper.h" #include "cdppcompiler.h" ModSyntaxNode *mod_parse(); extern ModSyntaxNode *rootNode; /************************************* * * Class ModelicaParser * *************************************/ /******************************************************************* * Function: *******************************************************************/ ModelicaParser &ModelicaParser::executeAndModify( ModSyntaxNode *node, ECircuit & circuit ) { ModSyntaxNodeList::NodesList::iterator it; assert( node ); switch( node->getType() ) { case ClassDefinitionNode: circuit.setId( ( (ClassDefinition*)node )->getClassId() ); return executeAndModify( ((ClassDefinition *)node)->getComposition(), circuit ); case DeclarationNode: node->evaluate(); node->semanticalValidation(); VarSymbol *var; var = ((Declaration *)node)->getVar(); EComp *ecomp; ecomp = ECompFactory::createInstance( var->getId(), var->getVarType()->getIdWithNoPackage(), var->getParamsDict() ); circuit.addComponent( ecomp ); break; case ConnectNode: node->evaluate(); node->semanticalValidation(); ReferenceSymbol *ref1, *ref2; ref1 = ((Connect *)node)->getReference1(); ref2 = ((Connect *)node)->getReference2(); circuit.connect( ref1->getContextId(), ref1->getReferencedId(), ref2->getContextId(), ref2->getReferencedId() ); break; case ModSyntaxNodeListNode: ModSyntaxNodeList *nlist; nlist = (ModSyntaxNodeList *)node; for( it = nlist->begin(); it != nlist->end(); it++ ) { executeAndModify( *it, circuit ); } break; default: node->evaluate(); node->semanticalValidation(); } return *this; } /******************************************************************* * Function: *******************************************************************/ ECircuit *ModelicaParser::parseAndExecute() { mod_parse(); if( rootNode == NULL ) { throw ModelicaParserException( "Error parsing Modelica file" ); } ECircuit *circuit = new ECircuit(); executeAndModify( rootNode, *circuit ); delete rootNode; return circuit; } /************************************* * * Class ECompFactory * *************************************/ /******************************************************************* * Function: *******************************************************************/ EComp *ECompFactory::createInstance( const string &objId, const string &typeId, ParamsDict *initParams ) { EComp *ecomp; RealValue p1, p2, val; if( typeId == "Ground" ) { ecomp = new Ground( objId ); } else if( typeId == "Resistor" ) { ecomp = new Resistance( objId, ( getParam( initParams, "R", p1 ) ? p1 : Resistance::DefaultR ) ); } else if( typeId == "Conductor" ) { val = ( getParam( initParams, "R", p1 ) ? p1 : Resistance::DefaultR ); assert( val != 0 ); ecomp = new Resistance( objId, 1/val ); } else if( typeId == "Capacitor" ) { ecomp = new Capacitor( objId, ( getParam( initParams, "C", p1 ) ? p1 : Capacitor::DefaultC ), ( getParam( initParams, "v", p2 ) ? p2 : Capacitor::DefaultInitialLoad ) ); } else if( typeId == "Inductor" ) { ecomp = new Inductor( objId, ( getParam( initParams, "L", p1 ) ? p1 : Inductor::DefaultI ), ( getParam( initParams, "v", p2 ) ? p2 : Inductor::DefaultInitialLoad ) ); } else if( typeId == "IdealTransformer" ) { ecomp = new Transformer( objId, ( getParam( initParams, "n", p1 ) ? p1 : Transformer::DefaultTR ) ); } else if( typeId == "IdealGyrator" ) { ecomp = new Gyrator( objId, ( getParam( initParams, "G", p1 ) ? p1 : Gyrator::DefaultGC ) ); } else { ecomp = createSourceInstance( objId, typeId, initParams ); if( ecomp == NULL ) { throw ModelicaParserException( "Not supported data type: " + typeId ); } } return ecomp; } /******************************************************************* * Function: *******************************************************************/ EComp *ECompFactory::createSourceInstance( const string &objId, const string &typeId, ParamsDict *initParams ) { EComp *ecomp; Signal *signal; bool isVS; string pname; RealValue p1, p2, p3, p4, p5; isVS = isVoltageSource( typeId ); pname = ( isVS ? "V" : "I" ); if( typeId == "ConstantVoltage" || typeId == "ConstantCurrent" ) { signal = new ConstantSignal( ( getParam( initParams, pname , p1 ) ? p1 : ConstantSignal::DefaultConstant ) ); } else if( typeId == "StepVoltage" || typeId == "StepCurrent" ) { signal = new StepSignal( ( getParam( initParams, pname , p1 ) ? p1 : StepSignal::DefaultHeight ), ( getParam( initParams, "offset" , p2 ) ? p2 : StepSignal::DefaultOffset ), ( getParam( initParams, "startTime" , p3 ) ? p3 : StepSignal::DefaultStartTime ) ); } else if( typeId == "SineVoltage" || typeId == "SineCurrent" ) { signal = new SineSignal( ( getParam( initParams, pname , p1 ) ? p1 : SineSignal::DefaultAmplitude ), ( getParam( initParams, "phase" , p2 ) ? p2 : SineSignal::DefaultPhase ), ( getParam( initParams, "freqHz" , p3 ) ? p3 : SineSignal::DefaultWaveFreq ), ( getParam( initParams, "offset" , p4 ) ? p4 : SineSignal::DefaultOffset ), ( getParam( initParams, "startTime" , p5 ) ? p5 : SineSignal::DefaultStartTime ) ); } else if( typeId == "PulseVoltage" || typeId == "PulseCurrent" ) { signal = new PulseSignal( ( getParam( initParams, pname , p1 ) ? p1 : PulseSignal::DefaultAmplitude ), ( getParam( initParams, "width" , p2 ) ? p2 : PulseSignal::DefaultWidth ), ( getParam( initParams, "period" , p3 ) ? p3 : PulseSignal::DefaultPeriod ), ( getParam( initParams, "offset" , p4 ) ? p4 : PulseSignal::DefaultOffset ), ( getParam( initParams, "startTime" , p5 ) ? p5 : PulseSignal::DefaultStartTime )); } else { return NULL; } assert( signal != NULL ); ecomp = ( isVS ? new VoltageSource( objId, signal ) : new CurrentSource( objId, signal ) ); return ecomp; } /******************************************************************* * Function: *******************************************************************/ bool ECompFactory::isVoltageSource( const string &typeId ) { return ( typeId == "ConstantVoltage" || typeId == "StepVoltage" || typeId == "SineVoltage" || typeId == "PulseVoltage" ); } /******************************************************************* * Function: *******************************************************************/ bool ECompFactory::getParam( ParamsDict *initParams, const string ¶mId, RealValue ¶mValue ) { ParamsDict::iterator it = initParams->find( paramId ); if( it != initParams->end() ) { paramValue = it->second; } return( it != initParams->end() ); }