add translator & XML2modelica
[scilab.git] / scilab / modules / scicos / src / translator / parsing / parser.mly
1 /*\r
2  *  Translator from Modelica 2.x to flat Modelica\r
3  *\r
4  *  Copyright (C) 2005 - 2007 Imagine S.A.\r
5  *  For more information or commercial use please contact us at www.amesim.com\r
6  *\r
7  *  This program is free software; you can redistribute it and/or\r
8  *  modify it under the terms of the GNU General Public License\r
9  *  as published by the Free Software Foundation; either version 2\r
10  *  of the License, or (at your option) any later version.\r
11  *\r
12  *  This program is distributed in the hope that it will be useful,\r
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15  *  GNU General Public License for more details.\r
16  *\r
17  *  You should have received a copy of the GNU General Public License\r
18  *  along with this program; if not, write to the Free Software\r
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
20  *\r
21  */\r
22 \r
23 /*\r
24  * Parser\r
25  * Grammar for the Modelica language v2.2\r
26  * V 1.0\r
27  * S. FURIC\r
28  */\r
29 \r
30 %{\r
31 \r
32 (** Modelica parser. *)\r
33 \r
34 (** Implementation based on {i Modelica language specification 2.0 } *)\r
35 \r
36 open Syntax\r
37 \r
38 exception Unclosed of int * string * int * string\r
39 exception Invalid_matrix of int * int\r
40 exception Invalid_array of int * int\r
41 exception End_of_file\r
42 \r
43 type location =\r
44   {\r
45     start: int; (* offset in the parsed stream *)\r
46     enddd: int;  (* offset in the parsed stream *)\r
47     filename: filename\r
48   }\r
49 \r
50 and filename =\r
51   | LibraryFile of string\r
52   | CommandLine\r
53 \r
54 type error_description =\r
55   {\r
56     err_msg: string list;\r
57     err_info: (string * string) list;\r
58     err_ctx: err_ctx\r
59   }\r
60 \r
61 and err_ctx =\r
62   {\r
63     location: location;\r
64   }\r
65 \r
66 exception SyntacticError of error_description\r
67 \r
68 let inputfile = ref CommandLine\r
69 \r
70 let node nature =\r
71   {\r
72     nature = nature;\r
73     info = { start = Parsing.symbol_start ();\r
74              enddd = Parsing.symbol_end ();\r
75              filename = !inputfile }\r
76   }\r
77 \r
78 let rhs_nodes n n' nature =\r
79   {\r
80     nature = nature;\r
81     info = { start = Parsing.rhs_start n;\r
82              enddd = Parsing.rhs_end n';\r
83              filename = !inputfile }\r
84   }\r
85 \r
86 let unclosed opening_symbol opening_pos closing_symbol closing_pos =\r
87   let offset = Parsing.rhs_start opening_pos\r
88   and offset' = Parsing.rhs_start closing_pos in\r
89   raise (Unclosed (offset, opening_symbol, offset', closing_symbol))\r
90 \r
91 let invalid_matrix_construction opening_pos error_pos =\r
92   raise (Invalid_matrix (\r
93     Parsing.rhs_start opening_pos, Parsing.rhs_start error_pos))\r
94 \r
95 let invalid_literal_array_construction opening_pos error_pos =\r
96   raise (Invalid_array (\r
97     Parsing.rhs_start opening_pos, Parsing.rhs_start error_pos))\r
98 \r
99 %}\r
100 \r
101 /*names*/\r
102 %token <string> IDENT END_IDENT\r
103 \r
104 /*literals*/\r
105 %token <string> UNSIGNED_INTEGER UNSIGNED_REAL STRING\r
106 \r
107 /*keywords*/\r
108 %token ALGORITHM AND ANNOTATION BLOCK BREAK CLASS CONNECT CONNECTOR CONSTANT\r
109 %token DISCRETE EACH ELSE ELSEIF ELSEWHEN ENCAPSULATED END\r
110 %token END_IF END_FOR END_WHEN END_WHILE\r
111 %token ENUMERATION EQUATION EXPANDABLE\r
112 %token EXTENDS EXTERNAL FALSE FINAL FLOW FOR FUNCTION IF IMPORT IN\r
113 %token INITIAL_ALGORITHM INITIAL_EQUATION\r
114 %token INNER INPUT LOOP MODEL NOT NOEVENT OR OUTER OUTPUT\r
115 %token PACKAGE PARAMETER PARTIAL\r
116 %token PROTECTED PUBLIC RECORD REDECLARE REPLACEABLE RESTRICTS RETURN\r
117 %token THEN TRUE TYPE WHEN WHILE WITHIN\r
118 \r
119 /*symbols*/\r
120 %token LP RP LSB RSB LCB RCB  /*  ( ) [ ] { }  */\r
121 %token DOT CM SC CL /*  . , ; :  */\r
122 %token PLUS MINUS STAR SLASH EXP /*  + - * / ^  */\r
123 %token EQ COLEQ /*  = :=  */\r
124 %token LT GT LE GE EE NE /*  < > <= >= == <>  */\r
125 \r
126 /*end of file*/\r
127 %token EOF\r
128 \r
129 %type <(location Syntax.toplevel_element_desc, location) Syntax.node> definition\r
130 %start definition\r
131 \r
132 %%\r
133 \r
134 \r
135 /*(2.2.1)*/\r
136 definition\r
137   : class_definitions\r
138       { node (ClassDefinitions (List.rev $1)) }\r
139   | toplevel_expression SC\r
140       { $1 }\r
141   | WITHIN SC\r
142       { node (Within []) }\r
143   | WITHIN within_name SC\r
144       { node (Within (List.rev $2)) }\r
145   | import_clause SC\r
146       { node (Import $1) }\r
147   | EOF\r
148       { raise End_of_file }\r
149   ;\r
150 \r
151 class_definitions\r
152   : FINAL class_definition SC\r
153       { [node (ClassDefinition (Some Final, $2))] }\r
154   | class_definition SC\r
155       { [node (ClassDefinition (None, $1))] }\r
156   | class_definitions FINAL class_definition SC\r
157       { node (ClassDefinition (Some Final, $3)) :: $1 }\r
158   | class_definitions class_definition SC\r
159       { node (ClassDefinition (None, $2)) :: $1 }\r
160 \r
161 toplevel_expression\r
162   : expression\r
163       { node (Expression $1) }\r
164   | component_reference component_list\r
165       { match $1.nature with\r
166           | IndexedAccess (type_spec_node, subscripts_node) ->\r
167               node (VariablesDefinitions (type_spec_node, Some subscripts_node, (List.rev $2)))\r
168           | type_spec ->\r
169               node (VariablesDefinitions (rhs_nodes 1 1 type_spec, None, (List.rev $2))) }\r
170   | component_reference COLEQ expression\r
171       { node (Command (node (Assign ($1, $3)))) }\r
172   | LP expression_list RP COLEQ component_reference LP RP\r
173       { node (Command (node (MultipleAssign ($2, $5, None)))) }\r
174   | LP expression_list RP COLEQ component_reference LP function_arguments RP\r
175       { node (Command (node (MultipleAssign ($2, $5, Some $7)))) }\r
176   | LP expression_list RP COLEQ component_reference LP function_arguments\r
177     error\r
178       { unclosed "(" 6 ")" 8 }\r
179   | LP expression_list RP COLEQ component_reference LP error\r
180       { unclosed "(" 6 ")" 7 }\r
181   | BREAK\r
182       { node (Command (node Break)) }\r
183   | RETURN\r
184       { node (Command (node Return)) }\r
185   | conditional_equation_a\r
186       { node (Command (node $1)) }\r
187   | for_clause_a\r
188       { node (Command (node $1)) }\r
189   | while_clause\r
190       { node (Command (node $1)) }\r
191   | when_clause_a\r
192       { node (Command (node $1)) }\r
193   ;\r
194 \r
195 within_name\r
196   : IDENT\r
197       { [$1] }\r
198   | within_name DOT IDENT\r
199       { $3 :: $1 }\r
200   ;\r
201 \r
202 /*(2.2.2)*/\r
203 class_definition\r
204   : encapsulated_option partial_option class_type class_specifier\r
205       { node (Definition ($1, $2, $3, $4)) }\r
206   ;\r
207 \r
208 class_type\r
209   : CLASS\r
210       { Class }\r
211   | MODEL\r
212       { Model }\r
213   | BLOCK\r
214       { Block }\r
215   | RECORD\r
216       { Record }\r
217   | EXPANDABLE CONNECTOR\r
218       { ExpandableConnector }\r
219   | CONNECTOR\r
220       { Connector }\r
221   | TYPE\r
222       { Type }\r
223   | PACKAGE\r
224       { Package }\r
225   | FUNCTION\r
226       { Function }\r
227   ;\r
228 \r
229 encapsulated_option\r
230   :\r
231       { None }\r
232   | ENCAPSULATED\r
233       { Some Encapsulated }\r
234   ;\r
235 \r
236 partial_option\r
237   :\r
238       { None }\r
239   | PARTIAL\r
240       { Some Partial }\r
241   ;\r
242 \r
243 class_specifier\r
244   : IDENT string_comment composition END_IDENT\r
245       { if $1 <> $4 then unclosed $1 1 $1 4\r
246         else node (LongSpecifier ($1, $2, $3)) }\r
247   | IDENT EQ base_prefix name array_subscripts_option class_modification_option\r
248     comment\r
249       { node (ShortSpecifier ($1, $3, $4, $5, $6, $7)) }\r
250   | IDENT EQ ENUMERATION LP enum_composition_option RP comment\r
251       { node (EnumerationSpecifier ($1, rhs_nodes 5 5 $5, $7)) }\r
252   | IDENT EQ ENUMERATION LP enum_composition_option error\r
253       { unclosed "(" 4 ")" 6 }\r
254   | EXTENDS IDENT class_modification_option string_comment composition END_IDENT\r
255       { if $2 <> $6 then unclosed $2 2 $2 6\r
256         else node (ExtensionSpecifier ($2, $3, $4, $5)) }\r
257   ;\r
258 \r
259 base_prefix\r
260   : type_prefix\r
261       { $1 }\r
262   ;\r
263 \r
264 enum_composition_option\r
265   :\r
266       { EnumList None }\r
267   | enum_composition\r
268       { $1 }\r
269   ;\r
270 \r
271 enum_composition\r
272   : enum_list\r
273       { EnumList (Some (List.rev $1)) }\r
274   | CL\r
275       { EnumColon}\r
276   ;\r
277 \r
278 enum_list\r
279   : enumeration_literal\r
280       { [$1] }\r
281   | enum_list CM enumeration_literal\r
282       { $3 :: $1 }\r
283   ;\r
284 \r
285 enumeration_literal\r
286   : IDENT comment\r
287       { node (EnumerationLiteral ($1, $2)) }\r
288   ;\r
289 \r
290 composition\r
291   : other_lists external_option\r
292       { node (Composition ([], List.rev $1, $2)) }\r
293   | element_list other_lists external_option\r
294       { node (Composition (List.rev $1, List.rev $2, $3)) }\r
295   ;\r
296 \r
297 other_lists\r
298   :\r
299       { [] }\r
300   | other_lists PUBLIC element_list\r
301       { rhs_nodes 2 3 (Public (List.rev $3)) :: $1 }\r
302   | other_lists PROTECTED element_list\r
303       { rhs_nodes 2 3 (Protected (List.rev $3)) :: $1 }\r
304   | other_lists equation_clause\r
305       { rhs_nodes 2 2 $2 :: $1 }\r
306   | other_lists algorithm_clause\r
307       { rhs_nodes 2 2 $2 :: $1 }\r
308   ;\r
309 \r
310 external_option\r
311   :\r
312       { None }\r
313   | EXTERNAL language_specification_option\r
314     external_function_call_option SC\r
315     annotation_sc_option\r
316       { Some (node (External ($2, $3, None, $5))) }\r
317   | EXTERNAL language_specification_option\r
318     external_function_call_option annotation SC\r
319     annotation_sc_option\r
320       { Some (node (External ($2, $3, Some $4, $6))) }\r
321   ;\r
322 \r
323 annotation_option\r
324   :\r
325       { None }\r
326   | annotation\r
327       { Some $1 }\r
328   ;\r
329 \r
330 annotation_sc_option\r
331   :\r
332       { None }\r
333   | annotation SC\r
334       { Some $1 }\r
335   ;\r
336 \r
337 language_specification_option\r
338   :\r
339       { None }\r
340   | STRING\r
341       { Some $1 }\r
342   ;\r
343 \r
344 external_function_call_option\r
345   :\r
346       { None }\r
347   | IDENT LP RP\r
348       { Some (node (ExternalFunctionCall (None, $1, []))) }\r
349   | IDENT LP expressions RP\r
350       { Some (node (ExternalFunctionCall (None, $1, $3))) }\r
351   | IDENT LP expressions error\r
352       { unclosed "(" 2 ")" 4 }\r
353   | IDENT LP error\r
354       { unclosed "(" 2 ")" 3 }\r
355   | component_reference EQ IDENT LP RP\r
356       { Some (node (ExternalFunctionCall (Some $1, $3, []))) }\r
357   | component_reference EQ IDENT LP expressions RP\r
358       { Some (node (ExternalFunctionCall (Some $1, $3, $5))) }\r
359   | component_reference EQ IDENT LP expressions error\r
360       { unclosed "(" 4 ")" 6 }\r
361   | component_reference EQ IDENT LP error\r
362       { unclosed "(" 4 ")" 5 }\r
363   ;\r
364 \r
365 expressions\r
366   : expression\r
367       { [$1] }\r
368   | expression CM expressions\r
369       { $1 :: $3 }\r
370   ;\r
371 \r
372 array_subscripts_option\r
373   :\r
374       { None }\r
375   | array_subscripts\r
376       { Some $1 }\r
377   ;\r
378 \r
379 class_modification_option\r
380   :\r
381       { None }\r
382   | class_modification\r
383       { Some $1 }\r
384   ;\r
385 \r
386 element_list\r
387   : annotation SC\r
388       { [node (ClassAnnotation $1)] }\r
389   | import_clause SC annotation_sc_option\r
390       { [node (ImportClause ($1, $3))] }\r
391   | extends_clause SC annotation_sc_option\r
392       { [node (ExtendsClause ($1, $3))] }\r
393   | redeclare_option final_option dynamic_scope_option\r
394     element_definition SC annotation_sc_option\r
395       { [node (ElementDefinition ($1, $2, $3, $4, $6))] }\r
396   | element_list import_clause SC annotation_sc_option\r
397       { rhs_nodes 2 3 (ImportClause ($2, $4)) :: $1 }\r
398   | element_list extends_clause SC annotation_sc_option\r
399       { rhs_nodes 2 3 (ExtendsClause ($2, $4)) :: $1 }\r
400   | element_list redeclare_option final_option dynamic_scope_option\r
401     element_definition SC annotation_sc_option\r
402       { rhs_nodes 2 5 (ElementDefinition ($2, $3, $4, $5, $7)) :: $1 }\r
403   ;\r
404 \r
405 element_definition\r
406   : class_definition\r
407       { node (ClassDefinitionElement (None, $1, [])) }\r
408   | component_clause\r
409       { node (ComponentClauseElement (None, $1, [])) }\r
410   | REPLACEABLE class_definition\r
411       { node (ClassDefinitionElement (Some Replaceable, $2, [])) }\r
412   | REPLACEABLE class_definition constraining_clauses\r
413       { node (ClassDefinitionElement (Some Replaceable, $2, List.rev $3)) }\r
414   | REPLACEABLE component_clause\r
415       { node (ComponentClauseElement (Some Replaceable, $2, [])) }\r
416   | REPLACEABLE component_clause constraining_clauses\r
417       { node (ComponentClauseElement (Some Replaceable, $2, List.rev $3)) }\r
418   ;\r
419 \r
420 redeclare_option\r
421   :\r
422       { None }\r
423   | REDECLARE\r
424       { Some Redeclare }\r
425   ;\r
426 \r
427 final_option\r
428   :\r
429       { None }\r
430   | FINAL\r
431       { Some Final }\r
432   ;\r
433 \r
434 dynamic_scope_option\r
435   :\r
436       { None }\r
437   | INNER\r
438       { Some Inner }\r
439   | OUTER\r
440       { Some Outer }\r
441   | INNER OUTER\r
442       { Some InnerOuter }\r
443   ;\r
444 \r
445 import_clause\r
446   : IMPORT IDENT EQ name comment\r
447       { node (NewIdentifier ($2, $4, $5)) }\r
448   | IMPORT name comment\r
449       { node (OldIdentifier ($2, $3)) }\r
450   | IMPORT name DOT STAR comment\r
451       { node (AllIdentifiers ($2, $5)) }\r
452   ;\r
453 \r
454 constraining_clauses\r
455   : constraining_clause\r
456       { [$1] }\r
457   | constraining_clauses constraining_clause\r
458       { $2 :: $1 }\r
459   ;\r
460 \r
461 /*(2.2.3)*/\r
462 extends_clause\r
463   : EXTENDS name class_modification_option annotation_option\r
464       { node (Extends ($2, $3, $4)) }\r
465   ;\r
466 \r
467 constraining_clause\r
468   : EXTENDS name class_modification_option comment\r
469       { node (Constraint (Extension, $2, $3, $4)) }\r
470   | RESTRICTS name class_modification_option comment\r
471       { node (Constraint (Restriction, $2, $3, $4)) }\r
472   ;\r
473 \r
474 /*(2.2.4)*/\r
475 component_clause\r
476   : type_prefix type_specifier array_subscripts_option component_list\r
477       { node (ComponentClause ($1, $2, $3, List.rev $4)) }\r
478   ;\r
479 \r
480 type_prefix\r
481   : flow_option variability_option inout_option\r
482       { node (TypePrefix ($1, $2, $3)) }\r
483   ;\r
484 \r
485 flow_option\r
486   :\r
487       { None }\r
488   | FLOW\r
489       { Some Flow }\r
490   ;\r
491 \r
492 variability_option\r
493   :\r
494       { None }\r
495   | DISCRETE\r
496       { Some Discrete }\r
497   | PARAMETER\r
498       { Some Parameter }\r
499   | CONSTANT\r
500       { Some Constant }\r
501   ;\r
502 \r
503 inout_option\r
504   :\r
505       { None }\r
506   | INPUT\r
507       { Some Input }\r
508   | OUTPUT\r
509       { Some Output }\r
510   ;\r
511 \r
512 type_specifier\r
513   : name\r
514       { $1 }\r
515   ;\r
516 \r
517 component_list\r
518   : component_declaration\r
519       { [$1] }\r
520   | component_list CM component_declaration\r
521       { $3 :: $1 }\r
522   ;\r
523 \r
524 component_declaration\r
525   : declaration comment\r
526       { node (ComponentDeclaration ($1, $2)) }\r
527   ;\r
528 \r
529 declaration\r
530   : IDENT array_subscripts_option modification_option\r
531       { node (Declaration ($1, $2, $3)) }\r
532   ;\r
533 \r
534 modification_option\r
535   :\r
536       { None }\r
537   | modification\r
538       { Some $1 }\r
539   ;\r
540 \r
541 /*(2.2.5)*/\r
542 modification\r
543   : class_modification EQ expression\r
544       { node (Modification ($1, Some $3)) }\r
545   | class_modification\r
546       { node (Modification ($1, None)) }\r
547   | EQ expression\r
548       { node (Eq $2) }\r
549   | COLEQ expression\r
550       { node (ColEq $2) }\r
551   ;\r
552 \r
553 class_modification\r
554   : LP RP\r
555       { node (ClassModification []) }\r
556   | LP argument_list RP\r
557       { node (ClassModification (List.rev $2)) }\r
558   | LP argument_list error\r
559       { unclosed "(" 1 ")" 3 }\r
560   | LP error\r
561       { unclosed "(" 1 ")" 2 }\r
562   ;\r
563 \r
564 argument_list\r
565   : argument\r
566       { [$1] }\r
567   | argument CM argument_list\r
568       { $1 :: $3 }\r
569   ;\r
570 \r
571 argument\r
572   : element_modification\r
573       { $1 }\r
574   | element_redeclaration\r
575       { $1 }\r
576   ;\r
577 \r
578 element_modification\r
579   : each_option final_option component_reference modification_option\r
580     string_comment\r
581       { node (ElementModification ($1, $2, $3, $4, $5)) }\r
582   ;\r
583 \r
584 each_option\r
585   :\r
586       { None }\r
587   | EACH\r
588       { Some Each }\r
589   ;\r
590 \r
591 element_redeclaration\r
592   : REDECLARE each_option final_option class_definition_or_component_clause1\r
593       { node (ElementRedeclaration ($2, $3, $4)) }\r
594   ;\r
595 \r
596 class_definition_or_component_clause1\r
597   : class_definition\r
598       { node (ClassDefinitionElement (None, $1, [])) }\r
599   | type_prefix type_specifier component_declaration\r
600       { let cpnt = node (ComponentClause ($1, $2, None, [$3])) in\r
601         node (ComponentClauseElement (None, cpnt, [])) }\r
602   | REPLACEABLE class_definition\r
603       { node (ClassDefinitionElement (Some Replaceable, $2, [])) }\r
604   | REPLACEABLE class_definition constraining_clauses\r
605       { node (ClassDefinitionElement (Some Replaceable, $2, List.rev $3)) }\r
606   | REPLACEABLE type_prefix type_specifier\r
607     component_declaration\r
608       { let cpnt = node (ComponentClause ($2, $3, None, [$4])) in\r
609         node (ComponentClauseElement (Some Replaceable, cpnt, [])) }\r
610   | REPLACEABLE type_prefix type_specifier\r
611     component_declaration constraining_clauses\r
612       { let cpnt = node (ComponentClause ($2, $3, None, [$4])) in\r
613         node (ComponentClauseElement (Some Replaceable, cpnt, List.rev $5)) }\r
614   ;\r
615 \r
616 /*(2.2.6)*/\r
617 equation_clause\r
618   : INITIAL_EQUATION\r
619       { EquationClause (Some Initial, []) }\r
620   | INITIAL_EQUATION equations\r
621       { EquationClause (Some Initial, List.rev $2) }\r
622   | EQUATION\r
623       { EquationClause (None, []) }\r
624   | EQUATION equations\r
625       { EquationClause (None, List.rev $2) }  ;\r
626 \r
627 equations\r
628   : equation comment SC annotation_sc_option\r
629       { [node (Equation (rhs_nodes 1 3 $1, $2, $4))] }\r
630   | equations equation comment SC annotation_sc_option\r
631       { rhs_nodes 2 5 (Equation (rhs_nodes 2 4 $2, $3, $5)) :: $1 }\r
632   ;\r
633 \r
634 algorithm_clause\r
635   : INITIAL_ALGORITHM\r
636       { AlgorithmClause (Some Initial, []) }\r
637   | INITIAL_ALGORITHM algorithms\r
638       { AlgorithmClause (Some Initial, List.rev $2) }\r
639   | ALGORITHM\r
640       { AlgorithmClause (None, []) }\r
641   | ALGORITHM algorithms\r
642       { AlgorithmClause (None, List.rev $2) }\r
643   ;\r
644 \r
645 algorithms\r
646   : algorithm comment SC annotation_sc_option\r
647       { [node (Algorithm (rhs_nodes 1 3 $1, $2, $4))] }\r
648   | algorithms algorithm comment SC annotation_sc_option\r
649       { rhs_nodes 2 5 (Algorithm (rhs_nodes 2 4 $2, $3, $5)) :: $1 }\r
650   ;\r
651 \r
652 equation\r
653   : simple_expression EQ expression\r
654       { Equal ($1, $3) }\r
655   | conditional_equation_e\r
656       { $1 }\r
657   | for_clause_e\r
658       { $1 }\r
659   | connect_clause\r
660       { $1 }\r
661   | when_clause_e\r
662       { $1 }\r
663   | component_reference LP RP\r
664       { FunctionCallE ($1, None) }\r
665   | component_reference LP function_arguments RP\r
666       { FunctionCallE ($1, Some $3) }\r
667   | component_reference LP function_arguments error\r
668       { unclosed "(" 2 ")" 4 }\r
669   | component_reference LP error\r
670       { unclosed "(" 2 ")" 3 }\r
671 ;\r
672 \r
673 algorithm\r
674   : component_reference COLEQ expression\r
675       { Assign ($1, $3) }\r
676   | component_reference LP RP\r
677       { FunctionCallA ($1, None) }\r
678   | component_reference LP function_arguments RP\r
679       { FunctionCallA ($1, Some $3) }\r
680   | component_reference LP function_arguments error\r
681       { unclosed "(" 2 ")" 4 }\r
682   | component_reference LP error\r
683       { unclosed "(" 2 ")" 3 }\r
684   | LP expression_list RP COLEQ component_reference LP RP\r
685       { MultipleAssign ($2, $5, None) }\r
686   | LP RP COLEQ component_reference LP RP\r
687       { MultipleAssign ([], $4, None) }\r
688   | LP expression_list RP COLEQ component_reference LP function_arguments RP\r
689       { MultipleAssign ($2, $5, Some $7) }\r
690   | LP RP COLEQ component_reference LP function_arguments RP\r
691       { MultipleAssign ([], $4, Some $6) }\r
692   | LP expression_list RP COLEQ component_reference LP function_arguments\r
693     error\r
694       { unclosed "(" 6 ")" 8 }\r
695   | LP RP COLEQ component_reference LP function_arguments error\r
696       { unclosed "(" 5 ")" 7 }\r
697   | LP expression_list RP COLEQ component_reference LP error\r
698       { unclosed "(" 6 ")" 7 }\r
699   | LP RP COLEQ component_reference LP error\r
700       { unclosed "(" 5 ")" 6 }\r
701   | LP expression_list error\r
702       { unclosed "(" 1 ")" 3 }\r
703   | LP error\r
704       { unclosed "(" 1 ")" 2 }\r
705   | BREAK\r
706       { Break }\r
707   | RETURN\r
708       { Return }\r
709   | conditional_equation_a\r
710       { $1 }\r
711   | for_clause_a\r
712       { $1 }\r
713   | while_clause\r
714       { $1 }\r
715   | when_clause_a\r
716       { $1 }\r
717   ;\r
718 \r
719 conditional_equation_e\r
720   : IF expression THEN\r
721       equations_e\r
722     else_if_expressions_e\r
723     else_option_e\r
724     END_IF\r
725       { ConditionalEquationE (($2, List.rev $4) :: $5, $6) }\r
726   ;\r
727 \r
728 else_if_expressions_e\r
729   :\r
730       { [] }\r
731   | ELSEIF expression THEN\r
732       equations_e\r
733     else_if_expressions_e\r
734       { ($2, List.rev $4) :: $5 }\r
735   ;\r
736 \r
737 else_option_e\r
738   :\r
739       { None }\r
740   | ELSE equations_e\r
741       { Some (List.rev $2) }\r
742   ;\r
743 \r
744 equations_e\r
745   : equation SC\r
746       { [node $1] }\r
747   | equations_e equation SC\r
748       { rhs_nodes 2 3 $2 :: $1 }\r
749   ;\r
750 \r
751 conditional_equation_a\r
752   : IF expression THEN\r
753       algorithms_a\r
754     else_if_expressions_a\r
755     else_option_a\r
756     END_IF\r
757       { ConditionalEquationA (($2, List.rev $4) :: $5, $6) }\r
758   ;\r
759 \r
760 else_if_expressions_a\r
761   :\r
762       { [] }\r
763   | ELSEIF expression THEN\r
764       algorithms_a\r
765     else_if_expressions_a\r
766       { ($2, List.rev $4) :: $5 }\r
767   ;\r
768 \r
769 else_option_a\r
770   :\r
771       { None }\r
772   | ELSE algorithms_a\r
773       { Some (List.rev $2) }\r
774   ;\r
775 \r
776 algorithms_a\r
777   : algorithm SC\r
778       { [node $1] }\r
779   | algorithms_a algorithm SC\r
780       { rhs_nodes 2 3 $2 :: $1 }\r
781   ;\r
782 \r
783 for_clause_e\r
784   : FOR for_indices LOOP\r
785       equations_e\r
786     END_FOR\r
787       { ForClauseE ($2, List.rev $4) }\r
788   ;\r
789 \r
790 for_clause_a\r
791   : FOR for_indices LOOP\r
792       algorithms_a\r
793     END_FOR\r
794       { ForClauseA ($2, List.rev $4) }\r
795   ;\r
796 \r
797 for_indices\r
798   : for_index\r
799       { [$1] }\r
800   | for_index CM for_indices\r
801       { $1 :: $3 }\r
802   ;\r
803 \r
804 for_index\r
805   : IDENT\r
806       { ($1, None) }\r
807   | IDENT IN expression\r
808       { ($1, Some $3) }\r
809   ;\r
810 \r
811 while_clause\r
812   : WHILE expression LOOP\r
813       algorithms_a\r
814     END_WHILE\r
815       { WhileClause ($2, List.rev $4) }\r
816   ;\r
817 \r
818 when_clause_e\r
819   : WHEN expression THEN\r
820       equations_e\r
821     else_when_expressions_e\r
822     END_WHEN\r
823       { WhenClauseE (($2, List.rev $4) :: $5) }\r
824   ;\r
825 \r
826 when_clause_a\r
827   : WHEN expression THEN\r
828       algorithms_a\r
829     else_when_expressions_a\r
830     END_WHEN\r
831       { WhenClauseA (($2, List.rev $4) :: $5) }\r
832   ;\r
833 \r
834 else_when_expressions_e\r
835   :\r
836       { [] }\r
837   | ELSEWHEN expression THEN\r
838       equations_e\r
839     else_when_expressions_e\r
840       { ($2, List.rev $4) :: $5 }\r
841   ;\r
842 \r
843 else_when_expressions_a\r
844   :\r
845       { [] }\r
846   | ELSEWHEN expression THEN\r
847       algorithms_a\r
848     else_when_expressions_a\r
849       { ($2, List.rev $4) :: $5 }\r
850   ;\r
851 \r
852 connect_clause\r
853   : CONNECT LP component_reference CM component_reference RP\r
854       { ConnectClause ($3, $5) }\r
855   | CONNECT LP component_reference CM component_reference error\r
856       { unclosed "(" 2 ")" 6 }\r
857   ;\r
858 \r
859 /*(2.2.7)*/\r
860 expression\r
861   : simple_expression\r
862       { $1 }\r
863   | IF expression THEN expression\r
864     elseifs_option\r
865     ELSE expression\r
866       { node (If (($2, $4) :: $5, $7)) }\r
867   ;\r
868 \r
869 elseifs_option\r
870   :\r
871       { [] }\r
872   | ELSEIF expression THEN expression\r
873     elseifs_option\r
874       { ($2, $4) :: $5 }\r
875   ;\r
876 \r
877 simple_expression\r
878   : logical_expression\r
879       { $1 }\r
880   | logical_expression CL logical_expression\r
881       { node (Range ($1, None, $3)) }\r
882   | logical_expression CL logical_expression CL logical_expression\r
883       { node (Range ($1, Some $3, $5)) }\r
884   ;\r
885 \r
886 logical_expression\r
887   : logical_term\r
888       { $1 }\r
889   | logical_expression OR logical_term\r
890       { node (BinaryOperation (rhs_nodes 2 2 Or, $1, $3)) }\r
891   ;\r
892 \r
893 logical_term\r
894   : logical_factor\r
895       { $1 }\r
896   | logical_term AND logical_factor\r
897       { node (BinaryOperation (rhs_nodes 2 2 And, $1, $3)) }\r
898   ;\r
899 \r
900 logical_factor\r
901   : relation\r
902       { $1 }\r
903   | NOT relation\r
904       { node (UnaryOperation (rhs_nodes 1 1 Not, $2)) }\r
905   ;\r
906 \r
907 relation\r
908   : arithmetic_expression\r
909       { $1 }\r
910   | arithmetic_expression LT arithmetic_expression\r
911       { node (BinaryOperation (rhs_nodes 2 2 Less, $1, $3)) }\r
912   | arithmetic_expression GT arithmetic_expression\r
913       { node (BinaryOperation (rhs_nodes 2 2 Greater, $1, $3)) }\r
914   | arithmetic_expression LE arithmetic_expression\r
915       { node (BinaryOperation (rhs_nodes 2 2 LessEqual, $1, $3)) }\r
916   | arithmetic_expression GE arithmetic_expression\r
917       { node (BinaryOperation (rhs_nodes 2 2 GreaterEqual, $1, $3)) }\r
918   | arithmetic_expression EE arithmetic_expression\r
919       { node (BinaryOperation (rhs_nodes 2 2 EqualEqual, $1, $3)) }\r
920   | arithmetic_expression NE arithmetic_expression\r
921       { node (BinaryOperation (rhs_nodes 2 2 NotEqual, $1, $3)) }\r
922   ;\r
923 \r
924 arithmetic_expression\r
925   : term\r
926       { $1 }\r
927   | arithmetic_expression PLUS term\r
928       { node (BinaryOperation (rhs_nodes 2 2 Plus, $1, $3)) }\r
929   | arithmetic_expression MINUS term\r
930       { node (BinaryOperation (rhs_nodes 2 2 Minus, $1, $3)) }\r
931   ;\r
932 \r
933 term\r
934   : unary_factor\r
935       { $1 }\r
936   | term STAR unary_factor\r
937       { node (BinaryOperation (rhs_nodes 2 2 Times, $1, $3)) }\r
938   | term SLASH unary_factor\r
939       { node (BinaryOperation (rhs_nodes 2 2 Divide, $1, $3)) }\r
940   ;\r
941 \r
942 unary_factor\r
943   : factor\r
944       { $1 }\r
945   | PLUS unary_factor\r
946       { node (UnaryOperation (rhs_nodes 1 1 UnaryPlus, $2)) }\r
947   | MINUS unary_factor\r
948       { node (UnaryOperation (rhs_nodes 1 1 UnaryMinus, $2)) }\r
949 \r
950 factor\r
951   : primary\r
952       { $1 }\r
953   | factor EXP primary\r
954       { node (BinaryOperation (rhs_nodes 2 2 Power, $1, $3)) }\r
955   ;\r
956 \r
957 primary\r
958   : UNSIGNED_INTEGER\r
959       { node (Integer $1) }\r
960   | UNSIGNED_REAL\r
961       { node (Real $1) }\r
962   | STRING\r
963       { node (String $1) }\r
964   | FALSE\r
965       { node False }\r
966   | TRUE\r
967       { node True }\r
968   | NOEVENT LP expression RP\r
969       { node (NoEvent $3) }\r
970   | component_reference\r
971       { $1 }\r
972   | component_reference LP RP\r
973       { node (FunctionCall ($1, None)) }\r
974   | component_reference LP function_arguments RP\r
975       { node (FunctionCall ($1, Some $3)) }\r
976   | component_reference LP function_arguments error\r
977       { unclosed "(" 2 ")" 4 }\r
978   | component_reference LP error\r
979       { unclosed "(" 2 ")" 3 }\r
980   | LP expression_list RP\r
981       { match $2 with\r
982           | [expr] -> node expr.Syntax.nature\r
983           | _ -> node (Tuple $2) }\r
984   | LP expression_list error\r
985       { unclosed "(" 1 ")" 3 }\r
986   | LSB expression_lists RSB\r
987       { node (MatrixConstruction $2) }\r
988   | LSB error\r
989       { invalid_matrix_construction 1 2 }\r
990   | LCB vector_elements RCB\r
991       { node (Vector $2) }\r
992   | LCB error\r
993       { invalid_literal_array_construction 1 2 }\r
994   | END\r
995       { node End }\r
996   ;\r
997 \r
998 expression_lists\r
999   : expression_list\r
1000       { [$1] }\r
1001   | expression_list SC expression_lists\r
1002       { $1 :: $3 }\r
1003   ;\r
1004 \r
1005 vector_elements\r
1006   : expression FOR for_indices\r
1007       { node (VectorReduction ($1, $3)) }\r
1008   | expression_list\r
1009       { node (VectorElements $1) }\r
1010   ;\r
1011 \r
1012 name\r
1013   : IDENT\r
1014       { node (Identifier $1) }\r
1015   | name DOT IDENT\r
1016       { node (FieldAccess ($1, $3)) }\r
1017   ;\r
1018 \r
1019 component_reference\r
1020   : IDENT\r
1021       { node (Identifier $1) }\r
1022   | IDENT array_subscripts\r
1023       { node (IndexedAccess (rhs_nodes 1 1 (Identifier $1), $2)) }\r
1024   | component_reference DOT IDENT\r
1025       { node (FieldAccess ($1, $3)) }\r
1026   | component_reference DOT IDENT array_subscripts\r
1027       { node (IndexedAccess (rhs_nodes 1 3 (FieldAccess ($1, $3)), $4)) }\r
1028   ;\r
1029 \r
1030 function_arguments\r
1031   : function_arguments_elements\r
1032       { node (ArgumentList (List.rev $1)) }\r
1033   | expression FOR for_indices\r
1034       { node (Reduction ($1, $3)) }\r
1035   ;\r
1036 \r
1037 function_arguments_elements\r
1038   : expression\r
1039       { [node (Argument $1)] }\r
1040   | named_argument\r
1041       { [$1] }\r
1042   | function_arguments_elements CM expression\r
1043       { node (Argument $3) :: $1 }\r
1044   | function_arguments_elements CM named_argument\r
1045       { $3 :: $1 }\r
1046   ;\r
1047 \r
1048 named_argument\r
1049   : IDENT EQ expression\r
1050       { node (NamedArgument ($1, $3)) }\r
1051   | FUNCTION IDENT\r
1052       { failwith "Not yet implemented" }\r
1053   | FUNCTION IDENT LP RP\r
1054       { failwith "Not yet implemented" }\r
1055   | FUNCTION IDENT LP function_arguments RP\r
1056       { failwith "Not yet implemented" }\r
1057   | FUNCTION IDENT LP function_arguments error\r
1058       { unclosed  "(" 3 ")" 5 }\r
1059   | FUNCTION IDENT LP error\r
1060       { unclosed  "(" 3 ")" 4 }\r
1061   ;\r
1062 \r
1063 expression_list\r
1064   : expression\r
1065       { [$1] }\r
1066   | expression CM expression_list\r
1067       { $1 :: $3 }\r
1068   ;\r
1069 \r
1070 array_subscripts\r
1071   : LSB subscripts RSB\r
1072       { node (Subscripts $2) }\r
1073   ;\r
1074 \r
1075 subscripts\r
1076   : subscript\r
1077       { [$1] }\r
1078   | subscript CM subscripts\r
1079       { $1 :: $3 }\r
1080   ;\r
1081 \r
1082 subscript\r
1083   : CL\r
1084       { node Colon }\r
1085   | expression\r
1086       { node (Subscript $1) }\r
1087   ;\r
1088 \r
1089 comment\r
1090   : string_comment annotation_option\r
1091       { node (Comment ($1, $2)) }\r
1092   ;\r
1093 \r
1094 string_comment\r
1095   :\r
1096       { [] }\r
1097   | strings\r
1098       { List.rev $1 }\r
1099   ;\r
1100 \r
1101 strings\r
1102   : STRING\r
1103       { [$1] }\r
1104   | strings PLUS STRING\r
1105       { $3 :: $1 }\r
1106   ;\r
1107 \r
1108 annotation\r
1109   : ANNOTATION class_modification\r
1110       { node (Annotation $2) }\r
1111   ;\r
1112 \r
1113 %%\r
1114 \r
1115 let parse filename token_fun lexbuf =\r
1116   inputfile := filename;\r
1117   try\r
1118     definition token_fun lexbuf\r
1119   with\r
1120     | Unclosed (pos, symbol, pos', symbol') ->\r
1121         raise (SyntacticError\r
1122           {err_msg = ["_Unclosed"; symbol];\r
1123            err_info = [];\r
1124            err_ctx =\r
1125              {location = {start = pos;\r
1126                           enddd = pos';\r
1127                           filename = filename}}})\r
1128     | Invalid_matrix (pos, pos') ->\r
1129         raise (SyntacticError\r
1130           {err_msg = ["_InvalidMatrixConstruct"];\r
1131            err_info = [];\r
1132            err_ctx =\r
1133              {location = {start = pos;\r
1134                           enddd = pos';\r
1135                           filename = filename}}})\r
1136     | Invalid_array (pos, pos') ->\r
1137         raise (SyntacticError\r
1138           {err_msg = ["_InvalidArrayConstruct"];\r
1139            err_info = [];\r
1140            err_ctx =\r
1141              {location = {start = pos;\r
1142                           enddd = pos';\r
1143                           filename = filename}}})\r
1144     | Parsing.Parse_error ->\r
1145         raise (SyntacticError\r
1146           {err_msg = ["_SyntaxError"];\r
1147            err_info = [];\r
1148            err_ctx =\r
1149              {location = {start = Lexing.lexeme_start lexbuf;\r
1150                           enddd = Lexing.lexeme_end lexbuf;\r
1151                           filename = filename}}})\r