%{ #include #include #include #include /* For math functions, cos(), sin(), etc. */ #include #include "modsynnode.h" #include "modexcept.h" ModSyntaxNode *rootNode; int mod_lex(void); void mod_error(const char *s); %} %union { double val; string *id; ModSyntaxNode *synNode; ModSyntaxNodeList *synNodeList; Symbol *symbol; PackageSymbol *packageSymbol; TypeSymbol *typeSymbol; ReferenceSymbol *referenceSymbol; }; %token NUM /* Simple double precision number */ %token IDENT STRING %token MODEL IMPORT CONNECT EQUATION END START %type class_definition class_specifier element import_clause component_clause argument element_modification equation connect_clause expression %type stored_definition composition element_list equation_clause modifier class_modification argument_list equation_list %type name package %type type_specifier %type connector_ref %type component_reference comment string_comment string_concat %right '=' /* Grammar follows */ %% stored_definition: class_definition ';' { $$ = new ModSyntaxNodeList(); $$->add( $1 ); rootNode = $$; } ; class_definition: MODEL IDENT class_specifier { $$ = new ClassDefinition( *$2, $3 ); } ; class_specifier: string_comment composition END IDENT { $$ = $2; } ; composition: element_list equation_clause { $1->addAll( $2 ); $$ = $1; } ; element_list: element ';' { ModSyntaxNodeList *slist = new ModSyntaxNodeList(); slist->add( $1 ); $$ = slist; } | element_list element ';' { $1->add( $2 ); $$ = $1; } ; element: import_clause { $$ = $1; } | component_clause { $$ = $1; } ; import_clause: IMPORT package comment { $$ = new Import( $2 ); } ; package: name { $$ = $1; } | name '.' '*' { $$ = $1; } ; component_clause: type_specifier IDENT modifier { $$ = new Declaration( $1, new VarSymbol(*($2)), $3 ); } ; type_specifier: IDENT { $$ = new TypeSymbol( *$1 ); } | type_specifier '.' IDENT { $1->concat( *$3 ); $$ = $1; } ; modifier: class_modification { $$ = $1; } ; class_modification: { $$ = new ModSyntaxNodeList(); } | '(' ')' { $$ = new ModSyntaxNodeList(); } | '(' argument_list ')' { $$ = $2; } ; argument_list: argument { ModSyntaxNodeList *slist = new ModSyntaxNodeList(); slist->add( $1 ); $$ = slist; } | argument_list ',' argument { $1->add( $3 ); $$ = $1; } ; argument: element_modification { $$ = $1; } ; element_modification: component_reference '=' expression string_comment { $$ = new ParamSymbol( *($1), $3 ); } | component_reference '(' START '=' expression ')' { $$ = new ParamSymbol( *($1), $5 ); } ; equation_clause: EQUATION equation_list { $$ = $2; } ; equation_list: equation ';' { ModSyntaxNodeList *slist = new ModSyntaxNodeList(); slist->add( $1 ); $$ = slist; } | equation_list equation ';' { $1->add( $2 ); $$ = $1; } ; equation: connect_clause { $$ = $1; } ; connect_clause: CONNECT '(' connector_ref ',' connector_ref ')' { $$ = new Connect( $3, $5 ); } ; expression: NUM { $$ = new Constant( $1 ); } ; name: IDENT { $$ = new PackageSymbol( *$1 ); } | name '.' IDENT { $1->concat( *$3 ); $$ = $1; } ; component_reference: IDENT { $$ = $1; } ; connector_ref: IDENT '.' IDENT { $$ = new ReferenceSymbol( *$1, *$3 ); } ; comment: string_comment { $$ = $1; } ; string_comment: { ; } | string_concat { $$ = $1; } ; string_concat: STRING { $$ = $1; } | string_concat '+' STRING { $$ = $1; } ; /* End of grammar */ %% void mod_error(const char *s) { ModelicaParserException e( "Error parsing Modelica code: " + string( s ) ); throw e; }