end of line
[scilab.git] / scilab / modules / scicos / src / translator / parsing / parser.mly
1 /*
2  *  Translator from Modelica 2.x to flat Modelica
3  *
4  *  Copyright (C) 2005 - 2007 Imagine S.A.
5  *  For more information or commercial use please contact us at www.amesim.com
6  *
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.
11  *
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.
16  *
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.
20  *
21  */
22
23 /*
24  * Parser
25  * Grammar for the Modelica language v2.2
26  * V 1.0
27  * S. FURIC
28  */
29
30 %{
31
32 (** Modelica parser. *)
33
34 (** Implementation based on {i Modelica language specification 2.0 } *)
35
36 open Syntax
37
38 exception Unclosed of int * string * int * string
39 exception Invalid_matrix of int * int
40 exception Invalid_array of int * int
41 exception End_of_file
42
43 type location =
44   {
45     start: int; (* offset in the parsed stream *)
46     enddd: int;  (* offset in the parsed stream *)
47     filename: filename
48   }
49
50 and filename =
51   | LibraryFile of string
52   | CommandLine
53
54 type error_description =
55   {
56     err_msg: string list;
57     err_info: (string * string) list;
58     err_ctx: err_ctx
59   }
60
61 and err_ctx =
62   {
63     location: location;
64   }
65
66 exception SyntacticError of error_description
67
68 let inputfile = ref CommandLine
69
70 let node nature =
71   {
72     nature = nature;
73     info = { start = Parsing.symbol_start ();
74              enddd = Parsing.symbol_end ();
75              filename = !inputfile }
76   }
77
78 let rhs_nodes n n' nature =
79   {
80     nature = nature;
81     info = { start = Parsing.rhs_start n;
82              enddd = Parsing.rhs_end n';
83              filename = !inputfile }
84   }
85
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))
90
91 let invalid_matrix_construction opening_pos error_pos =
92   raise (Invalid_matrix (
93     Parsing.rhs_start opening_pos, Parsing.rhs_start error_pos))
94
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))
98
99 %}
100
101 /*names*/
102 %token <string> IDENT END_IDENT
103
104 /*literals*/
105 %token <string> UNSIGNED_INTEGER UNSIGNED_REAL STRING
106
107 /*keywords*/
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
118
119 /*symbols*/
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 /*  < > <= >= == <>  */
125
126 /*end of file*/
127 %token EOF
128
129 %type <(location Syntax.toplevel_element_desc, location) Syntax.node> definition
130 %start definition
131
132 %%
133
134
135 /*(2.2.1)*/
136 definition
137   : class_definitions
138       { node (ClassDefinitions (List.rev $1)) }
139   | toplevel_expression SC
140       { $1 }
141   | WITHIN SC
142       { node (Within []) }
143   | WITHIN within_name SC
144       { node (Within (List.rev $2)) }
145   | import_clause SC
146       { node (Import $1) }
147   | EOF
148       { raise End_of_file }
149   ;
150
151 class_definitions
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 }
160
161 toplevel_expression
162   : expression
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)))
168           | type_spec ->
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
177     error
178       { unclosed "(" 6 ")" 8 }
179   | LP expression_list RP COLEQ component_reference LP error
180       { unclosed "(" 6 ")" 7 }
181   | BREAK
182       { node (Command (node Break)) }
183   | RETURN
184       { node (Command (node Return)) }
185   | conditional_equation_a
186       { node (Command (node $1)) }
187   | for_clause_a
188       { node (Command (node $1)) }
189   | while_clause
190       { node (Command (node $1)) }
191   | when_clause_a
192       { node (Command (node $1)) }
193   ;
194
195 within_name
196   : IDENT
197       { [$1] }
198   | within_name DOT IDENT
199       { $3 :: $1 }
200   ;
201
202 /*(2.2.2)*/
203 class_definition
204   : encapsulated_option partial_option class_type class_specifier
205       { node (Definition ($1, $2, $3, $4)) }
206   ;
207
208 class_type
209   : CLASS
210       { Class }
211   | MODEL
212       { Model }
213   | BLOCK
214       { Block }
215   | RECORD
216       { Record }
217   | EXPANDABLE CONNECTOR
218       { ExpandableConnector }
219   | CONNECTOR
220       { Connector }
221   | TYPE
222       { Type }
223   | PACKAGE
224       { Package }
225   | FUNCTION
226       { Function }
227   ;
228
229 encapsulated_option
230   :
231       { None }
232   | ENCAPSULATED
233       { Some Encapsulated }
234   ;
235
236 partial_option
237   :
238       { None }
239   | PARTIAL
240       { Some Partial }
241   ;
242
243 class_specifier
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
248     comment
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)) }
257   ;
258
259 base_prefix
260   : type_prefix
261       { $1 }
262   ;
263
264 enum_composition_option
265   :
266       { EnumList None }
267   | enum_composition
268       { $1 }
269   ;
270
271 enum_composition
272   : enum_list
273       { EnumList (Some (List.rev $1)) }
274   | CL
275       { EnumColon}
276   ;
277
278 enum_list
279   : enumeration_literal
280       { [$1] }
281   | enum_list CM enumeration_literal
282       { $3 :: $1 }
283   ;
284
285 enumeration_literal
286   : IDENT comment
287       { node (EnumerationLiteral ($1, $2)) }
288   ;
289
290 composition
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)) }
295   ;
296
297 other_lists
298   :
299       { [] }
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 }
308   ;
309
310 external_option
311   :
312       { None }
313   | EXTERNAL language_specification_option
314     external_function_call_option SC
315     annotation_sc_option
316       { Some (node (External ($2, $3, None, $5))) }
317   | EXTERNAL language_specification_option
318     external_function_call_option annotation SC
319     annotation_sc_option
320       { Some (node (External ($2, $3, Some $4, $6))) }
321   ;
322
323 annotation_option
324   :
325       { None }
326   | annotation
327       { Some $1 }
328   ;
329
330 annotation_sc_option
331   :
332       { None }
333   | annotation SC
334       { Some $1 }
335   ;
336
337 language_specification_option
338   :
339       { None }
340   | STRING
341       { Some $1 }
342   ;
343
344 external_function_call_option
345   :
346       { None }
347   | IDENT LP RP
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 }
353   | IDENT LP error
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 }
363   ;
364
365 expressions
366   : expression
367       { [$1] }
368   | expression CM expressions
369       { $1 :: $3 }
370   ;
371
372 array_subscripts_option
373   :
374       { None }
375   | array_subscripts
376       { Some $1 }
377   ;
378
379 class_modification_option
380   :
381       { None }
382   | class_modification
383       { Some $1 }
384   ;
385
386 element_list
387   : annotation SC
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 }
403   ;
404
405 element_definition
406   : class_definition
407       { node (ClassDefinitionElement (None, $1, [])) }
408   | component_clause
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)) }
418   ;
419
420 redeclare_option
421   :
422       { None }
423   | REDECLARE
424       { Some Redeclare }
425   ;
426
427 final_option
428   :
429       { None }
430   | FINAL
431       { Some Final }
432   ;
433
434 dynamic_scope_option
435   :
436       { None }
437   | INNER
438       { Some Inner }
439   | OUTER
440       { Some Outer }
441   | INNER OUTER
442       { Some InnerOuter }
443   ;
444
445 import_clause
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)) }
452   ;
453
454 constraining_clauses
455   : constraining_clause
456       { [$1] }
457   | constraining_clauses constraining_clause
458       { $2 :: $1 }
459   ;
460
461 /*(2.2.3)*/
462 extends_clause
463   : EXTENDS name class_modification_option annotation_option
464       { node (Extends ($2, $3, $4)) }
465   ;
466
467 constraining_clause
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)) }
472   ;
473
474 /*(2.2.4)*/
475 component_clause
476   : type_prefix type_specifier array_subscripts_option component_list
477       { node (ComponentClause ($1, $2, $3, List.rev $4)) }
478   ;
479
480 type_prefix
481   : flow_option variability_option inout_option
482       { node (TypePrefix ($1, $2, $3)) }
483   ;
484
485 flow_option
486   :
487       { None }
488   | FLOW
489       { Some Flow }
490   ;
491
492 variability_option
493   :
494       { None }
495   | DISCRETE
496       { Some Discrete }
497   | PARAMETER
498       { Some Parameter }
499   | CONSTANT
500       { Some Constant }
501   ;
502
503 inout_option
504   :
505       { None }
506   | INPUT
507       { Some Input }
508   | OUTPUT
509       { Some Output }
510   ;
511
512 type_specifier
513   : name
514       { $1 }
515   ;
516
517 component_list
518   : component_declaration
519       { [$1] }
520   | component_list CM component_declaration
521       { $3 :: $1 }
522   ;
523
524 component_declaration
525   : declaration comment
526       { node (ComponentDeclaration ($1, $2)) }
527   ;
528
529 declaration
530   : IDENT array_subscripts_option modification_option
531       { node (Declaration ($1, $2, $3)) }
532   ;
533
534 modification_option
535   :
536       { None }
537   | modification
538       { Some $1 }
539   ;
540
541 /*(2.2.5)*/
542 modification
543   : class_modification EQ expression
544       { node (Modification ($1, Some $3)) }
545   | class_modification
546       { node (Modification ($1, None)) }
547   | EQ expression
548       { node (Eq $2) }
549   | COLEQ expression
550       { node (ColEq $2) }
551   ;
552
553 class_modification
554   : LP RP
555       { node (ClassModification []) }
556   | LP argument_list RP
557       { node (ClassModification (List.rev $2)) }
558   | LP argument_list error
559       { unclosed "(" 1 ")" 3 }
560   | LP error
561       { unclosed "(" 1 ")" 2 }
562   ;
563
564 argument_list
565   : argument
566       { [$1] }
567   | argument CM argument_list
568       { $1 :: $3 }
569   ;
570
571 argument
572   : element_modification
573       { $1 }
574   | element_redeclaration
575       { $1 }
576   ;
577
578 element_modification
579   : each_option final_option component_reference modification_option
580     string_comment
581       { node (ElementModification ($1, $2, $3, $4, $5)) }
582   ;
583
584 each_option
585   :
586       { None }
587   | EACH
588       { Some Each }
589   ;
590
591 element_redeclaration
592   : REDECLARE each_option final_option class_definition_or_component_clause1
593       { node (ElementRedeclaration ($2, $3, $4)) }
594   ;
595
596 class_definition_or_component_clause1
597   : class_definition
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)) }
614   ;
615
616 /*(2.2.6)*/
617 equation_clause
618   : INITIAL_EQUATION
619       { EquationClause (Some Initial, []) }
620   | INITIAL_EQUATION equations
621       { EquationClause (Some Initial, List.rev $2) }
622   | EQUATION
623       { EquationClause (None, []) }
624   | EQUATION equations
625       { EquationClause (None, List.rev $2) }  ;
626
627 equations
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 }
632   ;
633
634 algorithm_clause
635   : INITIAL_ALGORITHM
636       { AlgorithmClause (Some Initial, []) }
637   | INITIAL_ALGORITHM algorithms
638       { AlgorithmClause (Some Initial, List.rev $2) }
639   | ALGORITHM
640       { AlgorithmClause (None, []) }
641   | ALGORITHM algorithms
642       { AlgorithmClause (None, List.rev $2) }
643   ;
644
645 algorithms
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 }
650   ;
651
652 equation
653   : simple_expression EQ expression
654       { Equal ($1, $3) }
655   | conditional_equation_e
656       { $1 }
657   | for_clause_e
658       { $1 }
659   | connect_clause
660       { $1 }
661   | when_clause_e
662       { $1 }
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 }
671 ;
672
673 algorithm
674   : component_reference COLEQ expression
675       { Assign ($1, $3) }
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
693     error
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 }
703   | LP error
704       { unclosed "(" 1 ")" 2 }
705   | BREAK
706       { Break }
707   | RETURN
708       { Return }
709   | conditional_equation_a
710       { $1 }
711   | for_clause_a
712       { $1 }
713   | while_clause
714       { $1 }
715   | when_clause_a
716       { $1 }
717   ;
718
719 conditional_equation_e
720   : IF expression THEN
721       equations_e
722     else_if_expressions_e
723     else_option_e
724     END_IF
725       { ConditionalEquationE (($2, List.rev $4) :: $5, $6) }
726   ;
727
728 else_if_expressions_e
729   :
730       { [] }
731   | ELSEIF expression THEN
732       equations_e
733     else_if_expressions_e
734       { ($2, List.rev $4) :: $5 }
735   ;
736
737 else_option_e
738   :
739       { None }
740   | ELSE equations_e
741       { Some (List.rev $2) }
742   ;
743
744 equations_e
745   : equation SC
746       { [node $1] }
747   | equations_e equation SC
748       { rhs_nodes 2 3 $2 :: $1 }
749   ;
750
751 conditional_equation_a
752   : IF expression THEN
753       algorithms_a
754     else_if_expressions_a
755     else_option_a
756     END_IF
757       { ConditionalEquationA (($2, List.rev $4) :: $5, $6) }
758   ;
759
760 else_if_expressions_a
761   :
762       { [] }
763   | ELSEIF expression THEN
764       algorithms_a
765     else_if_expressions_a
766       { ($2, List.rev $4) :: $5 }
767   ;
768
769 else_option_a
770   :
771       { None }
772   | ELSE algorithms_a
773       { Some (List.rev $2) }
774   ;
775
776 algorithms_a
777   : algorithm SC
778       { [node $1] }
779   | algorithms_a algorithm SC
780       { rhs_nodes 2 3 $2 :: $1 }
781   ;
782
783 for_clause_e
784   : FOR for_indices LOOP
785       equations_e
786     END_FOR
787       { ForClauseE ($2, List.rev $4) }
788   ;
789
790 for_clause_a
791   : FOR for_indices LOOP
792       algorithms_a
793     END_FOR
794       { ForClauseA ($2, List.rev $4) }
795   ;
796
797 for_indices
798   : for_index
799       { [$1] }
800   | for_index CM for_indices
801       { $1 :: $3 }
802   ;
803
804 for_index
805   : IDENT
806       { ($1, None) }
807   | IDENT IN expression
808       { ($1, Some $3) }
809   ;
810
811 while_clause
812   : WHILE expression LOOP
813       algorithms_a
814     END_WHILE
815       { WhileClause ($2, List.rev $4) }
816   ;
817
818 when_clause_e
819   : WHEN expression THEN
820       equations_e
821     else_when_expressions_e
822     END_WHEN
823       { WhenClauseE (($2, List.rev $4) :: $5) }
824   ;
825
826 when_clause_a
827   : WHEN expression THEN
828       algorithms_a
829     else_when_expressions_a
830     END_WHEN
831       { WhenClauseA (($2, List.rev $4) :: $5) }
832   ;
833
834 else_when_expressions_e
835   :
836       { [] }
837   | ELSEWHEN expression THEN
838       equations_e
839     else_when_expressions_e
840       { ($2, List.rev $4) :: $5 }
841   ;
842
843 else_when_expressions_a
844   :
845       { [] }
846   | ELSEWHEN expression THEN
847       algorithms_a
848     else_when_expressions_a
849       { ($2, List.rev $4) :: $5 }
850   ;
851
852 connect_clause
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 }
857   ;
858
859 /*(2.2.7)*/
860 expression
861   : simple_expression
862       { $1 }
863   | IF expression THEN expression
864     elseifs_option
865     ELSE expression
866       { node (If (($2, $4) :: $5, $7)) }
867   ;
868
869 elseifs_option
870   :
871       { [] }
872   | ELSEIF expression THEN expression
873     elseifs_option
874       { ($2, $4) :: $5 }
875   ;
876
877 simple_expression
878   : logical_expression
879       { $1 }
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)) }
884   ;
885
886 logical_expression
887   : logical_term
888       { $1 }
889   | logical_expression OR logical_term
890       { node (BinaryOperation (rhs_nodes 2 2 Or, $1, $3)) }
891   ;
892
893 logical_term
894   : logical_factor
895       { $1 }
896   | logical_term AND logical_factor
897       { node (BinaryOperation (rhs_nodes 2 2 And, $1, $3)) }
898   ;
899
900 logical_factor
901   : relation
902       { $1 }
903   | NOT relation
904       { node (UnaryOperation (rhs_nodes 1 1 Not, $2)) }
905   ;
906
907 relation
908   : arithmetic_expression
909       { $1 }
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)) }
922   ;
923
924 arithmetic_expression
925   : term
926       { $1 }
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)) }
931   ;
932
933 term
934   : unary_factor
935       { $1 }
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)) }
940   ;
941
942 unary_factor
943   : factor
944       { $1 }
945   | PLUS unary_factor
946       { node (UnaryOperation (rhs_nodes 1 1 UnaryPlus, $2)) }
947   | MINUS unary_factor
948       { node (UnaryOperation (rhs_nodes 1 1 UnaryMinus, $2)) }
949
950 factor
951   : primary
952       { $1 }
953   | factor EXP primary
954       { node (BinaryOperation (rhs_nodes 2 2 Power, $1, $3)) }
955   ;
956
957 primary
958   : UNSIGNED_INTEGER
959       { node (Integer $1) }
960   | UNSIGNED_REAL
961       { node (Real $1) }
962   | STRING
963       { node (String $1) }
964   | FALSE
965       { node False }
966   | TRUE
967       { node True }
968   | NOEVENT LP expression RP
969       { node (NoEvent $3) }
970   | component_reference
971       { $1 }
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
981       { match $2 with
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) }
988   | LSB error
989       { invalid_matrix_construction 1 2 }
990   | LCB vector_elements RCB
991       { node (Vector $2) }
992   | LCB error
993       { invalid_literal_array_construction 1 2 }
994   | END
995       { node End }
996   ;
997
998 expression_lists
999   : expression_list
1000       { [$1] }
1001   | expression_list SC expression_lists
1002       { $1 :: $3 }
1003   ;
1004
1005 vector_elements
1006   : expression FOR for_indices
1007       { node (VectorReduction ($1, $3)) }
1008   | expression_list
1009       { node (VectorElements $1) }
1010   ;
1011
1012 name
1013   : IDENT
1014       { node (Identifier $1) }
1015   | name DOT IDENT
1016       { node (FieldAccess ($1, $3)) }
1017   ;
1018
1019 component_reference
1020   : IDENT
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)) }
1028   ;
1029
1030 function_arguments
1031   : function_arguments_elements
1032       { node (ArgumentList (List.rev $1)) }
1033   | expression FOR for_indices
1034       { node (Reduction ($1, $3)) }
1035   ;
1036
1037 function_arguments_elements
1038   : expression
1039       { [node (Argument $1)] }
1040   | named_argument
1041       { [$1] }
1042   | function_arguments_elements CM expression
1043       { node (Argument $3) :: $1 }
1044   | function_arguments_elements CM named_argument
1045       { $3 :: $1 }
1046   ;
1047
1048 named_argument
1049   : IDENT EQ expression
1050       { node (NamedArgument ($1, $3)) }
1051   | FUNCTION IDENT
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 }
1061   ;
1062
1063 expression_list
1064   : expression
1065       { [$1] }
1066   | expression CM expression_list
1067       { $1 :: $3 }
1068   ;
1069
1070 array_subscripts
1071   : LSB subscripts RSB
1072       { node (Subscripts $2) }
1073   ;
1074
1075 subscripts
1076   : subscript
1077       { [$1] }
1078   | subscript CM subscripts
1079       { $1 :: $3 }
1080   ;
1081
1082 subscript
1083   : CL
1084       { node Colon }
1085   | expression
1086       { node (Subscript $1) }
1087   ;
1088
1089 comment
1090   : string_comment annotation_option
1091       { node (Comment ($1, $2)) }
1092   ;
1093
1094 string_comment
1095   :
1096       { [] }
1097   | strings
1098       { List.rev $1 }
1099   ;
1100
1101 strings
1102   : STRING
1103       { [$1] }
1104   | strings PLUS STRING
1105       { $3 :: $1 }
1106   ;
1107
1108 annotation
1109   : ANNOTATION class_modification
1110       { node (Annotation $2) }
1111   ;
1112
1113 %%
1114
1115 let parse filename token_fun lexbuf =
1116   inputfile := filename;
1117   try
1118     definition token_fun lexbuf
1119   with
1120     | Unclosed (pos, symbol, pos', symbol') ->
1121         raise (SyntacticError
1122           {err_msg = ["_Unclosed"; symbol];
1123            err_info = [];
1124            err_ctx =
1125              {location = {start = pos;
1126                           enddd = pos';
1127                           filename = filename}}})
1128     | Invalid_matrix (pos, pos') ->
1129         raise (SyntacticError
1130           {err_msg = ["_InvalidMatrixConstruct"];
1131            err_info = [];
1132            err_ctx =
1133              {location = {start = pos;
1134                           enddd = pos';
1135                           filename = filename}}})
1136     | Invalid_array (pos, pos') ->
1137         raise (SyntacticError
1138           {err_msg = ["_InvalidArrayConstruct"];
1139            err_info = [];
1140            err_ctx =
1141              {location = {start = pos;
1142                           enddd = pos';
1143                           filename = filename}}})
1144     | Parsing.Parse_error ->
1145         raise (SyntacticError
1146           {err_msg = ["_SyntaxError"];
1147            err_info = [];
1148            err_ctx =
1149              {location = {start = Lexing.lexeme_start lexbuf;
1150                           enddd = Lexing.lexeme_end lexbuf;
1151                           filename = filename}}})