copy SCI/ocaml to SCI/scicos/src/modelica_compiler
[scilab.git] / scilab / modules / scicos / src / modelica_compiler / parser.mly
1 /*  Scicos
2 *
3 *  Copyright (C) INRIA - S. FURIC
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * See the file ./license.txt
20 */
21
22 /*
23  * Parser
24  * Grammar for the Modelica language v.2.0
25  * V 1.0
26  * S. FURIC
27  */
28
29 %{
30
31 open ParseTree
32
33 %}
34
35 /*names*/
36 %token <string> IDENT
37
38 /*literals*/
39 %token <string> UNSIGNED_INTEGER UNSIGNED_NUMBER STRING
40
41 /*keywords*/
42 %token ALGORITHM AND ANNOTATION ASSERT BLOCK CLASS CONNECT CONNECTOR CONSTANT
43 %token DISCRETE EACH ELSE ELSEIF ELSEWHEN ENCAPSULATED END ENUMERATION EQUATION
44 %token EXTENDS EXTERNAL FALSE FINAL FLOW FOR FUNCTION IF IMPORT IN INITIAL
45 %token INNER INPUT LOOP MODEL NOT OR OUTER OUTPUT PACKAGE PARAMETER PARTIAL
46 %token PROTECTED PUBLIC RECORD REDECLARE REPLACEABLE TERMINATE THEN TRUE TYPE
47 %token WHEN WHILE WITHIN
48
49 /*symbols*/
50 %token LP RP LSB RSB LCB RCB  /*  ( ) [ ] { }  */
51 %token DOT CM SC CL /*  . , ; :  */
52 %token PLUS MINUS STAR SLASH EXP /*  + - * / ^  */
53 %token EQ COLEQ /*  = :=  */
54 %token LT GT LE GE EE NE /*  < > <= >= == <>  */
55
56 /*end of file*/
57 %token EOF
58
59 %type <ParseTree.t> stored_definition_eof
60 %start stored_definition_eof
61
62 %%
63
64 /*(0.0)*/
65 stored_definition_eof
66     : stored_definition EOF                                     { $1 }
67     ;
68
69 /*(2.2.1)*/
70 stored_definition
71     : class_definitions                                         { StoredDefinition (NotWithin, List.rev $1) }
72     | WITHIN SC class_definitions                               { StoredDefinition (Within None, List.rev $3) }
73     | WITHIN name SC class_definitions                          { StoredDefinition (Within (Some $2), List.rev $4) }
74     ;
75
76 class_definitions
77     :                                                           { [] }
78     | class_definitions class_definition SC                     { Definition (NotFinal, $2) :: $1 }
79     | class_definitions FINAL class_definition SC               { Definition (Final, $3) :: $1 }
80     ;
81
82 /*(2.2.2)*/
83 class_definition
84     : encapsulated_option partial_option CLASS
85       IDENT class_specifier                                     { ClassDefinition (Class, $4, $1, $2, $5) }
86     | encapsulated_option partial_option MODEL
87       IDENT class_specifier                                     { ClassDefinition (Model, $4, $1, $2, $5) }
88     | encapsulated_option partial_option RECORD
89       IDENT class_specifier                                     { ClassDefinition (Record, $4, $1, $2, $5) }
90     | encapsulated_option partial_option CONNECTOR
91       IDENT class_specifier                                     { ClassDefinition (Connector, $4, $1, $2, $5) }
92     | encapsulated_option partial_option TYPE
93       IDENT class_specifier                                     { ClassDefinition (Type, $4, $1, $2, $5) }
94     | encapsulated_option partial_option PACKAGE
95       IDENT class_specifier                                     { ClassDefinition (Package, $4, $1, $2, $5) }
96     | encapsulated_option partial_option FUNCTION
97       IDENT class_specifier                                     { ClassDefinition (Function, $4, $1, $2, $5) }
98     ;
99
100 encapsulated_option
101     :                                                           { NotEncapsulated }
102     | ENCAPSULATED                                              { Encapsulated }
103     ;
104
105 partial_option
106     :                                                           { NotPartial }
107     | PARTIAL                                                   { Partial }
108     ;
109
110 class_specifier
111     : string_comment composition END IDENT                      { Specifier ($1, $2, $4) }
112     | EQ base_prefix name array_subscripts_option class_modification_option
113       comment                                                   { ShortSpecifier ($2, $3, $4, $5, $6) }
114     | EQ ENUMERATION LP enum_list_option RP comment             { Enumeration ($4, $6) }
115     ;
116
117 base_prefix
118     : type_prefix                                               { $1 }
119     ;
120
121 enum_list_option
122     :                                                           { [] }
123     | enum_list                                                 { List.rev $1 }
124     ;
125
126 enum_list
127     : enumeration_literal                                       { [$1] }
128     | enum_list SC enumeration_literal                          { $3 :: $1 }
129     ;
130
131 enumeration_literal
132     : IDENT comment                                             { EnumerationLiteral ($1, $2) }
133     ;
134
135 composition
136     : element_list other_lists external_option                  { Composition ($1, List.rev $2, $3) }
137     ;
138
139 other_lists
140     :                                                           { [] }
141     | other_lists PUBLIC element_list                           { Public $3 :: $1 }
142     | other_lists PROTECTED element_list                        { Protected $3 :: $1 }
143     | other_lists equation_clause                               { EquationClauseElement $2 :: $1 }
144     | other_lists algorithm_clause                              { AlgorithmClauseElement $2 :: $1 }
145     ;
146
147 external_option
148     :                                                           { None }
149     | EXTERNAL language_specification_option
150                external_function_call_option SC annotation_option
151                                                                 { Some (External ($2, $3, $5)) }
152     ;
153
154 annotation_option
155     :                                                           { None }
156     | annotation SC                                             { Some $1 }
157     ;
158
159 language_specification_option
160     :                                                           { None }
161     | STRING                                                    { Some $1 }
162     ;
163
164 external_function_call_option
165     :                                                           { None }
166     | IDENT LP expressions RP                                   { Some (ExternalFunctionCall (None, $1, $3)) }
167     | component_reference EQ IDENT LP expressions RP            { Some (ExternalFunctionCall (Some $1, $3, $5)) }
168     ;
169
170
171 expressions
172     :                                                           { [] }
173     | expression CM expressions                                 { $1 :: $3 }
174     ;
175
176 array_subscripts_option
177     :                                                           { [||] }
178     | array_subscripts                                          { Array.of_list $1 }
179     ;
180
181 class_modification_option
182     :                                                           { None }
183     | class_modification                                        { Some $1 }
184     ;
185
186 element_list
187     :                                                           { [] }
188     | element_list IMPORT import_clause SC                      { ImportClause $3 :: $1 }
189     | element_list EXTENDS extends_clause SC                    { ExtendsClause $3 :: $1 }
190     | element_list final_option dynamic_scope_option
191         class_definition SC                                     { ClassDefinitionElement ($4, $2, $3) :: $1 }
192     | element_list final_option dynamic_scope_option
193         component_clause SC                                     { ComponentClauseElement ($4, $2, $3) :: $1 }
194     | element_list final_option dynamic_scope_option
195         REPLACEABLE class_definition
196         constraining_clause_option SC                           { ReplaceableClassDefinition ($5, $6, $2, $3) :: $1 }
197     | element_list final_option dynamic_scope_option
198         REPLACEABLE component_clause
199         constraining_clause_option SC                           { ReplaceableComponentClause ($5, $6, $2, $3) :: $1 }
200     | element_list annotation SC                                { AnnotationElement $2 :: $1 }
201     ;
202
203 final_option
204     :                                                           { NotFinal }
205     | FINAL                                                     { Final }
206     ;
207
208 dynamic_scope_option
209     :                                                           { NoDynamicScope }
210     | INNER                                                     { Inner }
211     | OUTER                                                     { Outer }
212     ;
213
214 import_clause
215     : IDENT EQ name comment                                     { NewIdentifier ($1, $3, $4) }
216     | name comment                                              { Identifier ($1, $2) }
217     | name DOT STAR comment                                     { AllIdentifiers ($1, $4) }
218     ;
219
220 constraining_clause_option
221     :                                                           { None }
222     | constraining_clause comment                               { Some ($1, $2) }
223     ;
224
225 /*(2.2.3)*/
226 extends_clause
227     : name class_modification_option                            { ($1, $2) }
228     ;
229
230 constraining_clause
231     : extends_clause                                            { $1 }
232     ;
233
234 /*(2.2.4)*/
235 component_clause
236     : type_prefix type_specifier array_subscripts_option
237         component_list                                          { ComponentClause ($1, $2, $3, List.rev $4) }
238     ;
239
240 type_prefix
241     : flow_option variability_option inout_option               { TypePrefix ($1, $2, $3) }
242     ;
243
244 flow_option
245     :                                                           { None }
246     | FLOW                                                      { Some Flow }
247     ;
248
249 variability_option
250     :                                                           { None }
251     | DISCRETE                                                  { Some Discrete }
252     | PARAMETER                                                 { Some Parameter }
253     | CONSTANT                                                  { Some Constant }
254     ;
255
256 inout_option
257     :                                                           { None }
258     | INPUT                                                     { Some Input }
259     | OUTPUT                                                    { Some Output }
260     ;
261
262 type_specifier
263     : name                                                      { $1 }
264     ;
265
266 component_list
267     : component_declaration                                     { [$1] }
268     | component_list CM component_declaration                   { $3 :: $1 }
269     ;
270
271 component_declaration
272     : declaration comment                                       { ComponentDeclaration ($1, $2) }
273     ;
274
275 declaration
276     : IDENT array_subscripts_option modification_option         { ($1, $2, $3) }
277     ;
278
279 modification_option
280     :                                                           { None }
281     | modification                                              { Some $1 }
282     ;
283
284 /*(2.2.5)*/
285 modification
286     : class_modification EQ expression                          { Modification ($1, Some $3) }
287     | class_modification                                        { Modification ($1, None) }
288     | EQ expression                                             { Eq $2 }
289     | COLEQ expression                                          { ColEq $2 }
290     ;
291
292 class_modification
293     : LP argument_list RP                                       { ClassModification (List.rev $2) }
294     ;
295
296 argument_list
297     : argument                                                  { [$1] }
298     | argument CM argument_list                                 { $1 :: $3 }
299     ;
300
301 argument
302     : element_modification                                      { $1 }
303     | element_redeclaration                                     { $1 }
304     ;
305
306 element_modification
307     : component_reference modification string_comment           { ElementModification (NotEach, NotFinal,$1, $2, $3) }
308     | EACH component_reference modification string_comment      { ElementModification (Each, NotFinal,$2, $3, $4) }
309     | FINAL component_reference modification string_comment     { ElementModification (NotEach, Final,$2, $3, $4) }
310     | EACH FINAL
311       component_reference modification string_comment           { ElementModification (Each, Final,$3, $4, $5) }
312     ;
313
314 element_redeclaration
315     : REDECLARE  class_definition_or_component_clause1          { ElementRedeclaration (NotEach, NotFinal, $2) }
316     | REDECLARE EACH class_definition_or_component_clause1      { ElementRedeclaration (Each, NotFinal, $3) }
317     | REDECLARE FINAL class_definition_or_component_clause1     { ElementRedeclaration (NotEach, Final, $3) }
318     | REDECLARE EACH FINAL
319       class_definition_or_component_clause1                     { ElementRedeclaration (Each, Final, $4) }
320     ;
321
322 class_definition_or_component_clause1
323     : class_definition                                          { Redeclaration (NotReplaceable, RedeclaredClassDefinition $1, None) }
324     | type_prefix type_specifier component_declaration          { Redeclaration (NotReplaceable, RedeclaredComponentClause ($1, $2, $3), None) }
325     | REPLACEABLE class_definition constraining_clause_option   { Redeclaration (Replaceable, RedeclaredClassDefinition $2, $3) }
326     | REPLACEABLE type_prefix type_specifier
327       component_declaration constraining_clause_option          { Redeclaration (Replaceable, RedeclaredComponentClause ($2, $3, $4), $5) }
328     ;
329
330 /*(2.2.6)*/
331 equation_clause
332     : INITIAL EQUATION equations                                { EquationClause (Initial, List.rev $3) }
333     | EQUATION equations                                        { EquationClause (NotInitial, List.rev $2) }
334     ;
335
336 equations
337     :                                                           { [] }
338     | equations equation comment SC                             { Equation ($2, $3) :: $1 }
339     | equations annotation SC                                   { EquationAnnotation $2 :: $1 }
340     ;
341
342 algorithm_clause
343     : INITIAL ALGORITHM algorithms                              { AlgorithmClause (Initial, List.rev $3) }
344     | ALGORITHM algorithms                                      { AlgorithmClause (NotInitial, List.rev $2) }
345     ;
346
347 algorithms
348     :                                                           { [] }
349     | algorithms algorithm comment SC                           { Algorithm ($2, $3) :: $1 }
350     | algorithms annotation SC                                  { AlgorithmAnnotation $2 :: $1 }
351     ;
352
353 equation
354     : simple_expression EQ expression                           { Equality ($1, $3) }
355     | conditional_equation_e                                    { $1 }
356     | for_clause_e                                              { $1 }
357     | connect_clause                                            { $1 }
358     | when_clause_e                                             { $1 }
359     | component_reference LP RP                                 { FunctionCallE ($1, None) }
360     | component_reference LP function_arguments RP              { FunctionCallE ($1, Some $3) }
361     ;
362
363 algorithm
364     : component_reference COLEQ expression                      { Assignment ($1, $3) }
365     | component_reference LP RP                                 { FunctionCallA ($1, None) }
366     | component_reference LP function_arguments RP              { FunctionCallA ($1, Some $3) }
367     | LP expression_list RP COLEQ
368       component_reference LP RP                                 { MultipleAssignment ($2, $5, None) }
369     | LP expression_list RP COLEQ
370       component_reference LP function_arguments RP              { MultipleAssignment ($2, $5, Some $7) }
371     | conditional_equation_a                                    { $1 }
372     | for_clause_a                                              { $1 }
373     | while_clause                                              { $1 }
374     | when_clause_a                                             { $1 }
375     ;
376
377 conditional_equation_e
378     : IF expression THEN
379         equations_e
380       else_if_expressions_e
381       else_option_e
382       END IF                                                    { ConditionalEquationE (($2, (List.rev $4)) :: $5, $6) }
383     ;
384
385 else_if_expressions_e
386     :                                                           { [] }
387     | ELSEIF expression THEN
388         equations_e
389       else_if_expressions_e                                     { ($2, (List.rev $4)) :: $5 }
390     ;
391
392 else_option_e
393     :                                                           { [] }
394     | ELSE equations_e                                          { List.rev $2 }
395     ;
396
397 equations_e
398     : equation SC                                               { [$1] }
399     | equations_e equation SC                                   { $2 :: $1 }
400     ;
401
402 conditional_equation_a
403     : IF expression THEN
404         algorithms_a
405       else_if_expressions_a
406       else_option_a
407       END IF                                                    { ConditionalEquationA (($2, (List.rev $4)) :: $5, $6) }
408     ;
409
410 else_if_expressions_a
411     :                                                           { [] }
412     | ELSEIF expression THEN
413         algorithms_a
414       else_if_expressions_a                                     { ($2, (List.rev $4)) :: $5 }
415     ;
416
417 else_option_a
418     :                                                           { [] }
419     | ELSE algorithms_a                                         { List.rev $2 }
420     ;
421
422 algorithms_a
423     : algorithm SC                                              { [$1] }
424     | algorithms_a algorithm SC                                 { $2 :: $1 }
425     ;
426
427 for_clause_e
428     : FOR for_indices LOOP
429         equations_e
430       END FOR                                                   { ForClauseE ($2, List.rev $4) }
431     ;
432
433 for_clause_a
434     : FOR for_indices LOOP
435         algorithms_a
436       END FOR                                                   { ForClauseA ($2, List.rev $4) }
437     ;
438
439 for_indices
440     : for_index                                                 { [$1] }
441     | for_index CM for_indices                                  { $1 :: $3 }
442     ;
443
444 for_index
445     : IDENT in_expression_option                                { ($1, $2) }
446     ;
447
448 in_expression_option
449     :                                                           { None }
450     | IN expression                                             { Some $2 }
451     ;
452
453 while_clause
454     : WHILE expression LOOP
455         algorithms_a
456       END WHILE                                                 { WhileClause ($2, List.rev $4) }
457     ;
458
459 when_clause_e
460     : WHEN expression THEN
461         equations_e
462       else_when_expressions_e
463       END WHEN                                                  { WhenClauseE (($2, $4) :: $5) }
464     ;
465
466 when_clause_a
467     : WHEN expression THEN
468         algorithms_a
469       else_when_expressions_a
470       END WHEN                                                  { WhenClauseA (($2, $4) :: $5) }
471     ;
472
473 else_when_expressions_e
474     :                                                           { [] }
475     | ELSEWHEN expression THEN
476         equations_e
477       else_when_expressions_e                                   { ($2, $4) :: $5 }
478     ;
479
480 else_when_expressions_a
481     :                                                           { [] }
482     | ELSEWHEN expression THEN
483         algorithms_a
484       else_when_expressions_a                                   { ($2, $4) :: $5 }
485     ;
486
487 connect_clause
488     : CONNECT LP connector_ref CM connector_ref RP              { ConnectClause ($3, $5) }
489     ;
490
491 connector_ref
492     : IDENT array_subscripts_option                             { [($1, $2)] }
493     | IDENT array_subscripts_option
494         DOT IDENT array_subscripts_option                       { [($1, $2); ($4, $5)] }
495     ;
496
497 /*(2.2.7)*/
498 expression
499     : simple_expression                                         { $1 }
500     | IF expression THEN expression
501       elseifs_option
502       ELSE expression                                           { If (($2, $4) :: $5, $7) }
503     ;
504
505 elseifs_option
506     :                                                           { [] }
507     | ELSEIF expression THEN expression
508       elseifs_option                                            { ($2, $4) :: $5 }
509     ;
510
511 simple_expression
512     : logical_expression                                        { $1 }
513     | logical_expression CL logical_expression                  { Range ($1, $3, None) }
514     | logical_expression
515         CL logical_expression CL logical_expression             { Range ($1, $3, Some $5) }
516     ;
517
518 logical_expression
519     : logical_term                                              { $1 }
520     | logical_expression OR logical_term                        { Or ($1, $3) }
521     ;
522
523 logical_term
524     : logical_factor                                            { $1 }
525     | logical_term AND logical_factor                           { And ($1, $3) }
526     ;
527
528 logical_factor
529     : relation                                                  { $1 }
530     | NOT relation                                              { Not $2 }
531     ;
532
533 relation
534     : arithmetic_expression                                     { $1 }
535     | arithmetic_expression LT arithmetic_expression            { LessThan ($1, $3) }
536     | arithmetic_expression GT arithmetic_expression            { GreaterThan ($1, $3) }
537     | arithmetic_expression LE arithmetic_expression            { LessEqualThan ($1, $3) }
538     | arithmetic_expression GE arithmetic_expression            { GreaterEqualThan ($1, $3) }
539     | arithmetic_expression EE arithmetic_expression            { Equals ($1, $3) }
540     | arithmetic_expression NE arithmetic_expression            { NotEquals ($1, $3) }
541     ;
542
543 arithmetic_expression
544     : signed_term                                               { $1 }
545     | arithmetic_expression PLUS term                           { Addition ($1, $3) }
546     | arithmetic_expression MINUS term                          { Subtraction ($1, $3) }
547     ;
548
549 signed_term
550     : term                                                      { $1 }
551     | PLUS term                                                 { Plus $2 }
552     | MINUS term                                                { Minus $2 }
553     ;
554
555 term
556     : factor                                                    { $1 }
557     | term STAR factor                                          { Multiplication ($1, $3) }
558     | term SLASH factor                                         { Division ($1, $3) }
559     ;
560
561 factor
562     : primary                                                   { $1 }
563     | primary EXP primary                                       { Power ($1, $3) }
564     ;
565
566 primary
567     : UNSIGNED_INTEGER                                          { Integer $1 }
568     | UNSIGNED_NUMBER                                           { Real $1 }
569     | STRING                                                    { String $1 }
570     | FALSE                                                     { False }
571     | TRUE                                                      { True }
572     | component_reference                                       { Reference $1 }
573     | component_reference LP RP                                 { FunctionCall ($1, None) }
574     | component_reference LP function_arguments RP              { FunctionCall ($1, Some $3) }
575     | LP expression_list RP                                     { ExpressionList (Array.of_list $2) }
576     | LSB expression_lists RSB                                  { ArrayConcatenation $2 }
577     | LCB function_arguments RCB                                { VectorOrRecord $2 }
578     ;
579
580 expression_lists
581     : expression_list                                           { [$1] }
582     | expression_list SC expression_lists                       { $1 :: $3 }
583     ;
584
585 name
586     : IDENT                                                     { [$1] }
587     | name DOT IDENT                                            { $1 @ [$3] }
588     ;
589
590 component_reference
591     : IDENT array_subscripts_option                             { [$1, $2] }
592     | IDENT array_subscripts_option DOT component_reference     { ($1, $2) :: $4 }
593     ;
594
595 function_arguments
596     : expression FOR for_indices                                { ArgList ([$1], Some $3) }
597     | expression CM expression_list FOR for_indices             { ArgList ($1 :: $3, Some $5) }
598     | expression                                                { ArgList ([$1], None) }
599     | expression CM expression_list                             { ArgList ($1 :: $3, None) }
600     | named_arguments FOR for_indices                           { NamedArgList ($1, Some $3) }
601     | named_arguments                                           { NamedArgList ($1, None) }
602     ;
603
604 named_arguments
605     : named_argument                                            { [$1] }
606     | named_argument CM named_arguments                         { $1 :: $3 }
607     ;
608
609 named_argument
610     : IDENT EQ expression                                       { ($1, $3) }
611     ;
612
613 expression_list
614     : expression                                                { [$1] }
615     | expression CM expression_list                             { $1 :: $3 }
616     ;
617
618 array_subscripts
619     : LSB subscripts RSB                                        { $2 }
620     ;
621
622 subscripts
623     : subscript                                                 { [$1] }
624     | subscript CM subscripts                                   { $1 :: $3 }
625     ;
626
627 subscript
628     : CL                                                        { All }
629     | expression                                                { Subscript $1 }
630     ;
631
632 comment
633     : string_comment                                            { Comment ($1, None) }
634     | string_comment annotation                                 { Comment ($1, Some $2) }
635     ;
636
637 string_comment
638     :                                                           { StringComment [] }
639     | strings                                                   { StringComment (List.rev $1) }
640     ;
641
642 strings
643     : STRING                                                    { [$1] }
644     | strings PLUS STRING                                       { $3 :: $1 }
645     ;
646
647 annotation
648     : ANNOTATION class_modification                             { Annotation $2 }
649     ;
650
651 %%
652
653 let parse filename token_fun lexbuf =
654   try stored_definition_eof token_fun lexbuf with
655     | Parsing.Parse_error ->
656         let linenum, linebeg =
657           Linenum.for_position filename (Lexing.lexeme_start lexbuf)
658         and linenum', linebeg' =
659           Linenum.for_position filename (Lexing.lexeme_end lexbuf)
660         in
661         let first_char = Lexing.lexeme_start lexbuf - linebeg
662         and first_char' = Lexing.lexeme_end lexbuf - linebeg'
663         in
664         Printf.eprintf
665           "Syntax error at line %d, characters %d to %d\n"
666           linenum
667           first_char 
668           ((Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf) + first_char);
669         raise Parsing.Parse_error