2 * Translator from Modelica 2.x to flat Modelica
4 * Copyright (C) 2005 - 2007 Imagine S.A.
5 * For more information or commercial use please contact us at www.amesim.com
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 * Grammar for the Modelica language v2.2
32 (** Modelica parser. *)
34 (** Implementation based on {i Modelica language specification 2.0 } *)
38 exception Unclosed of int * string * int * string
39 exception Invalid_matrix of int * int
40 exception Invalid_array of int * int
45 start: int; (* offset in the parsed stream *)
46 enddd: int; (* offset in the parsed stream *)
51 | LibraryFile of string
54 type error_description =
57 err_info: (string * string) list;
66 exception SyntacticError of error_description
68 let inputfile = ref CommandLine
73 info = { start = Parsing.symbol_start ();
74 enddd = Parsing.symbol_end ();
75 filename = !inputfile }
78 let rhs_nodes n n' nature =
81 info = { start = Parsing.rhs_start n;
82 enddd = Parsing.rhs_end n';
83 filename = !inputfile }
86 let unclosed opening_symbol opening_pos closing_symbol closing_pos =
87 let offset = Parsing.rhs_start opening_pos
88 and offset' = Parsing.rhs_start closing_pos in
89 raise (Unclosed (offset, opening_symbol, offset', closing_symbol))
91 let invalid_matrix_construction opening_pos error_pos =
92 raise (Invalid_matrix (
93 Parsing.rhs_start opening_pos, Parsing.rhs_start error_pos))
95 let invalid_literal_array_construction opening_pos error_pos =
96 raise (Invalid_array (
97 Parsing.rhs_start opening_pos, Parsing.rhs_start error_pos))
102 %token <string> IDENT END_IDENT
105 %token <string> UNSIGNED_INTEGER UNSIGNED_REAL STRING
108 %token ALGORITHM AND ANNOTATION BLOCK BREAK CLASS CONNECT CONNECTOR CONSTANT
109 %token DISCRETE EACH ELSE ELSEIF ELSEWHEN ENCAPSULATED END
110 %token END_IF END_FOR END_WHEN END_WHILE
111 %token ENUMERATION EQUATION EXPANDABLE
112 %token EXTENDS EXTERNAL FALSE FINAL FLOW FOR FUNCTION IF IMPORT IN
113 %token INITIAL_ALGORITHM INITIAL_EQUATION
114 %token INNER INPUT LOOP MODEL NOT NOEVENT OR OUTER OUTPUT
115 %token PACKAGE PARAMETER PARTIAL
116 %token PROTECTED PUBLIC RECORD REDECLARE REPLACEABLE RESTRICTS RETURN
117 %token THEN TRUE TYPE WHEN WHILE WITHIN
120 %token LP RP LSB RSB LCB RCB /* ( ) [ ] { } */
121 %token DOT CM SC CL /* . , ; : */
122 %token PLUS MINUS STAR SLASH EXP /* + - * / ^ */
123 %token EQ COLEQ /* = := */
124 %token LT GT LE GE EE NE /* < > <= >= == <> */
129 %type <(location Syntax.toplevel_element_desc, location) Syntax.node> definition
138 { node (ClassDefinitions (List.rev $1)) }
139 | toplevel_expression SC
143 | WITHIN within_name SC
144 { node (Within (List.rev $2)) }
148 { raise End_of_file }
152 : FINAL class_definition SC
153 { [node (ClassDefinition (Some Final, $2))] }
154 | class_definition SC
155 { [node (ClassDefinition (None, $1))] }
156 | class_definitions FINAL class_definition SC
157 { node (ClassDefinition (Some Final, $3)) :: $1 }
158 | class_definitions class_definition SC
159 { node (ClassDefinition (None, $2)) :: $1 }
163 { node (Expression $1) }
164 | component_reference component_list
165 { match $1.nature with
166 | IndexedAccess (type_spec_node, subscripts_node) ->
167 node (VariablesDefinitions (type_spec_node, Some subscripts_node, (List.rev $2)))
169 node (VariablesDefinitions (rhs_nodes 1 1 type_spec, None, (List.rev $2))) }
170 | component_reference COLEQ expression
171 { node (Command (node (Assign ($1, $3)))) }
172 | LP expression_list RP COLEQ component_reference LP RP
173 { node (Command (node (MultipleAssign ($2, $5, None)))) }
174 | LP expression_list RP COLEQ component_reference LP function_arguments RP
175 { node (Command (node (MultipleAssign ($2, $5, Some $7)))) }
176 | LP expression_list RP COLEQ component_reference LP function_arguments
178 { unclosed "(" 6 ")" 8 }
179 | LP expression_list RP COLEQ component_reference LP error
180 { unclosed "(" 6 ")" 7 }
182 { node (Command (node Break)) }
184 { node (Command (node Return)) }
185 | conditional_equation_a
186 { node (Command (node $1)) }
188 { node (Command (node $1)) }
190 { node (Command (node $1)) }
192 { node (Command (node $1)) }
198 | within_name DOT IDENT
204 : encapsulated_option partial_option class_type class_specifier
205 { node (Definition ($1, $2, $3, $4)) }
217 | EXPANDABLE CONNECTOR
218 { ExpandableConnector }
233 { Some Encapsulated }
244 : IDENT string_comment composition END_IDENT
245 { if $1 <> $4 then unclosed $1 1 $1 4
246 else node (LongSpecifier ($1, $2, $3)) }
247 | IDENT EQ base_prefix name array_subscripts_option class_modification_option
249 { node (ShortSpecifier ($1, $3, $4, $5, $6, $7)) }
250 | IDENT EQ ENUMERATION LP enum_composition_option RP comment
251 { node (EnumerationSpecifier ($1, rhs_nodes 5 5 $5, $7)) }
252 | IDENT EQ ENUMERATION LP enum_composition_option error
253 { unclosed "(" 4 ")" 6 }
254 | EXTENDS IDENT class_modification_option string_comment composition END_IDENT
255 { if $2 <> $6 then unclosed $2 2 $2 6
256 else node (ExtensionSpecifier ($2, $3, $4, $5)) }
264 enum_composition_option
273 { EnumList (Some (List.rev $1)) }
279 : enumeration_literal
281 | enum_list CM enumeration_literal
287 { node (EnumerationLiteral ($1, $2)) }
291 : other_lists external_option
292 { node (Composition ([], List.rev $1, $2)) }
293 | element_list other_lists external_option
294 { node (Composition (List.rev $1, List.rev $2, $3)) }
300 | other_lists PUBLIC element_list
301 { rhs_nodes 2 3 (Public (List.rev $3)) :: $1 }
302 | other_lists PROTECTED element_list
303 { rhs_nodes 2 3 (Protected (List.rev $3)) :: $1 }
304 | other_lists equation_clause
305 { rhs_nodes 2 2 $2 :: $1 }
306 | other_lists algorithm_clause
307 { rhs_nodes 2 2 $2 :: $1 }
313 | EXTERNAL language_specification_option
314 external_function_call_option SC
316 { Some (node (External ($2, $3, None, $5))) }
317 | EXTERNAL language_specification_option
318 external_function_call_option annotation SC
320 { Some (node (External ($2, $3, Some $4, $6))) }
337 language_specification_option
344 external_function_call_option
348 { Some (node (ExternalFunctionCall (None, $1, []))) }
349 | IDENT LP expressions RP
350 { Some (node (ExternalFunctionCall (None, $1, $3))) }
351 | IDENT LP expressions error
352 { unclosed "(" 2 ")" 4 }
354 { unclosed "(" 2 ")" 3 }
355 | component_reference EQ IDENT LP RP
356 { Some (node (ExternalFunctionCall (Some $1, $3, []))) }
357 | component_reference EQ IDENT LP expressions RP
358 { Some (node (ExternalFunctionCall (Some $1, $3, $5))) }
359 | component_reference EQ IDENT LP expressions error
360 { unclosed "(" 4 ")" 6 }
361 | component_reference EQ IDENT LP error
362 { unclosed "(" 4 ")" 5 }
368 | expression CM expressions
372 array_subscripts_option
379 class_modification_option
388 { [node (ClassAnnotation $1)] }
389 | import_clause SC annotation_sc_option
390 { [node (ImportClause ($1, $3))] }
391 | extends_clause SC annotation_sc_option
392 { [node (ExtendsClause ($1, $3))] }
393 | redeclare_option final_option dynamic_scope_option
394 element_definition SC annotation_sc_option
395 { [node (ElementDefinition ($1, $2, $3, $4, $6))] }
396 | element_list import_clause SC annotation_sc_option
397 { rhs_nodes 2 3 (ImportClause ($2, $4)) :: $1 }
398 | element_list extends_clause SC annotation_sc_option
399 { rhs_nodes 2 3 (ExtendsClause ($2, $4)) :: $1 }
400 | element_list redeclare_option final_option dynamic_scope_option
401 element_definition SC annotation_sc_option
402 { rhs_nodes 2 5 (ElementDefinition ($2, $3, $4, $5, $7)) :: $1 }
407 { node (ClassDefinitionElement (None, $1, [])) }
409 { node (ComponentClauseElement (None, $1, [])) }
410 | REPLACEABLE class_definition
411 { node (ClassDefinitionElement (Some Replaceable, $2, [])) }
412 | REPLACEABLE class_definition constraining_clauses
413 { node (ClassDefinitionElement (Some Replaceable, $2, List.rev $3)) }
414 | REPLACEABLE component_clause
415 { node (ComponentClauseElement (Some Replaceable, $2, [])) }
416 | REPLACEABLE component_clause constraining_clauses
417 { node (ComponentClauseElement (Some Replaceable, $2, List.rev $3)) }
446 : IMPORT IDENT EQ name comment
447 { node (NewIdentifier ($2, $4, $5)) }
448 | IMPORT name comment
449 { node (OldIdentifier ($2, $3)) }
450 | IMPORT name DOT STAR comment
451 { node (AllIdentifiers ($2, $5)) }
455 : constraining_clause
457 | constraining_clauses constraining_clause
463 : EXTENDS name class_modification_option annotation_option
464 { node (Extends ($2, $3, $4)) }
468 : EXTENDS name class_modification_option comment
469 { node (Constraint (Extension, $2, $3, $4)) }
470 | RESTRICTS name class_modification_option comment
471 { node (Constraint (Restriction, $2, $3, $4)) }
476 : type_prefix type_specifier array_subscripts_option component_list
477 { node (ComponentClause ($1, $2, $3, List.rev $4)) }
481 : flow_option variability_option inout_option
482 { node (TypePrefix ($1, $2, $3)) }
518 : component_declaration
520 | component_list CM component_declaration
524 component_declaration
525 : declaration comment
526 { node (ComponentDeclaration ($1, $2)) }
530 : IDENT array_subscripts_option modification_option
531 { node (Declaration ($1, $2, $3)) }
543 : class_modification EQ expression
544 { node (Modification ($1, Some $3)) }
546 { node (Modification ($1, None)) }
555 { node (ClassModification []) }
556 | LP argument_list RP
557 { node (ClassModification (List.rev $2)) }
558 | LP argument_list error
559 { unclosed "(" 1 ")" 3 }
561 { unclosed "(" 1 ")" 2 }
567 | argument CM argument_list
572 : element_modification
574 | element_redeclaration
579 : each_option final_option component_reference modification_option
581 { node (ElementModification ($1, $2, $3, $4, $5)) }
591 element_redeclaration
592 : REDECLARE each_option final_option class_definition_or_component_clause1
593 { node (ElementRedeclaration ($2, $3, $4)) }
596 class_definition_or_component_clause1
598 { node (ClassDefinitionElement (None, $1, [])) }
599 | type_prefix type_specifier component_declaration
600 { let cpnt = node (ComponentClause ($1, $2, None, [$3])) in
601 node (ComponentClauseElement (None, cpnt, [])) }
602 | REPLACEABLE class_definition
603 { node (ClassDefinitionElement (Some Replaceable, $2, [])) }
604 | REPLACEABLE class_definition constraining_clauses
605 { node (ClassDefinitionElement (Some Replaceable, $2, List.rev $3)) }
606 | REPLACEABLE type_prefix type_specifier
607 component_declaration
608 { let cpnt = node (ComponentClause ($2, $3, None, [$4])) in
609 node (ComponentClauseElement (Some Replaceable, cpnt, [])) }
610 | REPLACEABLE type_prefix type_specifier
611 component_declaration constraining_clauses
612 { let cpnt = node (ComponentClause ($2, $3, None, [$4])) in
613 node (ComponentClauseElement (Some Replaceable, cpnt, List.rev $5)) }
619 { EquationClause (Some Initial, []) }
620 | INITIAL_EQUATION equations
621 { EquationClause (Some Initial, List.rev $2) }
623 { EquationClause (None, []) }
625 { EquationClause (None, List.rev $2) } ;
628 : equation comment SC annotation_sc_option
629 { [node (Equation (rhs_nodes 1 3 $1, $2, $4))] }
630 | equations equation comment SC annotation_sc_option
631 { rhs_nodes 2 5 (Equation (rhs_nodes 2 4 $2, $3, $5)) :: $1 }
636 { AlgorithmClause (Some Initial, []) }
637 | INITIAL_ALGORITHM algorithms
638 { AlgorithmClause (Some Initial, List.rev $2) }
640 { AlgorithmClause (None, []) }
641 | ALGORITHM algorithms
642 { AlgorithmClause (None, List.rev $2) }
646 : algorithm comment SC annotation_sc_option
647 { [node (Algorithm (rhs_nodes 1 3 $1, $2, $4))] }
648 | algorithms algorithm comment SC annotation_sc_option
649 { rhs_nodes 2 5 (Algorithm (rhs_nodes 2 4 $2, $3, $5)) :: $1 }
653 : simple_expression EQ expression
655 | conditional_equation_e
663 | component_reference LP RP
664 { FunctionCallE ($1, None) }
665 | component_reference LP function_arguments RP
666 { FunctionCallE ($1, Some $3) }
667 | component_reference LP function_arguments error
668 { unclosed "(" 2 ")" 4 }
669 | component_reference LP error
670 { unclosed "(" 2 ")" 3 }
674 : component_reference COLEQ expression
676 | component_reference LP RP
677 { FunctionCallA ($1, None) }
678 | component_reference LP function_arguments RP
679 { FunctionCallA ($1, Some $3) }
680 | component_reference LP function_arguments error
681 { unclosed "(" 2 ")" 4 }
682 | component_reference LP error
683 { unclosed "(" 2 ")" 3 }
684 | LP expression_list RP COLEQ component_reference LP RP
685 { MultipleAssign ($2, $5, None) }
686 | LP RP COLEQ component_reference LP RP
687 { MultipleAssign ([], $4, None) }
688 | LP expression_list RP COLEQ component_reference LP function_arguments RP
689 { MultipleAssign ($2, $5, Some $7) }
690 | LP RP COLEQ component_reference LP function_arguments RP
691 { MultipleAssign ([], $4, Some $6) }
692 | LP expression_list RP COLEQ component_reference LP function_arguments
694 { unclosed "(" 6 ")" 8 }
695 | LP RP COLEQ component_reference LP function_arguments error
696 { unclosed "(" 5 ")" 7 }
697 | LP expression_list RP COLEQ component_reference LP error
698 { unclosed "(" 6 ")" 7 }
699 | LP RP COLEQ component_reference LP error
700 { unclosed "(" 5 ")" 6 }
701 | LP expression_list error
702 { unclosed "(" 1 ")" 3 }
704 { unclosed "(" 1 ")" 2 }
709 | conditional_equation_a
719 conditional_equation_e
722 else_if_expressions_e
725 { ConditionalEquationE (($2, List.rev $4) :: $5, $6) }
728 else_if_expressions_e
731 | ELSEIF expression THEN
733 else_if_expressions_e
734 { ($2, List.rev $4) :: $5 }
741 { Some (List.rev $2) }
747 | equations_e equation SC
748 { rhs_nodes 2 3 $2 :: $1 }
751 conditional_equation_a
754 else_if_expressions_a
757 { ConditionalEquationA (($2, List.rev $4) :: $5, $6) }
760 else_if_expressions_a
763 | ELSEIF expression THEN
765 else_if_expressions_a
766 { ($2, List.rev $4) :: $5 }
773 { Some (List.rev $2) }
779 | algorithms_a algorithm SC
780 { rhs_nodes 2 3 $2 :: $1 }
784 : FOR for_indices LOOP
787 { ForClauseE ($2, List.rev $4) }
791 : FOR for_indices LOOP
794 { ForClauseA ($2, List.rev $4) }
800 | for_index CM for_indices
807 | IDENT IN expression
812 : WHILE expression LOOP
815 { WhileClause ($2, List.rev $4) }
819 : WHEN expression THEN
821 else_when_expressions_e
823 { WhenClauseE (($2, List.rev $4) :: $5) }
827 : WHEN expression THEN
829 else_when_expressions_a
831 { WhenClauseA (($2, List.rev $4) :: $5) }
834 else_when_expressions_e
837 | ELSEWHEN expression THEN
839 else_when_expressions_e
840 { ($2, List.rev $4) :: $5 }
843 else_when_expressions_a
846 | ELSEWHEN expression THEN
848 else_when_expressions_a
849 { ($2, List.rev $4) :: $5 }
853 : CONNECT LP component_reference CM component_reference RP
854 { ConnectClause ($3, $5) }
855 | CONNECT LP component_reference CM component_reference error
856 { unclosed "(" 2 ")" 6 }
863 | IF expression THEN expression
866 { node (If (($2, $4) :: $5, $7)) }
872 | ELSEIF expression THEN expression
880 | logical_expression CL logical_expression
881 { node (Range ($1, None, $3)) }
882 | logical_expression CL logical_expression CL logical_expression
883 { node (Range ($1, Some $3, $5)) }
889 | logical_expression OR logical_term
890 { node (BinaryOperation (rhs_nodes 2 2 Or, $1, $3)) }
896 | logical_term AND logical_factor
897 { node (BinaryOperation (rhs_nodes 2 2 And, $1, $3)) }
904 { node (UnaryOperation (rhs_nodes 1 1 Not, $2)) }
908 : arithmetic_expression
910 | arithmetic_expression LT arithmetic_expression
911 { node (BinaryOperation (rhs_nodes 2 2 Less, $1, $3)) }
912 | arithmetic_expression GT arithmetic_expression
913 { node (BinaryOperation (rhs_nodes 2 2 Greater, $1, $3)) }
914 | arithmetic_expression LE arithmetic_expression
915 { node (BinaryOperation (rhs_nodes 2 2 LessEqual, $1, $3)) }
916 | arithmetic_expression GE arithmetic_expression
917 { node (BinaryOperation (rhs_nodes 2 2 GreaterEqual, $1, $3)) }
918 | arithmetic_expression EE arithmetic_expression
919 { node (BinaryOperation (rhs_nodes 2 2 EqualEqual, $1, $3)) }
920 | arithmetic_expression NE arithmetic_expression
921 { node (BinaryOperation (rhs_nodes 2 2 NotEqual, $1, $3)) }
924 arithmetic_expression
927 | arithmetic_expression PLUS term
928 { node (BinaryOperation (rhs_nodes 2 2 Plus, $1, $3)) }
929 | arithmetic_expression MINUS term
930 { node (BinaryOperation (rhs_nodes 2 2 Minus, $1, $3)) }
936 | term STAR unary_factor
937 { node (BinaryOperation (rhs_nodes 2 2 Times, $1, $3)) }
938 | term SLASH unary_factor
939 { node (BinaryOperation (rhs_nodes 2 2 Divide, $1, $3)) }
946 { node (UnaryOperation (rhs_nodes 1 1 UnaryPlus, $2)) }
948 { node (UnaryOperation (rhs_nodes 1 1 UnaryMinus, $2)) }
954 { node (BinaryOperation (rhs_nodes 2 2 Power, $1, $3)) }
959 { node (Integer $1) }
968 | NOEVENT LP expression RP
969 { node (NoEvent $3) }
970 | component_reference
972 | component_reference LP RP
973 { node (FunctionCall ($1, None)) }
974 | component_reference LP function_arguments RP
975 { node (FunctionCall ($1, Some $3)) }
976 | component_reference LP function_arguments error
977 { unclosed "(" 2 ")" 4 }
978 | component_reference LP error
979 { unclosed "(" 2 ")" 3 }
980 | LP expression_list RP
982 | [expr] -> node expr.Syntax.nature
983 | _ -> node (Tuple $2) }
984 | LP expression_list error
985 { unclosed "(" 1 ")" 3 }
986 | LSB expression_lists RSB
987 { node (MatrixConstruction $2) }
989 { invalid_matrix_construction 1 2 }
990 | LCB vector_elements RCB
993 { invalid_literal_array_construction 1 2 }
1001 | expression_list SC expression_lists
1006 : expression FOR for_indices
1007 { node (VectorReduction ($1, $3)) }
1009 { node (VectorElements $1) }
1014 { node (Identifier $1) }
1016 { node (FieldAccess ($1, $3)) }
1021 { node (Identifier $1) }
1022 | IDENT array_subscripts
1023 { node (IndexedAccess (rhs_nodes 1 1 (Identifier $1), $2)) }
1024 | component_reference DOT IDENT
1025 { node (FieldAccess ($1, $3)) }
1026 | component_reference DOT IDENT array_subscripts
1027 { node (IndexedAccess (rhs_nodes 1 3 (FieldAccess ($1, $3)), $4)) }
1031 : function_arguments_elements
1032 { node (ArgumentList (List.rev $1)) }
1033 | expression FOR for_indices
1034 { node (Reduction ($1, $3)) }
1037 function_arguments_elements
1039 { [node (Argument $1)] }
1042 | function_arguments_elements CM expression
1043 { node (Argument $3) :: $1 }
1044 | function_arguments_elements CM named_argument
1049 : IDENT EQ expression
1050 { node (NamedArgument ($1, $3)) }
1052 { failwith "Not yet implemented" }
1053 | FUNCTION IDENT LP RP
1054 { failwith "Not yet implemented" }
1055 | FUNCTION IDENT LP function_arguments RP
1056 { failwith "Not yet implemented" }
1057 | FUNCTION IDENT LP function_arguments error
1058 { unclosed "(" 3 ")" 5 }
1059 | FUNCTION IDENT LP error
1060 { unclosed "(" 3 ")" 4 }
1066 | expression CM expression_list
1071 : LSB subscripts RSB
1072 { node (Subscripts $2) }
1078 | subscript CM subscripts
1086 { node (Subscript $1) }
1090 : string_comment annotation_option
1091 { node (Comment ($1, $2)) }
1104 | strings PLUS STRING
1109 : ANNOTATION class_modification
1110 { node (Annotation $2) }
1115 let parse filename token_fun lexbuf =
1116 inputfile := filename;
1118 definition token_fun lexbuf
1120 | Unclosed (pos, symbol, pos', symbol') ->
1121 raise (SyntacticError
1122 {err_msg = ["_Unclosed"; symbol];
1125 {location = {start = pos;
1127 filename = filename}}})
1128 | Invalid_matrix (pos, pos') ->
1129 raise (SyntacticError
1130 {err_msg = ["_InvalidMatrixConstruct"];
1133 {location = {start = pos;
1135 filename = filename}}})
1136 | Invalid_array (pos, pos') ->
1137 raise (SyntacticError
1138 {err_msg = ["_InvalidArrayConstruct"];
1141 {location = {start = pos;
1143 filename = filename}}})
1144 | Parsing.Parse_error ->
1145 raise (SyntacticError
1146 {err_msg = ["_SyntaxError"];
1149 {location = {start = Lexing.lexeme_start lexbuf;
1150 enddd = Lexing.lexeme_end lexbuf;
1151 filename = filename}}})