Related Documentation:
For the example of adding a PulseGen to the Model Container, with the exception of adding a symbol for the pulse object (see below), the following steps are automated by the function pulse_gen given in the documentation for Extending the Model Container.
The following subheadings are in order of execution.
First add a new tokenizer to the analyzer.l file:
pulse { return(TOKEN_PULSE); }
|
The new token is added to the description.tokens file located in hierarchy/output/symbols/:
%token TOKEN_PULSE
|
A series of grammar rules must now be added:
struct symtab_Pulse * ppulse;
|
The prefix p for pulse indicates that this is a pointer.
Note: This is the only step in extending the functionality of the
Model Container that is not automated by the function pulse_gen.
%type <phsle> PulseSymbol
%type <ppulse> PulseSectionFront %type <ppulse> PulseSectionFront1 %type <pidin> PulseSectionFront2 %type <ppulse> PulseDescription %type <phsle> PulseComponent |
The next step is to add a rule for each of the declarations just made so that the parser knows what to do with them.
PulseSymbol
: PulseSection { #line //- put symbol table element on stack $$ = &$1->bio.ioh.iol.hsle; } |
The PulseSymbol uses a Bio Component symbol.
PulseDescription /* <ppulse> */
: { #line $$ = ParserContextGetActual((PARSERCONTEXT *)pacParserContext); } | PulseDescription ChildSectionOptionalInputOptionalParameters { #line //- link children if ($2) { SymbolAddChild(&$1->bio.ioh.iol.hsle, $2); } //- reset actual symbol ParserContextSetActual ((PARSERCONTEXT *)pacParserContext, &$1->bio.ioh.iol.hsle); //- put symbol description on stack $$ = $1; } | PulseDescription Parameters { #line //- link parameters SymbolParameterLinkAtEnd(&$1->bio.ioh.iol.hsle, $2); //- reset actual symbol ParserContextSetActual ((PARSERCONTEXT *)pacParserContext, &$1->bio.ioh.iol.hsle); //- put symbol on stack $$ = $1; } ; |
PulseSectionEnd
: EndPushedPidin TOKEN_PULSE { #line } ; |
PulseSectionFront /* <ppulse> */
: PulseSectionFront1 PulseSectionFront2 { #line //- prepare struct for symbol table $$ = $1; //- set actual symbol ParserContextSetActual ((PARSERCONTEXT *)pacParserContext, &$$->bio.ioh.iol.hsle); //- assign name to symbol SymbolSetName(&$$->bio.ioh.iol.hsle, $2); } ; |
PulseSectionFront1 /* <ppulse> */
: TOKEN_PULSE { #line //- prepare struct for symbol table $$ = PulseCalloc(); //- set actual symbol ParserContextSetActual ((PARSERCONTEXT *)pacParserContext, &$$->bio.ioh.iol.hsle); } ; |
Note: This is called by PulseCalloc, which must be defined for this to work.
PulseSectionFront2 /* <ppulse> */
: IdentifierOptionIndexPushedPidin { #line //- put identifier on stack $$ = $1; } ; |
PulseSection /* <ppulse> */
: PulseSectionFront InputOutputRelations OptionalItemInputRelations PulseDescription PulseSectionEnd { #line //- link input/output relations SymbolAssignBindableIO(&$4->bio.ioh.iol.hsle, $2); //- bind I/O relations SymbolAssignInputs(&$4->bio.ioh.iol.hsle, $3); //- put finished section info on stack $$ = $4; } ; |