source: CIVL/mods/dev.civl.abc/grammar/mfortran/MFortranParser2018.g

main
Last change on this file was aad342c, checked in by Stephen Siegel <siegel@…>, 3 years ago

Performing huge refactor to incorporate ABC, GMC, and SARL into CIVL repo and use Java modules.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5664 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 156.0 KB
Line 
1parser grammar MFortranParser2018;
2
3options {
4 language=Java;
5 superClass=BaseMFortranParser;
6 tokenVocab=MFortranLexer;
7}
8
9@header {
10 package dev.civl.abc.front.fortran.parse;
11
12 import dev.civl.abc.token.IF.CivlcToken;
13 import dev.civl.abc.front.fortran.ptree.MFPUtils;
14}
15
16@members {
17 int gctr0;
18 int gctr1;
19
20 public void initialize() {
21 MFPA.start_of_file(fileName, pathName);
22 }
23
24 public void finalize() {
25 MFPA.end_of_file(fileName, pathName);
26 }
27}
28
29/*
30 * ISO IECJTC1 SC22 WG5 N2146 Fortran 2018 Draft
31 */
32
33/*
34 * Rules omitted:
35 * R501 program
36 * R502 program_unit
37 * R503 external_subprogram
38 *
39 * OFP: top level rules will be handled by
40 * an antlr parser instance.
41 */
42
43/*
44 * R501: program
45 * R502: program unit
46 */
47
48/*
49 * R503: external subprogram
50 * is function subprogram
51 * or subroutine-subprogram
52 *
53 * OFP: a dummy rule provides an entry that
54 * an antlr Parser instance can call it to handle functions.
55 */
56ext_function_subprogram
57@init{
58 boolean hasPrefix=false;
59}
60@after{
61 MFPA.ext_function_subprogram(hasPrefix);
62}
63 : ( prefix {hasPrefix=true;} )?
64 function_subprogram
65 ;
66
67/*
68 * R504: specification part
69 *
70 * OFP: 'implicit_part' made non-optional
71 * for fixing ambiguity
72 */
73specification_part
74@init{
75 int numUS=0;
76 int numIS=0;
77 gctr0=0;
78 gctr1=0;
79}
80@after{
81 MFPA.specification_part(numUS, numIS, gctr0, gctr1);
82}
83 : ( use_stmt {numUS++;} )*
84 ( import_stmt {numIS++;} )*
85 implicit_part_recursion
86 ( declaration_construct {gctr1++;} )*
87 ;
88
89/*
90 * R505: implicit part
91 * R506: implicit part stmt
92 */
93implicit_part_recursion
94 : ((label)? IMPLICIT) =>
95 implicit_stmt {gctr0++;} implicit_part_recursion
96 | ((label)? PARAMETER) =>
97 parameter_stmt {gctr1++;} implicit_part_recursion
98 | ((label)? FORMAT) =>
99 format_stmt {gctr1++;} implicit_part_recursion
100 | ((label)? ENTRY) =>
101 entry_stmt {gctr1++;} implicit_part_recursion
102 | // empty
103 ;
104
105/*
106 * R507: declaration construct
107 * R508: specification construct
108 * R513: other specification stmt
109 * TODO:
110 * R1510 generic stmt
111 */
112declaration_construct
113@after{
114 MFPA.declaration_construct();
115}
116 : access_stmt
117 | allocatable_stmt
118 | asynchronous_stmt
119 | bind_stmt
120 | codimension_stmt
121 | common_stmt
122 | data_stmt
123 | derived_type_def
124 | dimension_stmt
125 | entry_stmt
126 | enum_def
127 | equivalence_stmt
128 | external_stmt
129 | format_stmt
130 | intent_stmt
131 | interface_block
132 | intrinsic_stmt
133 | namelist_stmt
134 | optional_stmt
135 | parameter_stmt
136 | pointer_stmt
137 | procedure_declaration_stmt
138 | protected_stmt
139 | save_stmt
140 | target_stmt
141 | type_declaration_stmt
142 | volatile_stmt
143 | value_stmt
144 | stmt_function_stmt
145 | pragma_type_qualifier_stmt
146 ;
147
148/*
149 * R509: execution part
150 */
151execution_part
152@init{
153 int numExec = 1;
154}
155@after{
156 MFPA.execution_part(numExec);
157}
158 : executable_construct
159 ( execution_part_construct {numExec++;} )*
160 ;
161
162/*
163 * R510: execution part construct
164 */
165execution_part_construct
166@after {
167 MFPA.execution_part_construct();
168}
169 : executable_construct
170 | data_stmt
171 | entry_stmt
172 | format_stmt
173 ;
174
175/*
176 * R511: internal subprogram part
177 */
178internal_subprogram_part
179@init{
180 int numIS = 0;
181}
182@after{
183 MFPA.internal_subprogram_part(numIS);
184}
185 : contains_stmt
186 ( internal_subprogram {numIS++;} )*
187 ;
188
189/*
190 * R512: internal subprogram
191 */
192internal_subprogram
193options {backtrack=true;}
194@after {
195 MFPA.internal_subprogram();
196}
197 : ( prefix )? function_subprogram
198 | subroutine_subprogram
199 ;
200
201/*
202 * R514: executable construct
203 * UDEL: A dummy rule 'pragma_stmt' is added for
204 * OpenMP pragma directives
205 * (wuwenhao@udel.edu)
206 * TODO:
207 * R1111 change team construct
208 * R1148 select rank construct
209 */
210executable_construct
211@after {
212 MFPA.executable_construct();
213}
214 : action_stmt
215 | associate_construct
216 | block_construct
217 | case_construct
218 | critical_construct
219 | do_construct
220 | forall_construct
221 | if_construct
222 | select_type_construct
223 | where_construct
224 | pragma_stmt
225 ;
226
227/*
228 * R515: action stmt
229 */
230action_stmt
231@after{
232 MFPA.action_stmt();
233 checkForInclude();
234}
235 : allocate_stmt
236 | assignment_stmt
237 | backspace_stmt
238 | call_stmt
239 | close_stmt
240 | computed_goto_stmt
241 | continue_stmt
242 | cycle_stmt
243 | deallocate_stmt
244 | endfile_stmt
245 | exit_stmt
246 | flush_stmt
247 | forall_stmt
248 | goto_stmt
249 | if_stmt
250 | inquire_stmt
251 | nullify_stmt
252 | open_stmt
253 | pointer_assignment_stmt
254 | print_stmt
255 | read_stmt
256 | return_stmt
257 | rewind_stmt
258 | stop_stmt
259 | sync_all_stmt
260 | sync_images_stmt
261 | sync_memory_stmt
262 | wait_stmt
263 | where_stmt
264 | write_stmt
265// New Features added in F2018
266// | lock_stmt
267// | unlock_stmt
268// | fail_image_stmt
269// | sync_team_stmt
270// | event_post_stmt
271// | event_wait_stmt
272// | form_team_stmt
273// Deleted features ()
274// | arithmetic_if_stmt
275// | assign_stmt
276// | assigned_goto_stmt
277// | errorstop_stmt
278// | pause_stmt
279 ;
280
281/*
282 * R516: keyword
283 */
284keyword returns [Token t]
285@after{
286 MFPA.keyword();
287}
288 : name {t = $name.t;}
289 ;
290
291/*
292 * Rules omitted:
293 * R601: alphanumeric character
294 * R602: underscore
295 */
296
297/*
298 * R603: name
299 */
300name returns [Token t]
301@after{
302 MFPA.name(t);
303}
304 : IDENT { t = $IDENT; }
305 ;
306
307/*
308 * R604: constant
309 * R606: named constant
310 * OFP: named_constant replaced by IDENT
311 */
312constant
313@after{
314 MFPA.constant(t);
315}
316 : literal_constant
317 | t=IDENT
318 ;
319
320/*
321 * R605: literal constant
322 */
323literal_constant
324@after {
325 MFPA.literal_constant();
326}
327 : int_literal_constant
328 | real_literal_constant
329 | complex_literal_constant
330 | logical_literal_constant
331 | char_literal_constant
332 | boz_literal_constant
333// Deleted Features (since F77)
334// | hollerith_literal_constant
335 ;
336
337/*
338 * R607: int constant
339 */
340int_constant
341@after{
342 MFPA.int_constant(c);
343}
344 : int_literal_constant
345 | c=IDENT
346 ;
347
348/*
349 * R608: intrinsic operator
350 */
351intrinsic_operator returns [Token t]
352@after{
353 MFPA.intrinsic_operator();
354}
355 : power_op { t = $power_op.t; }
356 | mult_op { t = $mult_op.t; }
357 | add_op { t = $add_op.t; }
358 | concat_op { t = $concat_op.t; }
359 | rel_op { t = $rel_op.t; }
360 | not_op { t = $not_op.t; }
361 | and_op { t = $and_op.t; }
362 | or_op { t = $or_op.t; }
363 | equiv_op { t = $equiv_op.t; }
364 ;
365
366/*
367 * R609 defined operator
368 */
369defined_operator
370 : DEFINED_OP
371 { MFPA.defined_operator($DEFINED_OP, false); }
372 | extended_intrinsic_op
373 { MFPA.defined_operator($extended_intrinsic_op.t, true); }
374 ;
375
376/*
377 * R610: extended intrinsic op
378 */
379extended_intrinsic_op returns [Token t]
380@after {
381 MFPA.extended_intrinsic_op();
382}
383 : intrinsic_operator { t = $intrinsic_operator.t; }
384 ;
385
386/*
387 * R611: label
388 */
389label returns [Token t]
390 : DIGIT_STR { t = $DIGIT_STR; }
391 ;
392
393// MFPA.label called here to store label in action class
394label_list
395@init{
396 int numLbl = 1;
397}
398@after{
399 MFPA.label_list(numLbl);
400}
401 : lbl=label { MFPA.label(lbl); }
402 ( COMMA lbl=label
403 { MFPA.label(lbl);numLbl++; } )*
404 ;
405
406/*
407 * R690: char constant
408 * UDEL: a DELETED feature
409 */
410 char_constant
411 : char_literal_constant { MFPA.int_constant(null); }
412 | IDENT { MFPA.int_constant($IDENT); }
413 ;
414
415/*
416 * R701: type param value
417 */
418type_param_value
419 : expr
420 { MFPA.type_param_value(MFPUtils.TYPE_PARAM_EXPR); }
421 | ASTERISK
422 { MFPA.type_param_value(MFPUtils.TYPE_PARAM_ASTERISK); }
423 | COLON
424 { MFPA.type_param_value(MFPUtils.TYPE_PARAM_COLON); }
425 ;
426
427/*
428 * R702: type spec
429 */
430type_spec
431@after {
432 MFPA.type_spec();
433}
434 : intrinsic_type_spec
435 | derived_type_spec
436 ;
437
438/*
439 * R703: declaration type spec
440 */
441declaration_type_spec
442 : intrinsic_type_spec
443 { MFPA.declaration_type_spec( null, null,
444 MFPUtils.F_INTRNSIC); }
445 | TYPE LPAREN intrinsic_type_spec RPAREN
446 { MFPA.declaration_type_spec( $TYPE, null,
447 MFPUtils.TYPE_INTRN); }
448 | TYPE LPAREN derived_type_spec RPAREN
449 { MFPA.declaration_type_spec( $TYPE, null,
450 MFPUtils.TYPE_DERIV); }
451 | TYPE LPAREN ASTERISK RPAREN
452 { MFPA.declaration_type_spec( $TYPE, $ASTERISK,
453 MFPUtils.TYPE_UNLMT); }
454 | CLASS LPAREN derived_type_spec RPAREN
455 { MFPA.declaration_type_spec( $CLASS, null,
456 MFPUtils.CLSS_DERIV); }
457 | CLASS LPAREN ASTERISK RPAREN
458 { MFPA.declaration_type_spec( $CLASS, $ASTERISK,
459 MFPUtils.CLSS_UNLMT); }
460 ;
461
462/*
463 * R704: intrinsic type spec
464 * R705: integer type spec
465 * OFP: Non-standard extionsion from BLAS
466 * 'DOUBLE COMPLEX' and 'DOUBLECOMPLEX'
467 */
468intrinsic_type_spec
469@init{
470 boolean hasKS = false;
471}
472 : INTEGER (kind_selector {hasKS = true;})?
473 { MFPA.intrinsic_type_spec(
474 $INTEGER, null,
475 MFPUtils.TYPE_INT, hasKS);}
476 | REAL (kind_selector {hasKS = true;})?
477 { MFPA.intrinsic_type_spec(
478 $REAL, null,
479 MFPUtils.TYPE_REAL, hasKS);}
480 | DOUBLE PRECISION
481 { MFPA.intrinsic_type_spec(
482 $DOUBLE, $PRECISION,
483 MFPUtils.TYPE_DBL, false);}
484 | DOUBLEPRECISION
485 { MFPA.intrinsic_type_spec(
486 $DOUBLEPRECISION, null,
487 MFPUtils.TYPE_DBL, false);}
488 | COMPLEX (kind_selector {hasKS = true;})?
489 { MFPA.intrinsic_type_spec(
490 $COMPLEX, null,
491 MFPUtils.TYPE_CPLX, hasKS);}
492 | DOUBLE COMPLEX
493 { MFPA.intrinsic_type_spec(
494 $DOUBLE, $COMPLEX,
495 MFPUtils.TYPE_DCPLX, false);}
496 | DOUBLECOMPLEX
497 { MFPA.intrinsic_type_spec(
498 $DOUBLECOMPLEX, null,
499 MFPUtils.TYPE_DCPLX, false);}
500 | CHARACTER (char_selector {hasKS = true;})?
501 { MFPA.intrinsic_type_spec(
502 $CHARACTER, null,
503 MFPUtils.TYPE_CHAR, hasKS);}
504 | LOGICAL (kind_selector {hasKS = true;})?
505 { MFPA.intrinsic_type_spec(
506 $LOGICAL, null,
507 MFPUtils.TYPE_BOOL, hasKS);}
508 ;
509
510/*
511 * R706: kind selector
512 */
513kind_selector
514@init{
515 boolean hasKSExpr = false;
516}
517@after{
518 MFPA.kind_selector(tk0, tk1, hasKSExpr);
519}
520 : LPAREN (tk0=KIND tk1=EQUALS)? expr RPAREN
521 {hasKSExpr = true;}
522 | tk0=ASTERISK tk1=DIGIT_STR
523 ;
524
525/*
526 * R707: signed int literal constant
527 * R710: signed digit string
528 * R712: sign
529 */
530signed_int_literal_constant
531@after{
532 MFPA.signed_int_literal_constant(sign);
533}
534 : (sign=PLUS | sign=MINUS)?
535 int_literal_constant
536 ;
537
538/*
539 * R708: int literal constant
540 */
541int_literal_constant
542 : DIGIT_STR (UNDERSCORE kind=kind_param)?
543 { MFPA.int_literal_constant($DIGIT_STR, kind); }
544 ;
545
546/*
547 * R709: kind param
548 * OFP: IDENT inlined for scalar_int_constant_name
549 */
550kind_param returns [Token t]
551@after{
552 MFPA.kind_param(t);
553}
554 : DIGIT_STR { t = $DIGIT_STR; }
555 | IDENT { t = $IDENT; }
556 ;
557
558/*
559 * R711: digit string
560 * OFP: Used as a fragment in OFP FortranLexer
561 * CIVL: Converted from PP-tokens output by a C Preprocessor.
562 */
563
564/*
565 * R713: signed real literal constant
566 */
567signed_real_literal_constant
568@after{
569 MFPA.signed_real_literal_constant(sign);
570}
571 : (sign=PLUS | sign=MINUS)?
572 real_literal_constant
573 ;
574
575/*
576 * R714: real literal constant
577 * OFP: Used as a terminal.
578 * Modified for handling a case like:
579 * ' if (1.and.1) then ...'
580 * Must be parsed in action implementation,
581 * so that exponent letter 'D'/'E' can be processed.
582 */
583real_literal_constant
584 : M_REAL_CONST (UNDERSCORE kind=kind_param)?
585 { MFPA.real_literal_constant($M_REAL_CONST, kind); }
586 ;
587
588/*
589 * R715: significand
590 * OFP: Used as a fragment in OFP FortranLexer
591 * R716: exponent letter
592 * R717: exponent
593 * OFP: Inlined in the terminal involving it.
594 * R715 -- 717:
595 * CIVL: Converted from PP-tokens output by a C Preprocessor.
596 */
597
598/*
599 * R718: complex literal constant
600 */
601complex_literal_constant
602@after {
603 MFPA.complex_literal_constant();
604}
605 : LPAREN real_part COMMA imag_part RPAREN
606 ;
607
608/*
609 * R719: real part
610 * OFP: 'named_constant' replaced by IDENT
611 */
612real_part
613 : signed_int_literal_constant
614 { MFPA.real_part(null,
615 MFPUtils.CPLXP.INT); }
616 | signed_real_literal_constant
617 { MFPA.real_part(null,
618 MFPUtils.CPLXP.REAL); }
619 | IDENT
620 { MFPA.real_part($IDENT,
621 MFPUtils.CPLXP.IDENT); }
622 ;
623
624/*
625 * R720: imag part
626 * OFP: 'named_constant' replaced by IDENT
627 */
628imag_part
629 : signed_int_literal_constant
630 { MFPA.imag_part(null,
631 MFPUtils.CPLXP.INT); }
632 | signed_real_literal_constant
633 { MFPA.imag_part(null,
634 MFPUtils.CPLXP.REAL); }
635 | IDENT
636 { MFPA.imag_part($IDENT,
637 MFPUtils.CPLXP.IDENT); }
638 ;
639
640/*
641 * R721: char selector
642 * OFP: scalar_int_initialization_expr replaced by expr
643 * KIND, if type_param_value, must be a scalar_int_initialization_expr
644 * KIND and LEN cannot both be specified
645 */
646char_selector
647@init {
648 int pos0 = MFPUtils.CHAR_SELECTOR_NONE;
649 int pos1 = MFPUtils.CHAR_SELECTOR_NONE;
650}
651@after{
652 MFPA.char_selector(len, kind, pos0, pos1);
653}
654 : ASTERISK char_length (COMMA)?
655 { pos0 = MFPUtils.CHAR_SELECTOR_CHARLEN; }
656 | LPAREN type_param_value
657 ( COMMA (kind=KIND EQUALS)? expr
658 { pos1 = MFPUtils.CHAR_SELECTOR_KINDEXPR; }
659 )?
660 RPAREN
661 { pos0 = MFPUtils.CHAR_SELECTOR_TYPEVAL; }
662 | LPAREN len=LEN EQUALS type_param_value
663 ( COMMA kind=KIND EQUALS expr
664 { pos1 = MFPUtils.CHAR_SELECTOR_KINDEXPR;}
665 )?
666 RPAREN
667 { pos0 = MFPUtils.CHAR_SELECTOR_TYPEVAL;}
668 | LPAREN kind=KIND EQUALS expr
669 ( COMMA (len=LEN EQUALS)? type_param_value
670 { pos1 = MFPUtils.CHAR_SELECTOR_TYPEVAL;}
671 )?
672 RPAREN
673 { pos0 = MFPUtils.CHAR_SELECTOR_KINDEXPR; }
674 ;
675
676/*
677 * R722: length selector
678 */
679length_selector
680 : LPAREN ( len=LEN EQUALS )? type_param_value RPAREN
681 { MFPA.length_selector(len, MFPUtils.CHAR_SELECTOR_TYPEVAL); }
682 | ASTERISK char_length (COMMA)?
683 { MFPA.length_selector(len, MFPUtils.CHAR_SELECTOR_CHARLEN); }
684 ;
685
686/*
687 * R723: char length
688 */
689char_length
690 : LPAREN type_param_value RPAREN { MFPA.char_length(true); }
691 | int_literal_constant { MFPA.char_length(false); }
692 ;
693
694/*
695 * R724: char literal constant
696 * OFP: UNDERSCORE is removed because it will be
697 * a part of the identifier token.
698 */
699char_literal_constant
700 : DIGIT_STR UNDERSCORE CHAR_CONST
701 { MFPA.char_literal_constant($DIGIT_STR, $CHAR_CONST); }
702 | IDENT CHAR_CONST
703 { MFPA.char_literal_constant($IDENT, $CHAR_CONST); }
704 | CHAR_CONST
705 { MFPA.char_literal_constant(null, $CHAR_CONST); }
706 ;
707
708/*
709 * R725: logical literal constant
710 */
711logical_literal_constant
712 : TRUE ( UNDERSCORE kind=kind_param)?
713 { MFPA.logical_literal_constant($TRUE, kind);}
714 | FALSE ( UNDERSCORE kind=kind_param)?
715 { MFPA.logical_literal_constant($FALSE, kind);}
716 ;
717
718/*
719 * R726: derived type def
720 * OFP: ( component_part )? inlined as ( component_def_stmt )*
721 * TODO: Incompleted
722 */
723derived_type_def
724@after{
725 MFPA.derived_type_def();
726}
727 : derived_type_stmt
728// OFP: matches INTEGER possibilities in component_def_stmt
729 ( type_param_or_comp_def_stmt_list )?
730 ( private_or_sequence )*
731 { /* OFP:
732 * if private_or_sequence present, component_def_stmt in
733 * type_param_or_comp_def_stmt_list is an error
734 */
735 }
736 ( component_def_stmt )*
737 ( type_bound_procedure_part )?
738 end_type_stmt
739 ;
740
741/*
742 * R727: derived type stmt
743 * OFP: generic_name_list substituted for type_param_name_list
744 */
745derived_type_stmt
746@init {
747 boolean hasASList = false;
748 boolean hasPNList = false;
749}
750@after{
751 checkForInclude();
752}
753 : (lbl=label)? TYPE
754 ( ( COMMA type_attr_spec_list {hasASList=true;} )? COLON_COLON )?
755 IDENT
756 ( LPAREN generic_name_list RPAREN {hasPNList=true;} )?
757 end_of_stmt
758 { MFPA.derived_type_stmt(
759 lbl, $TYPE, $IDENT, $end_of_stmt.t,
760 hasASList, hasPNList);
761 }
762 ;
763
764generic_name_list
765@init{
766 int numGN = 1;
767}
768@after{
769 MFPA.generic_name_list(numGN);
770}
771 : ident=IDENT
772 { MFPA.generic_name(ident); }
773 ( COMMA ident=IDENT
774 { numGN++;
775 MFPA.generic_name(ident);
776 }
777 )*
778 ;
779
780/*
781 * R728: type attr spec
782 * OFP: IDENT inlined for parent_type_name
783 */
784type_attr_spec
785 : access_spec
786 { MFPA.type_attr_spec(null, null,
787 MFPUtils.ATTR_ACCESS);}
788 | EXTENDS LPAREN IDENT RPAREN
789 {MFPA.type_attr_spec($EXTENDS, $IDENT,
790 MFPUtils.ATTR_EXTENDS);}
791 | ABSTRACT
792 {MFPA.type_attr_spec($ABSTRACT, null,
793 MFPUtils.ATTR_ABSTRACT);}
794// BIND (C)
795 | BIND LPAREN IDENT RPAREN
796 {MFPA.type_attr_spec($BIND, $IDENT,
797 MFPUtils.ATTR_BIND_C);}
798 ;
799
800type_attr_spec_list
801@init{
802 int numTAS = 1;
803}
804@after{
805 MFPA.type_attr_spec_list(numTAS);
806}
807 : type_attr_spec ( COMMA type_attr_spec {numTAS++;} )*
808 ;
809
810/*
811 * R729: private or sequence
812 */
813private_or_sequence
814@after {
815 MFPA.private_or_sequence();
816}
817 : private_components_stmt
818 | sequence_stmt
819 ;
820
821/*
822 * R730: end type stmt
823 */
824end_type_stmt
825@after{
826 checkForInclude();
827}
828 : (lbl=label)? END TYPE
829 (id=IDENT)? end_of_stmt
830 { MFPA.end_type_stmt(lbl, $END, $TYPE, id, $end_of_stmt.t);}
831 ;
832
833/*
834 * R731: sequence stmt
835 */
836sequence_stmt
837@after{
838 checkForInclude();
839}
840 : (lbl=label)? SEQUENCE end_of_stmt
841 { MFPA.sequence_stmt(lbl, $SEQUENCE, $end_of_stmt.t);}
842 ;
843
844/*
845 * R732: type param def stmt
846 * R736: component def stmt
847 * OFP: type_param_def_stmt(s) must precede component_def_stmt(s)
848 * TODO: Test whether this is reachable and
849 * type_param_attr_spec is tokenized KIND or LEN. (R435,440-F08)
850 */
851type_param_or_comp_def_stmt
852 : type_param_attr_spec COLON_COLON type_param_decl_list end_of_stmt
853 { MFPA.type_param_or_comp_def_stmt( $end_of_stmt.t,
854 MFPUtils.TPD_OR_CD.TYPE_PARAM_DEF);}
855 | component_attr_spec_list COLON_COLON component_decl_list end_of_stmt
856 { MFPA.type_param_or_comp_def_stmt( $end_of_stmt.t,
857 MFPUtils.TPD_OR_CD.COMP_DEF);}
858 ;
859
860type_param_or_comp_def_stmt_list
861@init{
862 int numTPCD = 1;
863}
864@after{
865 MFPA.type_param_or_comp_def_stmt_list();
866}
867 : type_param_or_comp_def_stmt ( type_param_or_comp_def_stmt {numTPCD++;} )*
868 ;
869
870/*
871 * R733: type param decl
872 * OFP: scalar_int_initialization_expr replaced by expr
873 * IDENT inlined for type_param_name
874 */
875type_param_decl
876@init{
877 boolean hasInit=false;
878}
879 : IDENT ( EQUALS expr {hasInit=true;} )?
880 { MFPA.type_param_decl($IDENT, hasInit); }
881 ;
882
883type_param_decl_list
884@init{
885 int numTPD = 1;
886}
887@after{
888 MFPA.type_param_decl_list(numTPD);
889}
890 : type_param_decl ( COMMA type_param_decl {numTPD++;} )*
891 ;
892
893/*
894 * R734: type param attr spec
895 */
896type_param_attr_spec
897 : KIND
898 { MFPA.type_param_attr_spec($KIND,
899 MFPUtils.ATTR_KIND); }
900 | LEN
901 { MFPA.type_param_attr_spec($LEN,
902 MFPUtils.ATTR_LEN); }
903 ;
904
905/*
906 * R735: component part
907 * OFP: inlined as ( component_def_stmt )* in R726
908 */
909
910/*
911 * R736: component def stmt
912 */
913component_def_stmt
914@after{
915 checkForInclude();
916}
917 : data_component_def_stmt
918 | proc_component_def_stmt
919 ;
920
921/*
922 * R737: data component def stmt
923 */
924data_component_def_stmt
925@init {
926 boolean hasSpec=false;
927}
928@after{
929 checkForInclude();
930}
931 : (lbl=label)?
932 declaration_type_spec
933 ( ( COMMA component_attr_spec_list {hasSpec=true;} )?
934 COLON_COLON
935 )? component_decl_list end_of_stmt
936 { MFPA.data_component_def_stmt(lbl, $end_of_stmt.t, hasSpec); }
937 ;
938
939/*
940 * R738: component attr spec
941 * OFP: component_attr_spec_extension
942 */
943component_attr_spec
944 : access_spec
945 { MFPA.component_attr_spec(null,
946 MFPUtils.ATTR_ACCESS);}
947 | ALLOCATABLE
948 { MFPA.component_attr_spec($ALLOCATABLE,
949 MFPUtils.ATTR_ALLOCATABLE);}
950 | CODIMENSION LBRACKET coarray_spec RBRACKET
951 {MFPA.component_attr_spec($CODIMENSION,
952 MFPUtils.ATTR_CODIMENSION);}
953 | CONTIGUOUS
954 {MFPA.component_attr_spec($CONTIGUOUS,
955 MFPUtils.ATTR_CONTIGUOUS);}
956 | DIMENSION LPAREN component_array_spec RPAREN
957 {MFPA.component_attr_spec($DIMENSION,
958 MFPUtils.ATTR_DIMENSION);}
959 | POINTER
960 {MFPA.component_attr_spec($POINTER,
961 MFPUtils.ATTR_POINTER);}
962 | component_attr_spec_extension
963 ;
964
965component_attr_spec_extension
966 : NO_LANG_EXT
967 ;
968
969component_attr_spec_list
970@init{
971 int numCAS = 1;
972}
973@after{
974 MFPA.component_attr_spec_list(numCAS);
975}
976 : component_attr_spec ( COMMA component_attr_spec {numCAS++;} )*
977 ;
978
979/*
980 * R739: component decl
981 */
982component_decl
983@init {
984 boolean hasCAS = false;
985 boolean hasCS = false;
986 boolean hasCL = false;
987 boolean hasCI = false;
988}
989 : IDENT
990 (LPAREN component_array_spec RPAREN {hasCAS=true;})?
991 (LBRACKET coarray_spec RBRACKET {hasCS=true;})?
992 (ASTERISK char_length {hasCL=true;})?
993 (component_initialization {hasCI =true;})?
994 { MFPA.component_decl($IDENT,
995 hasCAS, hasCS, hasCL, hasCI);}
996 ;
997
998component_decl_list
999@init{
1000 int numCD = 1;
1001}
1002@after{
1003 MFPA.component_decl_list(numCD);
1004}
1005 : component_decl ( COMMA component_decl {numCD++;} )*
1006 ;
1007
1008/*
1009 * R740: component array spec
1010 */
1011component_array_spec
1012 : explicit_shape_spec_list
1013 { MFPA.component_array_spec(true);}
1014 | deferred_shape_spec_list
1015 { MFPA.component_array_spec(false);}
1016 ;
1017
1018/*
1019 * R741: proc component def stmt
1020 */
1021proc_component_def_stmt
1022@init{
1023 boolean hasItf = false;
1024}
1025@after{
1026 checkForInclude();
1027}
1028 : (lbl=label)?
1029 PROCEDURE LPAREN ( proc_interface {hasItf=true;})? RPAREN COMMA
1030 proc_component_attr_spec_list COLON_COLON proc_decl_list end_of_stmt
1031 { MFPA.proc_component_def_stmt(lbl, $PROCEDURE, $end_of_stmt.t, hasItf);}
1032 ;
1033
1034/*
1035 * R742: proc component attr spec
1036 */
1037proc_component_attr_spec
1038 : POINTER
1039 {MFPA.proc_component_attr_spec($POINTER, id,
1040 MFPUtils.ATTR_POINTER);}
1041 | PASS ( LPAREN id=IDENT RPAREN )?
1042 {MFPA.proc_component_attr_spec($PASS, id,
1043 MFPUtils.ATTR_PASS);}
1044 | NOPASS
1045 {MFPA.proc_component_attr_spec($NOPASS, id,
1046 MFPUtils.ATTR_NOPASS);}
1047 | access_spec
1048 {MFPA.proc_component_attr_spec(null, id,
1049 MFPUtils.ATTR_ACCESS);}
1050 ;
1051
1052proc_component_attr_spec_list
1053@init{
1054 int numCAS = 1;
1055}
1056@after{
1057 MFPA.proc_component_attr_spec_list(numCAS);
1058}
1059 : proc_component_attr_spec
1060 ( COMMA proc_component_attr_spec {numCAS++;})*
1061 ;
1062
1063
1064/*
1065 * R743: component initialization
1066 * R744: initial data target
1067 * OFP: R447-F2008 can also be => initial_data_target,
1068 * (see NOTE 4.40 in J3/07-007)
1069 * initialization_expr replaced by expr
1070 */
1071component_initialization
1072@after {
1073 MFPA.component_initialization();
1074}
1075 : EQUALS expr
1076 | EQ_GT null_init
1077 ;
1078
1079/*
1080 * R745: private components stmt
1081 */
1082private_components_stmt
1083@init {
1084}
1085@after{
1086 checkForInclude();
1087}
1088 : (lbl=label)?
1089 PRIVATE end_of_stmt
1090 { MFPA.private_components_stmt(lbl, $PRIVATE, $end_of_stmt.t);}
1091 ;
1092
1093/*
1094 * R746: type bound procedure part
1095 */
1096type_bound_procedure_part
1097@init{
1098 int numTBPB = 1;
1099 boolean hasBPS = false;
1100}
1101 : contains_stmt ( binding_private_stmt {hasBPS=true;})?
1102 type_bound_proc_binding ( type_bound_proc_binding {numTBPB++;})*
1103 { MFPA.type_bound_procedure_part(numTBPB, hasBPS); }
1104 ;
1105
1106/*
1107 * R747: binding private stmt
1108 */
1109binding_private_stmt
1110@init{
1111}
1112@after{
1113 checkForInclude();
1114}
1115 : (lbl=label)?
1116 PRIVATE end_of_stmt
1117 { MFPA.binding_private_stmt(lbl, $PRIVATE, $end_of_stmt.t);}
1118 ;
1119
1120/*
1121 * R748: type bound proc binding
1122 */
1123type_bound_proc_binding
1124@init{
1125}
1126@after{
1127 checkForInclude();
1128}
1129 : (lbl=label)? type_bound_procedure_stmt end_of_stmt
1130 {MFPA.type_bound_proc_binding(lbl,
1131 MFPUtils.TBPB.PROCEDURE, $end_of_stmt.t);}
1132 | (lbl=label)? type_bound_generic_stmt end_of_stmt
1133 {MFPA.type_bound_proc_binding(lbl,
1134 MFPUtils.TBPB.GENERIC, $end_of_stmt.t);}
1135 | (lbl=label)? final_procedure_stmt end_of_stmt
1136 {MFPA.type_bound_proc_binding(lbl,
1137 MFPUtils.TBPB.FINAL, $end_of_stmt.t);}
1138 ;
1139
1140/*
1141 * R749: type bound procedure stmt
1142 * CIVL: type_bound_proc_decl_list substituted for binding_name_list
1143 * If tIN is not null, then both hasBAL and hasCC are required to be true
1144 */
1145type_bound_procedure_stmt
1146@init{
1147 boolean hasBAL = false;
1148 boolean hasCC = false;
1149 boolean hasPN = false;
1150}
1151@after{
1152 MFPA.type_bound_procedure_stmt(
1153 proc, tIN, hasBAL, hasCC);
1154}
1155 : proc=PROCEDURE
1156 ( LPAREN tIN=IDENT RPAREN)?
1157 ( (COMMA binding_attr_list {hasBAL=true;})?
1158 COLON_COLON {hasCC=true;}
1159 )?
1160 type_bound_proc_decl_list
1161// | proc=PROCEDURE
1162// ( LPAREN tIN=IDENT RPAREN)?
1163// COMMA binding_attr_list COLON_COLON {hasBAL=true; hasCC=true;}
1164// type_bound_proc_decl_list
1165 ;
1166
1167/*
1168 * R750: type bound proc decl
1169 */
1170type_bound_proc_decl
1171@after{
1172 MFPA.type_bound_proc_decl(tBN, tPN);
1173}
1174 : tBN=IDENT
1175 ( EQ_GT tPN=IDENT)?
1176 ;
1177
1178type_bound_proc_decl_list
1179@init{
1180 int numPD = 1;
1181}
1182@after{
1183 MFPA.type_bound_proc_decl_list(numPD);
1184}
1185 : type_bound_proc_decl
1186 (COMMA type_bound_proc_decl {numPD++;})*
1187 ;
1188
1189/*
1190 * R751: type bound generic stmt
1191 * OFP: generic_name_list substituted for binding_name_list
1192 */
1193type_bound_generic_stmt
1194@init{
1195 boolean hasAS = false;
1196}
1197 : GENERIC ( COMMA access_spec {hasAS=true;})?
1198 COLON_COLON generic_spec EQ_GT generic_name_list
1199 { MFPA.type_bound_generic_stmt($GENERIC, hasAS);}
1200 ;
1201
1202/*
1203 * R752: binding attr
1204 * OFP: IDENT inlined for arg_name
1205 */
1206binding_attr
1207@init{
1208 Token id = null;
1209}
1210 : PASS ( LPAREN IDENT RPAREN {id=$IDENT;})?
1211 { MFPA.binding_attr($PASS,
1212 MFPUtils.ATTR_PASS, id); }
1213 | NOPASS
1214 { MFPA.binding_attr($NOPASS,
1215 MFPUtils.ATTR_NOPASS, id); }
1216 | NON_OVERRIDABLE
1217 { MFPA.binding_attr($NON_OVERRIDABLE,
1218 MFPUtils.ATTR_NON_OVERRIDABLE, id); }
1219 | DEFERRED
1220 { MFPA.binding_attr($DEFERRED,
1221 MFPUtils.ATTR_DEFERRED, id); }
1222 | access_spec
1223 { MFPA.binding_attr(null,
1224 MFPUtils.ATTR_ACCESS, id); }
1225 ;
1226
1227binding_attr_list
1228@init{
1229 int numBA = 1;
1230}
1231@after{
1232 MFPA.binding_attr_list(numBA);
1233}
1234 : binding_attr
1235 ( COMMA binding_attr {numBA++;} )*
1236 ;
1237
1238/*
1239 * R753: final procedure stmt
1240 * OFP: generic_name_list substituted for final_subroutine_name_list
1241 */
1242final_procedure_stmt
1243 : FINAL ( COLON_COLON )? generic_name_list
1244 { MFPA.final_procedure_stmt($FINAL); }
1245 ;
1246
1247/*
1248 * R754: derived type spec
1249 */
1250derived_type_spec
1251@init{
1252 boolean hasList = false;
1253}
1254 : IDENT ( LPAREN type_param_spec_list {hasList=true;} RPAREN )?
1255 { MFPA.derived_type_spec($IDENT, hasList); }
1256 ;
1257
1258/*
1259 * R755: type param spec
1260 */
1261type_param_spec
1262@init{
1263 Token keyWord=null;
1264}
1265 : ( keyword EQUALS {keyWord=$keyword.t;})? type_param_value
1266 { MFPA.type_param_spec(keyWord);}
1267 ;
1268
1269type_param_spec_list
1270@init{
1271 int numTPS = 1;
1272}
1273@after{
1274 MFPA.type_param_spec_list(numTPS);
1275}
1276 : type_param_spec
1277 ( COMMA type_param_spec {numTPS++;})*
1278 ;
1279
1280/*
1281 * R756: structure constructor
1282 * OFP: inlined derived_type_spec (R662) to remove ambiguity using backtracking
1283 * If any of the type-param-specs in the list are an '*' or ':', the
1284 * component-spec-list is required.
1285 * the second alternative to the original rule for structure_constructor is
1286 * a subset of the first alternative because component_spec_list is a
1287 * subset of type_param_spec_list. by combining these two alternatives we can
1288 * remove the backtracking on this rule.
1289 */
1290structure_constructor
1291 : IDENT LPAREN type_param_spec_list RPAREN
1292 (LPAREN ( component_spec_list )? RPAREN)?
1293 { MFPA.structure_constructor($IDENT); }
1294 ;
1295
1296/*
1297 * R757: component spec
1298 */
1299component_spec
1300@init{
1301 Token keyWord = null;
1302}
1303 : ( keyword EQUALS { keyWord=$keyword.t; })? component_data_source
1304 { MFPA.component_spec(keyWord); }
1305 ;
1306
1307component_spec_list
1308@init{
1309 int numCS = 1;
1310}
1311@after{
1312 MFPA.component_spec_list(numCS);
1313}
1314 : component_spec
1315 ( COMMA component_spec {numCS++;})*
1316 ;
1317
1318/*
1319 * R758: component data source
1320 * OFP: All 'expr', 'data-target' and 'proc_target'
1321 * are 'expr', so they are regarded as 'expr'
1322 */
1323component_data_source
1324 : expr { MFPA.component_data_source(); }
1325 ;
1326
1327/*
1328 * R759: enum def
1329 */
1330enum_def
1331@init{
1332 int numEDS = 1;
1333}
1334@after{
1335 MFPA.enum_def(numEDS);
1336}
1337 : enum_def_stmt
1338 enumerator_def_stmt
1339 ( enumerator_def_stmt {numEDS++;} )*
1340 end_enum_stmt
1341 ;
1342
1343/*
1344 * R760: enum def stmt
1345 */
1346enum_def_stmt
1347@init {
1348}
1349@after{
1350 checkForInclude();
1351}
1352 : (lbl=label)?
1353 // ENUM , BIND ( C )
1354 ENUM COMMA BIND LPAREN IDENT RPAREN end_of_stmt
1355 { MFPA.enum_def_stmt(
1356 lbl, $ENUM, $BIND, $IDENT, $end_of_stmt.t);}
1357 ;
1358
1359/*
1360 * R761: enumerator def stmt
1361 */
1362enumerator_def_stmt
1363@init {
1364}
1365@after{
1366 checkForInclude();
1367}
1368 : (lbl=label)?
1369 ENUMERATOR ( COLON_COLON )? enumerator_list end_of_stmt
1370 { MFPA.enumerator_def_stmt(
1371 lbl, $ENUMERATOR, $end_of_stmt.t); }
1372 ;
1373
1374/*
1375 * R762: enumerator
1376 * OFP: scalar_int_initialization_expr replaced by expr
1377 * named_constant replaced by IDENT
1378 */
1379enumerator
1380@init{
1381 boolean hasExpr = false;
1382}
1383 : IDENT ( EQUALS expr { hasExpr = true; })?
1384 { MFPA.enumerator($IDENT, hasExpr); }
1385 ;
1386
1387enumerator_list
1388@init{
1389 int numE = 1;
1390}
1391@after{
1392 MFPA.enumerator_list(numE);
1393}
1394 : enumerator
1395 ( COMMA enumerator {numE++;})*
1396 ;
1397
1398/*
1399 * R763: end enum stmt
1400 */
1401end_enum_stmt
1402@init{
1403}
1404@after{
1405 checkForInclude();
1406}
1407 : (lbl=label)?
1408 END ENUM end_of_stmt
1409 { MFPA.end_enum_stmt(lbl, $END, $ENUM, $end_of_stmt.t); }
1410 ;
1411
1412/*
1413 * R764: boz literal constant (bin,oct and hex)
1414 */
1415boz_literal_constant
1416 : BIN_CONST { MFPA.boz_literal_constant($BIN_CONST); }
1417 | OCT_CONST { MFPA.boz_literal_constant($OCT_CONST); }
1418 | HEX_CONST { MFPA.boz_literal_constant($HEX_CONST); }
1419 ;
1420
1421/*
1422 * R765: binary constant
1423 * R766: octal constant
1424 * R767: hex constant
1425 * R768: hex digit
1426 * OFP: Used as a fragment in OFP FortranLexer
1427 * CIVL: Converted from PP-tokens output by a C Preprocessor.
1428 */
1429
1430/*
1431 * R769: array constructor
1432 */
1433array_constructor
1434@after{
1435 MFPA.array_constructor();
1436}
1437 : LPAREN SLASH ac_spec SLASH RPAREN
1438 | LBRACKET ac_spec RBRACKET
1439 ;
1440
1441/*
1442 * R770: ac spec
1443 */
1444ac_spec
1445options {backtrack=true;}
1446@init{
1447 boolean hsACVal = false;
1448 boolean hasTypeSpec = false;
1449}
1450@after {
1451 MFPA.ac_spec(hasTypeSpec, hsACVal);
1452}
1453 : type_spec COLON_COLON
1454 (ac_value_list {hsACVal = true;})?
1455 {hasTypeSpec = true;}
1456 | ac_value_list {hsACVal = true;}
1457 ;
1458
1459/*
1460 * CIVL: Listed rules are handled as terminals.
1461 * R771: lbracket
1462 * R772: rbracket
1463 */
1464
1465/*
1466 * R773: ac value
1467 */
1468ac_value
1469options {backtrack=true;}
1470@after {
1471 MFPA.ac_value();
1472}
1473 : expr
1474 | ac_implied_do
1475 ;
1476
1477ac_value_list
1478@init{
1479 int numAV = 1;
1480}
1481@after{
1482 MFPA.ac_value_list(numAV);
1483}
1484 : ac_value
1485 ( COMMA ac_value {numAV++;})*
1486 ;
1487
1488/*
1489 * R774: ac implied do
1490 */
1491ac_implied_do
1492 : LPAREN ac_value_list COMMA ac_implied_do_control RPAREN
1493 { MFPA.ac_implied_do();}
1494 ;
1495
1496/*
1497 * R775: ac implied do control
1498 * R776: ac do variable
1499 * OFP: scalar_int_expr replaced by expr
1500 * OFP: ac_do_variable replaced by do_variable
1501 */
1502ac_implied_do_control
1503@init{
1504 boolean hasStrd=false;
1505}
1506 : IDENT EQUALS expr COMMA expr
1507 ( COMMA expr {hasStrd=true;} )?
1508 { MFPA.ac_implied_do_control($IDENT, hasStrd); }
1509 ;
1510
1511/*
1512 * R801: type declaration stmt
1513 */
1514type_declaration_stmt
1515@init {
1516 int numAS = 0;
1517}
1518@after{
1519 checkForInclude();
1520}
1521 : (lbl=label)?
1522 declaration_type_spec
1523 ( (COMMA attr_spec {numAS ++;})* COLON_COLON )?
1524 entity_decl_list end_of_stmt
1525 { MFPA.type_declaration_stmt(lbl, numAS, $end_of_stmt.t); }
1526 ;
1527
1528/*
1529 * R802: attr spec
1530 */
1531attr_spec
1532 : access_spec
1533 { MFPA.attr_spec(null,
1534 MFPUtils.ATTR_ACCESS); }
1535 | ALLOCATABLE
1536 { MFPA.attr_spec($ALLOCATABLE,
1537 MFPUtils.ATTR_ALLOCATABLE);}
1538 | ASYNCHRONOUS
1539 { MFPA.attr_spec($ASYNCHRONOUS,
1540 MFPUtils.ATTR_ASYNCHRONOUS);}
1541 | CODIMENSION LBRACKET coarray_spec RBRACKET
1542 {MFPA.attr_spec($CODIMENSION,
1543 MFPUtils.ATTR_CODIMENSION);}
1544 | CONTIGUOUS
1545 {MFPA.attr_spec($CONTIGUOUS,
1546 MFPUtils.ATTR_CONTIGUOUS);}
1547 | DIMENSION LPAREN array_spec RPAREN
1548 {MFPA.attr_spec($DIMENSION,
1549 MFPUtils.ATTR_DIMENSION);}
1550 | EXTERNAL
1551 {MFPA.attr_spec($EXTERNAL,
1552 MFPUtils.ATTR_EXTERNAL);}
1553 | INTENT LPAREN intent_spec RPAREN
1554 {MFPA.attr_spec($INTENT,
1555 MFPUtils.ATTR_INTENT);}
1556 | INTRINSIC
1557 {MFPA.attr_spec($INTRINSIC,
1558 MFPUtils.ATTR_INTRINSIC);}
1559 | language_binding_spec
1560 {MFPA.attr_spec(null,
1561 MFPUtils.ATTR_BIND);}
1562 | OPTIONAL
1563 {MFPA.attr_spec($OPTIONAL,
1564 MFPUtils.ATTR_OPTIONAL);}
1565 | PARAMETER
1566 {MFPA.attr_spec($PARAMETER,
1567 MFPUtils.ATTR_PARAMETER);}
1568 | POINTER
1569 {MFPA.attr_spec($POINTER,
1570 MFPUtils.ATTR_POINTER);}
1571 | PROTECTED
1572 {MFPA.attr_spec($PROTECTED,
1573 MFPUtils.ATTR_PROTECTED);}
1574 | SAVE
1575 {MFPA.attr_spec($SAVE,
1576 MFPUtils.ATTR_SAVE);}
1577 | TARGET
1578 {MFPA.attr_spec($TARGET,
1579 MFPUtils.ATTR_TARGET);}
1580 | VALUE
1581 {MFPA.attr_spec($VALUE,
1582 MFPUtils.ATTR_VALUE);}
1583 | VOLATILE
1584 {MFPA.attr_spec($VOLATILE,
1585 MFPUtils.ATTR_VOLATILE);}
1586 | attr_spec_extension
1587 {MFPA.attr_spec(null,
1588 MFPUtils.ATTR_OTHER);}
1589 ;
1590
1591attr_spec_extension
1592 : NO_LANG_EXT
1593 {MFPA.attr_spec_extension($NO_LANG_EXT,
1594 MFPUtils.ATTR_EXT_NONE);}
1595 ;
1596
1597/*
1598 * R803: entity decl
1599 * OFP: IDENT inlined for object_name and function_name
1600 * IDENT ( ASTERISK char_length )? takes character and function
1601 * TODO: Pass more info to action
1602 */
1603entity_decl
1604@init{
1605 boolean hasAS=false;
1606 boolean hasCS=false;
1607 boolean hasCL=false;
1608 boolean hasInit=false;
1609}
1610 : IDENT
1611 ( LPAREN array_spec RPAREN {hasAS=true;} )?
1612 ( LBRACKET coarray_spec RBRACKET {hasCS=true;} )?
1613 ( ASTERISK char_length {hasCL=true;} )?
1614 ( initialization {hasInit=true;} )?
1615 { MFPA.entity_decl($IDENT, hasAS, hasCS, hasCL, hasInit); }
1616 ;
1617
1618entity_decl_list
1619@init{
1620 int numED = 1;
1621}
1622@after{
1623 MFPA.entity_decl_list(numED);
1624}
1625 : entity_decl
1626 ( COMMA entity_decl {numED ++;} )*
1627 ;
1628
1629/*
1630 * R804: object name
1631 */
1632object_name returns [Token t]
1633 : IDENT {t = $IDENT;}
1634 ;
1635
1636/*
1637 * R805: initialization
1638 * OFP: initialization_expr replaced by expr
1639 * CIVL: null_init is combined in designator
1640 */
1641initialization
1642 : EQUALS expr
1643 { MFPA.initialization(MFPUtils.INIT_VAL); }
1644// | EQ_GT null_init
1645// { MFPA.initialization(MFPUtils.INIT_PTR); }
1646 | EQ_GT designator
1647 { MFPA.initialization(MFPUtils.INIT_NUL); }
1648 ;
1649
1650/*
1651 * R806: null init
1652 * OFP: a reference to the NULL intrinsic function with no arguments
1653 */
1654null_init
1655// NULL ( )
1656 : IDENT LPAREN RPAREN
1657 { MFPA.null_init($IDENT); }
1658 ;
1659
1660/*
1661 * R807: access spec
1662 */
1663access_spec
1664 : PUBLIC
1665 { MFPA.access_spec($PUBLIC, MFPUtils.ATTR_PUBLIC);}
1666 | PRIVATE
1667 { MFPA.access_spec($PRIVATE, MFPUtils.ATTR_PRIVATE);}
1668 ;
1669
1670/*
1671 * R808: language binding spec
1672 * OFP: scalar_char_initialization_expr replaced by expr
1673 */
1674language_binding_spec
1675@init{
1676 boolean hasName = false;
1677}
1678// BIND ( C )
1679 : BIND LPAREN IDENT
1680 (COMMA name EQUALS expr { hasName=true; })? RPAREN
1681 { MFPA.language_binding_spec($BIND, $IDENT, hasName); }
1682 ;
1683
1684/*
1685 * R809: coarray spec (replaced by array_spec)
1686 * R810: deferred coshape spec (replaced by array_spec)
1687 * R811: explicit coshape spec (replaced by array_spec)
1688 * R812: lower cobound (see rule 817 lower bound)
1689 * R813: upper cobound (see rule 818 upper bound)
1690 * OFP: deferred-coshape-spec-list and explicit-coshape-spec rules
1691 * are ambiguous, thus we use the same method as for array-spec.
1692 * Enough information is provided so that the coarray_spec can
1693 * be figured out by the actions.
1694 * Note, that this means the parser can't determine all incorrect
1695 * syntax as many rules are combined into one.
1696 * It is the action's responsibility to enforce correct syntax.
1697 */
1698coarray_spec
1699@init{
1700 int numCS = 1;
1701}
1702 : array_spec_element
1703 (COMMA array_spec_element {numCS++;})*
1704 { MFPA.coarray_spec(numCS); }
1705 ;
1706
1707/*
1708 * R814: dimension spec
1709 */
1710dimension_spec
1711 : DIMENSION LPAREN array_spec RPAREN
1712 { MFPA.dimension_spec($DIMENSION); }
1713 ;
1714
1715/*
1716 * R815: array spec
1717 * R819: assumed shape spec
1718 * R821: assumed implied spec
1719 * R822: assumed size spec
1720 * R823: implied shape or assumed size spec
1721 * R824: implied shape spec
1722 * R825: assumed rank spec
1723 * CIVL: array_spec_element is shared by both array_spec and coarray_Spec
1724 * R815 array-spec
1725 * is R816 explicit_shape_spec is [ expr : ] expr
1726 * or R819 assumed-shape-spec is [ expr ] :
1727 * or R820 deferred-shape-spec is :
1728 * or R822 assumed-size-spec is explicit_shape_spec, assumed-implied-spec
1729 * or R824 implied-shape-spec is assumed-implied-spec, assumed-implied-spec-list
1730 * or R823 implied-shape-or-assumed-size-spec is assumed-implied-spec
1731 * or R825 assumed-rank-spec is ..
1732 * Note: R821 assumed-implied-spec is [ expr : ] *
1733 * All bounds are replaced as expr
1734 * Thus, array_spec_element should be:
1735 * case 0: expr
1736 * case 1: expr :
1737 * case 2: expr : expr
1738 * case 3: expr : *
1739 * case 4: *
1740 * case 5: :
1741 * case 6: ..
1742 */
1743array_spec
1744@init{
1745 int numAS = 1;
1746}
1747 : array_spec_element
1748 (COMMA array_spec_element {numAS++;})*
1749 { MFPA.array_spec(numAS);}
1750 ;
1751
1752array_spec_element
1753@init{
1754 int type = MFPUtils.ASE_1U;
1755}
1756@after{
1757 MFPA.array_spec_element(type);
1758}
1759 : expr ( COLON {type=MFPUtils.ASE_LN;}
1760 ( expr {type=MFPUtils.ASE_LU;}
1761 | ASTERISK {type=MFPUtils.ASE_LX;}
1762 )?
1763 )?
1764 | ASTERISK { type=MFPUtils.ASE_1X; }
1765 | COLON { type=MFPUtils.ASE_NN; }
1766 | DODOT { type=MFPUtils.ASE_RK; }
1767 ;
1768
1769
1770/*
1771 * R816: explicit shape spec
1772 * OFP: refactored to remove conditional from lhs and inlined lower_bound and upper_bound
1773 */
1774explicit_shape_spec
1775@init{
1776 boolean hasUB = false;
1777}
1778 : expr (COLON expr {hasUB=true;})?
1779 { MFPA.explicit_shape_spec(hasUB);}
1780 ;
1781
1782explicit_shape_spec_list
1783@init{
1784 int numESS = 1;
1785}
1786 : explicit_shape_spec
1787 ( COMMA explicit_shape_spec {numESS++;})*
1788 { MFPA.explicit_shape_spec_list(numESS);}
1789 ;
1790
1791/*
1792 * OFP: specification_expr inlined as expr
1793 * R817: lower bound
1794 * R818: upper bound
1795 */
1796
1797/*
1798 * R820: deferred shape spec
1799 * OFP: inlined as COLON in deferred_shape_spec_list
1800 */
1801deferred_shape_spec_list
1802@init{
1803 int numDSS = 1;
1804}
1805@after{
1806 MFPA.deferred_shape_spec_list(numDSS);
1807}
1808 : COLON
1809 ( COMMA COLON {numDSS++;} )*
1810 ;
1811
1812/*
1813 * R826: intent spec
1814 */
1815intent_spec
1816 : IN { MFPA.intent_spec(
1817 $IN, null); }
1818 | OUT { MFPA.intent_spec(
1819 null, $OUT); }
1820 | IN OUT { MFPA.intent_spec(
1821 $IN, $OUT); }
1822 | INOUT { MFPA.intent_spec(
1823 $INOUT, $INOUT); }
1824 ;
1825
1826/*
1827 * R827: access stmt
1828 */
1829access_stmt
1830@init {
1831 boolean hasList=false;
1832}
1833@after{
1834 checkForInclude();
1835}
1836 : (lbl=label)?
1837 access_spec (
1838 ( COLON_COLON )?
1839 access_id_list {hasList=true;}
1840 )? end_of_stmt
1841 { MFPA.access_stmt(lbl,$end_of_stmt.t,hasList); }
1842 ;
1843
1844/*
1845 * R828: access id
1846 * OFP: IDENT inlined for use_name
1847 * generic_spec can be IDENT so IDENT deleted
1848 */
1849access_id
1850 : generic_spec { MFPA.access_id(); }
1851 ;
1852
1853access_id_list
1854@init{
1855 int numAI = 1;
1856}
1857@after{
1858 MFPA.access_id_list(numAI);
1859}
1860 : access_id
1861 ( COMMA access_id {numAI++;} )*
1862 ;
1863
1864/*
1865 * R829: allocatable stmt
1866 */
1867allocatable_stmt
1868@init {
1869}
1870@after{
1871 checkForInclude();
1872}
1873 : (lbl=label)?
1874 ALLOCATABLE ( COLON_COLON )? allocatable_decl_list end_of_stmt
1875 { MFPA.allocatable_stmt(lbl, $ALLOCATABLE, $end_of_stmt.t);}
1876 ;
1877
1878/*
1879 * R830: allocatable decl
1880 */
1881allocatable_decl
1882@init{
1883 Token objName=null;
1884 boolean hasAS=false;
1885 boolean hasCS=false;
1886}
1887 : object_name {objName=$object_name.t;}
1888 ( LPAREN array_spec RPAREN {hasAS=true;} )?
1889 ( LBRACKET coarray_spec RBRACKET {hasCS=true;} )?
1890 { MFPA.allocatable_decl(objName, hasAS, hasCS);}
1891 ;
1892
1893allocatable_decl_list
1894@init{
1895 int numAD = 1;
1896}
1897@after{
1898 MFPA.allocatable_decl_list(numAD);
1899}
1900 : allocatable_decl
1901 ( COMMA allocatable_decl {numAD++;} )*
1902 ;
1903
1904/*
1905 * R831: asynchronous stmt
1906 * OFP: generic_name_list substituted for object_name_list
1907 */
1908asynchronous_stmt
1909@init {
1910}
1911@after{
1912 checkForInclude();
1913}
1914 : (lbl=label)?
1915 ASYNCHRONOUS ( COLON_COLON )? generic_name_list
1916 end_of_stmt
1917 { MFPA.asynchronous_stmt(lbl,$ASYNCHRONOUS,$end_of_stmt.t); }
1918 ;
1919
1920/*
1921 * R832: bind stmt
1922 */
1923bind_stmt
1924@init{
1925}
1926@after{
1927 checkForInclude();
1928}
1929 : (lbl=label)?
1930 language_binding_spec ( COLON_COLON )? bind_entity_list
1931 end_of_stmt
1932 { MFPA.bind_stmt(lbl, $end_of_stmt.t); }
1933 ;
1934
1935/*
1936 * R833: bind entity
1937 * OFP: 2nd arg is 'isCommonBlockName'
1938 * IDENT inlined for entity_name and common_block_name
1939 */
1940bind_entity
1941 : IDENT
1942 { MFPA.bind_entity($IDENT, false); }
1943 | SLASH IDENT SLASH
1944 { MFPA.bind_entity($IDENT, true); }
1945 ;
1946
1947bind_entity_list
1948@init{
1949 int numBE = 1;
1950}
1951@after{
1952 MFPA.bind_entity_list(numBE);
1953}
1954 : bind_entity
1955 ( COMMA bind_entity {numBE++;} )*
1956 ;
1957
1958/*
1959 * R834: codimension stmt
1960 */
1961codimension_stmt
1962@init{
1963}
1964@after{
1965 checkForInclude();
1966}
1967 : (lbl=label)?
1968 CODIMENSION ( COLON_COLON )? codimension_decl_list
1969 end_of_stmt
1970 { MFPA.codimension_stmt(lbl, $CODIMENSION, $end_of_stmt.t); }
1971 ;
1972
1973/*
1974 * R835: codimension decl
1975 */
1976codimension_decl
1977 : IDENT LBRACKET coarray_spec RBRACKET
1978 { MFPA.codimension_decl($IDENT, $LBRACKET, $RBRACKET);}
1979 ;
1980
1981codimension_decl_list
1982@init{
1983 int numCD = 1;
1984}
1985@after{
1986 MFPA.codimension_decl_list(numCD);
1987}
1988 : codimension_decl
1989 ( COMMA codimension_decl {numCD++;} )*
1990 ;
1991
1992/*
1993 * R836: contiguous stmt
1994 */
1995contiguous_stmt
1996@init{
1997}
1998@after{
1999 checkForInclude();
2000}
2001 : (lbl=label)?
2002 CONTIGUOUS ( COLON_COLON )? generic_name_list
2003 end_of_stmt
2004 { MFPA.contiguous_stmt(lbl, $CONTIGUOUS, $end_of_stmt.t); }
2005 ;
2006
2007/*
2008 * R837: data stmt
2009 */
2010data_stmt
2011@init{
2012 int numDSS = 1;
2013}
2014@after{
2015 checkForInclude();
2016}
2017 : (lbl=label)?
2018 DATA data_stmt_set
2019 ( ( COMMA )? data_stmt_set {numDSS++;})*
2020 end_of_stmt
2021 { MFPA.data_stmt(lbl, $DATA, $end_of_stmt.t, numDSS); }
2022 ;
2023
2024/*
2025 * R838: data stmt set
2026 */
2027data_stmt_set
2028 : data_stmt_object_list
2029 SLASH data_stmt_value_list SLASH
2030 { MFPA.data_stmt_set(); }
2031 ;
2032
2033/*
2034 * R839: data stmt object
2035 */
2036data_stmt_object
2037@after {
2038 MFPA.data_stmt_object();
2039}
2040 : variable
2041 | data_implied_do
2042 ;
2043
2044data_stmt_object_list
2045@init{
2046 int numDSO = 1;
2047}
2048@after{
2049 MFPA.data_stmt_object_list(numDSO);
2050}
2051 : data_stmt_object
2052 ( COMMA data_stmt_object {numDSO++;} )*
2053 ;
2054
2055/*
2056 * R840: data implied do
2057 * R842: data i do variable
2058 * OFP: scalar_int_expr replaced by expr
2059 * data_i_do_variable replaced by IDENT
2060 */
2061data_implied_do
2062@init{
2063 boolean hasStrd = false;
2064}
2065 : LPAREN data_i_do_object_list
2066 COMMA IDENT EQUALS expr
2067 COMMA expr
2068 ( COMMA expr { hasStrd = true; })? RPAREN
2069 { MFPA.data_implied_do($IDENT, hasStrd); }
2070 ;
2071
2072/*
2073 * R841: data i do object
2074 * OFP: data_ref inlined for scalar_structure_component and array_element
2075 */
2076data_i_do_object
2077@after {
2078 MFPA.data_i_do_object();
2079}
2080 : data_ref
2081 | data_implied_do
2082 ;
2083
2084data_i_do_object_list
2085@init{
2086 int numDIDO = 1;
2087}
2088@after{
2089 MFPA.data_i_do_object_list(numDIDO);
2090}
2091 : data_i_do_object
2092 ( COMMA data_i_do_object {numDIDO++;} )*
2093 ;
2094
2095/*
2096 * R843: data stmt value
2097 * R844: data stmt repeat
2098 * R846: int constant subobject
2099 * R847: constant subobject
2100 * OFP: Rule 844 inlined as:
2101 * designator (replacing Rule 847 in scalar-Rule 846)
2102 * | int_literal_constant (replacing scalar-int-constant)
2103 * And, if data stmt repeat does NOT appear,
2104 * then data-stmt-constant inlined as:
2105 * a set of typed literal constants (replacing scalar-constant)
2106 * designator (replacing scalar-constant-subobject and nitial-data-target)
2107 * signed int/real constants
2108 * structure constructor (also absorbs null-init)
2109 */
2110data_stmt_value
2111options {backtrack=true; k=3;}
2112@init {
2113 Token t = null;
2114}
2115@after{
2116 MFPA.data_stmt_value(t);
2117}
2118 : designator (ASTERISK data_stmt_constant {t=$ASTERISK;})?
2119 | int_literal_constant (ASTERISK data_stmt_constant {t=$ASTERISK;})?
2120 | signed_int_literal_constant
2121 | signed_real_literal_constant
2122 | complex_literal_constant
2123 | logical_literal_constant
2124 | char_literal_constant
2125 | boz_literal_constant
2126 | structure_constructor
2127 ;
2128
2129data_stmt_value_list
2130@init{
2131 int numDSV = 1;
2132}
2133@after{
2134 MFPA.data_stmt_value_list(numDSV);
2135}
2136 : data_stmt_value
2137 ( COMMA data_stmt_value {numDSV++;} )*
2138 ;
2139
2140/*
2141 * R845: data stmt constant
2142 * OFP: items are inlined as:
2143 * a set of typed literal constants (replacing scalar-constant)
2144 * designator (replacing scalar-constant-subobject and nitial-data-target)
2145 * signed int/real constants
2146 * structure constructor (also absorbs null-init)
2147 */
2148data_stmt_constant
2149options {backtrack=true; k=3;}
2150@after {
2151 MFPA.data_stmt_constant();
2152}
2153 : designator
2154 | signed_int_literal_constant
2155 | signed_real_literal_constant
2156 | complex_literal_constant
2157 | logical_literal_constant
2158 | char_literal_constant
2159 | boz_literal_constant
2160 | structure_constructor
2161 ;
2162
2163/*
2164 * R848: dimension stmt
2165 */
2166dimension_stmt
2167@init {
2168 int numDD = 1;
2169}
2170@after{
2171 checkForInclude();
2172}
2173 : (lbl=label)?
2174 DIMENSION ( COLON_COLON )?
2175 dimension_decl ( COMMA dimension_decl {numDD++;})*
2176 end_of_stmt
2177 { MFPA.dimension_stmt(lbl, $DIMENSION, $end_of_stmt.t, numDD); }
2178 ;
2179
2180dimension_decl
2181 : IDENT LPAREN array_spec RPAREN
2182 { MFPA.dimension_decl($IDENT);}
2183 ;
2184
2185/*
2186 * R849: intent stmt
2187 * OFP: generic_name_list substituted for dummy_arg_name_list
2188 */
2189intent_stmt
2190@init{
2191}
2192@after{
2193 checkForInclude();
2194}
2195 : (lbl=label)?
2196 INTENT LPAREN intent_spec RPAREN ( COLON_COLON )? generic_name_list
2197 end_of_stmt
2198 { MFPA.intent_stmt(lbl,$INTENT,$end_of_stmt.t);}
2199 ;
2200
2201/*
2202 * R850: optional stmt
2203 * OFP: generic_name_list substituted for dummy_arg_name_list
2204 */
2205optional_stmt
2206@init {
2207}
2208@after{
2209 checkForInclude();
2210}
2211 : (lbl=label)?
2212 OPTIONAL ( COLON_COLON )? generic_name_list
2213 end_of_stmt
2214 { MFPA.optional_stmt(lbl, $OPTIONAL, $end_of_stmt.t); }
2215 ;
2216
2217/*
2218 * R851: parameter stmt
2219 */
2220parameter_stmt
2221@init{
2222}
2223@after{
2224 checkForInclude();
2225}
2226 : (lbl=label)?
2227 PARAMETER LPAREN named_constant_def_list RPAREN
2228 end_of_stmt
2229 { MFPA.parameter_stmt(lbl,$PARAMETER,$end_of_stmt.t);}
2230 ;
2231
2232/*
2233 * R852: named constaant def
2234 * OFP: initialization_expr replaced by expr
2235 * named_constant replaced by IDENT
2236 */
2237named_constant_def
2238 : IDENT EQUALS expr
2239 { MFPA.named_constant_def($IDENT);}
2240 ;
2241
2242named_constant_def_list
2243@init{
2244 int numNCD = 1;
2245}
2246@after{
2247 MFPA.named_constant_def_list(numNCD);
2248}
2249 : named_constant_def
2250 ( COMMA named_constant_def {numNCD++;} )*
2251 ;
2252
2253/*
2254 * R853: pinter stmt
2255 */
2256pointer_stmt
2257@init{
2258 boolean isCrayPointer=false;
2259}
2260@after{
2261 checkForInclude();
2262}
2263 : (lbl=label)?
2264 POINTER
2265 ( cray_pointer_assoc_list {isCrayPointer = true;}
2266 | ( ( COLON_COLON )? pointer_decl_list )
2267 )
2268 end_of_stmt
2269 { if (isCrayPointer) {
2270 MFPA.cray_pointer_stmt(lbl,$POINTER,$end_of_stmt.t);
2271 } else {
2272 MFPA.pointer_stmt(lbl,$POINTER,$end_of_stmt.t);
2273 }
2274 }
2275 ;
2276
2277/*
2278 * R854: pointer decl
2279 * OFP: IDENT inlined as object_name and
2280 * proc_entity_name (removing second alt)
2281 */
2282pointer_decl
2283@init{
2284 boolean hasSL = false;
2285}
2286 : IDENT
2287 ( LPAREN deferred_shape_spec_list RPAREN {hasSL=true;})?
2288 { MFPA.pointer_decl($IDENT,hasSL);}
2289 ;
2290
2291cray_pointer_assoc
2292 : LPAREN pointer=IDENT COMMA pointee=IDENT RPAREN
2293 { MFPA.cray_pointer_assoc(pointer, pointee);}
2294 ;
2295
2296pointer_decl_list
2297@init{
2298 int numPD = 1;
2299}
2300@after{
2301 MFPA.pointer_decl_list(numPD);
2302}
2303 : pointer_decl
2304 ( COMMA pointer_decl {numPD++;} )*
2305 ;
2306
2307cray_pointer_assoc_list
2308@init{
2309 int numCPA = 1;
2310}
2311@after{
2312 MFPA.cray_pointer_assoc_list(numCPA);
2313}
2314 : cray_pointer_assoc
2315 ( COMMA cray_pointer_assoc {numCPA++;} )*
2316 ;
2317
2318/*
2319 * R855: protected stmt
2320 * OFP: generic_name_list substituted for entity_name_list
2321 */
2322protected_stmt
2323@init{
2324}
2325@after{
2326 checkForInclude();
2327}
2328 : (lbl=label)?
2329 PROTECTED ( COLON_COLON )? generic_name_list
2330 end_of_stmt
2331 { MFPA.protected_stmt(lbl,$PROTECTED,$end_of_stmt.t);}
2332 ;
2333
2334/*
2335 * R856: save stmt
2336 */
2337save_stmt
2338@init{
2339 boolean hasSEL = false;
2340}
2341@after{
2342 checkForInclude();
2343}
2344 : (lbl=label)?
2345 SAVE ( ( COLON_COLON )? saved_entity_list {hasSEL=true;} )?
2346 end_of_stmt
2347 { MFPA.save_stmt(lbl,$SAVE,$end_of_stmt.t,hasSEL);}
2348 ;
2349
2350/*
2351 * R857: saved entity
2352 * R858: proc pointer name
2353 * OFP: IDENT inlined for object_name,
2354 * proc_pointer_name (removing second alt),
2355 * common_block_name.
2356 */
2357saved_entity
2358 : id=IDENT
2359 { MFPA.saved_entity(id, false);}
2360 | SLASH id=IDENT SLASH
2361 {MFPA.saved_entity(id, true);} //Block Name
2362 ;
2363
2364saved_entity_list
2365@init{
2366 int numSE = 1;
2367}
2368@after{
2369 MFPA.saved_entity_list(numSE);
2370}
2371 : saved_entity
2372 ( COMMA saved_entity {numSE++;} )*
2373 ;
2374
2375/*
2376 * R859: target stmt
2377 * OFP: IDENT inlined for object_name
2378 */
2379target_stmt
2380@init{
2381}
2382@after{
2383 checkForInclude();
2384}
2385 : (lbl=label)?
2386 TARGET ( COLON_COLON )? target_decl_list
2387 end_of_stmt
2388 { MFPA.target_stmt(lbl,$TARGET,$end_of_stmt.t);}
2389 ;
2390
2391/*
2392 * R860: target decl
2393 */
2394target_decl
2395@init{
2396 boolean hasAS=false;
2397 boolean hasCS=false;
2398}
2399 : IDENT
2400 (LPAREN array_spec RPAREN {hasAS=true;} )?
2401 (LBRACKET coarray_spec RBRACKET {hasCS=true;} )?
2402 { MFPA.target_decl($IDENT,hasAS,hasCS);}
2403 ;
2404
2405target_decl_list
2406@init{
2407 int numTD = 1;
2408}
2409@after{
2410 MFPA.target_decl_list(numTD);
2411}
2412 : target_decl
2413 ( COMMA target_decl {numTD++;} )*
2414 ;
2415
2416/*
2417 * R861: value stmt
2418 * OFP: generic_name_list substituted for dummy_arg_name_list
2419 */
2420value_stmt
2421@init{
2422}
2423@after{
2424 checkForInclude();
2425}
2426 : (lbl=label)?
2427 VALUE ( COLON_COLON )? generic_name_list
2428 end_of_stmt
2429 { MFPA.value_stmt(lbl,$VALUE,$end_of_stmt.t);}
2430 ;
2431
2432/*
2433 * R862: volatile stmt
2434 * OFP: generic_name_list substituted for object_name_list
2435 */
2436volatile_stmt
2437@init{
2438}
2439@after{
2440 checkForInclude();
2441}
2442 : (lbl=label)?
2443 VOLATILE ( COLON_COLON )? generic_name_list
2444 end_of_stmt
2445 { MFPA.volatile_stmt(lbl,$VOLATILE,$end_of_stmt.t);}
2446 ;
2447
2448/*
2449 * R863: implicit stmt
2450 */
2451implicit_stmt
2452@after{
2453 checkForInclude();
2454}
2455 : (lbl=label)?
2456 IMPLICIT
2457 implicit_spec_list
2458 end_of_stmt
2459 { MFPA.implicit_stmt(
2460 lbl, $IMPLICIT, null, ins, $end_of_stmt.t);}
2461 | (lbl=label)?
2462 IMPLICIT NONE
2463 (LPAREN (ins = implicit_none_spec)? RPAREN)?
2464 end_of_stmt
2465 { MFPA.implicit_stmt(
2466 lbl, $IMPLICIT, $NONE, ins, $end_of_stmt.t);}
2467 ;
2468
2469/*
2470 * R864: implicit spec
2471 */
2472implicit_spec
2473 : declaration_type_spec LPAREN letter_spec_list RPAREN
2474 { MFPA.implicit_spec(); }
2475 ;
2476
2477implicit_spec_list
2478@init{
2479 int numIS = 1;
2480}
2481@after{
2482 MFPA.implicit_spec_list(numIS);
2483}
2484 : implicit_spec
2485 ( COMMA implicit_spec {numIS++;} )*
2486 ;
2487
2488/*
2489 * R865: letter spec
2490 * OFP: action should check the token text
2491 * which should be either a single letter
2492 * or a letter range (e.g., A-Z).
2493 */
2494letter_spec
2495 : id1=IDENT ( MINUS id2=IDENT )?
2496 { MFPA.letter_spec(id1, id2); }
2497 ;
2498
2499letter_spec_list
2500@init{
2501 int numLS = 1;
2502}
2503@after{
2504 MFPA.letter_spec_list(numLS);
2505}
2506 : letter_spec
2507 ( COMMA letter_spec {numLS++;} )*
2508 ;
2509
2510/*
2511 * R866: implicit none spec
2512 */
2513implicit_none_spec returns [Token t]
2514 : EXTERNAL { t = $EXTERNAL;}
2515 | TYPE { t = $TYPE;}
2516 ;
2517
2518/*
2519 * R867: import stmt
2520 * OFP: generic_name_list substituted for import_name_list
2521 */
2522import_stmt
2523@init{
2524 boolean hasINL = false;
2525}
2526@after{
2527 checkForInclude();
2528}
2529 : (lbl=label)?
2530 IMPORT ( ( COLON_COLON )? generic_name_list {hasINL=true;})?
2531 end_of_stmt
2532 { MFPA.import_stmt(lbl, $IMPORT, null, $end_of_stmt.t, hasINL);}
2533 | (lbl=label)?
2534 IMPORT COMMA ONLY COLON generic_name_list
2535 end_of_stmt
2536 { MFPA.import_stmt(lbl, $IMPORT, $ONLY, $end_of_stmt.t, true);}
2537 | (lbl=label)?
2538 IMPORT COMMA NONE
2539 end_of_stmt
2540 { MFPA.import_stmt(lbl, $IMPORT, $NONE, $end_of_stmt.t, false);}
2541 | (lbl=label)?
2542 IMPORT COMMA ALL
2543 end_of_stmt
2544 { MFPA.import_stmt(lbl, $IMPORT, $ALL, $end_of_stmt.t, false);}
2545 ;
2546
2547/*
2548 * R868: namelist stmt
2549 * OFP: IDENT inlined for namelist_group_name
2550 */
2551namelist_stmt
2552@init {
2553 int numNL =1;
2554}
2555@after{
2556 checkForInclude();
2557}
2558 : (lbl=label)?
2559 NAMELIST SLASH nlName=IDENT SLASH
2560 { MFPA.namelist_group_name(nlName);}
2561 namelist_group_object_list
2562 ( ( COMMA )? SLASH nlName=IDENT SLASH
2563 { MFPA.namelist_group_name(nlName);}
2564 namelist_group_object_list {numNL++;}
2565 )*
2566 end_of_stmt
2567 { MFPA.namelist_stmt(lbl,$NAMELIST,$end_of_stmt.t,numNL);}
2568 ;
2569
2570/*
2571 * R869: namelist group object
2572 * OFP: namelist_group_object was variable_name inlined as IDENT
2573 */
2574namelist_group_object_list
2575@init{
2576 int numNGO = 1;
2577}
2578@after{
2579 MFPA.namelist_group_object_list(numNGO);
2580}
2581 : goName=IDENT {MFPA.namelist_group_object(goName);}
2582 ( COMMA goName=IDENT
2583 { MFPA.namelist_group_object(goName); numNGO++;} )*
2584 ;
2585
2586/*
2587 * R870: equivalence stmt
2588 */
2589equivalence_stmt
2590@init{
2591}
2592@after{
2593 checkForInclude();
2594}
2595 : (lbl=label)?
2596 EQUIVALENCE equivalence_set_list
2597 end_of_stmt
2598 { MFPA.equivalence_stmt(lbl, $EQUIVALENCE, $end_of_stmt.t);}
2599 ;
2600
2601/*
2602 * R871: euivalence set
2603 */
2604equivalence_set
2605 : LPAREN equivalence_object COMMA equivalence_object_list RPAREN
2606 { MFPA.equivalence_set(); }
2607 ;
2608
2609equivalence_set_list
2610@init{
2611 int numES = 1;
2612}
2613 : equivalence_set
2614 ( COMMA equivalence_set {numES++;} )*
2615 { MFPA.equivalence_set_list(numES);}
2616 ;
2617
2618/*
2619 * R872: equivalence object
2620 * OFP: IDENT inlined for variable_name
2621 * data_ref inlined for array_element
2622 * data_ref is a IDENT so IDENT deleted (removing first alt)
2623 * substring is a data_ref so data_ref deleted (removing second alt)
2624 */
2625equivalence_object
2626 : substring { MFPA.equivalence_object(); }
2627 ;
2628
2629equivalence_object_list
2630@init{
2631 int numEO = 1;
2632}
2633@after{
2634 MFPA.equivalence_object_list(numEO);
2635}
2636 : equivalence_object
2637 ( COMMA equivalence_object {numEO++;} )*
2638 ;
2639
2640/*
2641 * R873: common stmt
2642 * OFP: MFPA.common_block_name must be called in any case.
2643 */
2644common_stmt
2645@init{
2646 int numBlocks=1;
2647}
2648@after{
2649 checkForInclude();
2650}
2651 : (lbl=label)?
2652 COMMON ( cb_name=common_block_name )?
2653 { MFPA.common_block_name(cb_name); }
2654 common_block_object_list
2655 ( ( COMMA )? cb_name=common_block_name
2656 { MFPA.common_block_name(cb_name); }
2657 common_block_object_list {numBlocks++;}
2658 )* end_of_stmt
2659 { MFPA.common_stmt(
2660 lbl, $COMMON, $end_of_stmt.t, numBlocks);}
2661 ;
2662
2663// OFP: SLASH_SLASH required in case of no spaces slashes, '//'
2664common_block_name returns [Token id]
2665 : SLASH_SLASH {id=null;}
2666 | SLASH (IDENT)? SLASH {id=$IDENT;}
2667 ;
2668
2669/*
2670 * R874: common block object
2671 */
2672common_block_object
2673@init{
2674 boolean hasSSL=false;
2675}
2676 : IDENT
2677 ( LPAREN explicit_shape_spec_list RPAREN {hasSSL=true;})?
2678 { MFPA.common_block_object($IDENT,hasSSL);}
2679 ;
2680
2681common_block_object_list
2682@init{
2683 int numCBO = 1;
2684}
2685@after{
2686 MFPA.common_block_object_list(numCBO);
2687}
2688 : common_block_object
2689 ( COMMA common_block_object {numCBO++;} )*
2690 ;
2691
2692/*
2693 * R896: quantified_expr
2694 * CIVL: CIVL extension
2695 */
2696quantified_expr
2697@init{
2698 boolean hasRestrict = false;
2699}
2700 : CIVL_PRIMITIVE LPAREN intrinsic_type_spec entity_decl_list
2701 (COLON (quantified_expr|expr) {hasRestrict = true;} )? RPAREN expr
2702 {MFPA.quantified_expr($CIVL_PRIMITIVE, hasRestrict);}
2703 ;
2704
2705/*
2706 * R897: civl_stmt
2707 * CIVL: CIVL extension
2708 */
2709civl_stmt
2710@init{
2711 boolean isQuantified = false;
2712 int numArgs = 0;
2713}
2714 : CIVL_PRIMITIVE LPAREN
2715 ( expr {numArgs++;}
2716 | quantified_expr {isQuantified = true;numArgs++;}
2717 )? RPAREN
2718 {MFPA.civl_stmt($CIVL_PRIMITIVE, numArgs);}
2719 ;
2720
2721/*
2722 * R897: pragma_type_qualifier_stmt
2723 * CIVL: CIVL extension
2724 */
2725pragma_type_qualifier_stmt
2726@after{
2727 checkForInclude();
2728}
2729 : PRAGMA IDENT CIVL_PRIMITIVE end_of_stmt
2730 { MFPA.pragma_type_qualifier_stmt($IDENT, $CIVL_PRIMITIVE);}
2731 ;
2732
2733/*
2734 * R898: pragma_stmt
2735 * CIVL: CIVL extension
2736 */
2737pragma_stmt
2738@init{
2739 boolean isCIVL = false;
2740}
2741@after{
2742 checkForInclude();
2743}
2744 : PRAGMA IDENT (pragma_tokens|civl_stmt {isCIVL = true;}) end_of_stmt
2745 { MFPA.pragma_stmt(isCIVL, $IDENT, $end_of_stmt.t);}
2746 ;
2747
2748/*
2749 * R899: pragma_tokens
2750 * CIVL: CIVL extension
2751 */
2752pragma_tokens
2753@init{
2754 int numPT=0;
2755}
2756@after{
2757 MFPA.pragma_token_list(numPT);
2758}
2759 : ( pt=(~ (EOS|EOF|CIVL_PRIMITIVE))
2760 { MFPA.pragma_token(pt); numPT++;}
2761 )+
2762 ;
2763
2764/*
2765 * R901: designator
2766 * OFP: designator
2767 * is rule 804 (as IDENT
2768 * or rule 913 (is data-ref)
2769 * or rule 914 (is data-ref)
2770 * or rule 917 (is data-ref)
2771 * or rule 918 (is data-ref containing rule 910)
2772 * or rule 915 (is data-ref with RE or IM)
2773 * or substring
2774 * (substring-range) may be matched in data-ref
2775 * this rule is now identical to substring
2776 * CIVL: TODO: Converter should recognize 'RE', 'IM' as RE, T_IM
2777 * Then change hasSR to be designator kind
2778 */
2779designator
2780@init{
2781 boolean hasSR = false;
2782}
2783 : data_ref (LPAREN substring_range {hasSR=true;} RPAREN)?
2784 { MFPA.designator(hasSR); }
2785 | char_literal_constant LPAREN substring_range RPAREN
2786 { MFPA.substring(true); }
2787 ;
2788
2789/*
2790 * R996: designator_or_func_ref
2791 * OFP: OFP extension
2792 * a function_reference is ambiguous with designator,
2793 * which could be an array element.
2794 * data_ref may (or not) match
2795 * LPAREN ( actual_arg_spec_list )? RPAREN
2796 * so is optional
2797 */
2798designator_or_func_ref
2799@init {
2800 int sType = MFPUtils.DOFR_NONE;
2801}
2802@after {
2803 MFPA.designator_or_func_ref(sType);
2804}
2805 : data_ref
2806 ( LPAREN substring_range_or_arg_list RPAREN
2807 { sType = $substring_range_or_arg_list.sType; }
2808 )?
2809 { if(sType == MFPUtils.DOFR_SRNG) {
2810 MFPA.designator(true);
2811 }else if (sType == MFPUtils.DOFR_ARGS) {
2812 MFPA.function_reference();
2813 }
2814 }
2815 | char_literal_constant LPAREN substring_range RPAREN
2816 { sType = MFPUtils.DOFR_SSTR;
2817 MFPA.substring(true);
2818 }
2819 ;
2820
2821substring_range_or_arg_list returns [int sType]
2822@init{
2823 boolean hasUB = false;
2824 boolean hasLB = false;
2825 Token keyword = null;
2826 int numAAS = 1;
2827}
2828@after {
2829 MFPA.substring_range_or_arg_list();
2830}
2831 : COLON (expr {hasUB = true;})?
2832 { MFPA.substring_range(hasLB, hasUB);
2833 sType = MFPUtils.DOFR_SRNG;
2834 } // substring_range
2835 | expr substr_range_or_arg_list_suffix
2836 { sType = $substr_range_or_arg_list_suffix.sType; }
2837 | IDENT EQUALS expr
2838 { MFPA.actual_arg_spec($IDENT, null, null); } // hasExpr=false
2839 ( COMMA actual_arg_spec {numAAS++;} )*
2840 { MFPA.actual_arg_spec_list(numAAS);
2841 sType = MFPUtils.DOFR_ARGS;
2842 }
2843 | ( IDENT EQUALS {keyword=$IDENT;} )? ASTERISK lbl=label
2844 { MFPA.actual_arg_spec(keyword, $ASTERISK, lbl); }
2845 ( COMMA actual_arg_spec {numAAS++;} )*
2846 { MFPA.actual_arg_spec_list(numAAS);
2847 sType = MFPUtils.DOFR_ARGS;
2848 }
2849 ;
2850
2851substr_range_or_arg_list_suffix returns [int sType]
2852@init{
2853 boolean hasUB = false;
2854 boolean hasLB = true;
2855 int numAAS = 1;
2856 int error = -1;
2857}
2858@after{
2859 MFPA.substr_range_or_arg_list_suffix();
2860}
2861 : { MFPA.actual_arg_spec_list(error); }
2862 COLON (expr {hasUB=true;})?
2863 { MFPA.substring_range(hasLB, hasUB);
2864 sType = MFPUtils.DOFR_SRNG;
2865 } // substring_range
2866 | { MFPA.actual_arg_spec(null, null, null); } // hasExpr=true
2867 ( COMMA actual_arg_spec {numAAS++;} )*
2868 { MFPA.actual_arg_spec_list(numAAS);
2869 sType = MFPUtils.DOFR_ARGS;
2870 }
2871 ;
2872
2873/*
2874 * R902: variable
2875 */
2876variable
2877 : designator
2878 { MFPA.variable(); }
2879 ;
2880
2881
2882/*
2883 * R903: variable name
2884 * OFP: is name (inlined as IDENT)
2885 */
2886
2887/*
2888 * R904: logical variable
2889 */
2890logical_variable
2891 : variable
2892 { MFPA.logical_variable(); }
2893 ;
2894
2895/*
2896 * R905: char variable
2897 */
2898char_variable
2899 : variable
2900 { MFPA.char_variable(); }
2901 ;
2902
2903/*
2904 * R906: default char variable
2905 */
2906
2907default_char_variable
2908 : variable
2909 { MFPA.default_char_variable(); }
2910 ;
2911
2912/*
2913 * R907: int variable
2914 */
2915int_variable
2916 : variable
2917 { MFPA.int_variable(); }
2918 ;
2919
2920/*
2921 * R908: substring
2922 * OFP: C908 (rule 909) parent_string shall be of type character
2923 * fix for ambiguity in data_ref allows it to match
2924 * LPAREN substring_range RPAREN
2925 * so required LPAREN substring_range RPAREN made optional
2926 */
2927substring
2928@init{
2929 boolean hasSR = false;
2930}
2931@after{
2932 MFPA.substring(hasSR);
2933}
2934 : data_ref
2935 (LPAREN substring_range RPAREN {hasSR=true;})?
2936 | char_literal_constant
2937 LPAREN substring_range RPAREN {hasSR=true;}
2938 ;
2939
2940/*
2941 * R909: parent string
2942 * OF: is rule 903 (as IDENT in data-ref)
2943 * or rule 913 (as data_ref)
2944 * or rule 914 (as data_ref)
2945 * or rule 917 (as data_ref)
2946 * or rule 604 (as char_literal_constant)
2947 * (IDENT in data-ref, and must be char type)
2948 * thus, inlined in rule 908 as (data_ref | char_literal_constant)
2949 */
2950
2951/*
2952 * R910: substring range
2953 * OFP: scalar_int_expr replaced by expr
2954 */
2955substring_range
2956@init{
2957 boolean hasUB = false;
2958 boolean hasLB = false;
2959}
2960 : (expr {hasLB = true;})? COLON (expr {hasUB = true;})?
2961 { MFPA.substring_range(hasLB, hasUB); }
2962 ;
2963
2964/*
2965 * R911: data ref
2966 */
2967data_ref
2968@init{
2969 int numPR = 1;
2970}
2971@after{
2972 MFPA.data_ref(numPR);
2973}
2974 : part_ref
2975 ( PERCENT part_ref {numPR++;})*
2976 ;
2977
2978/*
2979 * R912: part ref
2980 * OFP: IDENT inlined for part_name
2981 * with k=2, this path is chosen over
2982 * LPAREN substring_range RPAREN
2983 * TODO: error: if a function call,
2984 * should match id rather than
2985 * (section_subscript_list)
2986 */
2987part_ref
2988options{k=2;}
2989@init{
2990 boolean hasSSL = false;
2991 boolean hasIS = false;
2992 Token id = null;
2993}
2994@after{
2995 MFPA.part_ref(id, hasSSL, hasIS);
2996}
2997 : (IDENT LPAREN) =>
2998 IDENT LPAREN section_subscript_list RPAREN
2999 (image_selector {hasIS=true;})?
3000 { hasSSL=true; id=$IDENT;}
3001 | (IDENT LBRACKET) =>
3002 IDENT image_selector
3003 { hasIS=true; id=$IDENT;}
3004 | IDENT
3005 { id=$IDENT;}
3006 ;
3007
3008part_ref_no_image_selector
3009options{k=2;}
3010@init{
3011 boolean hasSSL = false;
3012 boolean hasIS = false;
3013 Token id = null;
3014}
3015@after{
3016 MFPA.part_ref(id, hasSSL, hasIS);
3017}
3018 : (IDENT LPAREN) =>
3019 IDENT LPAREN section_subscript_list RPAREN
3020 { hasSSL=true; id=$IDENT;}
3021 | IDENT
3022 { id=$IDENT;}
3023 ;
3024
3025/*
3026 * R913: structure component
3027 * OFP: inlined as data_ref
3028 */
3029
3030/*
3031 * R914: coindexed named object
3032 * CIVL: inlined as data_ref
3033 */
3034
3035/*
3036 * R915: complex part designator
3037 * CIVL: inlined as data_ref
3038 */
3039
3040/*
3041 * R916: type param inquiry
3042 * OFP: inlined in rule 902 then deleted as can be designator
3043 * IDENT inlined for type_param_name
3044 */
3045
3046/*
3047 * R917: array element
3048 * OFP: inlined as data_ref
3049 */
3050
3051/*
3052 * R918: array section
3053 * OFP: inlined in rule 901
3054 */
3055
3056/*
3057 * R919: subscript
3058 * OFP: inlined as expr
3059 * scalar_int_expr replaced by expr
3060 */
3061
3062/*
3063 * R920: section subscript
3064 * OFP: expr inlined for subscript, vector_subscript, and stride (thus deleted option 3)
3065 * refactored first optional expr from subscript_triplet modified to also match
3066 * actual_arg_spec_list to reduce ambiguities and need for backtracking
3067 */
3068section_subscript returns [boolean isEmpty]
3069@init{
3070 boolean hasUB = false;
3071 boolean hasLB = false;
3072 boolean hasStrd = false;
3073 boolean isAmbiguous = false;
3074}
3075 : expr section_subscript_ambiguous
3076 | COLON (expr {hasUB=true;})? (COLON expr {hasStrd=true;})?
3077 { MFPA.section_subscript(hasLB, hasUB, hasStrd, isAmbiguous); }
3078 | COLON_COLON expr
3079 { MFPA.section_subscript(hasLB, hasUB, true, isAmbiguous); }
3080 | IDENT EQUALS expr
3081 { MFPA.actual_arg_spec($IDENT, null, null); } // may be actual-arg, see rule 1524
3082 | IDENT EQUALS ASTERISK lbl=label
3083 { MFPA.actual_arg_spec($IDENT, $ASTERISK, lbl); } // may be actual-arg, see rule 1524
3084 | ASTERISK lbl=label
3085 { MFPA.actual_arg_spec(null, $ASTERISK, lbl); } // may be actual-arg, see rule 1524
3086 | { isEmpty = true; } // empty may be actual-arg, see rule 1524
3087 ;
3088
3089section_subscript_ambiguous
3090@init {
3091 boolean hasUB = false;
3092 boolean hasLB = true;
3093 boolean hasStrd = false;
3094 boolean isAmbiguous = false;
3095}
3096@after{
3097 MFPA.section_subscript(hasLB, hasUB, hasStrd, isAmbiguous);
3098}
3099 : COLON (expr {hasUB=true;})? (COLON expr {hasStrd=true;})?
3100 /* OFP: this alternative is necessary because
3101 * if alt1 above has no expr following the first COLON and
3102 * there is an optional second COLON with no WS between the two,
3103 * the lexer will make a COLON_COLON token but not two COLON tokens.
3104 * in this case, the second expr is required.
3105 * (for an example, see J3/04-007, Note 7.44.)
3106 */
3107 | COLON_COLON expr { hasStrd=true; }
3108 | { isAmbiguous=true; } // empty could be an actual-arg, see rule 1524
3109 ;
3110
3111section_subscript_list
3112@init{
3113 int numSS = 1;
3114}
3115@after{
3116 MFPA.section_subscript_list(numSS);
3117}
3118 : isEmpty=section_subscript { if (isEmpty) numSS--; }
3119 (COMMA section_subscript {numSS++;})*
3120 ;
3121
3122/*
3123 * R921: subscript triplet
3124 * R922: stride
3125 * R923: vector subscript
3126 * OFP: inlined in rule 920
3127 * subscript, stride and vector subscript inlined as expr
3128 */
3129
3130/*
3131 * R924: image selector
3132 */
3133image_selector
3134@init{
3135 boolean hasISSL = false;
3136}
3137 : LBRACKET cosubscript_list (COMMA image_selector_spec_list {hasISSL=true;} ) RBRACKET
3138 { MFPA.image_selector(hasISSL);}
3139 ;
3140
3141/*
3142 * R925: cosubscript
3143 * CIVL: is scalar-int-expr (inlined as expr)
3144 */
3145cosubscript_list
3146@init{
3147 int numE = 1;
3148}
3149@after{
3150 MFPA.cosubscript_list(numE);
3151}
3152 : expr
3153 ( COMMA expr {numE++;} )*
3154 ;
3155
3156/*
3157 * R926: image selector spec
3158 * CIVL: contains rule 942 (inlined as designator)
3159 * or rule 1115 (inlined as scalar-expr)
3160 * or rule 1026 (inlined is scalar-int-expr)
3161 */
3162image_selector_spec
3163 : STAT EQUALS designator
3164 { MFPA.image_selector_spec($STAT,
3165 MFPUtils.ATTR_STAT); }
3166 | TEAM EQUALS expr
3167 { MFPA.image_selector_spec($TEAM,
3168 MFPUtils.ATTR_TEAM); }
3169 | TEAM_NUMBER EQUALS expr
3170 { MFPA.image_selector_spec($TEAM_NUMBER,
3171 MFPUtils.ATTR_TEAM_NUMBER); }
3172 ;
3173
3174
3175image_selector_spec_list
3176@init{
3177 int numISS = 1;
3178}
3179@after{
3180 MFPA.image_selector_spec_list(numISS);
3181}
3182 : image_selector_spec
3183 ( COMMA image_selector_spec {numISS++;} )*
3184 ;
3185
3186/*
3187 * R927: allocate stmt
3188 * OFP: modified to remove backtracking by looking for the token inserted
3189 * during the lexical prepass if a COLON_COLON was found
3190 * (which required alt1 below).
3191 */
3192allocate_stmt
3193@init{
3194 boolean hasTS = false;
3195 boolean hasAOL = false;
3196}
3197@after{
3198 checkForInclude();
3199}
3200 : (lbl=label)?
3201 M_ALLOCATE_STMT_1 ALLOCATE LPAREN
3202 type_spec COLON_COLON allocation_list
3203 ( COMMA alloc_opt_list {hasAOL=true;} )? RPAREN
3204 end_of_stmt
3205 { MFPA.allocate_stmt(lbl, $ALLOCATE,
3206 $end_of_stmt.t, true, hasAOL);
3207 }
3208 | (lbl=label)?
3209 ALLOCATE LPAREN allocation_list
3210 ( COMMA alloc_opt_list {hasAOL=true;} )? RPAREN
3211 end_of_stmt
3212 { MFPA.allocate_stmt(lbl, $ALLOCATE,
3213 $end_of_stmt.t, hasTS, hasAOL);
3214 }
3215 ;
3216
3217/*
3218 * R928: alloc opt
3219 * R929: errmsg variable
3220 * R930: source expr
3221 * CIVL: contains rule 929 (inlined as int-variable)
3222 * or rule 930 (inlined as expr)
3223 * or rule 942 (inlined as designator)
3224 */
3225alloc_opt
3226 : ERRMSG EQUALS default_char_variable
3227 { MFPA.alloc_opt($ERRMSG,
3228 MFPUtils.ALLOC_OPT_ERRMSG); }
3229 | MOLD EQUALS expr
3230 { MFPA.alloc_opt($MOLD,
3231 MFPUtils.ALLOC_OPT_MOLD); }
3232 | SOURCE EQUALS expr
3233 { MFPA.alloc_opt($SOURCE,
3234 MFPUtils.ALLOC_OPT_SOURCE); }
3235 | STAT EQUALS designator
3236 { MFPA.alloc_opt($STAT,
3237 MFPUtils.ALLOC_OPT_STAT); }
3238 ;
3239
3240alloc_opt_list
3241@init{
3242 int numAO = 1;
3243}
3244@after{
3245 MFPA.alloc_opt_list(numAO);
3246}
3247 : alloc_opt
3248 ( COMMA alloc_opt {numAO++;} )*
3249 ;
3250
3251/*
3252 * R931: allocation
3253 */
3254allocation
3255@init{
3256 boolean hasASSL = false;
3257 boolean hasACS = false;
3258}
3259 : (allocate_object LBRACKET) =>
3260 allocate_object LBRACKET allocate_coarray_spec RBRACKET
3261 { MFPA.allocation(hasASSL, true); }
3262 /* OFP: This option (with allocate_shape_spec_list)
3263 * is caught by the allocate object.
3264 * If so, the section-subscript-list must
3265 * be changed into a allocate-shape-spec-list.
3266 */
3267// | (allocate_object LPAREN) =>
3268// allocate_object LPAREN allocate_shape_spec_list RPAREN
3269// ( LBRACKET allocate_coarray_spec {hasACS=true;} RBRACKET )?
3270// { MFPA.allocation(true, hasACS);}
3271 | (allocate_object) =>
3272 allocate_object
3273 { MFPA.allocation(hasASSL, hasACS);}
3274 ;
3275
3276allocation_list
3277@init{
3278 int numAl = 1;
3279}
3280@after{
3281 MFPA.allocation_list(numAl);
3282}
3283 : allocation
3284 ( COMMA allocation {numAl++;} )*
3285 ;
3286
3287/*
3288 * R932: allocate object
3289 * OFP: C644 (R932) An allocate-object shall not be a coindexed object.
3290 * IDENT inlined for variable_name
3291 * data_ref inlined for structure_component
3292 * data_ref is a IDENT so IDENT deleted
3293 * data_ref inlined and part_ref_no_image_selector called directly
3294 */
3295allocate_object
3296@init{
3297 int numPR = 1;
3298}
3299@after{
3300 MFPA.data_ref(numPR);
3301 MFPA.allocate_object();
3302}
3303 : part_ref_no_image_selector
3304 (PERCENT part_ref_no_image_selector {numPR++;})*
3305 ;
3306
3307allocate_object_list
3308@init{
3309 int numAO = 1;
3310}
3311@after{
3312 MFPA.allocate_object_list(numAO);
3313}
3314 : allocate_object
3315 ( COMMA allocate_object {numAO++;} )*
3316 ;
3317
3318/*
3319 * R933: allocate shape spec
3320 * OFP: always has upper bound
3321 * grammar was refactored to remove left recursion
3322 */
3323allocate_shape_spec
3324@init{
3325 boolean hasUB = true;
3326 boolean hasLB = false;
3327}
3328 : expr (COLON expr)?
3329 { MFPA.allocate_shape_spec(hasLB, hasUB); }
3330 ;
3331
3332allocate_shape_spec_list
3333@init{
3334 int numASS = 1;
3335}
3336@after{
3337 MFPA.allocate_shape_spec_list(numASS);
3338}
3339 : allocate_shape_spec
3340 ( COMMA allocate_shape_spec {numASS++;} )*
3341 ;
3342
3343/*
3344 * R934: lower bound expr
3345 * R935: upper bound expr
3346 * OFP: is scalar_int_expr inlined as expr
3347 */
3348
3349/*
3350 * R936: allocate coarray spec
3351 * OFP: TODO: unfinished
3352 */
3353allocate_coarray_spec
3354options{k=3;}
3355@after{
3356 MFPA.allocate_coarray_spec();
3357}
3358 : (ASTERISK) => ASTERISK
3359 | (expr COLON ASTERISK) => expr COLON ASTERISK
3360// | allocate_coshape_spec_list COMMA ( expr COLON )? ASTERISK
3361// | ASTERISK // TESTING
3362 ;
3363
3364/*
3365 * R937: allocate coshape spec
3366 */
3367allocate_coshape_spec
3368@init{
3369 boolean hasLB = false;
3370}
3371 : expr ( COLON expr { hasLB = true; })?
3372 { MFPA.allocate_coshape_spec(hasLB); }
3373 ;
3374
3375allocate_coshape_spec_list
3376@init{
3377 int numAOS = 1;
3378}
3379@after{
3380 MFPA.allocate_coshape_spec_list(numAOS);
3381}
3382 : allocate_coshape_spec
3383 ( COMMA allocate_coshape_spec {numAOS++;} )*
3384 ;
3385
3386/*
3387 * R938: nullify stmt
3388 */
3389nullify_stmt
3390@init{
3391}
3392@after{
3393 checkForInclude();
3394}
3395 : (lbl=label)?
3396 NULLIFY LPAREN pointer_object_list RPAREN
3397 end_of_stmt
3398 { MFPA.nullify_stmt(lbl, $NULLIFY, $end_of_stmt.t); }
3399 ;
3400
3401/*
3402 * R939: pointer object
3403 * OFP: IDENT inlined for variable_name and proc_pointer_name
3404 * data_ref inlined for structure_component
3405 * data_ref can be a IDENT so IDENT deleted
3406 */
3407pointer_object
3408 : data_ref
3409 { MFPA.pointer_object(); }
3410 ;
3411
3412pointer_object_list
3413@init{
3414 int numPO = 1;
3415}
3416@after{
3417 MFPA.pointer_object_list(numPO);
3418}
3419 : pointer_object
3420 ( COMMA pointer_object {numPO++;} )*
3421 ;
3422
3423/*
3424 * R940: deallocate stmt
3425 */
3426deallocate_stmt
3427@init{
3428 boolean hasDOL = false;
3429}
3430@after{
3431 checkForInclude();
3432}
3433 : (lbl=label)?
3434 DEALLOCATE LPAREN allocate_object_list
3435 ( COMMA dealloc_opt_list {hasDOL=true;})? RPAREN
3436 end_of_stmt
3437 { MFPA.deallocate_stmt(lbl,
3438 $DEALLOCATE, $end_of_stmt.t, hasDOL);}
3439 ;
3440
3441/*
3442 * R941: dealloc opt
3443 * R942: stat variable
3444 * OFP: stat_variable and errmsg_variable replaced by designator
3445 * CIVL: contains rule 929 (inlined as int-variable)
3446 * or rule 942 (inlined as designator)
3447 */
3448dealloc_opt
3449 : STAT EQUALS designator
3450 { MFPA.dealloc_opt($STAT,
3451 MFPUtils.DEALLOC_OPT_STAT); }
3452 | ERRMSG EQUALS default_char_variable
3453 { MFPA.dealloc_opt($ERRMSG,
3454 MFPUtils.DEALLOC_OPT_ERRMSG); }
3455 ;
3456
3457dealloc_opt_list
3458@init{
3459 int numDO = 1;
3460}
3461@after{
3462 MFPA.dealloc_opt_list(numDO);
3463}
3464 : dealloc_opt
3465 ( COMMA dealloc_opt {numDO++;} )*
3466 ;
3467
3468/*
3469 * R1001: primary
3470 * OFP: constant replaced by literal_constant as IDENT can be designator
3471 * IDENT inlined for type_param_name
3472 * data_ref in designator can be a IDENT so deleted
3473 * type_param_inquiry is designator PERCENT IDENT
3474 * can be designator so deleted
3475 * function_reference integrated with designator (was ambiguous)
3476 * and deleted (to reduce backtracking)
3477 */
3478primary
3479options {backtrack=true;} // alt 1,4 ambiguous
3480@after{
3481 MFPA.primary();
3482}
3483 : designator_or_func_ref
3484 | literal_constant
3485 | array_constructor
3486 | structure_constructor
3487 | LPAREN expr RPAREN
3488 ;
3489
3490/*
3491 * R1002: level 1 expr
3492 */
3493level_1_expr
3494@init{
3495 Token t = null;
3496}
3497 : (defined_unary_op {t = $defined_unary_op.t;})?
3498 primary
3499 { MFPA.level_1_expr(t);}
3500 ;
3501
3502/*
3503 * R1003: defined unary op . letter+ .
3504 */
3505defined_unary_op returns [Token t]
3506 : DEFINED_OP {t = $DEFINED_OP;}
3507 ;
3508
3509/*
3510 * R1004: mult operand
3511 * OFP: power_operand inserted as rule 1004 functionality
3512 */
3513power_operand
3514@init{
3515 Token t = null;
3516}
3517 : level_1_expr
3518 ( power_op power_operand {t = $power_op.t;})?
3519 { MFPA.power_operand(t);}
3520 ;
3521
3522mult_operand
3523@init{
3524 int numMO = 0;
3525}
3526 : power_operand
3527 ( mult_op power_operand
3528 { numMO++; MFPA.mult_operand__mult_op($mult_op.t); }
3529 )*
3530 { MFPA.mult_operand(numMO); }
3531 ;
3532
3533/*
3534 * R1005: add operand
3535 * OFP: This rule has been added so the unary plus/minus has
3536 * the correct precedence when actions are performed.
3537 * moved leading optionals to mult_operand
3538 */
3539signed_operand
3540 : (t=add_op)?
3541 mult_operand
3542 { MFPA.signed_operand(t);}
3543 ;
3544
3545add_operand
3546@init{
3547 int numAO = 0;
3548}
3549 : signed_operand
3550 ( t=add_op mult_operand
3551 { numAO++; MFPA.add_operand__add_op(t); }
3552 )*
3553 { MFPA.add_operand(numAO);}
3554 ;
3555
3556/*
3557 * R1006: level 2 expr
3558 * OFP: ( ( level_2_expr )? add_op )? add_operand
3559 * check notes on how to remove this left recursion
3560 * (WARNING something like the following)
3561 * : (add_op)? ( add_operand add_op )* add_operand
3562 *
3563 * moved leading optionals to add_operand
3564 */
3565level_2_expr
3566@init{
3567 int numCO = 0;
3568}
3569 : add_operand
3570 ( concat_op add_operand
3571 { numCO++;}
3572 )*
3573 { MFPA.level_2_expr(numCO); }
3574 ;
3575
3576/*
3577 * R1007: power op **
3578 */
3579power_op returns [Token t]
3580 : POWER {t = $POWER;}
3581 ;
3582
3583/*
3584 * R1008: mult op * or /
3585 */
3586mult_op returns [Token t]
3587 : ASTERISK { t = $ASTERISK; }
3588 | SLASH { t = $SLASH; }
3589 ;
3590
3591/*
3592 * R1009: add op + or -
3593 */
3594add_op returns [Token t]
3595 : PLUS {t = $PLUS;}
3596 | MINUS {t = $MINUS;}
3597 ;
3598
3599/*
3600 * R1010: level 3 expr
3601 * OFP: moved leading optional to level_2_expr
3602 */
3603level_3_expr
3604@init{Token t = null;}
3605 : level_2_expr
3606 (rel_op level_2_expr {t = $rel_op.t;})?
3607 { MFPA.level_3_expr(t);}
3608 ;
3609
3610/*
3611 * R1011: concat op //
3612 */
3613concat_op returns [Token t]
3614 : SLASH_SLASH {t = $SLASH_SLASH;}
3615 ;
3616
3617/*
3618 * R1012: level 4 expr
3619 * OFP: moved leading optional to level_3_expr
3620 * inlined level_3_expr for level_4_expr in rule 1014
3621 */
3622
3623/*
3624 * R1013: rel op .EQ. (==) or .NE.(/=) or .LT. (<) or .LE. (<=) or .GT. (>) or .GE. (>=)
3625 */
3626rel_op returns [Token t]
3627 : EQ {t=$EQ;}
3628 | NE {t=$NE;}
3629 | LT {t=$LT;}
3630 | LE {t=$LE;}
3631 | GT {t=$GT;}
3632 | GE {t=$GE;}
3633 | EQ_EQ {t=$EQ_EQ;}
3634 | SLASH_EQ {t=$SLASH_EQ;}
3635 | LESSTHAN {t=$LESSTHAN;}
3636 | LESSTHAN_EQ {t=$LESSTHAN_EQ;}
3637 | GREATERTHAN {t=$GREATERTHAN;}
3638 | GREATERTHAN_EQ {t=$GREATERTHAN_EQ;}
3639 ;
3640
3641/*
3642 * R1014: and operand
3643 * OFP: level_4_expr inlined as level_3_expr
3644 */
3645and_operand
3646@init {
3647 int numAO = 0;
3648}
3649 : ( t0=not_op )? level_3_expr
3650 ( and_op ( t1=not_op )? level_3_expr
3651 { MFPA.and_operand__not_op(t1);
3652 numAO++;
3653 t1=null;
3654 }
3655 )*
3656 { MFPA.and_operand(t0, numAO);}
3657 ;
3658
3659/*
3660 * R1015: or operand
3661 * OFP: moved leading optional to or_operand
3662 */
3663or_operand
3664@init{
3665 int numOO = 0;
3666}
3667 : and_operand (or_op and_operand {numOO++;})*
3668 { MFPA.or_operand(numOO); }
3669 ;
3670
3671/*
3672 * R1016: equiv operand
3673 * OFP: moved leading optional to or_operand
3674 */
3675equiv_operand
3676@init{
3677 int numEO = 0;
3678}
3679 : or_operand
3680 ( equiv_op or_operand
3681 { MFPA.equiv_operand__equiv_op($equiv_op.t);
3682 numEO++;
3683 }
3684 )*
3685 { MFPA.equiv_operand(numEO); }
3686 ;
3687
3688/*
3689 * R1017: level 5 expr
3690 * OFP: moved leading optional to equiv_operand
3691 */
3692level_5_expr
3693@init{
3694 int numDBO = 0;
3695}
3696 : equiv_operand
3697 ( defined_binary_op equiv_operand
3698 { MFPA.level_5_expr__defined_binary_op($defined_binary_op.t);
3699 numDBO++;
3700 }
3701 )*
3702 { MFPA.level_5_expr(numDBO); }
3703 ;
3704
3705/*
3706 * R1018: not op .NOT.
3707 */
3708not_op returns [Token t]
3709 : NOT {t = $NOT;}
3710 ;
3711
3712/*
3713 * R1019: and op .AND.
3714 */
3715and_op returns [Token t]
3716 : AND {t = $AND;}
3717 ;
3718
3719/*
3720 * R1020: or op .OR.
3721 */
3722or_op returns [Token t]
3723 : OR {t = $OR;}
3724 ;
3725
3726/*
3727 * R1021: equiv op .EQV. or .NEQV.
3728 */
3729equiv_op returns [Token t]
3730 : EQV {t = $EQV;}
3731 | NEQV {t = $NEQV;}
3732 ;
3733
3734/*
3735 * R1022: expr
3736 * OFP: moved leading optional to level_5_expr
3737 */
3738expr
3739 : level_5_expr {MFPA.expr();}
3740 ;
3741
3742/*
3743 * R1023: defined binary op . letter+ .
3744 */
3745defined_binary_op returns [Token t]
3746 : DEFINED_OP {t = $DEFINED_OP;}
3747 ;
3748
3749/*
3750 * R1024: logical expr
3751 * R1025: default char expr
3752 * R1026: int expr
3753 * R1027: numeric expr
3754 * R1028: specification expr
3755 * R1029: constant expr
3756 * R1030: default char constant expr
3757 * R1031: int constant expr
3758 * OFP: inlined as expr
3759 */
3760
3761/*
3762 * R1032: assignment stmt
3763 */
3764assignment_stmt
3765@init{
3766}
3767@after{
3768 checkForInclude();
3769}
3770 : (lbl=label)?
3771 M_ASSIGNMENT_STMT variable EQUALS expr
3772 end_of_stmt
3773 { MFPA.assignment_stmt(lbl, $end_of_stmt.t);}
3774 ;
3775
3776/*
3777 * R1033: pointer assignment stmt
3778 * OFP: ensure that part_ref in data_ref doesn't capture the LPAREN
3779 * data_pointer_object and proc_pointer_object replaced by designator
3780 * data_target and proc_target replaced by expr
3781 * third alt covered by first alt so proc_pointer_object assignment deleted
3782 * designator (rule 901), minus the substring part is data_ref, so designator
3783 * replaced by data_ref.
3784 *
3785 * TODO: alt1 and alt3 require the backtracking.
3786 * if find a way to disambiguate them,
3787 * should be able to remove backtracking.
3788 */
3789pointer_assignment_stmt
3790options{backtrack=true;}
3791@init{
3792}
3793@after{
3794 checkForInclude();
3795}
3796 : (lbl=label)?
3797 M_PTR_ASSIGNMENT_STMT data_ref EQ_GT expr
3798 end_of_stmt
3799 { MFPA.pointer_assignment_stmt(lbl,
3800 $end_of_stmt.t, MFPUtils.PAS_NONE);}
3801 | (lbl=label)?
3802 M_PTR_ASSIGNMENT_STMT data_ref
3803 LPAREN bounds_spec_list RPAREN EQ_GT expr
3804 end_of_stmt
3805 { MFPA.pointer_assignment_stmt(lbl,
3806 $end_of_stmt.t, MFPUtils.PAS_BOUND_SPEC);}
3807 | (lbl=label)?
3808 M_PTR_ASSIGNMENT_STMT data_ref
3809 LPAREN bounds_remapping_list RPAREN EQ_GT expr
3810 end_of_stmt
3811 { MFPA.pointer_assignment_stmt(lbl,
3812 $end_of_stmt.t, MFPUtils.PAS_BOUND_REMAP);}
3813 ;
3814
3815/*
3816 * R1034: data pointer object
3817 * OFP: ensure ( IDENT | designator ending in PERCENT IDENT)
3818 * IDENT inlined for variable_name and data_pointer_component_name
3819 * variable replaced by designator
3820 */
3821data_pointer_object
3822 : designator { MFPA.data_pointer_object(); }
3823 ;
3824
3825/*
3826 * R1035: bounds spec
3827 * OFP: lower_bound_expr replaced by expr
3828 */
3829bounds_spec
3830 : expr COLON { MFPA.bounds_spec(); }
3831 ;
3832
3833bounds_spec_list
3834@init{
3835 int numBS = 1;
3836}
3837@after{
3838 MFPA.bounds_spec_list(numBS);
3839}
3840 : bounds_spec
3841 ( COMMA bounds_spec {numBS++;} )*
3842 ;
3843
3844/*
3845 * R1036: bounds remapping
3846 * OFP: lower_bound_expr replaced by expr
3847 * upper_bound_expr replaced by expr
3848 */
3849bounds_remapping
3850 : expr COLON expr
3851 { MFPA.bounds_remapping(); }
3852 ;
3853
3854bounds_remapping_list
3855@init{
3856 int numBR = 1;
3857}
3858@after{
3859 MFPA.bounds_remapping_list(numBR);
3860}
3861 : bounds_remapping
3862 ( COMMA bounds_remapping {numBR++;} )*
3863 ;
3864
3865/*
3866 * R1037: data target
3867 * OFP: inlined as expr in rule 758 and 1033
3868 * expr can be designator (via primary) so variable deleted
3869 */
3870
3871/*
3872 * R1038: proc pointer object
3873 * OFP: ensure ( IDENT | ends in PERCENT IDENT )
3874 * IDENT inlined for proc_pointer_name
3875 * proc_component_ref replaced by designator PERCENT IDENT replaced
3876 * by designator
3877 */
3878proc_pointer_object
3879 : designator { MFPA.proc_pointer_object(); }
3880 ;
3881
3882/*
3883 * R1039: proc component ref
3884 * OFP: inlined as designator PERCENT IDENT in
3885 * rule 1038, 1040, 1522, an 1524
3886 * IDENT inlined for procedure_component_name
3887 * designator inlined for variable
3888 */
3889
3890/*
3891 * R1040: proc target
3892 * OFP: inlined as expr in R459 and R735
3893 * ensure ( expr | designator ending in PERCENT IDENT)
3894 * IDENT inlined for procedure_name
3895 * IDENT isa expr so IDENT deleted
3896 * proc_component_ref is variable PERCENT IDENT
3897 * can be designator so deleted
3898 */
3899
3900/*
3901 * R1041: where stmt
3902 * OFP: mask_expr replaced by expr
3903 * assignment_stmt inlined for where_assignment_stmt
3904 */
3905where_stmt
3906@init{
3907}
3908@after{
3909 checkForInclude();
3910}
3911 : (lbl=label)?
3912 M_WHERE_STMT WHERE LPAREN expr RPAREN
3913 assignment_stmt
3914 { MFPA.where_stmt(lbl, $WHERE); }
3915 ;
3916
3917/*
3918 * R1042: where construct
3919 */
3920where_construct
3921@init{
3922 int numC = 0;
3923 int numMC = 0;
3924 int numEwC = 0;
3925 boolean hasMEw = false;
3926 boolean hasEw = false;
3927}
3928 : where_construct_stmt
3929 ( where_body_construct {numC++;} )*
3930 ( masked_elsewhere_stmt ( where_body_construct { numMC++;} )*
3931 { hasMEw = true;
3932 MFPA.masked_elsewhere_stmt__end(numMC);
3933 }
3934 )*
3935 ( elsewhere_stmt ( where_body_construct {numEwC++;} )*
3936 { hasEw = true;
3937 MFPA.elsewhere_stmt__end(numEwC);
3938 }
3939 )?
3940 end_where_stmt
3941 { MFPA.where_construct(numC, hasMEw, hasEw);}
3942 ;
3943
3944/*
3945 * R1043: where construct stmt
3946 * OFP: mask_expr replaced by expr
3947 */
3948where_construct_stmt
3949@init{
3950 Token id = null;
3951}
3952@after{
3953 checkForInclude();
3954}
3955 : ( IDENT COLON {id=$IDENT;})?
3956 M_WHERE_CONSTRUCT_STMT WHERE LPAREN expr RPAREN
3957 end_of_stmt
3958 { MFPA.where_construct_stmt(id, $WHERE, $end_of_stmt.t);}
3959 ;
3960
3961/*
3962 * R1044: where body construct
3963 * OFP: assignment_stmt inlined for where_assignment_stmt
3964 */
3965where_body_construct
3966@after{
3967 MFPA.where_body_construct();
3968}
3969 : assignment_stmt
3970 | where_stmt
3971 | where_construct
3972 ;
3973
3974/*
3975 * R1045: where assignment stmt
3976 * OFP: inlined as assignment_stmt in rule 1041 and 1044
3977 */
3978
3979/*
3980 * R1046: mask expr
3981 * OFP: inlined mask_expr was logical_expr
3982 * inlined scalar_mask_expr was scalar_logical_expr
3983 * inlined scalar_logical_expr was logical_expr
3984 * CIVL: finally replaced as expr.
3985 */
3986
3987/*
3988 * R1047: masked elsewhere stmt
3989 * OFP: mask_expr replaced by expr
3990 */
3991masked_elsewhere_stmt
3992@init{
3993 Token id = null;
3994}
3995@after{
3996 checkForInclude();
3997}
3998 : (lbl=label)?
3999 ELSE WHERE LPAREN expr RPAREN ( IDENT {id=$IDENT;})?
4000 end_of_stmt
4001 { MFPA.masked_elsewhere_stmt(lbl,
4002 $ELSE, $WHERE, id, $end_of_stmt.t);}
4003 | (lbl=label)?
4004 ELSEWHERE LPAREN expr RPAREN ( IDENT {id=$IDENT;})?
4005 end_of_stmt
4006 { MFPA.masked_elsewhere_stmt(lbl,
4007 $ELSEWHERE, null, id, $end_of_stmt.t);}
4008 ;
4009
4010/*
4011 * R1048: elsewhere stmt
4012 */
4013elsewhere_stmt
4014@init{
4015 Token id = null;
4016}
4017@after{
4018 checkForInclude();
4019}
4020 : (lbl=label)?
4021 ELSE WHERE (IDENT {id=$IDENT;})?
4022 end_of_stmt
4023 { MFPA.elsewhere_stmt(lbl,
4024 $ELSE, $WHERE, id, $end_of_stmt.t);}
4025 | (lbl=label)?
4026 ELSEWHERE (IDENT {id=$IDENT;})?
4027 end_of_stmt
4028 { MFPA.elsewhere_stmt(lbl,
4029 $ELSEWHERE, null, id, $end_of_stmt.t);}
4030 ;
4031
4032/*
4033 * R1049: end where stmt
4034 */
4035end_where_stmt
4036@init{
4037 Token id=null;
4038}
4039@after{
4040 checkForInclude();
4041}
4042 : (lbl=label)?
4043 END WHERE ( IDENT {id=$IDENT;} )?
4044 end_of_stmt
4045 { MFPA.end_where_stmt(lbl,
4046 $END, $WHERE, id, $end_of_stmt.t);}
4047 ;
4048
4049/*
4050 * R1050: forall construct
4051 */
4052forall_construct
4053@after{
4054 MFPA.forall_construct();
4055}
4056 : forall_construct_stmt
4057 ( forall_body_construct )*
4058 end_forall_stmt
4059 ;
4060
4061/*
4062 * R1051: forall construct stmt
4063 * OFP: forall-construct-name inlined as IDENT
4064 */
4065forall_construct_stmt
4066@init{
4067 Token id = null;
4068}
4069@after{
4070 checkForInclude();
4071}
4072 : (lbl=label)?
4073 ( IDENT COLON {id=$IDENT;})?
4074 M_FORALL_CONSTRUCT_STMT FORALL concurrent_header
4075 end_of_stmt
4076 { MFPA.forall_construct_stmt(lbl,
4077 id, $FORALL, $end_of_stmt.t);}
4078 ;
4079
4080/*
4081 * R1052: forall body construct
4082 */
4083forall_body_construct
4084@after {
4085 MFPA.forall_body_construct();
4086}
4087 : forall_assignment_stmt
4088 | where_stmt
4089 | where_construct
4090 | forall_construct
4091 | forall_stmt
4092 ;
4093
4094/*
4095 * R1053: forall assignment stmt
4096 */
4097forall_assignment_stmt
4098@after{
4099 checkForInclude();
4100}
4101 : assignment_stmt
4102 { MFPA.forall_assignment_stmt(false); }
4103 | pointer_assignment_stmt
4104 { MFPA.forall_assignment_stmt(true); }
4105 ;
4106
4107/*
4108 * R1054: end forall stmt
4109 */
4110end_forall_stmt
4111@init{
4112 Token id=null;
4113}
4114@after{
4115 checkForInclude();
4116}
4117 : (lbl=label)?
4118 END FORALL ( IDENT {id=$IDENT;})?
4119 end_of_stmt
4120 { MFPA.end_forall_stmt(lbl,
4121 $END, $FORALL, id, $end_of_stmt.t);}
4122 ;
4123
4124/*
4125 * R1055: forall stmt
4126 * OFP: M_FORALL_STMT token is inserted by scanner
4127 * to remove need for backtracking
4128 */
4129forall_stmt
4130@init{
4131}
4132@after{
4133 checkForInclude();
4134}
4135 : (lbl=label)?
4136 M_FORALL_STMT FORALL concurrent_header forall_assignment_stmt
4137 { MFPA.forall_stmt(lbl, $FORALL);}
4138 ;
4139
4140/*
4141 * R1101: block
4142 */
4143block
4144@init{
4145 int numExec = 0;
4146}
4147@after {
4148 MFPA.block(numExec);
4149}
4150 : ( execution_part_construct {numExec++;})*
4151 ;
4152
4153/*
4154 * R1102: associate construct
4155 */
4156associate_construct
4157 : associate_stmt
4158 block
4159 end_associate_stmt
4160 { MFPA.associate_construct(); }
4161 ;
4162
4163/*
4164 * R1103: associate stmt
4165 */
4166associate_stmt
4167@init {
4168 Token id=null;
4169}
4170@after{
4171 checkForInclude();
4172}
4173 : (lbl=label)?
4174 ( IDENT COLON {id=$IDENT;})?
4175 ASSOCIATE LPAREN association_list RPAREN
4176 end_of_stmt
4177 { MFPA.associate_stmt(lbl,
4178 id, $ASSOCIATE, $end_of_stmt.t);}
4179 ;
4180
4181/*
4182 * R1104: association
4183 * OFP: IDENT inlined for associate_name
4184 */
4185association
4186 : IDENT EQ_GT selector
4187 { MFPA.association($IDENT); }
4188 ;
4189
4190association_list
4191@init{
4192 int numA = 1;
4193}
4194@after{
4195 MFPA.association_list(numA);
4196}
4197 : association
4198 ( COMMA association {numA++;} )*
4199 ;
4200
4201/*
4202 * R1105: selector
4203 * OFP: expr can be designator (via primary) so variable deleted
4204 */
4205selector
4206 : expr { MFPA.selector(); }
4207 ;
4208
4209/*
4210 * R1106: end associate stmt
4211 */
4212end_associate_stmt
4213@init{
4214 Token id=null;
4215}
4216@after{
4217 checkForInclude();
4218}
4219 : (lbl=label)?
4220 END ASSOCIATE (IDENT {id=$IDENT;})?
4221 end_of_stmt
4222 { MFPA.end_associate_stmt(lbl,
4223 $END, $ASSOCIATE, id, $end_of_stmt.t);}
4224 ;
4225
4226/*
4227 * R1107: block construct
4228 * OFP: C1107 A block-specification-part shall not contain a
4229 * COMMON, EQUIVALENCE, INTENT, NAMELIST, OPTIONAL,
4230 * statement function, or VALUE statement.
4231 * (implicit-part in specification-part can be removed)
4232 */
4233block_construct
4234@after{
4235 MFPA.block_construct();
4236}
4237 : block_stmt
4238 specification_part_and_block
4239 end_block_stmt
4240 ;
4241
4242/*
4243 * R1108: block stmt
4244 */
4245block_stmt
4246@init{
4247 Token name = null;
4248}
4249@after{
4250 checkForInclude();
4251}
4252 : (lbl=label)?
4253 ( IDENT COLON {name=$IDENT;})? BLOCK
4254 end_of_stmt
4255 { MFPA.block_stmt(lbl,
4256 name, $BLOCK, $end_of_stmt.t);}
4257 ;
4258
4259/*
4260 * R1109: block specification part
4261 */
4262specification_part_and_block
4263@init{
4264 int numUS = 0;
4265 int numIS = 0;
4266 gctr0 = 0;
4267}
4268 : ( use_stmt {numUS++;} )*
4269 ( import_stmt {numIS++;} )*
4270 declaration_construct_and_block
4271 { MFPA.specification_part_and_block(
4272 numUS, numIS, gctr0);}
4273 ;
4274
4275declaration_construct_and_block
4276@init{
4277 gctr0++;
4278}
4279 : ((label)? ENTRY) =>
4280 entry_stmt declaration_construct_and_block
4281 | ((label)? ENUM) =>
4282 enum_def declaration_construct_and_block
4283 | ((label)? FORMAT) =>
4284 format_stmt declaration_construct_and_block
4285 | ((label)? INTERFACE) =>
4286 interface_block declaration_construct_and_block
4287 | ((label)? PARAMETER) =>
4288 parameter_stmt declaration_construct_and_block
4289 | ((label)? PROCEDURE) =>
4290 procedure_declaration_stmt declaration_construct_and_block
4291 | (derived_type_stmt) =>
4292 derived_type_def declaration_construct_and_block
4293 | (type_declaration_stmt) =>
4294 type_declaration_stmt declaration_construct_and_block
4295 | ((label)? access_spec) =>
4296 access_stmt declaration_construct_and_block
4297 | ((label)? ALLOCATABLE) =>
4298 allocatable_stmt declaration_construct_and_block
4299 | ((label)? ASYNCHRONOUS) =>
4300 asynchronous_stmt declaration_construct_and_block
4301 | ((label)? BIND) =>
4302 bind_stmt declaration_construct_and_block
4303 | ((label)? CODIMENSION) =>
4304 codimension_stmt declaration_construct_and_block
4305 | ((label)? DATA) =>
4306 data_stmt declaration_construct_and_block
4307 | ((label)? DIMENSION) =>
4308 dimension_stmt declaration_construct_and_block
4309 | ((label)? EXTERNAL) =>
4310 external_stmt declaration_construct_and_block
4311 | ((label)? INTRINSIC) =>
4312 intrinsic_stmt declaration_construct_and_block
4313 | ((label)? POINTER) =>
4314 pointer_stmt declaration_construct_and_block
4315 | ((label)? PROTECTED) =>
4316 protected_stmt declaration_construct_and_block
4317 | ((label)? SAVE) =>
4318 save_stmt declaration_construct_and_block
4319 | ((label)? TARGET) =>
4320 target_stmt declaration_construct_and_block
4321 | ((label)? VOLATILE) =>
4322 volatile_stmt declaration_construct_and_block
4323 | block {gctr0--;} /* decrement extra count as this isn't a declConstruct */
4324 ;
4325
4326/*
4327 * R1110: end block stmt
4328 */
4329end_block_stmt
4330@init{
4331 Token name = null;
4332}
4333@after{
4334 checkForInclude();
4335}
4336 : (lbl=label)?
4337 END BLOCK (IDENT {name=$IDENT;})?
4338 end_of_stmt
4339 { MFPA.end_block_stmt(lbl,
4340 name, $END, $BLOCK, $end_of_stmt.t);}
4341 ;
4342
4343/*
4344 * R1111: change team construct
4345 */
4346change_team_construct
4347@after{
4348 MFPA.change_team_construct();
4349}
4350 : change_team_stmt block end_change_team_stmt
4351 ;
4352
4353/*
4354 * R1112: change team stmt
4355 */
4356change_team_stmt
4357@init{
4358 Token name = null;
4359 boolean hasCAL = false;
4360 boolean hasSSL = false;
4361}
4362@after{
4363 checkForInclude();
4364}
4365 : (lbl=label)?
4366 ( IDENT COLON {name=$IDENT;})? CHANGE TEAM
4367 LPAREN expr (COMMA coarray_association_list {hasCAL = true;})?
4368 ( COMMA sync_stat_list {hasSSL = true;} )? RPAREN
4369 { MFPA.change_team_stmt(lbl,
4370 name, $CHANGE, $TEAM, hasCAL, hasSSL);}
4371 ;
4372
4373/*
4374 * R1113: coarray association
4375 */
4376coarray_association
4377 : codimension_decl EQ_GT expr
4378 { MFPA.coarray_association(); }
4379 ;
4380
4381coarray_association_list
4382@init{
4383 int numCA = 1;
4384}
4385@after{
4386 MFPA.coarray_association_list(numCA);
4387}
4388 : coarray_association
4389 ( COMMA coarray_association {numCA++;} )*
4390 ;
4391
4392/*
4393 * R1114: end change team stmt
4394 */
4395end_change_team_stmt
4396@init{
4397 Token name = null;
4398 boolean hasSSL = false;
4399}
4400 : (lbl=label)?
4401 END TEAM
4402 ( LPAREN (sync_stat_list {hasSSL = true;})? RPAREN)?
4403 ( IDENT {name=$IDENT;})?
4404 { MFPA.end_change_team_stmt(lbl,
4405 $END, $TEAM, name, hasSSL);}
4406 ;
4407
4408/*
4409 * R1115: team value
4410 * CIVL: inlined in rule 1112 as expr
4411 */
4412
4413/*
4414 * R1116: critical construct
4415 */
4416critical_construct
4417 : critical_stmt block end_critical_stmt
4418 { MFPA.critical_construct();}
4419 ;
4420
4421/*
4422 * R1117: critical stmt
4423 */
4424critical_stmt
4425@init{
4426 Token name = null;
4427}
4428@after{
4429 checkForInclude();
4430}
4431 : (lbl=label)?
4432 (IDENT COLON {name=$IDENT;})? CRITICAL
4433 end_of_stmt
4434 { MFPA.critical_stmt(lbl,
4435 name, $CRITICAL, $end_of_stmt.t);}
4436 ;
4437
4438/*
4439 * R1118: end critical stmt
4440 */
4441end_critical_stmt
4442@init{
4443 Token name = null;
4444}
4445@after{
4446 checkForInclude();
4447}
4448 : (lbl=label)?
4449 END CRITICAL (IDENT {name=$IDENT;})?
4450 end_of_stmt
4451 { MFPA.end_critical_stmt(lbl,
4452 name, $END, $CRITICAL, $end_of_stmt.t);}
4453 ;
4454
4455/*
4456 * R1119: do construct
4457 * OFP: deleted second alternative, nonblock_do_construct, to reduce backtracking,
4458 * see comments for 'F08 rule 835 nonblock_do_construct' on how termination
4459 * of nested loops must be handled.
4460 * CIVL: F2008 rule 835 is deleted in F2018
4461 */
4462do_construct
4463 : do_stmt
4464 block
4465 end_do
4466 { MFPA.do_construct(); }
4467 ;
4468
4469/*
4470 * R1120: do stmt
4471 * R1121: label do stmt
4472 * R1122: nonlabel do stmt
4473 * OFP: label_do_stmt and nonlabel_do_stmt inlined
4474 */
4475do_stmt
4476@init {
4477 Token id=null;
4478 Token doLbl =null;
4479 boolean hasLC = false;
4480}
4481@after{
4482 checkForInclude();
4483}
4484 : (lbl=label)?
4485 ( IDENT COLON {id=$IDENT;})? DO
4486 ( DIGIT_STR {doLbl=$DIGIT_STR;})?
4487 ( loop_control {hasLC=true;})?
4488 end_of_stmt
4489 { MFPA.do_stmt(lbl,
4490 id, $DO, doLbl, $end_of_stmt.t, hasLC);}
4491 ;
4492
4493/*
4494 * R1123: loop control
4495 * R1124: do variable
4496 * OFP: scalar_int_expr replaced by expr
4497 * scalar_logical_expr replaced by expr
4498 * CIVL: do_variable replaced as IDENT
4499 */
4500loop_control
4501@init{
4502 boolean hasOE = false;
4503}
4504 : ( COMMA )? IDENT EQUALS expr COMMA expr
4505 ( COMMA expr {hasOE=true;})?
4506 { MFPA.loop_control($IDENT, hasOE);}
4507 | ( COMMA )? WHILE LPAREN expr RPAREN
4508 { MFPA.loop_control($WHILE, hasOE);}
4509 | ( COMMA )? CONCURRENT concurrent_header
4510 { MFPA.loop_control($CONCURRENT, hasOE);}
4511 ;
4512
4513/*
4514 * R1125: concurrent header
4515 * CIVL: integer_type_spec (705) replaced by intrinsic_type_spec
4516 * scalar_mask_expr replaced as expr
4517 */
4518concurrent_header
4519@init{
4520 boolean hasITS = false;
4521 boolean hasME = false;
4522}
4523 : LPAREN
4524 (intrinsic_type_spec COLON_COLON {hasITS = true;})?
4525 concurrent_control_list
4526 ( COMMA expr {hasME = true;})?
4527 RPAREN
4528 { MFPA.concurrent_header(hasITS, hasME); }
4529 ;
4530
4531/*
4532 * R1126: concurrent control
4533 * OFP: IDENT inlined for index_name
4534 * expr inlined for concurrent_limit and concurrent_step
4535 *
4536 */
4537concurrent_control
4538@init{
4539 boolean hasStrd = false;
4540}
4541 : IDENT EQUALS expr COLON expr
4542 ( COLON expr {hasStrd=true;})?
4543 { MFPA.concurrent_control($IDENT, hasStrd);}
4544 ;
4545
4546concurrent_control_list
4547@init{
4548 int numCC = 1;
4549}
4550@after{
4551 MFPA.concurrent_control_list(numCC);
4552}
4553 : concurrent_control
4554 ( COMMA concurrent_control {numCC++;} )*
4555 ;
4556
4557/*
4558 * R1127: concurrent limit
4559 * R1128: concurrent step
4560 * CIVL: is scalar_int_expr replaced as expr.
4561 */
4562
4563/*
4564 * R1129: concurrent locality
4565 */
4566concurrent_locality
4567@init{
4568 int numCL = 0;
4569}
4570@after{
4571 MFPA.concurrent_locality(numCL);
4572}
4573 : (locality_spec {numCL++;}) *
4574 ;
4575
4576/*
4577 * R1130: locality spec
4578 */
4579locality_spec
4580 : LOCAL LPAREN generic_name_list RPAREN
4581 { MFPA.locality_spec($LOCAL, null); }
4582 | LOCAL_INT LPAREN generic_name_list RPAREN
4583 { MFPA.locality_spec($LOCAL_INT, null); }
4584 | SHARED LPAREN generic_name_list RPAREN
4585 { MFPA.locality_spec($SHARED, null); }
4586 | DEFAULT LPAREN NONE RPAREN
4587 { MFPA.locality_spec($DEFAULT, $NONE); }
4588 ;
4589
4590/*
4591 * R1131: end do
4592 * OFP: TODO continue-stmt is ambiguous with same in action statement,
4593 * check there for label and if label matches do-stmt label,
4594 * then match end-do
4595 * do_term_action_stmt added to allow block_do_construct to cover
4596 * nonblock_do_construct as well.
4597 */
4598end_do
4599@after{
4600 MFPA.end_do();
4601}
4602 : end_do_stmt
4603 | do_term_action_stmt
4604 ;
4605
4606/* OFP: try requiring an action_stmt and then we can simply insert
4607 * the new M_LBL_DO_TERMINAL during the Sale's prepass.
4608 * EOS is in action_stmt.
4609 * added the END DO and ENDDO options to this rule
4610 * because of the token M_LBL_DO_TERMINAL that is inserted
4611 * if they end a labeled DO.
4612 *
4613 */
4614do_term_action_stmt
4615@init{
4616 Token id=null;
4617 Token endToken = null;
4618 Token doToken = null;
4619}
4620@after{
4621 checkForInclude();
4622}
4623 : (lbl=label)? M_LBL_DO_TERMINAL
4624 ( action_stmt
4625 | ( END DO {endToken=$END; doToken=$DO;}
4626 (IDENT {id=$IDENT;})?
4627 )
4628 end_of_stmt
4629 )
4630 { MFPA.do_term_action_stmt(lbl, id,
4631 endToken, doToken, $end_of_stmt.t);}
4632 ;
4633
4634/*
4635 * R1132: end do stmt
4636 * OFP: IDENT inlined for do_construct_name
4637 */
4638end_do_stmt
4639@init{
4640 Token id=null;
4641}
4642@after{
4643 checkForInclude();
4644}
4645 : (lbl=label)?
4646 END DO ( IDENT {id=$IDENT;} )?
4647 end_of_stmt
4648 { MFPA.end_do_stmt(lbl, id,
4649 $END, $DO, $end_of_stmt.t);}
4650 ;
4651
4652/*
4653 * R1133: cycle stmt
4654 * OFP: IDENT inlined for do_construct_name
4655 */
4656cycle_stmt
4657@init{
4658 Token id = null;
4659}
4660@after{
4661 checkForInclude();
4662}
4663 : (lbl=label)?
4664 CYCLE (IDENT {id=$IDENT;})?
4665 end_of_stmt
4666 { MFPA.cycle_stmt(lbl,
4667 $CYCLE, id, $end_of_stmt.t); }
4668 ;
4669
4670/*
4671 * R1134: if construct
4672 */
4673if_construct
4674@init{
4675 int numB = 1;
4676}
4677@after{
4678 MFPA.if_construct(numB);
4679}
4680 : if_then_stmt block
4681 ( else_if_stmt block {numB++;} )*
4682 ( else_stmt block {numB++;} )?
4683 end_if_stmt
4684 ;
4685
4686/*
4687 * R1135: if then stmt
4688 * OFP: scalar_logical_expr replaced by expr
4689 */
4690if_then_stmt
4691@after{
4692 checkForInclude();
4693}
4694 : (lbl=label)?
4695 ( id=IDENT COLON )?
4696 IF LPAREN expr RPAREN THEN
4697 end_of_stmt
4698 { MFPA.if_then_stmt(lbl, id,
4699 $IF, $THEN, $end_of_stmt.t);}
4700 ;
4701
4702/*
4703 * R1136: else if stmt
4704 * OFP: scalar_logical_expr replaced by expr
4705 */
4706else_if_stmt
4707@after{
4708 checkForInclude();
4709}
4710 : (lbl=label)?
4711 ELSE IF LPAREN expr RPAREN THEN
4712 ( id=IDENT )?
4713 end_of_stmt
4714 { MFPA.else_if_stmt(lbl, id,
4715 $ELSE, $IF, $THEN, $end_of_stmt.t);}
4716 | (lbl=label)?
4717 ELSEIF LPAREN expr RPAREN THEN
4718 ( id=IDENT )?
4719 end_of_stmt
4720 { MFPA.else_if_stmt(lbl, id,
4721 $ELSEIF, null, $THEN, $end_of_stmt.t);}
4722 ;
4723
4724/*
4725 * R1137: else stmt
4726 */
4727else_stmt
4728@after{
4729 checkForInclude();
4730}
4731 : (lbl=label)?
4732 ELSE ( id=IDENT )?
4733 end_of_stmt
4734 { MFPA.else_stmt(lbl, id,
4735 $ELSE, $end_of_stmt.t); }
4736 ;
4737
4738/*
4739 * R1138: end if stmt
4740 */
4741end_if_stmt
4742@after{
4743 checkForInclude();
4744}
4745 : (lbl=label)?
4746 END IF ( id=IDENT )?
4747 end_of_stmt
4748 { MFPA.end_if_stmt(lbl, id, $END, $IF, $end_of_stmt.t);}
4749 ;
4750
4751/*
4752 * R1139: if stmt
4753 * OFP: scalar_logical_expr replaced by expr
4754 * M_IF_STMT inserted by scanner to remove need for backtracking
4755 */
4756if_stmt
4757@init{
4758}
4759@after{
4760 checkForInclude();
4761}
4762 : (lbl=label)?
4763 M_IF_STMT IF LPAREN expr RPAREN
4764 action_stmt
4765 { MFPA.if_stmt(lbl, $IF); }
4766 ;
4767
4768/*
4769 * R1140: case construct
4770 */
4771case_construct
4772@after {
4773 MFPA.case_construct();
4774}
4775 : select_case_stmt ( case_stmt block )* end_select_stmt
4776 ;
4777
4778/*
4779 * R1141: select case stmt
4780 * OFP: case_expr replaced by expr
4781 */
4782select_case_stmt
4783@init{
4784 Token id = null;
4785 Token t0 = null;
4786 Token t1 = null;
4787}
4788@after{
4789 checkForInclude();
4790}
4791 : (lbl=label)?
4792 ( IDENT COLON {id=$IDENT;})?
4793 ( SELECT CASE {t0=$SELECT; t1=$CASE;}
4794 | SELECTCASE {t0=$SELECTCASE; t1=null;}
4795 ) LPAREN expr RPAREN
4796 end_of_stmt
4797 { MFPA.select_case_stmt(lbl,
4798 id, t0, t1, $end_of_stmt.t);}
4799 ;
4800
4801/*
4802 * R1142: case stmt
4803 */
4804case_stmt
4805@init{
4806 Token id=null;
4807}
4808@after{
4809 checkForInclude();
4810}
4811 : (lbl=label)?
4812 CASE case_selector ( IDENT {id=$IDENT;})?
4813 end_of_stmt
4814 { MFPA.case_stmt(lbl,
4815 $CASE, id, $end_of_stmt.t);}
4816 ;
4817
4818/*
4819 * R1143: end select stmt
4820 */
4821end_select_stmt
4822@init{
4823 Token id=null;
4824}
4825@after{
4826 checkForInclude();
4827}
4828 : (lbl=label)?
4829 END SELECT (IDENT {id=$IDENT;})?
4830 end_of_stmt
4831 { MFPA.end_select_stmt(lbl,
4832 $END, $SELECT, id, $end_of_stmt.t);}
4833 ;
4834
4835/*
4836 * R1144: case expr
4837 * OFP: inlined case_expr as expr
4838 */
4839
4840/*
4841 * R1145: case selector
4842 */
4843case_selector
4844 : LPAREN case_value_range_list RPAREN
4845 { MFPA.case_selector(null); }
4846 | DEFAULT
4847 { MFPA.case_selector($DEFAULT); }
4848 ;
4849
4850/*
4851 * R1146: case value range
4852 */
4853case_value_range
4854@after{
4855 MFPA.case_value_range();
4856}
4857 : COLON case_value
4858 | case_value case_value_range_suffix
4859 ;
4860
4861case_value_range_suffix
4862@after{
4863 MFPA.case_value_range_suffix();
4864}
4865 : COLON ( case_value )?
4866 | { /* empty */ }
4867 ;
4868
4869case_value_range_list
4870@init{
4871 int numCVR = 1;
4872}
4873@after{
4874 MFPA.case_value_range_list(numCVR);
4875}
4876 : case_value_range {numCVR++;}
4877 ( COMMA case_value_range {numCVR++;} )*
4878 ;
4879
4880/*
4881 * R1147: case value
4882 * CIVL: constant-expr replaced as expr
4883 */
4884case_value
4885 : expr { MFPA.case_value(); }
4886 ;
4887
4888/*
4889 * R1148: select rank construct
4890 */
4891select_rank_construct
4892 : select_rank_stmt
4893 (select_rank_case_stmt block)*
4894 end_select_rank_stmt
4895 { MFPA.select_rank_construct(); }
4896 ;
4897
4898/*
4899 * R1149: select rank stmt
4900 */
4901select_rank_stmt
4902@after{
4903 checkForInclude();
4904}
4905 : (lbl=label)?
4906 (sname=IDENT COLON)?
4907 SELECT RANK LPAREN
4908 (aname=IDENT EQ_GT)? selector RPAREN
4909 end_of_stmt
4910 { MFPA.select_rank_stmt(lbl,
4911 sname, $SELECT, $RANK, aname, $end_of_stmt.t); }
4912 | (lbl=label)?
4913 (sname=IDENT COLON)?
4914 SELECTRANK LPAREN
4915 (aname=IDENT EQ_GT)? selector RPAREN
4916 end_of_stmt
4917 { MFPA.select_rank_stmt(lbl,
4918 sname, $SELECTRANK, null, aname, $end_of_stmt.t); }
4919 ;
4920
4921/*
4922 * R1150: select rank case stmt
4923 */
4924select_rank_case_stmt
4925@init{
4926 Token id = null;
4927}
4928 : (lbl=label)?
4929 RANK LPAREN expr RPAREN ( IDENT {id=$IDENT;} )?
4930 { MFPA.select_rank_case_stmt(lbl, $RANK, null, id); }
4931 | (lbl=label)?
4932 RANK LPAREN ASTERISK RPAREN ( IDENT {id=$IDENT;})?
4933 { MFPA.select_rank_case_stmt(lbl, $RANK, $ASTERISK, id); }
4934 | (lbl=label)?
4935 RANK DEFAULT ( IDENT {id=$IDENT;})?
4936 { MFPA.select_rank_case_stmt(lbl, $RANK, $DEFAULT, id); }
4937 ;
4938
4939/*
4940 * R1151: end select rank stmt
4941 */
4942end_select_rank_stmt
4943@init{
4944 Token id=null;
4945}
4946@after{
4947 checkForInclude();
4948}
4949 : (lbl=label)?
4950 END SELECT ( IDENT {id=$IDENT;} )?
4951 end_of_stmt
4952 { MFPA.end_select_rank_stmt(lbl,
4953 $END, $SELECT, id, $end_of_stmt.t);}
4954 ;
4955
4956/*
4957 * R1152: select type construct
4958 */
4959select_type_construct
4960 : select_type_stmt ( type_guard_stmt block )*
4961 end_select_type_stmt
4962 { MFPA.select_type_construct(); }
4963 ;
4964
4965/*
4966 * R1153: select type stmt
4967 * OFP: IDENT inlined for select_construct_name and associate_name
4968 */
4969select_type_stmt
4970@after{checkForInclude();}
4971 : (lbl=label)?
4972 (sname=IDENT COLON)?
4973 SELECT TYPE LPAREN
4974 (aname=IDENT EQ_GT)? selector RPAREN
4975 end_of_stmt
4976 { MFPA.select_type_stmt(lbl,
4977 sname, $SELECT, $TYPE, aname, $end_of_stmt.t);}
4978 | (lbl=label)?
4979 (sname=IDENT COLON)?
4980 SELECTTYPE LPAREN
4981 (aname=IDENT EQ_GT)? selector RPAREN
4982 end_of_stmt
4983 { MFPA.select_type_stmt(lbl,
4984 sname, $SELECTTYPE, null, aname, $end_of_stmt.t);}
4985 ;
4986
4987/*
4988 * R1154: type guard stmt
4989 * OFP: IDENT inlined for select_construct_name
4990 *
4991 */
4992type_guard_stmt
4993@init{
4994 Token sname = null;
4995}
4996@after{
4997 checkForInclude();
4998}
4999 : (lbl=label)?
5000 TYPE IS LPAREN type_spec RPAREN
5001 ( IDENT {sname=$IDENT;} )?
5002 end_of_stmt
5003 { MFPA.type_guard_stmt(lbl,
5004 $TYPE, $IS, sname, $end_of_stmt.t);}
5005 | (lbl=label)?
5006 CLASS IS LPAREN type_spec RPAREN
5007 ( IDENT {sname=$IDENT;} )?
5008 end_of_stmt
5009 { MFPA.type_guard_stmt(lbl,
5010 $CLASS, $IS, sname, $end_of_stmt.t);}
5011 | (lbl=label)?
5012 CLASS DEFAULT
5013 ( IDENT {sname=$IDENT;} )?
5014 end_of_stmt
5015 { MFPA.type_guard_stmt(lbl,
5016 $CLASS, $DEFAULT, sname, $end_of_stmt.t);}
5017 ;
5018
5019/*
5020 * R1155: end select type stmt
5021 * OFP: IDENT inlined for select_construct_name
5022 */
5023end_select_type_stmt
5024@init{
5025 Token id = null;
5026}
5027@after{
5028 checkForInclude();
5029}
5030 : (lbl=label)?
5031 END SELECT ( IDENT {id=$IDENT;})?
5032 end_of_stmt
5033 { MFPA.end_select_type_stmt(lbl,
5034 $END, $SELECT, id, $end_of_stmt.t);}
5035 ;
5036
5037/*
5038 * R1156: exit stmt
5039 * OFP: IDENT inlined for do_construct_name
5040 */
5041exit_stmt
5042@init{
5043 Token id = null;
5044}
5045@after{
5046 checkForInclude();
5047}
5048 : (lbl=label)?
5049 EXIT (IDENT {id=$IDENT;})?
5050 end_of_stmt
5051 { MFPA.exit_stmt(lbl,
5052 $EXIT, id, $end_of_stmt.t); }
5053 ;
5054
5055/*
5056 * R1157: goto stmt
5057 */
5058goto_stmt
5059@init{
5060 Token toLbl=null;
5061}
5062@after{
5063 checkForInclude();
5064}
5065 : (lbl=label)?
5066 GO TO DIGIT_STR
5067 end_of_stmt
5068 { MFPA.goto_stmt(lbl,
5069 $GO, $TO, $DIGIT_STR, $end_of_stmt.t); }
5070 | (lbl=label)?
5071 GOTO DIGIT_STR
5072 end_of_stmt
5073 { MFPA.goto_stmt(lbl,
5074 $GOTO, null, $DIGIT_STR, $end_of_stmt.t); }
5075 ;
5076
5077/*
5078 * R1158: computed goto stmt
5079 */
5080computed_goto_stmt
5081@after{
5082 checkForInclude();
5083}
5084 : (lbl=label)?
5085 GO TO LPAREN label_list RPAREN ( COMMA )? expr
5086 end_of_stmt
5087 { MFPA.computed_goto_stmt(lbl,
5088 $GO, $TO, $end_of_stmt.t); }
5089 | (lbl=label)?
5090 GOTO LPAREN label_list RPAREN ( COMMA )? expr
5091 end_of_stmt
5092 { MFPA.computed_goto_stmt(lbl,
5093 $GOTO, null, $end_of_stmt.t); }
5094 ;
5095
5096/*
5097 * R1159: continue stmt
5098 */
5099continue_stmt
5100@after{
5101 checkForInclude();
5102}
5103 : (lbl=label)?
5104 CONTINUE
5105 end_of_stmt
5106 { MFPA.continue_stmt(lbl,
5107 $CONTINUE, $end_of_stmt.t); }
5108 ;
5109
5110/*
5111 * R1160: stop stmt
5112 * CIVL: scalar-logical-expr replaced by expr
5113 * rule 1162 stop code inlined as expr with type integer/char
5114 */
5115stop_stmt
5116@init{
5117 boolean hasSC = false;
5118}
5119@after{
5120 checkForInclude();
5121}
5122 : (lbl=label)?
5123 STOP (stop_code {hasSC=true;})?
5124 (COMMA quiet=QUIET EQUALS expr)?
5125 end_of_stmt
5126 { MFPA.stop_stmt(lbl,
5127 $STOP, quiet, $end_of_stmt.t, hasSC); }
5128 ;
5129
5130/*
5131 * R1161: error stop stmt
5132 * CIVL: scalar-logical-expr replaced by expr
5133 * rule 1162 stop code inlined as expr with type integer/char
5134 */
5135error_stop_stmt
5136@init{
5137 boolean hasSC = false;
5138}
5139@after{
5140 checkForInclude();
5141}
5142 : (lbl=label)?
5143 ERROR STOP (stop_code {hasSC=true;})?
5144 (COMMA quiet=QUIET EQUALS expr)?
5145 end_of_stmt
5146 { MFPA.error_stop_stmt(lbl,
5147 $ERROR, $STOP, quiet, $end_of_stmt.t, hasSC); }
5148 | (lbl=label)?
5149 ERRORSTOP (expr {hasSC=true;})?
5150 (COMMA quiet=QUIET EQUALS expr)?
5151 end_of_stmt
5152 { MFPA.error_stop_stmt(lbl,
5153 $ERRORSTOP, null, quiet, $end_of_stmt.t, hasSC); }
5154 ;
5155
5156/*
5157 * R1162: stop code
5158 * OFP: DIGIT_STR must be 5 digits or less
5159 * CIVL: scalar_char_constant replaced as char_constant
5160 */
5161stop_code
5162 : char_constant
5163 { MFPA.stop_code(null); }
5164 | DIGIT_STR
5165 { MFPA.stop_code($DIGIT_STR); }
5166 ;
5167
5168/*
5169 * R1163: fail image stmt
5170 */
5171/*
5172fail_image_stmt
5173 : (lbl=label)?
5174 FAIL IMAGE
5175 { MFPA.fail_image_stmt(lbl, $FAIL, $IMAGE); }
5176 | (lbl=label)?
5177 FAILIMAGE
5178 { MFPA.fail_image_stmt(lbl, $FAILIMAGE, null); }
5179 ;
5180*/
5181
5182/*
5183 * R1164: sync all stmt
5184 */
5185sync_all_stmt
5186@init{
5187 boolean hasSSL = false;
5188}
5189@after{
5190 checkForInclude();
5191}
5192 : (lbl=label)?
5193 SYNC ALL (LPAREN RPAREN)?
5194 end_of_stmt
5195 { MFPA.sync_all_stmt(lbl,
5196 $SYNC, $ALL, $end_of_stmt.t, hasSSL); }
5197 | (lbl=label)?
5198 SYNC ALL LPAREN sync_stat_list RPAREN
5199 end_of_stmt
5200 { MFPA.sync_all_stmt(lbl,
5201 $SYNC, $ALL, $end_of_stmt.t, true); }
5202 ;
5203
5204/*
5205 * R1165: sync stat
5206 * OFP: expr is a stat-variable or an errmsg-variable
5207 * {'STAT','ERRMSG'} exprs are variables
5208 */
5209sync_stat
5210 : IDENT EQUALS expr
5211 { MFPA.sync_stat($IDENT); }
5212 ;
5213
5214sync_stat_list
5215@init{
5216 int numSS = 1;
5217}
5218@after{
5219 MFPA.sync_stat_list(numSS);
5220}
5221 : sync_stat
5222 ( COMMA sync_stat {numSS++;} )*
5223 ;
5224
5225/*
5226 * R1166: sync images stmt
5227 */
5228sync_images_stmt
5229@init{
5230 boolean hasSSL = false;
5231}
5232@after{
5233 checkForInclude();
5234}
5235 : (lbl=label)?
5236 SYNC IMAGES LPAREN image_set
5237 (COMMA sync_stat_list {hasSSL=true;})? RPAREN
5238 end_of_stmt
5239 { MFPA.sync_images_stmt(lbl,
5240 $SYNC, $IMAGES, $end_of_stmt.t, hasSSL); }
5241 ;
5242
5243/*
5244 * R1167: image set
5245 */
5246image_set
5247 : expr {MFPA.image_set(null); }
5248 | ASTERISK { MFPA.image_set($ASTERISK); }
5249 ;
5250
5251/*
5252 * R1168: sync memory stmt
5253 */
5254sync_memory_stmt
5255@init{
5256 boolean hasSSL = false;
5257}
5258@after{
5259 checkForInclude();
5260}
5261 : (lbl=label)?
5262 SYNC MEMORY (LPAREN RPAREN)?
5263 end_of_stmt
5264 { MFPA.sync_memory_stmt(lbl,
5265 $SYNC, $MEMORY, $end_of_stmt.t, hasSSL); }
5266 | (lbl=label)?
5267 SYNC MEMORY LPAREN sync_stat_list RPAREN
5268 end_of_stmt
5269 { MFPA.sync_memory_stmt(lbl,
5270 $SYNC, $MEMORY, $end_of_stmt.t, true); }
5271 ;
5272
5273/*
5274 * R1169: sync team stmt
5275 */
5276/*
5277sync_team_stmt
5278@init{
5279 boolean hasSSL = false;
5280}
5281@after{
5282 checkForInclude();
5283}
5284 : (lbl=label)?
5285 SYNC TEAM LPAREN variable
5286 (COMMA sync_stat_list {hasSSL = true;} )? RPAREN
5287 end_of_stmt
5288 { MFPA.sync_team_stmt(lbl,
5289 $SYNC, $TEAM, hasSSL, $end_of_stmt.t); }
5290 | (lbl=label)?
5291 SYNCTEAM LPAREN variable
5292 (COMMA sync_stat_list {hasSSL = true;} )? RPAREN
5293 end_of_stmt
5294 { MFPA.sync_team_stmt(lbl,
5295 $SYNCTEAM, null, hasSSL, $end_of_stmt.t); }
5296 ;
5297*/
5298
5299/*
5300 * R1170: event post stmt
5301 */
5302/*
5303event_post_stmt
5304@init{
5305 boolean hasSSL = false;
5306}
5307@after{
5308 checkForInclude();
5309}
5310 : (lbl=label)?
5311 EVENT POST LPAREN variable
5312 (COMMA sync_stat_list {hasSSL = true;} )? RPAREN
5313 end_of_stmt
5314 { MFPA.event_post_stmt(lbl,
5315 $EVENT, $POST, hasSSL, $end_of_stmt.t); }
5316 | (lbl=label)?
5317 EVENTPOST LPAREN variable
5318 (COMMA sync_stat_list {hasSSL = true;} )? RPAREN
5319 end_of_stmt
5320 { MFPA.event_post_stmt(lbl,
5321 $EVENTPOST, null, hasSSL, $end_of_stmt.t); }
5322 ;
5323*/
5324
5325/*
5326 * R1171: event variable
5327 * CIVL: inlined as variable
5328 */
5329
5330/*
5331 * R1172: event wait stmt
5332 */
5333/*
5334event_wait_stmt
5335@init{
5336 boolean hasEWSL = false;
5337}
5338@after{
5339 checkForInclude();
5340}
5341 : (lbl=label)?
5342 EVENT WAIT LPAREN variable
5343 (COMMA event_wait_spec_list {hasEWSL = true;} )? RPAREN
5344 end_of_stmt
5345 { MFPA.event_wait_stmt(lbl,
5346 $EVENT, $WAIT, hasEWSL, $end_of_stmt.t); }
5347 | (lbl=label)?
5348 EVENTWAIT LPAREN variable
5349 (COMMA event_wait_spec_list {hasEWSL = true;} )? RPAREN
5350 end_of_stmt
5351 { MFPA.event_wait_stmt(lbl,
5352 $EVENTWAIT, null, hasEWSL, $end_of_stmt.t); }
5353 ;
5354*/
5355
5356/*
5357 * R1173: event wait spec
5358 */
5359/*
5360event_wait_spec
5361 : until_spec
5362 { MFPA.event_wait_spec(
5363 MFPUtils.EWS.UNTIL); }
5364 | sync_stat
5365 { MFPA.event_wait_spec(
5366 MFPUtils.EWS.SYNC); }
5367 ;
5368
5369event_wait_spec_list
5370@init{
5371 int numEWS = 1;
5372}
5373@after{
5374 MFPA.event_wait_spec_list(numEWS);
5375}
5376 : event_wait_spec
5377 ( COMMA event_wait_spec {numEWS++;} )*
5378 ;
5379*/
5380
5381/*
5382 * R1174: until spec
5383 * CIVL: scalar_int_expr replaced as expr
5384 */
5385/*
5386until_spec
5387 : UNTIL_COUNT EQUALS expr
5388 { MFPA.until_spec($UNTIL_COUNT); }
5389 ;
5390
5391*/
5392
5393/*
5394 * R1175: form team stmt
5395 */
5396/*
5397form_team_stmt
5398@init{
5399 boolean hasTFSL = false;
5400}
5401@after{
5402 checkForInclude();
5403}
5404 : (lbl=label)?
5405 FORM TEAM LPAREN expr COMMA variable
5406 (COMMA form_team_spec_list {hasTFSL = true;} )? RPAREN
5407 end_of_stmt
5408 { MFPA.form_team_stmt(lbl,
5409 $FORM, $TEAM, hasTFSL, $end_of_stmt.t); }
5410 | (lbl=label)?
5411 FORMTEAM LPAREN expr COMMA variable
5412 (COMMA form_team_spec_list {hasTFSL = true;} )? RPAREN
5413 end_of_stmt
5414 { MFPA.form_team_stmt(lbl,
5415 $FORMTEAM, null, hasTFSL, $end_of_stmt.t); }
5416 ;
5417*/
5418
5419/*
5420 * R1176: team number
5421 * CIVL: inlined as expr
5422 */
5423
5424/*
5425 * R1177: team variable
5426 * CIVL: inlined as variable
5427 */
5428
5429/*
5430 * R1178: form team spec
5431 * CIVL: scalar_int_expr inlined as expr
5432 */
5433/*
5434form_team_spec
5435 : NEW_INDEX EQUALS expr
5436 { MFPA.form_team_spec($NEW_INDEX); }
5437 | sync_stat
5438 { MFPA.form_team_spec(null); }
5439 ;
5440
5441form_team_spec_list
5442@init{
5443 int numFTS = 1;
5444}
5445@after{
5446 MFPA.form_team_spec_list(numFTS);
5447}
5448 : form_team_spec
5449 ( COMMA form_team_spec {numFTS++;} )*
5450 ;
5451*/
5452
5453/*
5454 * R1179: lock stmt
5455 * OFP: lock_variable replaced by expr
5456 */
5457/*
5458lock_stmt
5459@init{
5460 boolean hasLSL = false;
5461}
5462@after{
5463 checkForInclude();
5464}
5465 : (lbl=label)?
5466 LOCK LPAREN expr
5467 (COMMA lock_stat_list {hasLSL=true;})? RPAREN
5468 end_of_stmt
5469 { MFPA.lock_stmt(lbl,
5470 $LOCK, $end_of_stmt.t, hasLSL); }
5471 ;
5472*/
5473
5474/*
5475 * R1180: lock stat
5476 * OFP: expr is a scalar-logical-variable
5477 */
5478/*
5479lock_stat
5480 : ACQUIRED_LOCK EQUALS expr
5481 { MFPA.lock_stat($ACQUIRED_LOCK); }
5482 | sync_stat
5483 { MFPA.lock_stat(null); }
5484 ;
5485
5486lock_stat_list
5487@init{
5488 int numLS =0;
5489}
5490@after{
5491 MFPA.lock_stat_list(numLS);
5492}
5493 : lock_stat
5494 ( COMMA lock_stat {numLS++;} )*
5495 ;
5496*/
5497
5498/*
5499 * R1181: unlcok stmt
5500 * R1182: lock variable
5501 * OFP: lock_variable replaced by expr
5502 */
5503/*
5504unlock_stmt
5505@init{
5506 boolean hasSSL = false;
5507}
5508@after{
5509 checkForInclude();
5510}
5511 : (lbl=label)?
5512 UNLOCK LPAREN expr
5513 (COMMA sync_stat_list {hasSSL=true;})? RPAREN
5514 end_of_stmt
5515 { MFPA.unlock_stmt(lbl,
5516 $UNLOCK, $end_of_stmt.t, hasSSL);}
5517 ;
5518*/
5519
5520/*
5521 * R1201: io unit
5522 * OFP: file_unit_number replaced by expr
5523 * internal_file_variable is expr so deleted
5524 */
5525io_unit
5526@after {
5527 MFPA.io_unit(asterisk);
5528}
5529 : expr
5530 | asterisk=ASTERISK
5531 ;
5532
5533/*
5534 * R1202: file until number
5535 * OFP: scalar_int_expr replaced by expr
5536 */
5537file_unit_number
5538@after{
5539 MFPA.file_unit_number();
5540}
5541 : expr
5542 ;
5543
5544/*
5545 * R1203: internal file variable
5546 * OFP: is char_variable inlined (and then deleted in rule 1201)
5547 */
5548
5549/*
5550 * R1204: open stmt
5551 */
5552open_stmt
5553@init{
5554}
5555@after{
5556 checkForInclude();
5557}
5558 : (lbl=label)?
5559 OPEN LPAREN connect_spec_list RPAREN
5560 end_of_stmt
5561 { MFPA.open_stmt(lbl,
5562 $OPEN, $end_of_stmt.t);}
5563 ;
5564
5565/*
5566 * R1205: connect spec
5567 * OFP: check expr type with identifier
5568 * {'UNIT','ACCESS','ACTION','ASYNCHRONOUS','BLANK',
5569 * 'DECIMAL', 'DELIM','ENCODING', 'FILE','FORM', 'PAD',
5570 * 'POSITION','RECL','ROUND','SIGN','STATUS' } are expr
5571 * {'IOMSG','IOSTAT'} are variables
5572 * {'ERR'} is DIGIT_STR
5573 */
5574connect_spec
5575 : expr
5576 { MFPA.connect_spec(null); }
5577 | IDENT EQUALS expr
5578 { MFPA.connect_spec($IDENT); }
5579 ;
5580
5581connect_spec_list
5582@init{
5583 int numCS = 1;
5584}
5585@after{
5586 MFPA.connect_spec_list(numCS);
5587}
5588 : connect_spec
5589 ( COMMA connect_spec {numCS++;} )*
5590 ;
5591
5592/*
5593 * R1206: file name expr
5594 * OFP: was scalar_default_char_expr inlined as expr
5595 */
5596
5597/*
5598 * R1207: iomsg variable
5599 * OFP: inlined as scalar_default_char_variable in
5600 * rule 1205, 1209, 1213, 1222, 1226, and 1228
5601 */
5602
5603/*
5604 * R1208: close stmt
5605 */
5606close_stmt
5607@init{
5608}
5609@after{
5610 checkForInclude();
5611}
5612 : (lbl=label)?
5613 CLOSE LPAREN close_spec_list RPAREN
5614 end_of_stmt
5615 { MFPA.close_stmt(lbl,
5616 $CLOSE, $end_of_stmt.t);}
5617 ;
5618
5619/*
5620 * R1209: close spec
5621 * OFP: IDENT is in {'UNIT','IOSTAT','IOMSG','ERR','STATUS'}
5622 * file_unit_number, scalar_int_variable, iomsg_variable,
5623 * and label replaced by expr
5624 */
5625close_spec
5626 : expr
5627 { MFPA.close_spec(null); }
5628 | IDENT EQUALS expr
5629 { MFPA.close_spec($IDENT); }
5630 ;
5631
5632close_spec_list
5633@init{
5634 int numCS = 1;
5635}
5636 : close_spec
5637 ( COMMA close_spec {numCS++;} )*
5638 { MFPA.close_spec_list(numCS); }
5639 ;
5640
5641/*
5642 * R1210: read stmt
5643 */
5644read_stmt
5645options{k=3;}
5646@init{
5647 boolean hasIIL = false;
5648}
5649@after{
5650 checkForInclude();
5651}
5652 : ((label)? READ LPAREN) =>
5653 (lbl=label)?
5654 READ LPAREN io_control_spec_list RPAREN
5655 ( input_item_list {hasIIL=true;})?
5656 end_of_stmt
5657 { MFPA.read_stmt(lbl,
5658 $READ, $end_of_stmt.t, hasIIL);}
5659 | ((label)? READ) =>
5660 (lbl=label)?
5661 READ format
5662 ( COMMA input_item_list {hasIIL=true;} )?
5663 end_of_stmt
5664 { MFPA.read_stmt(lbl,
5665 $READ, $end_of_stmt.t, hasIIL);}
5666 ;
5667
5668/*
5669 * R1211: write stmt
5670 */
5671write_stmt
5672@init{
5673 boolean hasOIL=false;
5674}
5675@after{
5676 checkForInclude();
5677}
5678 : (lbl=label)?
5679 WRITE LPAREN io_control_spec_list RPAREN
5680 ( output_item_list {hasOIL=true;} )?
5681 end_of_stmt
5682 { MFPA.write_stmt(lbl,
5683 $WRITE, $end_of_stmt.t, hasOIL); }
5684 ;
5685
5686/*
5687 * R1212: print stmt
5688 */
5689print_stmt
5690@init{
5691 boolean hasOIL =false;
5692}
5693@after{
5694 checkForInclude();
5695}
5696 : (lbl=label)?
5697 PRINT format
5698 ( COMMA output_item_list {hasOIL=true;})?
5699 end_of_stmt
5700 { MFPA.print_stmt(lbl,
5701 $PRINT, $end_of_stmt.t, hasOIL); }
5702 ;
5703
5704/*
5705 * R1213: io control spec
5706 * R1214: id variable
5707 * OFP: check expr type with identifier
5708 * io_unit and format are both (expr|'*') so combined
5709 * CIVL: id variable was scalar int variable combined in expr
5710 */
5711io_control_spec
5712 : expr
5713 { MFPA.io_control_spec(null, null);
5714 } /* Optional {'UNIT', 'FMT', 'NML'} */
5715 | ASTERISK
5716 { MFPA.io_control_spec(null, $ASTERISK);
5717 } /* Optional {'UNIT', 'FMT', 'NML'} */
5718 | IDENT EQUALS ASTERISK
5719 { MFPA.io_control_spec($IDENT, $ASTERISK);
5720 } /* {'UNIT','FMT'} */
5721 | IDENT EQUALS expr
5722 { MFPA.io_control_spec($IDENT, null);
5723 } /* {'UNIT', 'FMT', 'ADVANCE','ASYNCHRONOUS', */
5724 /* 'BLANK','DECIMAL','DELIM','PAD','POS', */
5725 /* 'REC','ROUND','SIGN'} are expr */
5726 /* {'ID','IOMSG',IOSTAT','SIZE'} are variables */
5727 /* {'END','EOR','ERR'} are labels */
5728 /* {'NML'} is IDENT} */
5729 ;
5730
5731io_control_spec_list
5732@init{
5733 int numICS = 1;
5734}
5735@after{
5736 MFPA.io_control_spec_list(numICS);
5737}
5738 : io_control_spec
5739 ( COMMA io_control_spec {numICS++;} )*
5740 ;
5741
5742/*
5743 * R1215: format
5744 * OFP: default_char_expr replaced by expr
5745 * label replaced by DIGIT_STR is expr so deleted
5746 */
5747format
5748@after {
5749 MFPA.format(asterisk);
5750}
5751 : expr
5752 | asterisk=ASTERISK
5753 ;
5754
5755/*
5756 * R1216: input item
5757 */
5758input_item
5759@after {
5760 MFPA.input_item();
5761}
5762 : variable
5763 | io_implied_do
5764 ;
5765
5766input_item_list
5767@init{
5768 int numII = 1;
5769}
5770@after{
5771 MFPA.input_item_list(numII);
5772}
5773 : input_item
5774 ( COMMA input_item {numII++;} )*
5775 ;
5776
5777/*
5778 * R1217: output item
5779 */
5780output_item
5781options{backtrack=true;}
5782@after{
5783 MFPA.output_item();
5784}
5785 : expr
5786 | io_implied_do
5787 ;
5788
5789output_item_list
5790@init{
5791 int numOI = 1;
5792}
5793@after{
5794 MFPA.output_item_list(numOI);
5795}
5796 : output_item
5797 ( COMMA output_item {numOI++;} )*
5798 ;
5799
5800/*
5801 * R1218: io implied do
5802 */
5803io_implied_do
5804 : LPAREN io_implied_do_object io_implied_do_suffix RPAREN
5805 { MFPA.io_implied_do(); }
5806 ;
5807
5808/*
5809 * R1219: io implied do object
5810 * OFP: expr in output_item can be variable in input_item so input_item deleted
5811 */
5812io_implied_do_object
5813 : output_item
5814 { MFPA.io_implied_do_object(); }
5815 ;
5816
5817io_implied_do_suffix
5818options{backtrack=true;}
5819 : COMMA io_implied_do_object io_implied_do_suffix
5820 | COMMA io_implied_do_control
5821 ;
5822
5823/*
5824 * R1220: io implied do control
5825 * OFP: scalar_int_expr replaced by expr
5826 */
5827io_implied_do_control
5828@init{
5829 boolean hasStrd=false;
5830}
5831 : IDENT EQUALS expr COMMA expr
5832 ( COMMA expr {hasStrd=true;})?
5833 { MFPA.io_implied_do_control($IDENT, hasStrd); }
5834 ;
5835
5836/*
5837 * R1221: dtv type spec
5838 * OFP: Not used
5839 */
5840dtv_type_spec
5841 : TYPE LPAREN derived_type_spec RPAREN
5842 { MFPA.dtv_type_spec($TYPE); }
5843 | CLASS LPAREN derived_type_spec RPAREN
5844 { MFPA.dtv_type_spec($CLASS); }
5845 ;
5846
5847/*
5848 * R1222: wait stmt
5849 */
5850wait_stmt
5851@init{
5852}
5853@after{
5854 checkForInclude();
5855}
5856 : (lbl=label)?
5857 WAIT LPAREN wait_spec_list RPAREN
5858 end_of_stmt
5859 { MFPA.wait_stmt(lbl,
5860 $WAIT, $end_of_stmt.t); }
5861 ;
5862
5863/*
5864 * R1223: wait spec
5865 * OFP: {'UNIT','END','EOR','ERR','ID','IOMSG','IOSTAT'}
5866 * file_unit_number, scalar_int_variable, iomsg_variable,
5867 * and label replaced by expr
5868 */
5869wait_spec
5870 : expr
5871 { MFPA.wait_spec(null); }
5872 | IDENT EQUALS expr
5873 { MFPA.wait_spec($IDENT); }
5874 ;
5875
5876wait_spec_list
5877@init{
5878 int numWS = 1;
5879}
5880@after{
5881 MFPA.wait_spec_list(numWS);
5882}
5883 : wait_spec
5884 ( COMMA wait_spec {numWS++;} )*
5885 ;
5886
5887/*
5888 * R1224: backspace stmt
5889 */
5890backspace_stmt
5891options {k=3;}
5892@init{
5893}
5894@after{
5895 checkForInclude();
5896}
5897 : ((label)? BACKSPACE LPAREN) =>
5898 (lbl=label)?
5899 BACKSPACE LPAREN position_spec_list RPAREN
5900 end_of_stmt
5901 { MFPA.backspace_stmt(lbl,
5902 $BACKSPACE, $end_of_stmt.t, true);}
5903 | ((label)? BACKSPACE) =>
5904 (lbl=label)?
5905 BACKSPACE file_unit_number
5906 end_of_stmt
5907 { MFPA.backspace_stmt(lbl,
5908 $BACKSPACE, $end_of_stmt.t, false);}
5909 ;
5910
5911/*
5912 * R1225: endfile stmt
5913 */
5914endfile_stmt
5915options{k=3;}
5916@init{
5917}
5918@after{
5919 checkForInclude();
5920}
5921 : ((label)? END FILE LPAREN) =>
5922 (lbl=label)?
5923 END FILE LPAREN position_spec_list RPAREN
5924 end_of_stmt
5925 { MFPA.endfile_stmt(lbl,
5926 $END, $FILE, $end_of_stmt.t, true);}
5927 | ((label)? END FILE) =>
5928 (lbl=label)?
5929 END FILE file_unit_number
5930 end_of_stmt
5931 { MFPA.endfile_stmt(lbl,
5932 $END, $FILE, $end_of_stmt.t, false);}
5933 ;
5934
5935/*
5936 * R1226: rewind stmt
5937 */
5938rewind_stmt
5939options{k=3;}
5940@init{
5941}
5942@after{
5943 checkForInclude();
5944}
5945 : ((label)? REWIND LPAREN) =>
5946 (lbl=label)?
5947 REWIND LPAREN position_spec_list RPAREN
5948 end_of_stmt
5949 { MFPA.rewind_stmt(lbl,
5950 $REWIND, $end_of_stmt.t, true);}
5951 | ((label)? REWIND) =>
5952 (lbl=label)?
5953 REWIND file_unit_number
5954 end_of_stmt
5955 { MFPA.rewind_stmt(lbl,
5956 $REWIND, $end_of_stmt.t, false);}
5957 ;
5958
5959/*
5960 * R1227: position spec
5961 * OFP: {'UNIT','IOSTAT','IOMSG','ERR'}
5962 * file_unit_number, scalar_int_variable, iomsg_variable,
5963 * label replaced by expr
5964 */
5965position_spec
5966 : expr
5967 { MFPA.position_spec(null); }
5968 | IDENT EQUALS expr
5969 { MFPA.position_spec($IDENT); }
5970 ;
5971
5972position_spec_list
5973@init{
5974 int numPS = 1;
5975}
5976@after{
5977 MFPA.position_spec_list(numPS);
5978}
5979 : position_spec
5980 ( COMMA position_spec {numPS++;} )*
5981 ;
5982
5983/*
5984 * R1228: flush stmt
5985 */
5986flush_stmt
5987options {k=3;}
5988@after{
5989 checkForInclude();
5990}
5991 : ((label)? FLUSH LPAREN) =>
5992 (lbl=label)?
5993 FLUSH LPAREN flush_spec_list RPAREN
5994 end_of_stmt
5995 { MFPA.flush_stmt(lbl,
5996 $FLUSH, $end_of_stmt.t, true); }
5997 | ((label)? FLUSH) =>
5998 (lbl=label)?
5999 FLUSH file_unit_number
6000 end_of_stmt
6001 { MFPA.flush_stmt(lbl,
6002 $FLUSH, $end_of_stmt.t, false);}
6003 ;
6004
6005/*
6006 * R1229: flush spec
6007 * OFP: {'UNIT','IOSTAT','IOMSG','ERR'}
6008 * file_unit_number, scalar_int_variable, iomsg_variable,
6009 * and label replaced by expr
6010 */
6011flush_spec
6012 : expr
6013 { MFPA.flush_spec(null); }
6014 | IDENT EQUALS expr
6015 { MFPA.flush_spec($IDENT); }
6016 ;
6017
6018flush_spec_list
6019@init{
6020 int numFS = 1;
6021}
6022@after{
6023 MFPA.flush_spec_list(numFS);
6024}
6025 : flush_spec
6026 ( COMMA flush_spec {numFS++;} )*
6027 ;
6028
6029/*
6030 * R1230: inquire stmt
6031 * CIVL: scalar_int_variable replaced as expr
6032 */
6033inquire_stmt
6034@init{
6035}
6036@after{
6037 checkForInclude();
6038}
6039 : (lbl=label)?
6040 INQUIRE LPAREN inquire_spec_list RPAREN
6041 end_of_stmt
6042 { MFPA.inquire_stmt(lbl,
6043 $INQUIRE, null, $end_of_stmt.t, false);}
6044 | (lbl=label)?
6045 M_INQUIRE_STMT_2 INQUIRE LPAREN
6046 IDENT /* 'IOLENGTH' */ EQUALS expr
6047 RPAREN output_item_list
6048 end_of_stmt
6049 { MFPA.inquire_stmt(lbl,
6050 $INQUIRE, $IDENT, $end_of_stmt.t, true);}
6051 ;
6052
6053/*
6054 * R1231: inquire spec
6055 * OFP: {'UNIT','FILE'} are expr
6056 * {'ACCESS', 'ACTION', 'ASYNCHRONOUS', 'BLANK', 'DECIMAL',
6057 * 'DELIM', 'DIRECT', 'ENCODING', 'ERR', 'EXIST', 'FORM',
6058 * 'FORMATTED', 'ID', 'IOMSG', 'IOSTAT', 'NAME', 'NAMED',
6059 * 'NEXTREC', 'NUMBER', 'OPENED', 'PAD', 'PENDING', 'POS',
6060 * 'POSITION', 'READ', 'READWRITE', 'RECL', 'ROUND',
6061 * 'SEQUENTIAL', 'SIGN', 'SIZE', 'STREAM', 'UNFORMATTED',
6062 * 'WRITE'} are variable
6063 * file_name_expr and file_unit_number replaced by expr
6064 * scalar_default_char_variable replaced by designator
6065 */
6066inquire_spec
6067 : expr
6068 { MFPA.inquire_spec(null); }
6069 | IDENT EQUALS expr
6070 { MFPA.inquire_spec($IDENT); }
6071 ;
6072
6073inquire_spec_list
6074@init{
6075 int numIS = 1;
6076}
6077@after{
6078 MFPA.inquire_spec_list(numIS);
6079}
6080 : inquire_spec
6081 ( COMMA inquire_spec {numIS++;} )*
6082 ;
6083
6084/*
6085 * R1301: format stmt
6086 * OFP: label is required. accept as optional for error report.
6087 */
6088format_stmt
6089@init{
6090}
6091@after{
6092 checkForInclude();
6093}
6094 : (lbl=label)?
6095 FORMAT format_specification
6096 end_of_stmt
6097 { MFPA.format_stmt(lbl,
6098 $FORMAT, $end_of_stmt.t); }
6099 ;
6100
6101/*
6102 * R1302: format specification
6103 */
6104format_specification
6105@init{
6106 boolean hasFIL=false;
6107 boolean hasUFI=false;
6108}
6109 : LPAREN ( format_item_list {hasFIL=true;})?
6110 (COMMA unlimited_format_item {hasUFI=true;})? RPAREN
6111 { MFPA.format_specification(hasFIL, hasUFI); }
6112 ;
6113
6114/*
6115 * R1303: format items
6116 * OFP: r replaced by int_literal_constant replaced by
6117 * char_literal_constant replaced by CHAR_CONST
6118 * char_string_edit_desc replaced by CHAR_CONST
6119 */
6120format_item
6121@init{
6122 Token descOrDigit=null;
6123 boolean hasFIL = false;
6124}
6125 : M_DATA_EDIT_DESC
6126 { MFPA.format_item($M_DATA_EDIT_DESC, hasFIL); }
6127 | M_CTRL_EDIT_DESC
6128 { MFPA.format_item($M_CTRL_EDIT_DESC, hasFIL);}
6129 | M_CSTR_EDIT_DESC
6130 { MFPA.format_item($M_CSTR_EDIT_DESC, hasFIL);}
6131 | (DIGIT_STR {descOrDigit=$DIGIT_STR;} )?
6132 LPAREN format_item_list RPAREN
6133 { MFPA.format_item(descOrDigit, hasFIL);}
6134 ;
6135
6136/* OFP: the comma is not always required. */
6137format_item_list
6138@init{
6139 int numFI = 1;
6140}
6141@after{
6142 MFPA.format_item_list(numFI);
6143}
6144 : format_item
6145 ( (COMMA)? format_item {numFI++;} )*
6146 ;
6147
6148/*
6149 * R1305: unlimited format item
6150 */
6151unlimited_format_item
6152 : ASTERISK LPAREN format_item_list RPAREN
6153 { MFPA.unlimited_format_item(); }
6154 ;
6155
6156/*
6157 * OFP: Rules below in the comment are combined into rule 1303
6158 * R1304: format item
6159 * format_item_list
6160 * char_string_edit_desc replaced by CHAR_CONST
6161 * R1306: r
6162 * inlined in rule 1301 and 1313 as int_literal_constant
6163 * (then as DIGIT_STRING)
6164 * R1307: data edit spec
6165 *
6166 * R1308: w
6167 * R1309: m
6168 * R1310: d
6169 * R1311: e
6170 * w,m,d,e replaced by int_literal_constant replaced by DIGIT_STR
6171 * R1312: v
6172 * inlined as signed_int_literal_constant in v_list replaced by (PLUS or MINUS) DIGIT_STR
6173 * R1313: control edit spec
6174 * inlined/combined in rule 1307 and data_plus_control_edit_desc
6175 * r replaced by int_literal_constant replaced by DIGIT_STR
6176 * k replaced by signed_int_literal_constant replaced by (PLUS|MINUS)? DIGIT_STR
6177 * position_edit_desc inlined
6178 * sign_edit_desc replaced by T_ID_OR_OTHER was {'SS','SP','S'}
6179 * blank_interp_edit_desc replaced by T_ID_OR_OTHER was {'BN','BZ'}
6180 * round_edit_desc replaced by T_ID_OR_OTHER was {'RU','RD','RZ','RN','RC','RP'}
6181 * decimal_edit_desc replaced by T_ID_OR_OTHER was {'DC','DP'}
6182 * leading T_ID_OR_OTHER alternates combined with data_edit_desc in data_plus_control_edit_desc
6183 * R1314: k
6184 * inlined in rule 1313 as signed_int_literal_constant
6185 * n in rule 1314 was replaced by int_literal_constant replaced by DIGIT_STR
6186 * C1009: k shall not have a kind parameter specified for it
6187 * R1315: position edit spec
6188 * inlined in rule 1313
6189 * R1316: n
6190 * inlined in rule 1315 as int_literal_constant (is DIGIT_STR, see C1311)
6191 * C1311: a kind parameter shall not be specified for k.
6192 * R1317: sign edit desc
6193 * inlined in rule 1313 as T_ID_OR_OTHER was {'SS','SP','S'}
6194 * R1318: blank interp edit desc
6195 * inlined in rule 1313 as T_ID_OR_OTHER was {'BN','BZ'}
6196 * R1319: round edit desc
6197 * inlined in rule 1313 as T_ID_OR_OTHER was {'RU','RD','RZ','RN','RC','RP'}
6198 * R1320: decimal edit desc
6199 * inlined in rule 1313 as T_ID_OR_OTHER was {'DC','DP'}
6200 * R1321: char string edit spec
6201 * was char_literal_constant inlined in rule 1313 as CHAR_CONST
6202 */
6203
6204/*
6205 * R1401: main program
6206 * OFP: A starting rule as the entry point.
6207 * 'program_stmt' (R1402) made to be non-optional,
6208 * then an empty program with a single 'end' will
6209 * not be ambiguous.
6210 */
6211main_program
6212@init{
6213 boolean hasEP = false;
6214 boolean hasISP = false;
6215}
6216@after{
6217 MFPA.main_program(hasEP, hasISP);
6218}
6219 : program_stmt
6220 specification_part
6221 ( execution_part {hasEP = true;} )?
6222 ( internal_subprogram_part {hasISP = true;} )?
6223 end_program_stmt
6224 ;
6225
6226/*
6227 * R1402: program stmt
6228 * OFP: IDENT inlined for program_name
6229 */
6230program_stmt
6231@init{
6232}
6233@after{
6234 checkForInclude();
6235}
6236 : (lbl=label)?
6237 PROGRAM IDENT
6238 end_of_stmt
6239 { MFPA.program_stmt(lbl,
6240 $PROGRAM, $IDENT, $end_of_stmt.t); }
6241 ;
6242
6243/*
6244 * R1403: end program stmt
6245 * OFP: IDENT inlined for program_name
6246 */
6247end_program_stmt
6248@init{
6249 Token id = null;
6250}
6251@after{
6252 checkForInclude();
6253}
6254 : (lbl=label)?
6255 END PROGRAM (IDENT {id=$IDENT;})?
6256 end_of_stmt
6257 { MFPA.end_program_stmt(lbl,
6258 $END, $PROGRAM, id, $end_of_stmt.t); }
6259 | (lbl=label)?
6260 END
6261 end_of_stmt
6262 { MFPA.end_program_stmt(lbl,
6263 $END, null, null, $end_of_stmt.t); }
6264 ;
6265
6266/*
6267 * R1404: module
6268 * C1403: A module specification-part shall not contain a
6269 * stmt-function-stmt, an entry-stmt or a format-stmt
6270 * OFP: specification_part made non-optional
6271 * to remove END ambiguity (as can be empty)
6272 */
6273module
6274@after {
6275 MFPA.module();
6276}
6277 : module_stmt
6278 specification_part
6279 ( module_subprogram_part )?
6280 end_module_stmt
6281 ;
6282
6283/*
6284 * R1405: module stmt
6285 */
6286module_stmt
6287@init{
6288 Token id = null;
6289}
6290@after{
6291 checkForInclude();
6292}
6293 : (lbl=label)?
6294 MODULE ( IDENT {id=$IDENT;} )?
6295 end_of_stmt
6296 { MFPA.module_stmt(lbl,
6297 $MODULE, id, $end_of_stmt.t);}
6298 ;
6299
6300/*
6301 * R1406: end module stmt
6302 */
6303end_module_stmt
6304@init{
6305 Token id = null;
6306}
6307@after{
6308 checkForInclude();
6309}
6310 : (lbl=label)?
6311 END MODULE (IDENT {id=$IDENT;})?
6312 end_of_stmt
6313 { MFPA.end_module_stmt(lbl,
6314 $END, $MODULE, id, $end_of_stmt.t);}
6315 | (lbl=label)? END
6316 end_of_stmt
6317 { MFPA.end_module_stmt(lbl,
6318 $END, null, id, $end_of_stmt.t);}
6319 ;
6320
6321/*
6322 * R1407: module subprogram part
6323 */
6324module_subprogram_part
6325@init{
6326 int numMS = 0;
6327}
6328@after{
6329 MFPA.module_subprogram_part(numMS);
6330}
6331 : contains_stmt
6332 ( module_subprogram {numMS++;} )*
6333 ;
6334
6335/*
6336 * R1408: module subprogram
6337 */
6338module_subprogram
6339options {backtrack=true;}
6340@init{
6341 boolean hasPref = false;
6342}
6343@after{
6344 MFPA.module_subprogram(hasPref);
6345}
6346 : (prefix {hasPref=true;})? function_subprogram
6347 | subroutine_subprogram
6348 | separate_module_subprogram
6349 ;
6350
6351/*
6352 * R1409: use stmt
6353 */
6354use_stmt
6355@init{
6356 boolean hasMN = false;
6357 boolean hasRL = false;
6358 boolean hasOL = false;
6359}
6360@after{
6361 checkForInclude();
6362}
6363 : (lbl=label)?
6364 USE ((COMMA module_nature {hasMN=true;})? COLON_COLON)?
6365 IDENT (COMMA rename_list {hasRL=true;})?
6366 end_of_stmt
6367 { MFPA.use_stmt(lbl,
6368 $USE, $IDENT, null, $end_of_stmt.t, hasMN, hasRL, hasOL);}
6369 | (lbl=label)?
6370 USE ((COMMA module_nature {hasMN=true;})? COLON_COLON)?
6371 IDENT COMMA ONLY COLON (only_list {hasOL=true;})?
6372 end_of_stmt
6373 { MFPA.use_stmt(lbl,
6374 $USE, $IDENT, $ONLY, $end_of_stmt.t, hasMN, hasRL, hasOL);}
6375 ;
6376
6377/*
6378 * R1410: module nature
6379 */
6380module_nature
6381 : INTRINSIC
6382 { MFPA.module_nature($INTRINSIC); }
6383 | NON_INTRINSIC
6384 { MFPA.module_nature($NON_INTRINSIC); }
6385 ;
6386
6387/*
6388 * R1411: rename
6389 * R1414: local defined operator
6390 * R1415: use defined operator
6391 * OFP: DEFINED_OP inlined for local_defined_operator
6392 * and use_defined_operator
6393 * IDENT inlined for local_name and use_name
6394 */
6395rename
6396 : id1=IDENT EQ_GT id2=IDENT
6397 { MFPA.rename(id1, id2, null, null, null, null); }
6398 | op1=OPERATOR LPAREN defOp1=DEFINED_OP RPAREN
6399 EQ_GT op2=OPERATOR LPAREN defOp2=DEFINED_OP RPAREN
6400 { MFPA.rename(null, null, op1, defOp1, op2, defOp2); }
6401 ;
6402
6403rename_list
6404@init{
6405 int numRn = 1;
6406}
6407@after{
6408 MFPA.rename_list(numRn);
6409}
6410 : rename
6411 ( COMMA rename {numRn++;} )*
6412 ;
6413
6414/*
6415 * R1412: only
6416 * R1413: only use stmt
6417 * OFP: IDENT inlined for only_use_name
6418 * generic_spec can be IDENT so IDENT deleted
6419 */
6420only
6421@init{
6422 boolean isRenamed = false;
6423}
6424@after {
6425 MFPA.only(isRenamed);
6426}
6427 : generic_spec
6428 | rename {isRenamed=true;}
6429 ;
6430
6431only_list
6432@init{
6433 int numO = 1;
6434}
6435@after{
6436 MFPA.only_list(numO);
6437}
6438 : only
6439 ( COMMA only {numO++;} )*
6440 ;
6441
6442/*
6443 * R1416: submodule
6444 * OFP: specification_part made non-optional
6445 * to remove END ambiguity (as can be empty)
6446 */
6447submodule
6448@init{
6449 boolean hasMSP = false;
6450}
6451@after{
6452 MFPA.submodule(hasMSP);
6453}
6454 : submodule_stmt
6455 specification_part
6456 ( module_subprogram_part {hasMSP=true;} )?
6457 end_submodule_stmt
6458 ;
6459
6460/*
6461 * R1417: submodule stmt
6462 * CIVL: name replaced as IDENT
6463 */
6464submodule_stmt
6465@init{
6466}
6467@after{
6468 checkForInclude();
6469}
6470 : (lbl=label)?
6471 SUBMODULE LPAREN parent_identifier RPAREN IDENT
6472 end_of_stmt
6473 { MFPA.submodule_stmt(lbl,
6474 $SUBMODULE, $IDENT, $end_of_stmt.t);}
6475 ;
6476
6477/*
6478 * R1418: parent identifier
6479 */
6480parent_identifier
6481 : ancestor=IDENT
6482 ( COLON parent=IDENT)?
6483 { MFPA.parent_identifier(ancestor, parent); }
6484 ;
6485
6486/*
6487 * R1419: end submodule stmt
6488 */
6489end_submodule_stmt
6490@after{
6491 checkForInclude();
6492}
6493 : (lbl=label)?
6494 END (smod=SUBMODULE (sname=IDENT)?)?
6495 end_of_stmt
6496 { MFPA.end_submodule_stmt(lbl,
6497 $END, smod, sname, $end_of_stmt.t);}
6498 ;
6499
6500/*
6501 * R1420: block data
6502 * OFP: specification_part made non-optional
6503 * to remove END ambiguity (as can be empty).
6504 */
6505block_data
6506@after {
6507 MFPA.block_data();
6508}
6509 : block_data_stmt
6510 specification_part
6511 end_block_data_stmt
6512 ;
6513
6514/*
6515 * R1421: block data stmt
6516 */
6517block_data_stmt
6518@init{
6519 Token id = null;
6520}
6521@after{
6522 checkForInclude();
6523}
6524 : (lbl=label)?
6525 BLOCK DATA (IDENT {id=$IDENT;})?
6526 end_of_stmt
6527 { MFPA.block_data_stmt(lbl,
6528 $BLOCK, $DATA, id, $end_of_stmt.t);}
6529 | (lbl=label)?
6530 BLOCKDATA (IDENT {id=$IDENT;})?
6531 end_of_stmt
6532 { MFPA.block_data_stmt(lbl,
6533 $BLOCKDATA, null, id, $end_of_stmt.t);}
6534 ;
6535
6536/*
6537 * R1422: end block data stmt
6538 */
6539end_block_data_stmt
6540@init{
6541 Token id = null;
6542}
6543@after{
6544 checkForInclude();
6545}
6546 : (lbl=label)?
6547 END BLOCK DATA (IDENT {id=$IDENT;})?
6548 end_of_stmt
6549 { MFPA.end_block_data_stmt(lbl,
6550 $END, $BLOCK, $DATA, id, $end_of_stmt.t);}
6551 | (lbl=label)?
6552 END BLOCKDATA (IDENT {id=$IDENT;})?
6553 end_of_stmt
6554 { MFPA.end_block_data_stmt(lbl,
6555 $END, $BLOCKDATA, null, id, $end_of_stmt.t);}
6556 | (lbl=label)?
6557 END end_of_stmt
6558 { MFPA.end_block_data_stmt(lbl,
6559 $END, null, null, id, $end_of_stmt.t);}
6560 ;
6561
6562/*
6563 * R1501: interface block
6564 */
6565interface_block
6566@after {
6567 MFPA.interface_block();
6568}
6569 : interface_stmt
6570 ( interface_specification )*
6571 end_interface_stmt
6572 ;
6573
6574/*
6575 * R1502: interface specification
6576 */
6577interface_specification
6578@after {
6579 MFPA.interface_specification();
6580}
6581 : interface_body
6582 | procedure_stmt
6583 ;
6584
6585/*
6586 * R1503: interface stmt
6587 * OFP: the last argument to the action specifies
6588 * whether this is an abstract interface or not.
6589 */
6590interface_stmt
6591@init{
6592 boolean hasGS = false;
6593}
6594@after{
6595 checkForInclude();
6596}
6597 : (lbl=label)?
6598 INTERFACE (generic_spec {hasGS=true;})?
6599 end_of_stmt
6600 { MFPA.interface_stmt(lbl,
6601 null, $INTERFACE, $end_of_stmt.t, hasGS);}
6602 | (lbl=label)?
6603 ABSTRACT INTERFACE
6604 end_of_stmt
6605 { MFPA.interface_stmt(lbl,
6606 $ABSTRACT, $INTERFACE, $end_of_stmt.t, hasGS);}
6607 ;
6608
6609/*
6610 * R1504: end interface stmt
6611 */
6612end_interface_stmt
6613@init{
6614 boolean hasGS = false;
6615}
6616@after{
6617 checkForInclude();
6618}
6619 : (lbl=label)?
6620 END INTERFACE ( generic_spec {hasGS=true;})?
6621 end_of_stmt
6622 { MFPA.end_interface_stmt(lbl,
6623 $END, $INTERFACE, $end_of_stmt.t, hasGS);}
6624 ;
6625
6626/*
6627 * R1505: interface body
6628 * OFP: the last argument to the action specifies
6629 * whether this is an abstract interface or not.
6630 * CIVL: 1st arg for isFunc
6631 */
6632interface_body
6633options {backtrack=true;}
6634@init{
6635 boolean hasPref = false;
6636}
6637 : (prefix {hasPref=true;})?
6638 function_stmt specification_part
6639 end_function_stmt
6640 { MFPA.interface_body(true, hasPref); }
6641 | subroutine_stmt specification_part
6642 end_subroutine_stmt
6643 { MFPA.interface_body(false, hasPref);}
6644 ;
6645
6646/*
6647 * R1506: procedure stmt
6648 * R1507: specific procedure
6649 * OFP: generic_name_list substituted for specific procedur list
6650 */
6651procedure_stmt
6652@init{
6653 Token mod = null;
6654}
6655@after{
6656 checkForInclude();
6657}
6658 : (lbl=label)?
6659 ( MODULE {mod=$MODULE;})?
6660 PROCEDURE generic_name_list
6661 end_of_stmt
6662 { MFPA.procedure_stmt(lbl,
6663 mod, $PROCEDURE, $end_of_stmt.t);}
6664 ;
6665
6666/*
6667 * R1508: generic spec
6668 * OFP: IDENT inlined for generic_name
6669 */
6670generic_spec
6671 : IDENT
6672 { MFPA.generic_spec(null, $IDENT,
6673 MFPUtils.GS_NAME);}
6674 | OPERATOR LPAREN defined_operator RPAREN
6675 { MFPA.generic_spec($OPERATOR, null,
6676 MFPUtils.GS_OPERATOR);}
6677 | ASSIGNMENT LPAREN EQUALS RPAREN
6678 { MFPA.generic_spec($ASSIGNMENT, $EQUALS,
6679 MFPUtils.GS_ASSIGNMENT);}
6680 | defined_io_generic_spec
6681 { MFPA.generic_spec(null, null,
6682 MFPUtils.GS_IO_SPEC); }
6683 ;
6684
6685/*
6686 * R1509: defined io generic spec
6687 */
6688defined_io_generic_spec
6689 : READ LPAREN FORMATTED RPAREN
6690 { MFPA.defined_io_generic_spec($READ, $FORMATTED,
6691 MFPUtils.DIGS.FMT_R);}
6692 | READ LPAREN UNFORMATTED RPAREN
6693 { MFPA.defined_io_generic_spec($READ, $UNFORMATTED,
6694 MFPUtils.DIGS.UFMT_R);}
6695 | WRITE LPAREN FORMATTED RPAREN
6696 { MFPA.defined_io_generic_spec($WRITE, $FORMATTED,
6697 MFPUtils.DIGS.FMT_W);}
6698 | WRITE LPAREN UNFORMATTED RPAREN
6699 { MFPA.defined_io_generic_spec($WRITE, $UNFORMATTED,
6700 MFPUtils.DIGS.UFMT_W);}
6701 ;
6702
6703/*
6704 * R1510: generic stmt
6705 * OFP: generic_name_list substituted for specific_procedure_list
6706 */
6707generic_stmt
6708@init{
6709 boolean hasAS = false;
6710}
6711 : GENERIC ( COMMA access_spec {hasAS=true;})?
6712 COLON_COLON generic_spec EQ_GT generic_name_list
6713 { MFPA.generic_stmt($GENERIC, hasAS);}
6714 ;
6715
6716/*
6717 * R1511: external stmt
6718 */
6719external_stmt
6720@init{
6721}
6722@after{
6723 checkForInclude();
6724}
6725 : (lbl=label)?
6726 EXTERNAL ( COLON_COLON )? generic_name_list
6727 end_of_stmt
6728 { MFPA.external_stmt(lbl,
6729 $EXTERNAL, $end_of_stmt.t);}
6730 ;
6731
6732/*
6733 * R1512: procedure declaration stmt
6734 */
6735procedure_declaration_stmt
6736@init{
6737 boolean hasPI = false;
6738 int numPD = 0;
6739}
6740@after{
6741 checkForInclude();
6742}
6743 : (lbl=label)?
6744 PROCEDURE LPAREN ( proc_interface {hasPI=true;})? RPAREN
6745 ( ( COMMA proc_attr_spec {numPD++;})* COLON_COLON )?
6746 proc_decl_list
6747 end_of_stmt
6748 { MFPA.procedure_declaration_stmt(lbl,
6749 $PROCEDURE, $end_of_stmt.t, hasPI, numPD);}
6750 ;
6751
6752/*
6753 * R1513: proc interface
6754 * OFP: IDENT inlined for interface_name
6755 */
6756proc_interface
6757 : IDENT { MFPA.proc_interface($IDENT); }
6758 | declaration_type_spec { MFPA.proc_interface(null); }
6759 ;
6760
6761/*
6762 * R1514: proc attr spec
6763 */
6764proc_attr_spec
6765 : access_spec
6766 { MFPA.proc_attr_spec(null,
6767 MFPUtils.ATTR_ACCESS); }
6768 | language_binding_spec
6769 { MFPA.proc_attr_spec(null,
6770 MFPUtils.ATTR_BIND_C); }
6771 | INTENT LPAREN intent_spec RPAREN
6772 { MFPA.proc_attr_spec($INTENT,
6773 MFPUtils.ATTR_INTENT); }
6774 | OPTIONAL
6775 { MFPA.proc_attr_spec($OPTIONAL,
6776 MFPUtils.ATTR_OPTIONAL); }
6777 | POINTER
6778 { MFPA.proc_attr_spec($POINTER,
6779 MFPUtils.ATTR_POINTER); }
6780 | PROTECTED
6781 { MFPA.proc_attr_spec($PROTECTED,
6782 MFPUtils.ATTR_PROTECTED); }
6783 | SAVE
6784 { MFPA.proc_attr_spec($SAVE,
6785 MFPUtils.ATTR_SAVE); }
6786/* features inherited from OFP */
6787 | proc_attr_spec_extension
6788 { MFPA.proc_attr_spec(null,
6789 MFPUtils.ATTR_OTHER); }
6790 ;
6791
6792proc_attr_spec_extension
6793 : NO_LANG_EXT
6794 ;
6795
6796/*
6797 * R1515: proc decl
6798 * OFP: IDENT inlined for procedure_entity_name
6799 */
6800proc_decl
6801@init{
6802 boolean hasPPI = false;
6803}
6804 : IDENT ( EQ_GT proc_pointer_init {hasPPI=true;} )?
6805 { MFPA.proc_decl($IDENT, hasPPI); }
6806 ;
6807
6808proc_decl_list
6809@init{
6810 int numPd = 1;
6811}
6812@after{
6813 MFPA.proc_decl_list(numPd);
6814}
6815 : proc_decl
6816 ( COMMA proc_decl {numPd++;} )*
6817 ;
6818
6819/*
6820 * R1516: interface name
6821 * OFP: was name inlined as IDENT
6822 */
6823
6824/*
6825 * R1517: proc pointer init
6826 * R1518: initial proc target
6827 * CIVL: initial proc target inlined as IDENT
6828 */
6829proc_pointer_init
6830 : null_init
6831 { MFPA.proc_pointer_init(null); }
6832 | IDENT
6833 { MFPA.proc_pointer_init($IDENT); }
6834 ;
6835
6836/*
6837 * R1519: intrinsic stmt
6838 * OFP: generic_name_list substituted for
6839 * intrinsic_procedure_name_list
6840 */
6841intrinsic_stmt
6842@init{
6843}
6844@after{
6845 checkForInclude();
6846}
6847 : (lbl=label)?
6848 INTRINSIC (COLON_COLON)? generic_name_list
6849 end_of_stmt
6850 { MFPA.intrinsic_stmt(lbl,
6851 $INTRINSIC, $end_of_stmt.t);}
6852 ;
6853
6854/*
6855 * R1520: function reference
6856 * OFP: replaced by designator_or_func_ref
6857 * to reduce backtracking
6858 */
6859
6860/*
6861 * R1521: call stmt
6862 * C1525: The procedure-designator shall designate a subroutine.
6863 */
6864call_stmt
6865@init{
6866 boolean hasAASL = false;
6867}
6868@after{
6869 checkForInclude();
6870}
6871 : (lbl=label)?
6872 CALL procedure_designator
6873 ( LPAREN
6874 ( actual_arg_spec_list {hasAASL=true;})? RPAREN
6875 )?
6876 end_of_stmt
6877 { MFPA.call_stmt(lbl,
6878 $CALL, $end_of_stmt.t, hasAASL);}
6879 ;
6880
6881/*
6882 * R1522: procedure designator
6883 * OFP: must be (IDENT | designator PERCENT IDENT)
6884 * IDENT inlined for procedure_name and binding_name
6885 * proc_component_ref is variable PERCENT IDENT
6886 * (variable is designator)
6887 * data_ref subset of designator
6888 * so data_ref PERCENT IDENT deleted
6889 * designator (R603), minus the substring part is data_ref,
6890 * so designator replaced by data_ref
6891 */
6892procedure_designator
6893 : data_ref { MFPA.procedure_designator();}
6894 ;
6895
6896/*
6897 * R1523: actual arg spec
6898 * OFP: TODO - delete greedy?
6899 * R1524: actual arg
6900 * OFP: ensure ( expr | designator ending in PERCENT IDENT)
6901 * IDENT inlined for procedure_name
6902 * expr is a designator (via primary) so variable deleted
6903 * designator is a IDENT so IDENT deleted
6904 * proc_component_ref is variable PERCENT IDENT can be designator
6905 * so deleted
6906 * R1525: alt return spec
6907 * OFP: inlined as ASTERISK label in rule 1524
6908 */
6909actual_arg_spec
6910@init{
6911 Token keyword = null;
6912}
6913 : (IDENT EQUALS {keyword=$IDENT;})?
6914 ( expr
6915 { MFPA.actual_arg_spec(keyword, null, null); }
6916 | ASTERISK lbl=label
6917 { MFPA.actual_arg_spec(keyword, $ASTERISK, lbl); })
6918 ;
6919
6920actual_arg_spec_list
6921options{greedy=false;}
6922@init{
6923 int numAAS = 1;
6924}
6925@after{
6926 MFPA.actual_arg_spec_list(numAAS);
6927}
6928 : actual_arg_spec
6929 ( COMMA actual_arg_spec {numAAS++;} )*
6930 ;
6931
6932/*
6933 * R1526: prefix
6934 * C1544: shall not specify both PURE and IMPURE.
6935 * C1545: shall not specify both NON_RECURSIVE and RECURSIVE.
6936 */
6937prefix
6938@init{
6939 int numPref = 1;
6940}
6941@after{
6942 MFPA.prefix(numPref);
6943}
6944 : prefix_spec
6945 (prefix_spec {numPref++;})*
6946 ;
6947
6948/*
6949 * R1527: prefix spec
6950 */
6951prefix_spec
6952 : declaration_type_spec
6953 { MFPA.prefix_spec(null, MFPUtils.PFX_TYPE); }
6954 | ELEMENTAL
6955 {MFPA.prefix_spec($ELEMENTAL, MFPUtils.PFX_ELEMENTAL);}
6956 | IMPURE
6957 {MFPA.prefix_spec($IMPURE, MFPUtils.PFX_IMPURE);}
6958 | MODULE
6959 {MFPA.prefix_spec($MODULE, MFPUtils.PFX_MODULE);}
6960 | NON_RECURSIVE
6961 {MFPA.prefix_spec($NON_RECURSIVE, MFPUtils.PFX_NON_RECURSIVE);}
6962 | PURE
6963 {MFPA.prefix_spec($PURE, MFPUtils.PFX_PURE);}
6964 | RECURSIVE
6965 {MFPA.prefix_spec($RECURSIVE, MFPUtils.PFX_RECURSIVE);}
6966 ;
6967
6968/*
6969 * R1528: proc language binding spec
6970 * CIVL: inlined as language binding spec in rule 1514
6971 */
6972
6973/*
6974 * R1529: function subprogram
6975 * OFP: left factored optional prefix in function_stmt
6976 * from function_subprogram
6977 * specification_part made non-optional
6978 * to remove END ambiguity (as can be empty)
6979 */
6980function_subprogram
6981@init {
6982 boolean hasEP = false;
6983 boolean hasISP = false;
6984}
6985 : function_stmt
6986 specification_part
6987 ( execution_part { hasEP=true; })?
6988 ( internal_subprogram_part { hasISP=true; })?
6989 end_function_stmt
6990 { MFPA.function_subprogram(hasEP, hasISP); }
6991 ;
6992
6993/*
6994 * R1530: function stmt
6995 * OFP: left factored optional prefix from function_stmt
6996 * generic_name_list substituted for dummy_arg_name_list
6997 */
6998function_stmt
6999@init {
7000 boolean hasGNL=false;
7001 boolean hasSffx=false;
7002}
7003@after{
7004 checkForInclude();
7005}
7006 : (lbl=label)?
7007 FUNCTION IDENT LPAREN
7008 ( generic_name_list {hasGNL=true;})?
7009 RPAREN (suffix {hasSffx=true;})?
7010 end_of_stmt
7011 { MFPA.function_stmt(lbl, $FUNCTION,
7012 $IDENT, $end_of_stmt.t, hasGNL, hasSffx);}
7013 ;
7014
7015/*
7016 * R1531: dummy arg stmt
7017 * OFP: was name inlined as IDENT
7018 */
7019
7020/*
7021 * R1532: suffix
7022 * CIVL: proc_language_binding_spec replaced as language_binding_spec
7023 * result_name replaced as IDENT
7024 */
7025suffix
7026@init{
7027 Token rname = null;
7028 boolean hasPLBS = false;
7029}
7030 : language_binding_spec
7031 ( RESULT LPAREN IDENT RPAREN {rname=$IDENT;} )?
7032 { MFPA.suffix(rname, true); }
7033 | RESULT LPAREN IDENT RPAREN
7034 ( language_binding_spec {hasPLBS = true;} )?
7035 { MFPA.suffix($IDENT, hasPLBS); }
7036 ;
7037
7038/*
7039 * R1533: end function stmt
7040 */
7041end_function_stmt
7042@init{
7043 Token id = null;
7044}
7045@after{
7046 checkForInclude();
7047}
7048 : (lbl=label)?
7049 END FUNCTION (IDENT {id=$IDENT;})?
7050 end_of_stmt
7051 { MFPA.end_function_stmt(lbl,
7052 $END, $FUNCTION, id, $end_of_stmt.t);}
7053 | (lbl=label)?
7054 END end_of_stmt
7055 { MFPA.end_function_stmt(lbl,
7056 $END, null, id, $end_of_stmt.t);}
7057 ;
7058
7059/*
7060 * R1534: subroutine subprogram
7061 * OFP: specification_part made non-optional
7062 * to remove END ambiguity (as can be empty)
7063 */
7064subroutine_subprogram
7065@init {
7066 boolean hasEP = false;
7067 boolean hasISP = false;
7068}
7069 : subroutine_stmt
7070 specification_part
7071 ( execution_part { hasEP=true; })?
7072 ( internal_subprogram_part { hasISP=true; })?
7073 end_subroutine_stmt
7074 { MFPA.subroutine_subprogram(hasEP, hasISP); }
7075 ;
7076
7077/*
7078 * R1535: subroutine stmt
7079 * CIVL: proc_language_binding_spec replaced as language_binding_spec
7080 * result_name replaced as IDENT
7081 */
7082subroutine_stmt
7083@init{
7084 boolean hasPref=false;
7085 boolean hasDAL=false;
7086 boolean hasBS=false;
7087 boolean hasAS=false;
7088}
7089@after{
7090 checkForInclude();
7091}
7092 : (lbl=label)?
7093 (prefix {hasPref=true;})?
7094 SUBROUTINE IDENT
7095 ( LPAREN (dummy_arg_list {hasDAL=true;})?
7096 RPAREN {hasAS=true;}
7097 (language_binding_spec {hasBS=true;})?
7098 )?
7099 end_of_stmt
7100 { MFPA.subroutine_stmt(lbl,
7101 $SUBROUTINE, $IDENT, $end_of_stmt.t,
7102 hasPref, hasDAL, hasBS, hasAS);}
7103 ;
7104
7105/*
7106 * R1536: dummy arg
7107 * OFP: IDENT inlined for dummy_arg_name
7108 */
7109dummy_arg
7110options{greedy=false; memoize=false;}
7111 : IDENT {MFPA.dummy_arg($IDENT);}
7112 | ASTERISK {MFPA.dummy_arg($ASTERISK);}
7113 ;
7114
7115dummy_arg_list
7116@init{
7117 int numDA = 1;
7118}
7119@after{
7120 MFPA.dummy_arg_list(numDA);
7121}
7122 : dummy_arg
7123 ( COMMA dummy_arg {numDA++;} )*
7124 ;
7125
7126/*
7127 * R1537: end subroutine stmt
7128 */
7129end_subroutine_stmt
7130@init{
7131 Token id = null;
7132}
7133@after{
7134 checkForInclude();
7135}
7136 : (lbl=label)?
7137 END SUBROUTINE (IDENT {id=$IDENT;})?
7138 end_of_stmt
7139 { MFPA.end_subroutine_stmt(lbl,
7140 $END, $SUBROUTINE, id, $end_of_stmt.t);}
7141 | (lbl=label)?
7142 END
7143 end_of_stmt
7144 { MFPA.end_subroutine_stmt(lbl,
7145 $END, null, id, $end_of_stmt.t);}
7146 ;
7147
7148/*
7149 * R1538: separate module subprogram
7150 * OFP: specification_part made non-optional
7151 * to remove END ambiguity (as can be empty)
7152 */
7153separate_module_subprogram
7154@init{
7155 boolean hasEP = false;
7156 boolean hasISP = false;
7157}
7158@after{
7159 MFPA.separate_module_subprogram(hasEP, hasISP);
7160}
7161 : mp_subprogram_stmt
7162 specification_part
7163 ( execution_part {hasEP=true;} )?
7164 ( internal_subprogram_part {hasISP=true;} )?
7165 end_mp_subprogram_stmt
7166 ;
7167
7168/*
7169 * R1539: mp subprogram stmt
7170 * CIVL: procedure_name replaced as IDENT
7171 */
7172mp_subprogram_stmt
7173@init{
7174}
7175@after{
7176 checkForInclude();
7177}
7178 : (lbl=label)?
7179 MODULE PROCEDURE IDENT
7180 end_of_stmt
7181 { MFPA.mp_subprogram_stmt(lbl,
7182 $MODULE, $PROCEDURE, $IDENT, $end_of_stmt.t);}
7183 ;
7184
7185/*
7186 * R1540: end mp subprogram stmt
7187 * CIVL: procedure_name replaced as IDENT
7188 */
7189end_mp_subprogram_stmt
7190@init{
7191 Token proc = null;
7192 Token name = null;
7193}
7194@after{
7195 checkForInclude();
7196}
7197 : (lbl=label)?
7198 END
7199 ( PROCEDURE {proc=$PROCEDURE;}
7200 ( IDENT {name=$IDENT;})?
7201 )?
7202 end_of_stmt
7203 { MFPA.end_mp_subprogram_stmt(lbl,
7204 $END, proc, name, $end_of_stmt.t);}
7205 ;
7206
7207/*
7208 * R1541: entry stmt
7209 * OFP: INDENT inlined for entry_name
7210 */
7211entry_stmt
7212@init {
7213 boolean hasDAL=false;
7214 boolean hasSffx=false;
7215}
7216@after{
7217 checkForInclude();
7218}
7219 : (lbl=label)?
7220 ENTRY IDENT
7221 ( LPAREN (dummy_arg_list {hasDAL=true;})?
7222 RPAREN (suffix {hasSffx=true;})?
7223 )?
7224 end_of_stmt
7225 { MFPA.entry_stmt(lbl,
7226 $ENTRY, $IDENT, $end_of_stmt.t,
7227 hasDAL, hasSffx);}
7228 ;
7229
7230/*
7231 * R1542: return stmt
7232 * OFP: scalar_int_expr replaced by expr
7233 */
7234return_stmt
7235@init{
7236 boolean hasExpr = false;
7237}
7238@after{
7239 checkForInclude();
7240}
7241 : (lbl=label)?
7242 RETURN (expr {hasExpr=true;})?
7243 end_of_stmt
7244 { MFPA.return_stmt(lbl,
7245 $RETURN, $end_of_stmt.t, hasExpr);}
7246 ;
7247
7248/*
7249 * R1543: contains stmt
7250 */
7251contains_stmt
7252@init{
7253}
7254@after{
7255 checkForInclude();
7256}
7257 : (lbl=label)?
7258 CONTAINS
7259 end_of_stmt
7260 { MFPA.contains_stmt(lbl,
7261 $CONTAINS, $end_of_stmt.t); }
7262 ;
7263
7264/*
7265 * R1544: stmt fucntion stmt
7266 * OFP: scalar_expr replaced by expr
7267 * generic_name_list substituted for dummy_arg_name_list
7268 * TODO Hopefully scanner and parser can help work together
7269 * here to work around ambiguity.
7270 * why can't this be accepted as an assignment statement
7271 * and then the parser look up the symbol for the IDENT
7272 * to see if it is a function??
7273 * Need scanner to send special token if it sees what?
7274 * TODO - won't do a(b==3,c) = 2
7275 */
7276stmt_function_stmt
7277@init{
7278 boolean hasGNL = false;
7279}
7280@after{
7281 checkForInclude();
7282}
7283 : (lbl=label)?
7284 STMT_FUNCTION IDENT LPAREN
7285 ( generic_name_list {hasGNL=true;})?
7286 RPAREN EQUALS expr
7287 end_of_stmt
7288 { MFPA.stmt_function_stmt(lbl,
7289 $IDENT, $end_of_stmt.t, hasGNL);}
7290 ;
7291
7292/*
7293 * In total, there are 473 real rules defined in Fortran 2018 Std.
7294 * Rules below are deprecated rules for back-compatability or
7295 * extended rules supporting parsing/verifying Fortran programs.
7296 */
7297
7298/*
7299 * R-1: end of stmt
7300 * OFP: The first branch:
7301 * added this to have a way to match the EOS and EOF combinations
7302 * (EOF) => EOF is done with lookahead because if it's not there,
7303 * then antlr will crash with an internal error while trying to
7304 * generate the java code. (as of 12.11.06)
7305 * The second branch:
7306 * don't call MFPA.end_of_file() here or the action will be called
7307 * before end_of_program action called
7308 */
7309end_of_stmt returns [Token t]
7310 : EOS
7311 { t = $EOS;}
7312 | (EOF) => EOF
7313 { t = $EOF;}
7314 ;
7315
7316/*
7317 * R-1101: assign stmt
7318 * OFP: The ASSIGN statement is a deleted feature.
7319 */
7320//assign_stmt
7321//@after{
7322// checkForInclude();
7323//}
7324// : (lbl=label)?
7325// ASSIGN tlbl=label TO IDENT
7326// end_of_stmt
7327// { MFPA.assign_stmt(lbl,
7328// $ASSIGN, tlbl, $TO, $IDENT, $end_of_stmt.t);}
7329// ;
7330
7331/*
7332 * R-1102: assign stmt
7333 * OFP: The assigned GOTO statement is a deleted feature.
7334 */
7335//assigned_goto_stmt
7336//@after{
7337// checkForInclude();
7338//}
7339// : (lbl=label)?
7340// ( go=GOTO
7341// | go=GO to=TO
7342// )
7343// IDENT (COMMA stmt_label_list)?
7344// end_of_stmt
7345// { MFPA.assigned_goto_stmt(lbl,
7346// go, to, $IDENT, $end_of_stmt.t); }
7347// ;
7348
7349/*
7350 * R-1103: stmt label list
7351 * OFP: Used with assigned_goto_stmt (deleted feature)
7352 */
7353//stmt_label_list
7354//@init{
7355// int numSL = 1;
7356//}
7357//@after{
7358// MFPA.stmt_label_list(numSL);
7359//}
7360// : LPAREN label
7361// ( COMMA label {numSL ++;} )* RPAREN
7362// ;
7363
7364
7365/*
7366 * R-1104: pause stmt
7367 * OFP: The PAUSE statement is a deleted feature.
7368 */
7369//pause_stmt
7370//@after{
7371// checkForInclude();
7372//}
7373// : (lbl=label)?
7374// PAUSE
7375// ( tlbl=label
7376// | char_literal_constant
7377// )?
7378// end_of_stmt
7379// { MFPA.pause_stmt(lbl,
7380// $PAUSE, tlbl, $end_of_stmt.t); }
7381// ;
7382
7383/*
7384 * R-1105: arithmetic if stmt
7385 * OFP: The arithmetic if statement is a deleted feature.
7386 * scalar_numeric_expr replaced by expr
7387 */
7388//arithmetic_if_stmt
7389//@after{
7390// checkForInclude();
7391//}
7392// : (lbl=label)?
7393// M_ARITHMETIC_IF_STMT IF LPAREN expr RPAREN
7394// lbl0=label COMMA lbl1=label COMMA lbl2=label
7395// end_of_stmt
7396// { MFPA.arithmetic_if_stmt(lbl,
7397// $IF, lbl0, lbl1, lbl2, $end_of_stmt.t); }
7398// ;
7399
7400/*x
7401 * R-1106: errorstop-stmt
7402 * OFP: rule 856 in Fortran 2008 std.
7403 */
7404//errorstop_stmt
7405//@init{
7406// boolean hasSC = false;
7407//}
7408//@after{
7409// checkForInclude();
7410//}
7411// : (lbl=label)?
7412// ERROR STOP (stop_code {hasSC=true;})?
7413// end_of_stmt
7414// { MFPA.errorstop_stmt(lbl,
7415// $ERROR, $STOP, $end_of_stmt.t, hasSC); }
7416// ;
7417
7418/*
7419 * R-601: hollerith literal constant
7420 * OFP: Hollerith constants were deleted in F77;
7421 * Hollerith edit descriptors deleted in F95.
7422 */
7423//hollerith_literal_constant
7424// : HOLLERITH
7425// { MFPA.hollerith_literal_constant($HOLLERITH); }
7426// ;
Note: See TracBrowser for help on using the repository browser.