source: CIVL/mods/dev.civl.abc/grammar/fortran/FortranParser08.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: 170.7 KB
RevLine 
[aad342c]1/*
2 * NOTES
3 *
4 * R303, R406, R417, R427, R428 underscore - added _ to rule (what happened
5 * to it?) * R410 sign - had '?' rather than '-'
6 * R1209 import-stmt: MISSING a ]
7 *
8 * check comments regarding deleted for correctness
9 *
10 * Replace all occurrences of T_EOS with end_of_stmt rule call so there is
11 * a way to look ahead at the next token to see if it belongs to the same
12 * input stream as the current one. This serves as a way to detect that an
13 * include statement had occurred during the lexical phase.
14 *
15 * TODO add (label)? to all statements...
16 * finished: continue-stmt, end-do-stmt
17 *
18 */
19
20
21// added (label)? to any rule for a statement (*_stmt, for the most
22// part) because the draft says a label can exist with any statement.
23// questions are:
24// - what about constructs such as if/else; where can labels all occur?
25// - or the masked_elsewhere_stmt rule...
26
27
28parser grammar FortranParser08;
29
30options {
31 language=Java;
32 superClass=AbstractFortranParser;
33//////////////
34// NOTE: tokenVocab causes an antlr warning if used in conjuction
35// with FortranParserExtras. The warning should be ignored as an inconsistent
36// tokens file will be generated otherwise.
37 tokenVocab=FortranLexer;
38}
39
40// If the package (in header) is defined (see below), antlr v3.2 will
41// emit an error. However, the error can be safely ignored and
42// rerunning make will build the OFP jar file correctly.
43//
44@header {
45package dev.civl.abc.front.fortran.old.parse;
46import dev.civl.abc.token.IF.CivlcToken;
47}
48
49@members {
50 int gCount1;
51 int gCount2;
52
53 public void initialize(String[] args, String filename, String path) {
54 action = new FortranParserActionTreeMaker(args, this, filename);
55 initialize(this, action, filename, path);
56 action.start_of_file(filename, path);
57 }
58
59 public void eofAction() {
60 action.end_of_file(filename, pathname);
61 }
62}
63
64
65/**
66 * Section/Clause 1: Overview
67 */
68
69
70/*
71 * Section/Clause 2: Fortran concepts
72 */
73
74
75/*
76 * Got rid of the following rules:
77 * program
78 * program_unit
79 * external_subprogram
80 *
81 * this was done because Main() should now handle the top level rules
82 * to try and reduce the amount of backtracking that must be done!
83 * --Rickett, 12.07.06
84 *
85 * for some reason, leaving these three rules in, even though main()
86 * does NOT call them, prevents the parser from failing on the tests:
87 * main_program.f03
88 * note_6.24.f03
89 * it appears to be something with the (program_unit)* part of the
90 * program rule. --12.07.06
91 * --resolved: there's a difference in the code that is generated for
92 * the end_of_stmt rule if these three rules are in there.
93 * to get around this, i modified the end_of_stmt rule.
94 * see it for more details. --12.11.06
95 *
96 */
97
98/*
99 * R201-F08 program
100 * is program-unit
101 * [ program-unit ] ...
102 */
103
104////////////
105// R201-F08
106//
107// Removed from grammar and called explicitly
108//
109
110
111/*
112 * R202-F08 program-unit
113 * is main-program
114 * or external-subprogram
115 * or module
116 * or submodule // NEW_TO_2008
117 * or block-data
118 */
119
120////////////
121// R202-F08
122//
123// Removed from grammar and called explicitly
124//
125
126
127/*
128 * R203-F08 external-subprogram
129 * is function-subprogram
130 * or subroutine-subprogram
131 */
132
133////////////
134// R203-F08
135//
136// Removed from grammar and called explicitly
137//
138
139/*
140 * R1101-F08 main-program
141 * is [ program-stmt ]
142 * [ specification-part ]
143 * [ execution-part ]
144 * [ internal-subprogram-part ]
145 * end-program-stmt
146 */
147
148////////////
149// R1101-F08
150//
151// We need a start rule as a entry point in the parser
152//
153// specification_part made non-optional to remove END ambiguity
154// (as can be empty)
155//
156main_program
157@init
158{
159 boolean hasProgramStmt = false;
160 boolean hasExecutionPart = false;
161 boolean hasInternalSubprogramPart = false;
162 action.main_program__begin();
163}
164 : ( program_stmt {hasProgramStmt = true;} )?
165 specification_part
166 ( execution_part {hasExecutionPart = true;} )?
167 ( internal_subprogram_part {hasInternalSubprogramPart = true;} )?
168 end_program_stmt
169 {
170 action.main_program(hasProgramStmt, hasExecutionPart, hasInternalSubprogramPart);
171 }
172 ;
173
174// added rule so could have one rule for main() to call for attempting
175// to match a function subprogram. the original rule,
176// external_subprogram, has (prefix)? for a function_subprogram.
177ext_function_subprogram
178@init{boolean hasPrefix=false;}
179 : (prefix {hasPrefix=true;})? function_subprogram
180 {action.ext_function_subprogram(hasPrefix);}
181 ;
182
183// R204
184// ERR_CHK 204 see ERR_CHK 207, implicit_part? removed (was after import_stmt*)
185specification_part
186@init{int numUseStmts=0; int numImportStmts=0; int numDeclConstructs=0;}
187 : ( use_stmt {numUseStmts++;})*
188 ( import_stmt {numImportStmts++;})*
189 ( declaration_construct {numDeclConstructs++;})*
190 {action.specification_part(numUseStmts, numImportStmts,
191 0, numDeclConstructs);}
192 ;
193
194// R205 implicit_part removed from grammar (see ERR_CHK 207)
195
196// R206 implicit_part_stmt removed from grammar (see ERR_CHK 207)
197
198/*
199 * R207-F08 declaration-construct
200 * is derived-type-def
201 * or entry-stmt
202 * or enum-def // NEW_NAME_2008 (was enum-alias-def)
203 * or format-stmt
204 * or interface-block
205 * or parameter-stmt
206 * or procedure-declaration-stmt
207 * or other-specification-stmt // NEW_NAME_2008 (was specification-stmt)
208 * or type-declaration-stmt
209 * or stmt-function-stmt
210 */
211
212////////////
213// R207-F08
214//
215declaration_construct
216@after {action.declaration_construct();}
217 : derived_type_def
218 | entry_stmt
219 | enum_def
220 | format_stmt
221 | interface_block
222 | parameter_stmt
223 | procedure_declaration_stmt
224 | other_specification_stmt
225 | type_declaration_stmt
226 | stmt_function_stmt
227 ;
228
229// R208
230execution_part
231@after {
232 action.execution_part();
233}
234 : executable_construct
235 ( execution_part_construct )*
236 ;
237
238// R209
239execution_part_construct
240@after {
241 action.execution_part_construct();
242}
243 : executable_construct
244 | format_stmt
245 | entry_stmt
246 | data_stmt
247 ;
248
249/*
250 * R210-F08 internal-subprogram-part
251 * is contains-stmt
252 * [ internal-subprogram ] ... // DIFFERENT_2008 (can have contains only)
253 */
254
255////////////
256// R210-F08
257//
258internal_subprogram_part
259@init{int count = 0;}
260 : contains_stmt
261 ( internal_subprogram {count += 1;} )*
262 { action.internal_subprogram_part(count); }
263 ;
264
265// R211
266// modified to factor optional prefix
267internal_subprogram
268@after {
269 action.internal_subprogram();
270}
271 : ( prefix )? function_subprogram
272 | subroutine_subprogram
273 ;
274
275/*
276 * R212-F08 other-specification-stmt // NEW_NAME_2008 (was specification-stmt)
277 * is access-stmt
278 * or allocatable-stmt
279 * or asynchronous-stmt
280 * or bind-stmt
281 * or codimension-stmt // NEW_TO_2008
282 * or common-stmt
283 * or data-stmt
284 * or dimension-stmt
285 * or equivalence-stmt
286 * or external-stmt
287 * or intent-stmt
288 * or intrinsic-stmt
289 * or namelist-stmt
290 * or optional-stmt
291 * or pointer-stmt
292 * or protected-stmt
293 * or save-stmt
294 * or target-stmt
295 * or volatile-stmt
296 * or value-stmt
297 */
298
299////////////
300// R212-F08
301//
302other_specification_stmt
303@after {action.specification_stmt();}
304 : access_stmt
305 | allocatable_stmt
306 | asynchronous_stmt
307 | bind_stmt
308 | codimension_stmt // NEW_TO_2008
309 | common_stmt
310 | data_stmt
311 | dimension_stmt
312 | equivalence_stmt
313 | external_stmt
314 | intent_stmt
315 | intrinsic_stmt
316 | namelist_stmt
317 | optional_stmt
318 | pointer_stmt
319 | protected_stmt
320 | save_stmt
321 | target_stmt
322 | volatile_stmt
323 | value_stmt
324 ;
325
326/*
327 * R213-F08 executable-construct
328 * is action-stmt
329 * or associate-construct
330 * or block-construct // NEW_TO_2008
331 * or case-construct
332 * or critical-construct // NEW_TO_2008
333 * or do-construct
334 * or forall-construct
335 * or if-construct
336 * or select-type-construct
337 * or where-construct
338 */
339
340////////////
341// R213-F03
342//
343// This rule is overridden in FortranParserExtras grammar
344//
345executable_construct
346@after {action.executable_construct();}
347 : action_stmt
348 | associate_construct
349 | case_construct
350 | do_construct
351 | forall_construct
352 | if_construct
353 | select_type_construct
354 | where_construct
355 | pragma_stmt //For OMP STATEMENT (W.Wu)
356 ;
357
358
359/*
360 * R214-F08 action-stmt
361 * is allocate-stmt
362 * or assignment-stmt
363 * or backspace-stmt
364 * or call-stmt
365 * or close-stmt
366 * or continue-stmt
367 * or cycle-stmt
368 * or deallocate-stmt
369 * or end-function-stmt
370 * or end-mp-subprogram-stmt // NEW_TO_2008
371 * or end-program-stmt
372 * or end-subroutine-stmt
373 * or endfile-stmt
374 * or errorstop-stmt // NEW_TO_2008
375 * or exit-stmt
376 * or flush-stmt
377 * or forall-stmt
378 * or goto-stmt
379 * or if-stmt
380 * or inquire-stmt
381 * or lock-stmt // NEW_TO_2008
382 * or nullify-stmt
383 * or open-stmt
384 * or pointer-assignment-stmt
385 * or print-stmt
386 * or read-stmt
387 * or return-stmt
388 * or rewind-stmt
389 * or stop-stmt
390 * or sync-all-stmt // NEW_TO_2008
391 * or sync-images-stmt // NEW_TO_2008
392 * or sync-memory-stmt // NEW_TO_2008
393 * or unlock-stmt // NEW_TO_2008
394 * or wait-stmt
395 * or where-stmt
396 * or write-stmt
397 * or arithmetic-if-stmt
398 * or computed-goto-stmt
399 */
400
401// R214
402// C201 (R208) An execution-part shall not contain an end-function-stmt, end-program-stmt, or
403// end-subroutine-stmt. (But they can be in a branch target statement, which
404// is not in the grammar, so the end-xxx-stmts deleted.)
405// TODO continue-stmt is ambiguous with same in end-do, check for label and if
406// label matches do-stmt label, then match end-do there
407// the original generated rules do not allow the label, so add (label)?
408action_stmt
409@after {
410 action.action_stmt();
411 checkForInclude();
412}
413// Removed backtracking by inserting extra tokens in the stream by the
414// prepass that signals whether we have an assignment-stmt, a
415// pointer-assignment-stmt, or an arithmetic if. this approach may work for
416// other parts of backtracking also. however, need to see if there is a way
417// to define tokens w/o defining them in the lexer so that the lexer doesn't
418// have to add them to it's parsing.. 02.05.07
419 : allocate_stmt
420 | assignment_stmt
421 | backspace_stmt
422 | call_stmt
423 | close_stmt
424 | continue_stmt
425 | cycle_stmt
426 | deallocate_stmt
427 | endfile_stmt
428 | exit_stmt
429 | flush_stmt
430 | forall_stmt
431 | goto_stmt
432 | if_stmt
433 | inquire_stmt
434 | nullify_stmt
435 | open_stmt
436 | pointer_assignment_stmt
437 | print_stmt
438 | read_stmt
439 | return_stmt
440 | rewind_stmt
441 | stop_stmt
442 | wait_stmt
443 | where_stmt
444 | write_stmt
445 | arithmetic_if_stmt
446 | computed_goto_stmt
447 | assign_stmt
448 | assigned_goto_stmt
449 | pause_stmt
450 ;
451
452// R215
453keyword returns [Token tk]
454@after {
455 action.keyword();
456}
457 : name {tk = $name.tk;}
458 ;
459
460/**
461 * Section/Clause 3: Lexical tokens and source form
462 */
463
464// R301 character not used
465
466// R302 alphanumeric_character converted to fragment
467
468// R303 underscore inlined
469
470// R304
471name returns [Token tk]
472 : T_IDENT { tk = $T_IDENT; action.name(tk); }
473 ;
474
475// R305
476// ERR_CHK 305 named_constant replaced by T_IDENT
477constant
478 : literal_constant { action.constant(null); }
479 | T_IDENT { action.constant($T_IDENT); }
480 ;
481
482scalar_constant
483@after {
484 action.scalar_constant();
485}
486 : constant
487 ;
488
489// R306
490literal_constant
491@after {
492 action.literal_constant();
493}
494 : int_literal_constant
495 | real_literal_constant
496 | complex_literal_constant
497 | logical_literal_constant
498 | char_literal_constant
499 | boz_literal_constant
500 | hollerith_literal_constant // deleted in F77
501 ;
502
503// R307 named_constant was name inlined as T_IDENT
504
505// R308
506// C302 R308 int_constant shall be of type integer
507// inlined integer portion of constant
508int_constant
509 : int_literal_constant { action.int_constant(null); }
510 | T_IDENT { action.int_constant($T_IDENT); }
511 ;
512
513// R309
514// C303 R309 char_constant shall be of type character
515// inlined character portion of constant
516char_constant
517 : char_literal_constant { action.int_constant(null); }
518 | T_IDENT { action.int_constant($T_IDENT); }
519 ;
520
521// R310
522intrinsic_operator returns [Token tk]
523@after {
524 action.intrinsic_operator();
525}
526 : power_op { tk = $power_op.tk; }
527 | mult_op { tk = $mult_op.tk; }
528 | add_op { tk = $add_op.tk; }
529 | concat_op { tk = $concat_op.tk; }
530 | rel_op { tk = $rel_op.tk; }
531 | not_op { tk = $not_op.tk; }
532 | and_op { tk = $and_op.tk; }
533 | or_op { tk = $or_op.tk; }
534 | equiv_op { tk = $equiv_op.tk; }
535 ;
536
537// R311
538// removed defined_unary_op or defined_binary_op ambiguity with T_DEFINED_OP
539defined_operator
540 : T_DEFINED_OP
541 { action.defined_operator($T_DEFINED_OP, false); }
542 | extended_intrinsic_op
543 { action.defined_operator($extended_intrinsic_op.tk, true); }
544 ;
545
546// R312
547extended_intrinsic_op returns [Token tk]
548@after {
549 action.extended_intrinsic_op();
550}
551 : intrinsic_operator { tk = $intrinsic_operator.tk; }
552 ;
553
554// R313
555// ERR_CHK 313 five characters or less
556label returns [Token tk]
557 : T_DIGIT_STRING { tk = $T_DIGIT_STRING; action.label($T_DIGIT_STRING); }
558 ;
559
560// action.label called here to store label in action class
561label_list
562@init{ int count=0;}
563 : {action.label_list__begin();}
564 lbl=label {count++;}
565 ( T_COMMA lbl=label {count++;} )*
566 {action.label_list(count);}
567 ;
568
569
570/**
571 * Section/Clause 4: Types
572 */
573
574
575// R401
576type_spec
577@after {
578 action.type_spec();
579}
580 : intrinsic_type_spec
581 | derived_type_spec
582 ;
583
584// R402
585// ERR_CHK 402 scalar_int_expr replaced by expr
586type_param_value
587 : expr { action.type_param_value(true, false, false); }
588 | T_ASTERISK { action.type_param_value(false, true, false); }
589 | T_COLON { action.type_param_value(false, false, true); }
590 ;
591
592// inlined scalar_int_expr C101 shall be a scalar
593
594// inlined scalar_expr
595
596// R403
597// Nonstandard Extension: source BLAS
598// | T_DOUBLE T_COMPLEX
599// | T_DOUBLECOMPLEX
600intrinsic_type_spec
601@init{boolean hasKindSelector = false;}
602 : T_INTEGER (kind_selector {hasKindSelector = true;})?
603 {action.intrinsic_type_spec($T_INTEGER, null,
604 IActionEnums.IntrinsicTypeSpec_INTEGER,
605 hasKindSelector);}
606 | T_REAL (kind_selector {hasKindSelector = true;})?
607 {action.intrinsic_type_spec($T_REAL, null,
608 IActionEnums.IntrinsicTypeSpec_REAL,
609 hasKindSelector);}
610 | T_DOUBLE T_PRECISION
611 {action.intrinsic_type_spec($T_DOUBLE, $T_PRECISION,
612 IActionEnums.
613 IntrinsicTypeSpec_DOUBLEPRECISION,
614 false);}
615 | T_DOUBLEPRECISION
616 {action.intrinsic_type_spec($T_DOUBLEPRECISION, null,
617 IActionEnums.
618 IntrinsicTypeSpec_DOUBLEPRECISION,
619 false);}
620 | T_COMPLEX (kind_selector {hasKindSelector = true;})?
621 {action.intrinsic_type_spec($T_COMPLEX, null,
622 IActionEnums.IntrinsicTypeSpec_COMPLEX,
623 hasKindSelector);}
624 | T_DOUBLE T_COMPLEX
625 {action.intrinsic_type_spec($T_DOUBLE, $T_COMPLEX,
626 IActionEnums.
627 IntrinsicTypeSpec_DOUBLECOMPLEX,
628 false);}
629 | T_DOUBLECOMPLEX
630 {action.intrinsic_type_spec($T_DOUBLECOMPLEX, null,
631 IActionEnums.
632 IntrinsicTypeSpec_DOUBLECOMPLEX,
633 false);}
634 | T_CHARACTER (char_selector {hasKindSelector = true;})?
635 {action.intrinsic_type_spec($T_CHARACTER, null,
636 IActionEnums.
637 IntrinsicTypeSpec_CHARACTER,
638 hasKindSelector);}
639 | T_LOGICAL (kind_selector {hasKindSelector = true;})?
640 {action.intrinsic_type_spec($T_LOGICAL, null,
641 IActionEnums.IntrinsicTypeSpec_LOGICAL,
642 hasKindSelector);}
643 ;
644
645// R404
646// ERR_CHK 404 scalar_int_initialization_expr replaced by expr
647// Nonstandard extension: source common practice
648// | T_ASTERISK T_DIGIT_STRING // e.g., COMPLEX*16
649// TODO - check to see if second alternative is where it should go
650kind_selector
651@init{Token tk1=null; Token tk2=null;}
652 : T_LPAREN (T_KIND T_EQUALS {tk1=$T_KIND; tk2=$T_EQUALS;})? expr T_RPAREN
653 { action.kind_selector(tk1, tk2, true); }
654 | T_ASTERISK T_DIGIT_STRING
655 { action.kind_selector($T_ASTERISK, $T_DIGIT_STRING, false); }
656 ;
657
658// R405
659signed_int_literal_constant
660@init{Token sign = null;}
661 : (T_PLUS {sign=$T_PLUS;} | T_MINUS {sign=$T_MINUS;})?
662 int_literal_constant
663 { action.signed_int_literal_constant(sign); }
664 ;
665
666// R406
667int_literal_constant
668@init{Token kind = null;}
669 : T_DIGIT_STRING (T_UNDERSCORE kind_param {kind = $kind_param.tk;})?
670 {action.int_literal_constant($T_DIGIT_STRING, kind);}
671 ;
672
673// R407
674// T_IDENT inlined for scalar_int_constant_name
675kind_param returns [Token tk]
676 : T_DIGIT_STRING
677 { tk = $T_DIGIT_STRING; action.kind_param($T_DIGIT_STRING); }
678 | T_IDENT
679 { tk = $T_IDENT; action.kind_param($T_IDENT); }
680 ;
681
682// R408 signed_digit_string inlined
683
684// R409 digit_string converted to fragment
685
686// R410 sign inlined
687
688// R411
689boz_literal_constant
690 : BINARY_CONSTANT { action.boz_literal_constant($BINARY_CONSTANT); }
691 | OCTAL_CONSTANT { action.boz_literal_constant($OCTAL_CONSTANT); }
692 | HEX_CONSTANT { action.boz_literal_constant($HEX_CONSTANT); }
693 ;
694
695// R412 binary-constant converted to terminal
696
697// R413 octal_constant converted to terminal
698
699// R414 hex_constant converted to terminal
700
701// R415 hex_digit inlined
702
703// R416
704signed_real_literal_constant
705@init{Token sign = null;}
706 : (T_PLUS {sign=$T_PLUS;} | T_MINUS {sign=$T_MINUS;})?
707 real_literal_constant
708 {action.signed_real_literal_constant(sign);}
709 ;
710
711// R417 modified to use terminal
712// Grammar Modified slightly to prevent problems with input such as:
713// if(1.and.1) then ...
714real_literal_constant
715@init{Token kind = null;}
716// WARNING must parse T_REAL_CONSTANT in action (look for D)
717 : T_REAL_CONSTANT (T_UNDERSCORE kind_param {kind = $kind_param.tk;})?
718 { action.real_literal_constant($T_REAL_CONSTANT, kind); }
719
720 ;
721
722// R418 significand converted to fragment
723
724// R419 exponent_letter inlined in new Exponent
725
726// R420 exponent inlined in new Exponent
727
728// R421
729complex_literal_constant
730@after {
731 action.complex_literal_constant();
732}
733 : T_LPAREN real_part T_COMMA imag_part T_RPAREN
734 ;
735
736// R422
737// ERR_CHK 422 named_constant replaced by T_IDENT
738real_part
739 : signed_int_literal_constant
740 { action.real_part(true, false, null); }
741 | signed_real_literal_constant
742 { action.real_part(false, true, null); }
743 | T_IDENT
744 { action.real_part(false, false, $T_IDENT); }
745 ;
746
747// R423
748// ERR_CHK 423 named_constant replaced by T_IDENT
749imag_part
750 : signed_int_literal_constant
751 { action.imag_part(true, false, null); }
752 | signed_real_literal_constant
753 { action.imag_part(false, true, null); }
754 | T_IDENT
755 { action.imag_part(false, false, $T_IDENT); }
756 ;
757
758// R424
759// ERR_CHK 424a scalar_int_initialization_expr replaced by expr
760// ERR_CHK 424b T_KIND, if type_param_value, must be a
761// scalar_int_initialization_expr
762// ERR_CHK 424c T_KIND and T_LEN cannot both be specified
763char_selector
764@init {
765 int kindOrLen1; kindOrLen1 = IActionEnums.KindLenParam_none;
766 int kindOrLen2; kindOrLen2 = IActionEnums.KindLenParam_none;
767 Token tk = null;
768 boolean hasAsterisk = false;
769}
770 // length-selector without type-param-value
771 : T_ASTERISK char_length (T_COMMA)?
772 {
773 hasAsterisk=true;
774 action.char_selector(null, null, kindOrLen1, kindOrLen2, hasAsterisk);
775 }
776 // type-param-value but no LEN=
777 | T_LPAREN type_param_value
778 ( T_COMMA (T_KIND T_EQUALS {tk=$T_KIND;})? expr
779 {kindOrLen2=IActionEnums.KindLenParam_kind;}
780 )?
781 T_RPAREN
782 {
783 kindOrLen1 = IActionEnums.KindLenParam_len;
784 action.char_selector(null, tk, kindOrLen1, kindOrLen2, hasAsterisk);
785 }
786 // type-param-value with LEN=
787 | T_LPAREN T_LEN T_EQUALS type_param_value
788 ( T_COMMA T_KIND T_EQUALS expr
789 {kindOrLen2=IActionEnums.KindLenParam_kind; tk=$T_KIND;}
790 )?
791 T_RPAREN
792 {
793 kindOrLen1 = IActionEnums.KindLenParam_len;
794 action.char_selector($T_LEN, tk, kindOrLen1, kindOrLen2, hasAsterisk);
795 }
796 // KIND= first
797 | T_LPAREN T_KIND T_EQUALS expr
798 ( T_COMMA (T_LEN T_EQUALS {tk=$T_LEN;})? type_param_value
799 {kindOrLen2=IActionEnums.KindLenParam_len;}
800 )?
801 T_RPAREN
802 {
803 kindOrLen1 = IActionEnums.KindLenParam_kind;
804 action.char_selector($T_KIND, tk, kindOrLen1, kindOrLen2, hasAsterisk);
805 }
806 ;
807
808// R425
809length_selector
810@init {Token len = null;}
811 : T_LPAREN ( T_LEN { len=$T_LEN; } T_EQUALS )? type_param_value T_RPAREN
812 { action.length_selector(len, IActionEnums.KindLenParam_len, false); }
813 | T_ASTERISK char_length (T_COMMA)?
814 { action.length_selector(len, IActionEnums.KindLenParam_none, true); }
815 ;
816
817// R426
818char_length
819 : T_LPAREN type_param_value T_RPAREN { action.char_length(true); }
820 | scalar_int_literal_constant { action.char_length(false); }
821 ;
822
823scalar_int_literal_constant
824@after {action.scalar_int_literal_constant();}
825 : int_literal_constant
826 ;
827
828// R427
829// char_literal_constant
830// // options {k=2;}
831// : T_DIGIT_STRING T_UNDERSCORE T_CHAR_CONSTANT
832// // removed the T_UNDERSCORE because underscores are valid characters
833// // for identifiers, which means the lexer would match the T_IDENT and
834// // T_UNDERSCORE as one token (T_IDENT).
835// | T_IDENT T_CHAR_CONSTANT
836// | T_CHAR_CONSTANT
837// ;
838char_literal_constant
839 : T_DIGIT_STRING T_UNDERSCORE T_CHAR_CONSTANT
840 { action.char_literal_constant($T_DIGIT_STRING, null, $T_CHAR_CONSTANT); }
841 // removed the T_UNDERSCORE because underscores are valid characters
842 // for identifiers, which means the lexer would match the T_IDENT and
843 // T_UNDERSCORE as one token (T_IDENT).
844 | T_IDENT T_CHAR_CONSTANT
845 { action.char_literal_constant(null, $T_IDENT, $T_CHAR_CONSTANT); }
846 | T_CHAR_CONSTANT
847 { action.char_literal_constant(null, null, $T_CHAR_CONSTANT); }
848 ;
849
850//
851// Note: Hollerith constants were deleted in F77; Hollerith edit descriptors
852// deleted in F95.
853//
854hollerith_literal_constant
855 : T_HOLLERITH
856 { action.hollerith_literal_constant($T_HOLLERITH); }
857 ;
858
859// R428
860logical_literal_constant
861@init{Token kind = null;}
862 : T_TRUE ( T_UNDERSCORE kind_param {kind = $kind_param.tk;})?
863 {action.logical_literal_constant($T_TRUE, true, kind);}
864 | T_FALSE ( T_UNDERSCORE kind_param {kind = $kind_param.tk;})?
865 {action.logical_literal_constant($T_FALSE, false, kind);}
866 ;
867
868// R429
869// ( component_part )? inlined as ( component_def_stmt )*
870derived_type_def
871@after {
872 action.derived_type_def();
873}
874 : derived_type_stmt
875 // matches T_INTEGER possibilities in component_def_stmt
876 type_param_or_comp_def_stmt_list
877 ( private_or_sequence )*
878 { /* ERR_CHK 429
879 * if private_or_sequence present, component_def_stmt in
880 * type_param_or_comp_def_stmt_list
881 * is an error
882 */
883 }
884 ( component_def_stmt )*
885 ( type_bound_procedure_part )?
886 end_type_stmt
887 ;
888
889// Includes:
890// ( type_param_def_stmt)*
891// ( component_def_stmt )* if starts with T_INTEGER (could be a parse error)
892// REMOVED T_INTEGER junk (see statement above) with k=1
893// TODO this must be tested can we get rid of this????
894type_param_or_comp_def_stmt_list
895@after {
896 action.type_param_or_comp_def_stmt_list();
897}
898///options {k=1;}
899// : (T_INTEGER) => (kind_selector)? T_COMMA type_param_or_comp_def_stmt
900// type_param_or_comp_def_stmt_list
901 : (kind_selector)? T_COMMA type_param_or_comp_def_stmt
902 type_param_or_comp_def_stmt_list
903 |
904 { /* ERR_CHK R435
905 * type_param_def_stmt(s) must precede component_def_stmt(s)
906 */
907 }
908 ;
909
910type_param_or_comp_def_stmt
911 : type_param_attr_spec T_COLON_COLON type_param_decl_list end_of_stmt
912 // TODO: See if this is reachable now that type_param_attr_spec is
913 // tokenized T_KIND or T_LEN. See R435
914 {action.type_param_or_comp_def_stmt($end_of_stmt.tk,
915 IActionEnums.TypeParamOrCompDef_typeParam);}
916 | component_attr_spec_list T_COLON_COLON component_decl_list end_of_stmt
917 // See R440
918 {action.type_param_or_comp_def_stmt($end_of_stmt.tk,
919 IActionEnums.TypeParamOrCompDef_compDef);}
920 ;
921
922// R430
923// generic_name_list substituted for type_param_name_list
924derived_type_stmt
925@init {
926 Token lbl=null;
927 boolean hasTypeAttrSpecList=false;
928 boolean hasGenericNameList=false;
929}
930@after{checkForInclude();}
931 : (label {lbl=$label.tk;})? T_TYPE
932 ( ( T_COMMA type_attr_spec_list {hasTypeAttrSpecList=true;} )?
933 T_COLON_COLON )? T_IDENT
934 ( T_LPAREN generic_name_list T_RPAREN {hasGenericNameList=true;} )?
935 end_of_stmt
936 {action.derived_type_stmt(lbl, $T_TYPE, $T_IDENT, $end_of_stmt.tk,
937 hasTypeAttrSpecList, hasGenericNameList);}
938 ;
939
940type_attr_spec_list
941@init{int count = 0;}
942 : {action.type_attr_spec_list__begin();}
943 type_attr_spec {count++;} ( T_COMMA type_attr_spec {count++;} )*
944 {action.type_attr_spec_list(count);}
945 ;
946
947generic_name_list
948@init{int count = 0;}
949 : {action.generic_name_list__begin();}
950 ident=T_IDENT
951 {
952 count++;
953 action.generic_name_list_part(ident);
954 } ( T_COMMA ident=T_IDENT
955 {
956 count++;
957 action.generic_name_list_part(ident);
958 } )*
959 {action.generic_name_list(count);}
960 ;
961
962// R431
963// T_IDENT inlined for parent_type_name
964type_attr_spec
965 : access_spec
966 {action.type_attr_spec(null, null,
967 IActionEnums.TypeAttrSpec_access_spec);}
968 | T_EXTENDS T_LPAREN T_IDENT T_RPAREN
969 {action.type_attr_spec($T_EXTENDS, $T_IDENT,
970 IActionEnums.TypeAttrSpec_extends);}
971 | T_ABSTRACT
972 {action.type_attr_spec($T_ABSTRACT, null,
973 IActionEnums.TypeAttrSpec_abstract);}
974 | T_BIND T_LPAREN T_IDENT /* 'C' */ T_RPAREN
975 {action.type_attr_spec($T_BIND, $T_IDENT,
976 IActionEnums.TypeAttrSpec_bind);}
977 ;
978
979// R432
980private_or_sequence
981@after {
982 action.private_or_sequence();
983}
984 : private_components_stmt
985 | sequence_stmt
986 ;
987
988// R433
989end_type_stmt
990@init {Token lbl = null;Token id=null;}
991@after{checkForInclude();}
992 : (label {lbl=$label.tk;})? T_END T_TYPE ( T_IDENT {id=$T_IDENT;})?
993 end_of_stmt
994 {action.end_type_stmt(lbl, $T_END, $T_TYPE, id, $end_of_stmt.tk);}
995 | (label {lbl=$label.tk;})? T_ENDTYPE ( T_IDENT {id=$T_IDENT;})?
996 end_of_stmt
997 {action.end_type_stmt(lbl, $T_ENDTYPE, null, id, $end_of_stmt.tk);}
998 ;
999
1000// R434
1001sequence_stmt
1002@init {Token lbl = null;}
1003@after{checkForInclude();}
1004 : (label {lbl=$label.tk;})? T_SEQUENCE end_of_stmt
1005 {action.sequence_stmt(lbl, $T_SEQUENCE, $end_of_stmt.tk);}
1006 ;
1007
1008// R435 type_param_def_stmt inlined in type_param_or_comp_def_stmt_list
1009
1010// R436
1011// ERR_CHK 436 scalar_int_initialization_expr replaced by expr
1012// T_IDENT inlined for type_param_name
1013type_param_decl
1014@init{ boolean hasInit=false; }
1015 : T_IDENT ( T_EQUALS expr {hasInit=true;})?
1016 {action.type_param_decl($T_IDENT, hasInit);}
1017 ;
1018
1019type_param_decl_list
1020@init{int count=0;}
1021 : {action.type_param_decl_list__begin();}
1022 type_param_decl {count++;} ( T_COMMA type_param_decl {count++;} )*
1023 {action.type_param_decl_list(count);}
1024 ;
1025
1026/*
1027 * R437-F08 component-attr-spec
1028 * is access-spec
1029 * or ALLOCATABLE
1030 * or CODIMENSION lbracket coarray-spec rbracket // NEW_TO_2008
1031 * or CONTIGUOUS // NEW_TO_2008
1032 * or DIMENSION ( component-array-spec )
1033 * or POINTER
1034 */
1035
1036////////////
1037// R437-F08, R441-F03
1038//
1039// TODO it appears there is a bug in the standard for a parameterized type,
1040// it needs to accept KIND, LEN keywords, see NOTE 4.24 and 4.25
1041component_attr_spec
1042 : access_spec
1043 {action.component_attr_spec(null, IActionEnums.ComponentAttrSpec_access_spec);}
1044 | T_ALLOCATABLE
1045 {action.component_attr_spec($T_ALLOCATABLE, IActionEnums.ComponentAttrSpec_allocatable);}
1046 | T_CODIMENSION T_LBRACKET coarray_spec T_RBRACKET // NEW_TO_2008
1047 {action.component_attr_spec($T_CODIMENSION, IActionEnums.ComponentAttrSpec_codimension);}
1048 | T_CONTIGUOUS // NEW_TO_2008
1049 {action.component_attr_spec($T_CONTIGUOUS, IActionEnums.ComponentAttrSpec_contiguous);}
1050 | T_DIMENSION T_LPAREN component_array_spec T_RPAREN
1051 {action.component_attr_spec($T_DIMENSION, IActionEnums.ComponentAttrSpec_dimension);}
1052 | T_POINTER
1053 {action.component_attr_spec($T_POINTER, IActionEnums.ComponentAttrSpec_pointer);}
1054 | component_attr_spec_extension
1055 // are T_KIND and T_LEN correct?
1056// | T_KIND
1057// {action.component_attr_spec($T_KIND,
1058// IActionEnums.ComponentAttrSpec_kind);}
1059// | T_LEN
1060// {action.component_attr_spec($T_LEN,
1061// IActionEnums.ComponentAttrSpec_len);}
1062 ;
1063
1064// language extension point
1065component_attr_spec_extension : T_NO_LANGUAGE_EXTENSION ;
1066
1067component_attr_spec_list
1068@init{int count=1;}
1069 : {action.component_attr_spec_list__begin();}
1070 component_attr_spec ( T_COMMA component_attr_spec {count++;} )*
1071 {action.component_attr_spec_list(count);}
1072 ;
1073
1074// R437
1075// ADD isKind boolean.
1076type_param_attr_spec
1077 : T_IDENT /* { KIND | LEN } */
1078 { action.type_param_attr_spec($T_IDENT); }
1079 ;
1080
1081// R438 component_part inlined as ( component_def_stmt )* in R429
1082
1083// R439
1084component_def_stmt
1085@after{checkForInclude();}
1086 : data_component_def_stmt
1087 {action.component_def_stmt(IActionEnums.ComponentDefType_data);}
1088 | proc_component_def_stmt
1089 {action.component_def_stmt(IActionEnums.
1090 ComponentDefType_procedure);}
1091 ;
1092
1093
1094// R440
1095data_component_def_stmt
1096@init {Token lbl = null; boolean hasSpec=false; }
1097@after{checkForInclude();}
1098 : (label {lbl=$label.tk;})? declaration_type_spec
1099 ( ( T_COMMA component_attr_spec_list {hasSpec=true;})?
1100 T_COLON_COLON )? component_decl_list end_of_stmt
1101 {action.data_component_def_stmt(lbl, $end_of_stmt.tk, hasSpec);}
1102 ;
1103
1104
1105/*
1106 * R438-F08 component-decl
1107 * is component-name [ ( component-array-spec ) ]
1108 * [ lbracket coarray-spec rbracket ] // NEW_TO_2008
1109 * [ * char-length ] [ component-initialization ]
1110 */
1111
1112////////////
1113// R438-F08, R442-F03
1114//
1115// T_IDENT inlined as component_name
1116component_decl
1117@init {
1118 boolean hasComponentArraySpec = false;
1119 boolean hasCoarraySpec = false;
1120 boolean hasCharLength = false;
1121 boolean hasComponentInitialization = false;
1122}
1123 : T_IDENT (T_LPAREN component_array_spec T_RPAREN {hasComponentArraySpec=true;})?
1124 (T_LBRACKET coarray_spec T_RBRACKET {hasCoarraySpec=true;})?
1125 (T_ASTERISK char_length {hasCharLength=true;})?
1126 (component_initialization {hasComponentInitialization =true;})?
1127 {action.component_decl($T_IDENT, hasComponentArraySpec,
1128 hasCoarraySpec, hasCharLength,
1129 hasComponentInitialization);}
1130 ;
1131
1132component_decl_list
1133@init{int count=0;}
1134 : {action.component_decl_list__begin();}
1135 component_decl {count++;} ( T_COMMA component_decl {count++;} )*
1136 {action.component_decl_list(count);}
1137 ;
1138
1139// R443
1140component_array_spec
1141 : explicit_shape_spec_list
1142 {action.component_array_spec(true);}
1143 | deferred_shape_spec_list
1144 {action.component_array_spec(false);}
1145 ;
1146
1147// deferred_shape_spec replaced by T_COLON
1148deferred_shape_spec_list
1149@init{int count=0;}
1150 : {action.deferred_shape_spec_list__begin();}
1151 T_COLON {count++;} ( T_COMMA T_COLON {count++;} )*
1152 {action.deferred_shape_spec_list(count);}
1153 ;
1154
1155// R444
1156// R447-F2008 can also be => initial_data_target, see NOTE 4.40 in J3/07-007
1157// ERR_CHK 444 initialization_expr replaced by expr
1158component_initialization
1159@after {
1160 action.component_initialization();
1161}
1162 : T_EQUALS expr
1163 | T_EQ_GT null_init
1164 ;
1165
1166// R445
1167proc_component_def_stmt
1168@init {Token lbl = null; boolean hasInterface=false;}
1169@after{checkForInclude();}
1170 : (label {lbl=$label.tk;})? T_PROCEDURE T_LPAREN
1171 ( proc_interface {hasInterface=true;})? T_RPAREN T_COMMA
1172 proc_component_attr_spec_list T_COLON_COLON proc_decl_list
1173 end_of_stmt
1174 {action.proc_component_def_stmt(lbl, $T_PROCEDURE,
1175 $end_of_stmt.tk, hasInterface);}
1176 ;
1177
1178// R446
1179// T_IDENT inlined for arg_name
1180proc_component_attr_spec
1181@init{ Token id=null; }
1182 : T_POINTER
1183 {action.proc_component_attr_spec($T_POINTER, id,
1184 IActionEnums.
1185 ProcComponentAttrSpec_pointer);}
1186 | T_PASS ( T_LPAREN T_IDENT T_RPAREN {id=$T_IDENT;} )?
1187 {action.proc_component_attr_spec($T_PASS, id,
1188 IActionEnums.
1189 ProcComponentAttrSpec_pass);}
1190 | T_NOPASS
1191 {action.proc_component_attr_spec($T_NOPASS, id,
1192 IActionEnums.
1193 ProcComponentAttrSpec_nopass);}
1194 | access_spec
1195 {action.
1196 proc_component_attr_spec(null, id,
1197 IActionEnums.
1198 ProcComponentAttrSpec_access_spec);}
1199 ;
1200
1201proc_component_attr_spec_list
1202@init{int count=0;}
1203 : {action.proc_component_attr_spec_list__begin();}
1204 proc_component_attr_spec {count++;}
1205 ( T_COMMA proc_component_attr_spec {count++;})*
1206 {action.proc_component_attr_spec_list(count);}
1207 ;
1208
1209// R447
1210private_components_stmt
1211@init {Token lbl = null;}
1212@after{checkForInclude();}
1213 : (label {lbl=$label.tk;})? T_PRIVATE end_of_stmt
1214 {action.private_components_stmt(lbl, $T_PRIVATE, $end_of_stmt.tk);}
1215 ;
1216
1217// R448
1218type_bound_procedure_part
1219@init{int count=0; boolean hasBindingPrivateStmt = false;}
1220 : contains_stmt
1221 ( binding_private_stmt {hasBindingPrivateStmt=true;})?
1222 proc_binding_stmt ( proc_binding_stmt {count++;})*
1223 {action.type_bound_procedure_part(count,
1224 hasBindingPrivateStmt);}
1225 ;
1226
1227// R449
1228binding_private_stmt
1229@init {Token lbl = null;}
1230@after{checkForInclude();}
1231 : (label {lbl=$label.tk;})? T_PRIVATE end_of_stmt
1232 {action.binding_private_stmt(lbl, $T_PRIVATE, $end_of_stmt.tk);}
1233 ;
1234
1235// R450
1236proc_binding_stmt
1237@init {Token lbl = null;}
1238@after{checkForInclude();}
1239 : (label {lbl=$label.tk;})? specific_binding end_of_stmt
1240 {action.proc_binding_stmt(lbl,
1241 IActionEnums.BindingStatementType_specific, $end_of_stmt.tk);}
1242 | (label {lbl=$label.tk;})? generic_binding end_of_stmt
1243 {action.proc_binding_stmt(lbl,
1244 IActionEnums.BindingStatementType_generic, $end_of_stmt.tk);}
1245 | (label {lbl=$label.tk;})? final_binding end_of_stmt
1246 {action.proc_binding_stmt(lbl,
1247 IActionEnums.BindingStatementType_final, $end_of_stmt.tk);}
1248 ;
1249
1250// R451
1251// T_IDENT inlined for interface_name, binding_name and procedure_name
1252specific_binding
1253@init {
1254 Token interfaceName=null;
1255 Token bindingName=null;
1256 Token procedureName=null;
1257 boolean hasBindingAttrList=false;
1258}
1259 : T_PROCEDURE (T_LPAREN tmpId1=T_IDENT T_RPAREN {interfaceName=tmpId1;})?
1260 ( ( T_COMMA binding_attr_list {hasBindingAttrList=true;})?
1261 T_COLON_COLON )?
1262 tmpId2=T_IDENT {bindingName=tmpId2;}
1263 ( T_EQ_GT tmpId3=T_IDENT {procedureName=tmpId3;})?
1264 { action.specific_binding($T_PROCEDURE, interfaceName, bindingName,
1265 procedureName, hasBindingAttrList);}
1266 ;
1267
1268// R452
1269// generic_name_list substituted for binding_name_list
1270generic_binding
1271@init{boolean hasAccessSpec=false;}
1272 : T_GENERIC ( T_COMMA access_spec {hasAccessSpec=true;})? T_COLON_COLON
1273 generic_spec T_EQ_GT generic_name_list
1274 {action.generic_binding($T_GENERIC, hasAccessSpec);}
1275 ;
1276
1277// R453
1278// T_IDENT inlined for arg_name
1279binding_attr
1280@init{Token id = null;}
1281 : T_PASS ( T_LPAREN T_IDENT T_RPAREN {id=$T_IDENT;})?
1282 { action.binding_attr($T_PASS, IActionEnums.AttrSpec_PASS, id); }
1283 | T_NOPASS
1284 { action.binding_attr($T_NOPASS, IActionEnums.AttrSpec_NOPASS, id); }
1285 | T_NON_OVERRIDABLE
1286 { action.binding_attr($T_NON_OVERRIDABLE,
1287 IActionEnums.AttrSpec_NON_OVERRIDABLE, id); }
1288 | T_DEFERRED
1289 { action.binding_attr($T_DEFERRED, IActionEnums.AttrSpec_DEFERRED,
1290 id); }
1291 | access_spec
1292 { action.binding_attr(null, IActionEnums.AttrSpec_none, id); }
1293 ;
1294
1295binding_attr_list
1296@init{int count=0;}
1297 : {action.binding_attr_list__begin();}
1298 binding_attr {count++;} ( T_COMMA binding_attr {count++;} )*
1299 {action.binding_attr_list(count);}
1300 ;
1301
1302// R454
1303// generic_name_list substituted for final_subroutine_name_list
1304final_binding
1305 : T_FINAL ( T_COLON_COLON )? generic_name_list
1306 { action.final_binding($T_FINAL); }
1307 ;
1308
1309// R455
1310derived_type_spec
1311@init{boolean hasList = false;}
1312 : T_IDENT ( T_LPAREN type_param_spec_list {hasList=true;} T_RPAREN )?
1313 { action.derived_type_spec($T_IDENT, hasList); }
1314 ;
1315
1316// R456
1317type_param_spec
1318@init{ Token keyWord=null; }
1319 : ( keyword T_EQUALS {keyWord=$keyword.tk;})? type_param_value
1320 {action.type_param_spec(keyWord);}
1321 ;
1322
1323type_param_spec_list
1324@init{int count=0;}
1325 : {action.type_param_spec_list__begin();}
1326 type_param_spec {count++;}( T_COMMA type_param_spec {count++;})*
1327 {action.type_param_spec_list(count);}
1328 ;
1329
1330// R457
1331// inlined derived_type_spec (R662) to remove ambiguity using backtracking
1332// ERR_CHK R457
1333// If any of the type-param-specs in the list are an '*' or ':', the
1334// component-spec-list is required.
1335// the second alternative to the original rule for structure_constructor is
1336// a subset of the first alternative because component_spec_list is a
1337// subset of type_param_spec_list. by combining these two alternatives we can
1338// remove the backtracking on this rule.
1339structure_constructor
1340// options {backtrack=true;}
1341// : T_IDENT T_LPAREN type_param_spec_list T_RPAREN
1342// T_LPAREN
1343// ( component_spec_list )?
1344// T_RPAREN
1345// | T_IDENT
1346// T_LPAREN
1347// ( component_spec_list )?
1348// T_RPAREN
1349 : T_IDENT T_LPAREN type_param_spec_list T_RPAREN
1350 (T_LPAREN
1351 ( component_spec_list )?
1352 T_RPAREN)?
1353 { action.structure_constructor($T_IDENT); }
1354 ;
1355
1356// R458
1357component_spec
1358@init { Token keyWord = null; }
1359 : ( keyword T_EQUALS { keyWord=$keyword.tk; })? component_data_source
1360 { action.component_spec(keyWord); }
1361 ;
1362
1363component_spec_list
1364@init{int count=0;}
1365 : {action.component_spec_list__begin();}
1366 component_spec {count++;}( T_COMMA component_spec {count++;})*
1367 {action.component_spec_list(count);}
1368 ;
1369
1370// R459
1371// is (expr | data-target | proc-target)
1372// data_target isa expr so data_target deleted
1373// proc_target isa expr so proc_target deleted
1374component_data_source
1375 : expr
1376 { action.component_data_source(); }
1377 ;
1378
1379// R460
1380enum_def
1381@init{ int numEls=1; }
1382 : enum_def_stmt
1383 enumerator_def_stmt
1384 ( enumerator_def_stmt {numEls++;})*
1385 end_enum_stmt
1386 {action.enum_def(numEls);}
1387 ;
1388
1389// R461
1390enum_def_stmt
1391@init {Token lbl = null;}
1392@after{checkForInclude();}
1393 : (label {lbl=$label.tk;})? T_ENUM T_COMMA T_BIND T_LPAREN
1394 T_IDENT /* 'C' */ T_RPAREN end_of_stmt
1395 {action.enum_def_stmt(lbl, $T_ENUM, $T_BIND, $T_IDENT,
1396 $end_of_stmt.tk);}
1397 ;
1398
1399// R462
1400enumerator_def_stmt
1401@init {Token lbl = null;}
1402@after{checkForInclude();}
1403 : (label {lbl=$label.tk;})? T_ENUMERATOR ( T_COLON_COLON )?
1404 enumerator_list end_of_stmt
1405 {action.enumerator_def_stmt(lbl, $T_ENUMERATOR, $end_of_stmt.tk);}
1406 ;
1407
1408// R463
1409// ERR_CHK 463 scalar_int_initialization_expr replaced by expr
1410// ERR_CHK 463 named_constant replaced by T_IDENT
1411enumerator
1412@init{boolean hasExpr = false;}
1413 : T_IDENT ( T_EQUALS expr { hasExpr = true; })?
1414 { action.enumerator($T_IDENT, hasExpr); }
1415 ;
1416
1417enumerator_list
1418@init{int count=0;}
1419 : {action.enumerator_list__begin();}
1420 enumerator {count++;}( T_COMMA enumerator {count++;})*
1421 {action.enumerator_list(count);}
1422 ;
1423
1424// R464
1425end_enum_stmt
1426@init {Token lbl = null;}
1427@after{checkForInclude();}
1428 : (label {lbl=$label.tk;})? T_END T_ENUM end_of_stmt
1429 { action.end_enum_stmt(lbl, $T_END, $T_ENUM, $end_of_stmt.tk); }
1430 | (label {lbl=$label.tk;})? T_ENDENUM end_of_stmt
1431 { action.end_enum_stmt(lbl, $T_ENDENUM, null, $end_of_stmt.tk); }
1432 ;
1433
1434// R465
1435array_constructor
1436 : T_LPAREN T_SLASH ac_spec T_SLASH T_RPAREN
1437 { action.array_constructor(); }
1438 | T_LBRACKET ac_spec T_RBRACKET
1439 { action.array_constructor(); }
1440 ;
1441
1442// R466
1443// refactored to remove optional from lhs
1444ac_spec
1445options {backtrack=true;}
1446@after {
1447 action.ac_spec();
1448}
1449 : type_spec T_COLON_COLON (ac_value_list)?
1450 | ac_value_list
1451 ;
1452
1453// R467 left_square_bracket inlined as T_LBRACKET
1454
1455// R468 right_square_bracket inlined as T_RBRACKET
1456
1457// R469
1458ac_value
1459options {backtrack=true;}
1460@after {
1461 action.ac_value();
1462}
1463 : expr
1464 | ac_implied_do
1465 ;
1466
1467ac_value_list
1468@init{int count=0;}
1469 : {action.ac_value_list__begin();}
1470 ac_value {count++;}( T_COMMA ac_value {count++;})*
1471 {action.ac_value_list(count);}
1472 ;
1473
1474// R470
1475ac_implied_do
1476 : T_LPAREN ac_value_list T_COMMA ac_implied_do_control T_RPAREN
1477 {action.ac_implied_do();}
1478 ;
1479
1480// R471
1481// ERR_CHK 471a scalar_int_expr replaced by expr
1482// ERR_CHK 471b ac_do_variable replaced by do_variable
1483ac_implied_do_control
1484@init{boolean hasStride=false;}
1485 : do_variable T_EQUALS expr T_COMMA expr ( T_COMMA expr {hasStride=true;})?
1486 {action.ac_implied_do_control(hasStride);}
1487 ;
1488
1489// R472 inlined ac_do_variable as scalar_int_variable (and finally T_IDENT)
1490// in R471
1491// C493 (R472) ac-do-variable shall be a named variable
1492scalar_int_variable
1493 : variable
1494 { action.scalar_int_variable(); }
1495 ;
1496
1497
1498/**
1499 * Section/Clause 5: Attribute declarations and specifications
1500 */
1501
1502
1503// R501
1504type_declaration_stmt
1505@init {Token lbl = null; int numAttrSpecs = 0;}
1506@after{checkForInclude();}
1507 : (label {lbl=$label.tk;})? declaration_type_spec
1508 ( (T_COMMA attr_spec {numAttrSpecs += 1;})* T_COLON_COLON )?
1509 entity_decl_list end_of_stmt
1510 { action.type_declaration_stmt(lbl, numAttrSpecs, $end_of_stmt.tk); }
1511 ;
1512
1513// R502
1514declaration_type_spec
1515 : intrinsic_type_spec
1516 { action.declaration_type_spec(null,
1517 IActionEnums.DeclarationTypeSpec_INTRINSIC); }
1518 | T_TYPE T_LPAREN derived_type_spec T_RPAREN
1519 { action.declaration_type_spec($T_TYPE,
1520 IActionEnums.DeclarationTypeSpec_TYPE); }
1521 | T_CLASS T_LPAREN derived_type_spec T_RPAREN
1522 { action.declaration_type_spec($T_CLASS,
1523 IActionEnums.DeclarationTypeSpec_CLASS); }
1524 | T_CLASS T_LPAREN T_ASTERISK T_RPAREN
1525 { action.declaration_type_spec($T_CLASS,
1526 IActionEnums.DeclarationTypeSpec_unlimited); }
1527 ;
1528
1529
1530/*
1531 * R502-F08 attr-spec
1532 * is access-spec
1533 * or ALLOCATABLE
1534 * or ASYNCHRONOUS
1535 * or CODIMENSION lbracket coarray-spec rbracket // NEW_TO_2008
1536 * or CONTIGUOUS // NEW_TO_2008
1537 * or DIMENSION ( array-spec )
1538 * or EXTERNAL
1539 * or INTENT ( intent-spec )
1540 * or INTRINSIC
1541 * or language-binding-spec
1542 * or OPTIONAL
1543 * or PARAMETER
1544 * or POINTER
1545 * or PROTECTED
1546 * or SAVE
1547 * or TARGET
1548 * or VALUE
1549 * or VOLATILE
1550 */
1551
1552////////////
1553// R502-F08, R503-F03
1554//
1555attr_spec
1556 : access_spec
1557 {action.attr_spec(null, IActionEnums.AttrSpec_access);}
1558 | T_ALLOCATABLE
1559 {action.attr_spec($T_ALLOCATABLE, IActionEnums.AttrSpec_ALLOCATABLE);}
1560 | T_ASYNCHRONOUS
1561 {action.attr_spec($T_ASYNCHRONOUS, IActionEnums.AttrSpec_ASYNCHRONOUS);}
1562 | T_CODIMENSION T_LBRACKET coarray_spec T_RBRACKET // NEW_TO_2008
1563 {action.attr_spec($T_CODIMENSION, IActionEnums.AttrSpec_CODIMENSION);}
1564 | T_CONTIGUOUS // NEW_TO_2008
1565 {action.attr_spec($T_CONTIGUOUS, IActionEnums.AttrSpec_CONTIGUOUS);}
1566 | T_DIMENSION T_LPAREN array_spec T_RPAREN
1567 {action.attr_spec($T_DIMENSION, IActionEnums.AttrSpec_DIMENSION);}
1568 | T_EXTERNAL
1569 {action.attr_spec($T_EXTERNAL, IActionEnums.AttrSpec_EXTERNAL);}
1570 | T_INTENT T_LPAREN intent_spec T_RPAREN
1571 {action.attr_spec($T_INTENT, IActionEnums.AttrSpec_INTENT);}
1572 | T_INTRINSIC
1573 {action.attr_spec($T_INTRINSIC, IActionEnums.AttrSpec_INTRINSIC);}
1574 | language_binding_spec
1575 {action.attr_spec(null, IActionEnums.AttrSpec_language_binding);}
1576 | T_OPTIONAL
1577 {action.attr_spec($T_OPTIONAL, IActionEnums.AttrSpec_OPTIONAL);}
1578 | T_PARAMETER
1579 {action.attr_spec($T_PARAMETER, IActionEnums.AttrSpec_PARAMETER);}
1580 | T_POINTER
1581 {action.attr_spec($T_POINTER, IActionEnums.AttrSpec_POINTER);}
1582 | T_PROTECTED
1583 {action.attr_spec($T_PROTECTED, IActionEnums.AttrSpec_PROTECTED);}
1584 | T_SAVE
1585 {action.attr_spec($T_SAVE, IActionEnums.AttrSpec_SAVE);}
1586 | T_TARGET
1587 {action.attr_spec($T_TARGET, IActionEnums.AttrSpec_TARGET);}
1588 | T_VALUE
1589 {action.attr_spec($T_VALUE, IActionEnums.AttrSpec_VALUE);}
1590 | T_VOLATILE
1591 {action.attr_spec($T_VOLATILE, IActionEnums.AttrSpec_VOLATILE);}
1592// TODO are T_KIND and T_LEN correct?
1593 | T_KIND
1594 {action.attr_spec($T_KIND, IActionEnums.AttrSpec_KIND);}
1595 | T_LEN
1596 {action.attr_spec($T_LEN, IActionEnums.AttrSpec_LEN);}
1597 | attr_spec_extension
1598 ;
1599
1600// language extension point
1601attr_spec_extension : T_NO_LANGUAGE_EXTENSION ;
1602
1603
1604/*
1605 * R503-F08 entity-decl
1606 * is object-name [( array-spec )]
1607 * [ lracket coarray-spec rbracket ]
1608 * [ * char-length ] [ initialization ]
1609 * or function-name [ * char-length ]
1610 */
1611
1612////////////
1613// R503-F08, R504-F03
1614//
1615// T_IDENT inlined for object_name and function_name
1616// T_IDENT ( T_ASTERISK char_length )? takes character and function
1617// TODO Pass more info to action....
1618entity_decl
1619@init{
1620 boolean hasArraySpec=false;
1621 boolean hasCoarraySpec=false;
1622 boolean hasCharLength=false;
1623 boolean hasInitialization=false;
1624}
1625 : T_IDENT ( T_LPAREN array_spec T_RPAREN {hasArraySpec=true;} )?
1626 ( T_LBRACKET coarray_spec T_RBRACKET {hasCoarraySpec=true;} )?
1627 ( T_ASTERISK char_length {hasCharLength=true;} )?
1628 ( initialization {hasInitialization=true;} )?
1629 {
1630 action.entity_decl($T_IDENT, hasArraySpec,
1631 hasCoarraySpec, hasCharLength, hasInitialization);
1632 }
1633 ;
1634
1635entity_decl_list
1636@init{int count = 0;}
1637 : {action.entity_decl_list__begin();}
1638 entity_decl {count += 1;} ( T_COMMA entity_decl {count += 1;} )*
1639 {action.entity_decl_list(count);}
1640 ;
1641
1642/*
1643 * R505-F03 object-name
1644 * is name
1645 */
1646
1647////////////
1648// R505-F03, R504-F08
1649//
1650object_name returns [Token tk]
1651 : T_IDENT {tk = $T_IDENT;}
1652 ;
1653
1654// R506
1655// ERR_CHK 506 initialization_expr replaced by expr
1656initialization
1657 : T_EQUALS expr { action.initialization(true, false); }
1658 | T_EQ_GT null_init { action.initialization(false, true); }
1659 ;
1660
1661// R507
1662// C506 The function-reference shall be a reference to the NULL intrinsic
1663// function with no arguments.
1664null_init
1665 : T_IDENT /* 'NULL' */ T_LPAREN T_RPAREN
1666 { action.null_init($T_IDENT); }
1667 ;
1668
1669/*
1670 * R509-F08 coarray-spec
1671 * is deferred-coshape-spec-list
1672 * or explicit-coshape-spec
1673 */
1674
1675////////////
1676// R509-F08
1677//
1678// deferred-coshape-spec-list and explicit-coshape-spec rules are ambiguous so
1679// we use the same method as for array-spec. Enough information is provided so
1680// that the coarray_spec can be figured out by the actions. Note, that this
1681// means the parser can't determine all incorrect syntax as many rules are
1682// combined into one. It is the action's responsiblity to enforce correct syntax.
1683//
1684coarray_spec
1685@init{int count=0;}
1686 : array_spec_element {count++;} (T_COMMA array_spec_element {count++;})*
1687 {action.coarray_spec(count);}
1688 ;
1689
1690// R508
1691access_spec
1692 : T_PUBLIC
1693 {action.access_spec($T_PUBLIC, IActionEnums.AttrSpec_PUBLIC);}
1694 | T_PRIVATE
1695 {action.access_spec($T_PRIVATE, IActionEnums.AttrSpec_PRIVATE);}
1696 ;
1697
1698// R509
1699// ERR_CHK 509 scalar_char_initialization_expr replaced by expr
1700language_binding_spec
1701@init{boolean hasName = false;}
1702 : T_BIND T_LPAREN T_IDENT /* 'C' */
1703 (T_COMMA name T_EQUALS expr {hasName=true;})? T_RPAREN
1704 { action.language_binding_spec($T_BIND, $T_IDENT, hasName); }
1705 ;
1706
1707// R510
1708array_spec
1709@init{int count=0;}
1710 : array_spec_element {count++;}
1711 (T_COMMA array_spec_element {count++;})*
1712 {action.array_spec(count);}
1713 ;
1714
1715// Array specifications can consist of these beasts. Note that we can't
1716// mix/match arbitrarily, so we have to check validity in actions.
1717// Types: 0 expr (e.g. 3 or m+1)
1718// 1 expr: (e.g. 3:)
1719// 2 expr:expr (e.g. 3:5 or 7:(m+1))
1720// 3 expr:* (e.g. 3:* end of assumed size)
1721// 4 * (end of assumed size)
1722// 5 : (could be part of assumed or deferred shape)
1723array_spec_element
1724@init{int type=IActionEnums.ArraySpecElement_expr;}
1725 : expr ( T_COLON {type=IActionEnums.ArraySpecElement_expr_colon;}
1726 ( expr {type=IActionEnums.ArraySpecElement_expr_colon_expr;}
1727 | T_ASTERISK
1728 {type=IActionEnums.ArraySpecElement_expr_colon_asterisk;} )?
1729 )?
1730 { action.array_spec_element(type); }
1731 | T_ASTERISK
1732 { action.array_spec_element(IActionEnums.
1733 ArraySpecElement_asterisk); }
1734 | T_COLON
1735 { action.array_spec_element(IActionEnums.ArraySpecElement_colon); }
1736 ;
1737
1738// R511
1739// refactored to remove conditional from lhs and inlined lower_bound and
1740// upper_bound
1741explicit_shape_spec
1742@init{boolean hasUpperBound=false;}
1743 : expr (T_COLON expr {hasUpperBound=true;})?
1744 {action.explicit_shape_spec(hasUpperBound);}
1745 ;
1746
1747explicit_shape_spec_list
1748@init{ int count=0;}
1749 : {action.explicit_shape_spec_list__begin();}
1750 explicit_shape_spec {count++;}
1751 ( T_COMMA explicit_shape_spec {count++;})*
1752 {action.explicit_shape_spec_list(count);}
1753 ;
1754
1755// R512 lower_bound was specification_expr inlined as expr
1756
1757// R513 upper_bound was specification_expr inlined as expr
1758
1759// R514 assumed_shape_spec was ( lower_bound )? T_COLON not used in R510
1760// array_spec
1761
1762// R515 deferred_shape_spec inlined as T_COLON in deferred_shape_spec_list
1763
1764// R516 assumed_size_spec absorbed into array_spec.
1765
1766// R517
1767intent_spec
1768 : T_IN { action.intent_spec($T_IN, null,
1769 IActionEnums.IntentSpec_IN); }
1770 | T_OUT { action.intent_spec($T_OUT, null,
1771 IActionEnums.IntentSpec_OUT); }
1772 | T_IN T_OUT { action.intent_spec($T_IN, $T_OUT,
1773 IActionEnums.IntentSpec_INOUT); }
1774 | T_INOUT { action.intent_spec($T_INOUT, null,
1775 IActionEnums.IntentSpec_INOUT); }
1776 ;
1777
1778// R518
1779access_stmt
1780@init {Token lbl = null;boolean hasList=false;}
1781@after{checkForInclude();}
1782 : (label {lbl=$label.tk;})? access_spec ( ( T_COLON_COLON )?
1783 access_id_list {hasList=true;})? end_of_stmt
1784 { action.access_stmt(lbl,$end_of_stmt.tk,hasList); }
1785 ;
1786
1787// R519
1788// T_IDENT inlined for use_name
1789// generic_spec can be T_IDENT so T_IDENT deleted
1790// TODO - can this only be T_IDENTS? generic_spec is more than that..
1791access_id
1792 : generic_spec
1793 { action.access_id(); }
1794 ;
1795
1796access_id_list
1797@init{ int count=0;}
1798 : {action.access_id_list__begin();}
1799 access_id {count++;} ( T_COMMA access_id {count++;} )*
1800 {action.access_id_list(count);}
1801 ;
1802
1803////////////
1804// R520-F03, R526-F08
1805// - form of F08 used with allocatable_decl_list
1806//
1807allocatable_stmt
1808@init {Token lbl = null;}
1809@after{checkForInclude();}
1810 : (label {lbl=$label.tk;})?
1811 T_ALLOCATABLE ( T_COLON_COLON )? allocatable_decl_list end_of_stmt
1812 {action.allocatable_stmt(lbl, $T_ALLOCATABLE, $end_of_stmt.tk);}
1813 ;
1814
1815/*
1816 * R527-F08 allocatable-decl
1817 * is object-name [ ( array-spec ) ] [ lbracket ( coarray-spec ) ]
1818 */
1819
1820////////////
1821// R527-F08
1822//
1823allocatable_decl
1824@init{Token objName=null; boolean hasArraySpec=false; boolean hasCoarraySpec=false;}
1825 : object_name {objName=$object_name.tk;}
1826 ( T_LPAREN array_spec T_RPAREN {hasArraySpec=true;} )?
1827 ( T_LBRACKET coarray_spec T_RBRACKET {hasCoarraySpec=true;} )?
1828 {action.allocatable_decl(objName, hasArraySpec, hasCoarraySpec);}
1829 ;
1830
1831allocatable_decl_list
1832@init{int count=0;}
1833 : {action.allocatable_decl_list__begin();}
1834 allocatable_decl {count++;} ( T_COMMA allocatable_decl {count++;} )*
1835 {action.allocatable_decl_list(count);}
1836 ;
1837
1838// R521
1839// generic_name_list substituted for object_name_list
1840asynchronous_stmt
1841@init {Token lbl = null;}
1842@after{checkForInclude();}
1843 : (label {lbl=$label.tk;})? T_ASYNCHRONOUS ( T_COLON_COLON )?
1844 generic_name_list end_of_stmt
1845 {action.asynchronous_stmt(lbl,$T_ASYNCHRONOUS,$end_of_stmt.tk);}
1846 ;
1847
1848// R522
1849bind_stmt
1850@init {Token lbl = null;}
1851@after{checkForInclude();}
1852 : (label {lbl=$label.tk;})? language_binding_spec
1853 ( T_COLON_COLON )? bind_entity_list end_of_stmt
1854 { action.bind_stmt(lbl, $end_of_stmt.tk); }
1855 ;
1856
1857// R523
1858// T_IDENT inlined for entity_name and common_block_name
1859bind_entity
1860 : T_IDENT
1861 { action.bind_entity($T_IDENT, false); }// isCommonBlockName=false
1862 | T_SLASH T_IDENT T_SLASH
1863 { action.bind_entity($T_IDENT, true); }// isCommonBlockname=true
1864 ;
1865
1866bind_entity_list
1867@init{ int count=0;}
1868 : {action.bind_entity_list__begin();}
1869 bind_entity {count++;} ( T_COMMA bind_entity {count++;} )*
1870 {action.bind_entity_list(count);}
1871 ;
1872
1873// R524
1874data_stmt
1875@init {Token lbl = null; int count=1;}
1876@after{checkForInclude();}
1877 : (label {lbl=$label.tk;})? T_DATA data_stmt_set ( ( T_COMMA )?
1878 data_stmt_set {count++;})* end_of_stmt
1879 { action.data_stmt(lbl, $T_DATA, $end_of_stmt.tk, count); }
1880 ;
1881
1882// R525
1883data_stmt_set
1884 : data_stmt_object_list
1885 T_SLASH
1886 data_stmt_value_list
1887 T_SLASH
1888 { action.data_stmt_set(); }
1889 ;
1890
1891// R526
1892data_stmt_object
1893@after {
1894 action.data_stmt_object();
1895}
1896 : variable
1897 | data_implied_do
1898 ;
1899
1900data_stmt_object_list
1901@init{ int count=0;}
1902 : {action.data_stmt_object_list__begin();}
1903 data_stmt_object {count++;} ( T_COMMA data_stmt_object {count++;} )*
1904 {action.data_stmt_object_list(count);}
1905 ;
1906
1907
1908// R527
1909// ERR_CHK 527 scalar_int_expr replaced by expr
1910// data_i_do_variable replaced by T_IDENT
1911data_implied_do
1912@init {
1913 boolean hasThirdExpr = false;
1914}
1915 : T_LPAREN data_i_do_object_list T_COMMA T_IDENT T_EQUALS
1916 expr T_COMMA expr ( T_COMMA expr { hasThirdExpr = true; })? T_RPAREN
1917 { action.data_implied_do($T_IDENT, hasThirdExpr); }
1918 ;
1919
1920// R528
1921// data_ref inlined for scalar_structure_component and array_element
1922data_i_do_object
1923@after {
1924 action.data_i_do_object();
1925}
1926 : data_ref
1927 | data_implied_do
1928 ;
1929
1930data_i_do_object_list
1931@init{ int count=0;}
1932 : {action.data_i_do_object_list__begin();}
1933 data_i_do_object {count++;} ( T_COMMA data_i_do_object {count++;} )*
1934 {action.data_i_do_object_list(count);}
1935 ;
1936
1937// R529 data_i_do_variable was scalar_int_variable inlined as T_IDENT
1938// C556 (R529) The data-i-do-variable shall be a named variable.
1939
1940// R530
1941// ERR_CHK R530 designator is scalar-constant or integer constant when
1942// followed by '*'
1943// data_stmt_repeat inlined from R531
1944// structure_constructure covers null_init if 'NULL()' so null_init deleted
1945// TODO - check for other cases of signed_real_literal_constant and
1946// real_literal_constant problems
1947data_stmt_value
1948options {backtrack=true; k=3;}
1949@init {Token ast = null;}
1950@after{action.data_stmt_value(ast);}
1951 : designator (T_ASTERISK data_stmt_constant {ast=$T_ASTERISK;})?
1952 | int_literal_constant (T_ASTERISK data_stmt_constant {ast=$T_ASTERISK;})?
1953 | signed_real_literal_constant
1954 | signed_int_literal_constant
1955 | complex_literal_constant
1956 | logical_literal_constant
1957 | char_literal_constant
1958 | boz_literal_constant
1959 | structure_constructor // is null_init if 'NULL()'
1960 | hollerith_literal_constant // deleted in F77
1961 ;
1962
1963data_stmt_value_list
1964@init{ int count=0;}
1965 : {action.data_stmt_value_list__begin();}
1966 data_stmt_value {count++;} ( T_COMMA data_stmt_value {count++;} )*
1967 {action.data_stmt_value_list(count);}
1968 ;
1969
1970// R531 data_stmt_repeat inlined as (int_literal_constant | designator) in R530
1971// ERRCHK 531 int_constant shall be a scalar_int_constant
1972// scalar_int_constant replaced by int_constant replaced by
1973// int_literal_constant as T_IDENT covered by designator
1974// scalar_int_constant_subobject replaced by designator
1975
1976scalar_int_constant
1977 : int_constant
1978 { action.scalar_int_constant(); }
1979 ;
1980
1981// R532
1982// scalar_constant_subobject replaced by designator
1983// scalar_constant replaced by literal_constant as designator can be T_IDENT
1984// then literal_constant inlined (except for signed portion)
1985// structure_constructure covers null_init if 'NULL()' so null_init deleted
1986// The lookahead in the alternative for signed_real_literal_constant is
1987// necessary because ANTLR won't look far enough ahead by itself and when it
1988// sees a T_DIGIT_STRING, it tries the signed_int_literal_constant. this isn't
1989// correct since the new version of the real_literal_constants can start with
1990// a T_DIGIT_STRING.
1991data_stmt_constant
1992options {backtrack=true; k=3;}
1993@after {
1994 action.data_stmt_constant();
1995}
1996 : designator
1997 | signed_int_literal_constant
1998 | signed_real_literal_constant
1999 | complex_literal_constant
2000 | logical_literal_constant
2001 | char_literal_constant
2002 | boz_literal_constant
2003 | structure_constructor // is null_init if 'NULL()'
2004 ;
2005
2006
2007/*
2008 * R531-F08 codimension-stmt
2009 * is CODIMENSION [ :: ] codimension-decl-list
2010 */
2011
2012////////////
2013// R531-F08
2014//
2015codimension_stmt
2016@init {Token lbl = null;}
2017@after{checkForInclude();}
2018 : (label {lbl=$label.tk;})?
2019 T_CODIMENSION ( T_COLON_COLON )? codimension_decl_list end_of_stmt
2020 { action.codimension_stmt(lbl, $T_CODIMENSION, $end_of_stmt.tk); }
2021 ;
2022
2023/*
2024 * R532-08 codimension-decl
2025 * is coarray-name lbracket coarray-spec rbracket
2026 */
2027
2028////////////
2029// R532-F08
2030//
2031codimension_decl
2032 : T_IDENT T_LBRACKET coarray_spec T_RBRACKET
2033 {action.codimension_decl($T_IDENT, $T_LBRACKET, $T_RBRACKET);}
2034 ;
2035
2036codimension_decl_list
2037@init{int count=0;}
2038 : {action.codimension_decl_list__begin();}
2039 codimension_decl {count++;} ( T_COMMA codimension_decl {count++;} )*
2040 {action.codimension_decl_list(count);}
2041 ;
2042
2043// R533 int_constant_subobject was constant_subobject inlined as designator
2044// in R531
2045
2046// R534 constant_subobject inlined as designator in R533
2047// C566 (R534) constant-subobject shall be a subobject of a constant.
2048
2049// R535, R543-F2008
2050// array_name replaced by T_IDENT
2051dimension_stmt
2052@init {Token lbl=null; int count=1;}
2053@after{checkForInclude();}
2054 : (label {lbl=$label.tk;})? T_DIMENSION ( T_COLON_COLON )?
2055 dimension_decl ( T_COMMA dimension_decl {count++;})* end_of_stmt
2056 { action.dimension_stmt(lbl, $T_DIMENSION, $end_of_stmt.tk, count); }
2057 ;
2058
2059// R535-subrule
2060dimension_decl
2061 : T_IDENT T_LPAREN array_spec T_RPAREN
2062 {action.dimension_decl($T_IDENT);}
2063 ;
2064
2065// R536
2066// generic_name_list substituted for dummy_arg_name_list
2067intent_stmt
2068@init {Token lbl = null;}
2069@after{checkForInclude();}
2070 : (label {lbl=$label.tk;})? T_INTENT T_LPAREN intent_spec T_RPAREN
2071 ( T_COLON_COLON )? generic_name_list end_of_stmt
2072 {action.intent_stmt(lbl,$T_INTENT,$end_of_stmt.tk);}
2073 ;
2074
2075// R537
2076// generic_name_list substituted for dummy_arg_name_list
2077optional_stmt
2078@init {Token lbl = null;}
2079@after{checkForInclude();}
2080 : (label {lbl=$label.tk;})? T_OPTIONAL ( T_COLON_COLON )?
2081 generic_name_list end_of_stmt
2082 { action.optional_stmt(lbl, $T_OPTIONAL, $end_of_stmt.tk); }
2083
2084 ;
2085
2086// R538
2087parameter_stmt
2088@init {Token lbl = null;}
2089@after{checkForInclude();}
2090 : (label {lbl=$label.tk;})? T_PARAMETER T_LPAREN
2091 named_constant_def_list T_RPAREN end_of_stmt
2092 {action.parameter_stmt(lbl,$T_PARAMETER,$end_of_stmt.tk);}
2093 ;
2094
2095named_constant_def_list
2096@init{ int count=0;}
2097 : {action.named_constant_def_list__begin();}
2098 named_constant_def {count++;}
2099 ( T_COMMA named_constant_def {count++;} )*
2100 {action.named_constant_def_list(count);}
2101 ;
2102
2103// R539
2104// ERR_CHK 539 initialization_expr replaced by expr
2105// ERR_CHK 539 named_constant replaced by T_IDENT
2106named_constant_def
2107 : T_IDENT T_EQUALS expr
2108 {action.named_constant_def($T_IDENT);}
2109 ;
2110
2111/*
2112 * R550-F08
2113 * is POINTER [ :: ] pointer-decl-list
2114 */
2115
2116////////////
2117// R550-F08, R540-F03
2118//
2119// Cray pointer extension added 11/17/2010
2120//
2121pointer_stmt
2122@init {Token lbl=null; boolean isCrayPointer=false;}
2123@after{checkForInclude();}
2124 : (label {lbl=$label.tk;})? T_POINTER
2125 (
2126 cray_pointer_assoc_list {isCrayPointer = true;}
2127 |
2128 ( ( T_COLON_COLON )? pointer_decl_list )
2129 ) end_of_stmt
2130 {
2131 if (isCrayPointer) {
2132 action.cray_pointer_stmt(lbl,$T_POINTER,$end_of_stmt.tk);
2133 } else {
2134 action.pointer_stmt(lbl,$T_POINTER,$end_of_stmt.tk);
2135 }
2136 }
2137 ;
2138
2139pointer_decl_list
2140@init{int count=0;}
2141 : {action.pointer_decl_list__begin();}
2142 pointer_decl {count++;} ( T_COMMA pointer_decl {count++;} )*
2143 {action.pointer_decl_list(count);}
2144 ;
2145
2146/*
2147 * R551-F08
2148 * is object-name [ ( deferred-shape-spec-list ) ]
2149 * or proc-entity-name
2150 */
2151
2152////////////
2153// R551-F08, R541-F03
2154//
2155// T_IDENT inlined as object_name and proc_entity_name (removing second alt)
2156pointer_decl
2157@init{boolean hasSpecList=false;}
2158 : T_IDENT ( T_LPAREN deferred_shape_spec_list T_RPAREN
2159 {hasSpecList=true;})?
2160 {action.pointer_decl($T_IDENT,hasSpecList);}
2161 ;
2162
2163cray_pointer_assoc_list
2164@init{int count=0;}
2165 : {action.cray_pointer_assoc_list__begin();}
2166 cray_pointer_assoc {count++;} ( T_COMMA cray_pointer_assoc {count++;} )*
2167 {action.cray_pointer_assoc_list(count);}
2168 ;
2169
2170cray_pointer_assoc
2171 : T_LPAREN pointer=T_IDENT T_COMMA pointee=T_IDENT T_RPAREN
2172 {action.cray_pointer_assoc(pointer, pointee);}
2173 ;
2174
2175// R542
2176// generic_name_list substituted for entity_name_list
2177protected_stmt
2178@init {Token lbl = null;}
2179@after{checkForInclude();}
2180 : (label {lbl=$label.tk;})? T_PROTECTED ( T_COLON_COLON )?
2181 generic_name_list end_of_stmt
2182 {action.protected_stmt(lbl,$T_PROTECTED,$end_of_stmt.tk);}
2183 ;
2184
2185// R543
2186save_stmt
2187@init {Token lbl = null; boolean hasSavedEntityList=false;}
2188@after{checkForInclude();}
2189 : (label {lbl=$label.tk;})? T_SAVE ( ( T_COLON_COLON )?
2190 saved_entity_list {hasSavedEntityList=true;})? end_of_stmt
2191 {action.save_stmt(lbl,$T_SAVE,$end_of_stmt.tk,hasSavedEntityList);}
2192 ;
2193
2194// R544
2195// T_IDENT inlined for object_name, proc_pointer_name (removing second alt),
2196// and common_block_name
2197saved_entity
2198 : id=T_IDENT
2199 {action.saved_entity(id, false);}
2200 | T_SLASH id=T_IDENT T_SLASH
2201 {action.saved_entity(id, true);} // is common block name
2202 ;
2203
2204saved_entity_list
2205@init{ int count=0;}
2206 : {action.saved_entity_list__begin();}
2207 saved_entity {count++;} ( T_COMMA saved_entity {count++;} )*
2208 {action.saved_entity_list(count);}
2209 ;
2210
2211
2212// R545 proc_pointer_name was name inlined as T_IDENT
2213
2214// R546, R555-F08
2215// T_IDENT inlined for object_name
2216target_stmt
2217@init {Token lbl = null;int count=1;}
2218@after{checkForInclude();}
2219 : (label {lbl=$label.tk;})?
2220 T_TARGET ( T_COLON_COLON )? target_decl_list end_of_stmt
2221 {action.target_stmt(lbl,$T_TARGET,$end_of_stmt.tk);}
2222 ;
2223
2224/*
2225 * R557-F08 target-decl
2226 * is object-name [ ( array-spec ) ]
2227 * [ lbracket coarray-spec rbracket ]
2228 */
2229
2230////////////
2231// R557-F08
2232//
2233target_decl
2234@init{boolean hasArraySpec=false; boolean hasCoarraySpec=false;}
2235 : T_IDENT (T_LPAREN array_spec T_RPAREN {hasArraySpec=true;} )?
2236 (T_LBRACKET coarray_spec T_RBRACKET {hasCoarraySpec=true;} )?
2237 {action.target_decl($T_IDENT,hasArraySpec,hasCoarraySpec);}
2238 ;
2239
2240// R557-F08
2241target_decl_list
2242@init{ int count=0;}
2243 : {action.target_decl_list__begin();}
2244 target_decl {count++;} ( T_COMMA target_decl {count++;} )*
2245 {action.target_decl_list(count);}
2246 ;
2247
2248// R547
2249// generic_name_list substituted for dummy_arg_name_list
2250value_stmt
2251@init {Token lbl = null;}
2252@after{checkForInclude();}
2253 : (label {lbl=$label.tk;})? T_VALUE ( T_COLON_COLON )?
2254 generic_name_list end_of_stmt
2255 {action.value_stmt(lbl,$T_VALUE,$end_of_stmt.tk);}
2256 ;
2257
2258// R548
2259// generic_name_list substituted for object_name_list
2260volatile_stmt
2261@init {Token lbl = null;}
2262@after{checkForInclude();}
2263 : (label {lbl=$label.tk;})? T_VOLATILE ( T_COLON_COLON )?
2264 generic_name_list end_of_stmt
2265 {action.volatile_stmt(lbl,$T_VOLATILE,$end_of_stmt.tk);}
2266 ;
2267
2268// R549
2269implicit_stmt
2270@init {Token lbl = null;}
2271@after{checkForInclude();}
2272 : (label {lbl=$label.tk;})? T_IMPLICIT implicit_spec_list end_of_stmt
2273 {action.implicit_stmt(lbl, $T_IMPLICIT, null, $end_of_stmt.tk,
2274 true);} // hasImplicitSpecList=true
2275 | (label {lbl=$label.tk;})? T_IMPLICIT T_NONE end_of_stmt
2276 {action.implicit_stmt(lbl, $T_IMPLICIT, $T_NONE, $end_of_stmt.tk,
2277 false);} // hasImplicitSpecList=false
2278 ;
2279
2280// R550
2281implicit_spec
2282 : declaration_type_spec T_LPAREN letter_spec_list T_RPAREN
2283 { action.implicit_spec(); }
2284 ;
2285
2286implicit_spec_list
2287@init{ int count=0;}
2288 : {action.implicit_spec_list__begin();}
2289 implicit_spec {count++;} ( T_COMMA implicit_spec {count++;} )*
2290 {action.implicit_spec_list(count);}
2291 ;
2292
2293
2294// R551
2295// TODO: here, we'll accept a T_IDENT, and then we'll have to do error
2296// checking on it.
2297letter_spec
2298 : id1=T_IDENT ( T_MINUS id2=T_IDENT )?
2299 { action.letter_spec(id1, id2); }
2300 ;
2301
2302letter_spec_list
2303@init{ int count=0;}
2304 : {action.letter_spec_list__begin();}
2305 letter_spec {count++;} ( T_COMMA letter_spec {count++;} )*
2306 {action.letter_spec_list(count);}
2307 ;
2308
2309// R552
2310// T_IDENT inlined for namelist_group_name
2311namelist_stmt
2312@init {Token lbl = null;int count =1;}
2313@after{checkForInclude();}
2314 : (label {lbl=$label.tk;})? T_NAMELIST T_SLASH nlName=T_IDENT T_SLASH
2315 {action.namelist_group_name(nlName);}
2316 namelist_group_object_list
2317 ( ( T_COMMA )? T_SLASH nlName=T_IDENT T_SLASH
2318 {action.namelist_group_name(nlName);}
2319 namelist_group_object_list {count++;})* end_of_stmt
2320 {action.namelist_stmt(lbl,$T_NAMELIST,$end_of_stmt.tk,count);}
2321 ;
2322
2323// R553 namelist_group_object was variable_name inlined as T_IDENT
2324
2325// T_IDENT inlined for namelist_group_object
2326namelist_group_object_list
2327@init{ int count=0;}
2328 : {action.namelist_group_object_list__begin();}
2329 goName=T_IDENT {action.namelist_group_object(goName); count++;}
2330 ( T_COMMA goName=T_IDENT
2331 {action.namelist_group_object(goName); count++;} )*
2332 {action.namelist_group_object_list(count);}
2333 ;
2334
2335// R554
2336equivalence_stmt
2337@init {Token lbl = null;}
2338@after{checkForInclude();}
2339 : (label {lbl=$label.tk;})? T_EQUIVALENCE equivalence_set_list
2340 end_of_stmt
2341 {action.equivalence_stmt(lbl, $T_EQUIVALENCE, $end_of_stmt.tk);}
2342 ;
2343
2344// R555
2345equivalence_set
2346 : T_LPAREN equivalence_object T_COMMA equivalence_object_list T_RPAREN
2347 { action.equivalence_set(); }
2348 ;
2349
2350
2351equivalence_set_list
2352@init{ int count=0;}
2353 : {action.equivalence_set_list__begin();}
2354 equivalence_set {count++;} ( T_COMMA equivalence_set {count++;} )*
2355 {action.equivalence_set_list(count);}
2356 ;
2357
2358// R556
2359// T_IDENT inlined for variable_name
2360// data_ref inlined for array_element
2361// data_ref isa T_IDENT so T_IDENT deleted (removing first alt)
2362// substring isa data_ref so data_ref deleted (removing second alt)
2363equivalence_object
2364 : substring { action.equivalence_object(); }
2365 ;
2366
2367equivalence_object_list
2368@init{ int count=0;}
2369 : {action.equivalence_object_list__begin();}
2370 equivalence_object {count++;}
2371 ( T_COMMA equivalence_object {count++;} )*
2372 {action.equivalence_object_list(count);}
2373 ;
2374
2375// R557
2376// action.common_block_name must be called here because it needs
2377// to be called even if optional '/common_block_name/' is not present
2378common_stmt
2379@init {Token lbl=null; int numBlocks=1;}
2380@after{checkForInclude();}
2381 : (label {lbl=$label.tk;})?
2382 T_COMMON ( cb_name=common_block_name )?
2383 { action.common_block_name(cb_name); }
2384 common_block_object_list
2385 ( ( T_COMMA )? cb_name=common_block_name
2386 { action.common_block_name(cb_name); }
2387 common_block_object_list {numBlocks++;} )* end_of_stmt
2388 {action.common_stmt(lbl, $T_COMMON, $end_of_stmt.tk, numBlocks);}
2389 ;
2390
2391// T_SLASH_SLASH must be a option in case there are no spaces slashes, '//'
2392common_block_name returns [Token id]
2393 : T_SLASH_SLASH {id=null;}
2394 | T_SLASH (T_IDENT)? T_SLASH {id=$T_IDENT;}
2395 ;
2396
2397// R558
2398// T_IDENT inlined for variable_name and proc_pointer_name
2399// T_IDENT covered by first alt so second deleted
2400common_block_object
2401@init{boolean hasShapeSpecList=false;}
2402 : T_IDENT ( T_LPAREN explicit_shape_spec_list T_RPAREN
2403 {hasShapeSpecList=true;})?
2404 {action.common_block_object($T_IDENT,hasShapeSpecList);}
2405 ;
2406
2407common_block_object_list
2408@init{ int count=0;}
2409 : {action.common_block_object_list__begin();}
2410 common_block_object {count++;}
2411 ( T_COMMA common_block_object {count++;} )*
2412 {action.common_block_object_list(count);}
2413 ;
2414
2415pragma_stmt
2416@after{checkForInclude();}
2417 : goName=T_PRAGMA
2418 pragmaId=T_IDENT
2419 pragma_tokens
2420 eosToken=T_EOS
2421 {action.pragma_stmt(goName, pragmaId, eosToken);}
2422 ;
2423
2424pragma_tokens
2425@init{ int count=0;}
2426 :
2427 {action.pragma_token_list__begin();}
2428 (goName=(~ T_EOS)
2429 {action.pragma_token(goName); count++;} )+
2430 {action.pragma_token_list(count);}
2431 ;
2432
2433/**
2434 * Section/Clause 6: Use of data objects
2435 */
2436
2437
2438// R601
2439variable
2440 : designator {action.variable();}
2441 ;
2442
2443// R602 variable_name was name inlined as T_IDENT
2444
2445// R603
2446// : object-name // T_IDENT (data-ref isa T_IDENT)
2447// | array-element // R616 is data-ref
2448// | array-section // R617 is data-ref [ (substring-range) ]
2449// | structure-component // R614 is data-ref
2450// | substring
2451// (substring-range) may be matched in data-ref
2452// this rule is now identical to substring
2453designator
2454@init{boolean hasSubstringRange = false;}
2455 : data_ref (T_LPAREN substring_range {hasSubstringRange=true;} T_RPAREN)?
2456 { action.designator(hasSubstringRange); }
2457 | char_literal_constant T_LPAREN substring_range T_RPAREN
2458 { hasSubstringRange=true; action.substring(hasSubstringRange); }
2459 ;
2460
2461//
2462// a function_reference is ambiguous with designator, ie, foo(b) could be an
2463// array element
2464// function_reference : procedure_designator T_LPAREN
2465// ( actual_arg_spec_list )? T_RPAREN
2466// procedure_designator isa data_ref
2467// C1220 (R1217) The procedure-designator shall designate a function.
2468// data_ref may (or not) match T_LPAREN ( actual_arg_spec_list )? T_RPAREN,
2469// so is optional
2470designator_or_func_ref
2471@init {
2472 boolean hasSubstringRangeOrArgList = false;
2473 boolean hasSubstringRange = false;
2474}
2475@after {
2476 action.designator_or_func_ref();
2477}
2478 : data_ref (T_LPAREN substring_range_or_arg_list
2479 {
2480 hasSubstringRangeOrArgList = true;
2481 hasSubstringRange=
2482 $substring_range_or_arg_list.isSubstringRange;
2483 }
2484 T_RPAREN)?
2485 {
2486 if (hasSubstringRangeOrArgList) {
2487 if (hasSubstringRange) {
2488 action.designator(hasSubstringRange);
2489 } else {
2490 // hasActualArgSpecList=true
2491 action.function_reference(true);
2492 }
2493 }
2494 }
2495 | char_literal_constant T_LPAREN substring_range T_RPAREN
2496 { hasSubstringRange=true; action.substring(hasSubstringRange); }
2497 ;
2498
2499substring_range_or_arg_list returns [boolean isSubstringRange]
2500@init {
2501 boolean hasUpperBound = false;
2502 Token keyword = null;
2503 int count = 0;
2504}
2505@after {
2506 action.substring_range_or_arg_list();
2507}
2508 : T_COLON (expr {hasUpperBound = true;})? // substring_range
2509 {
2510 // hasLowerBound=false
2511 action.substring_range(false, hasUpperBound);
2512 isSubstringRange=true;
2513 }
2514 | {
2515 /* mimic actual-arg-spec-list */
2516 action.actual_arg_spec_list__begin();
2517 }
2518 expr substr_range_or_arg_list_suffix
2519 {
2520 isSubstringRange =
2521 $substr_range_or_arg_list_suffix.isSubstringRange;
2522 }
2523 | {
2524 /* mimic actual-arg-spec-list */
2525 action.actual_arg_spec_list__begin();
2526 }
2527 T_IDENT T_EQUALS expr
2528 {
2529 count++;
2530 action.actual_arg(true, null);
2531 action.actual_arg_spec($T_IDENT);
2532 }
2533 ( T_COMMA actual_arg_spec {count++;} )*
2534 {
2535 action.actual_arg_spec_list(count);
2536 isSubstringRange = false;
2537 }
2538 | {
2539 /* mimic actual-arg-spec-list */
2540 action.actual_arg_spec_list__begin();
2541 }
2542 ( T_IDENT T_EQUALS {keyword=$T_IDENT;} )? T_ASTERISK label
2543 {
2544 count++;
2545 action.actual_arg(false, $label.tk);
2546 action.actual_arg_spec(keyword);
2547 }
2548 ( T_COMMA actual_arg_spec {count++;} )*
2549 {
2550 action.actual_arg_spec_list(count);
2551 isSubstringRange = false;
2552 }
2553 ;
2554
2555substr_range_or_arg_list_suffix returns [boolean isSubstringRange]
2556@init {boolean hasUpperBound = false; int count = 0;}
2557@after{action.substr_range_or_arg_list_suffix();}
2558 : {
2559 // guessed wrong on list creation, inform of error
2560 action.actual_arg_spec_list(-1);
2561 }
2562 T_COLON (expr {hasUpperBound=true;})? // substring_range
2563 {
2564 // hasLowerBound=true
2565 action.substring_range(true, hasUpperBound);
2566 isSubstringRange = true;
2567 }
2568 |
2569 {
2570 count++;
2571 action.actual_arg(true, null); // hasExpr=true, label=null
2572 action.actual_arg_spec(null); // keywork=null
2573 }
2574 ( T_COMMA actual_arg_spec {count++;} )*
2575 {
2576 action.actual_arg_spec_list(count);
2577 isSubstringRange=false;
2578 } // actual_arg_spec_list
2579 ;
2580
2581// R604
2582logical_variable
2583 : variable
2584 { action.logical_variable(); }
2585 ;
2586
2587// R605
2588default_logical_variable
2589 : variable
2590 { action.default_logical_variable(); }
2591 ;
2592
2593scalar_default_logical_variable
2594 : variable
2595 { action.scalar_default_logical_variable(); }
2596 ;
2597
2598// R606
2599char_variable
2600 : variable
2601 { action.char_variable(); }
2602 ;
2603
2604// R607
2605default_char_variable
2606 : variable
2607 { action.default_char_variable(); }
2608 ;
2609
2610scalar_default_char_variable
2611 : variable
2612 { action.scalar_default_char_variable(); }
2613 ;
2614
2615// R608
2616int_variable
2617 : variable
2618 { action.int_variable(); }
2619 ;
2620
2621// R609
2622// C608 (R610) parent_string shall be of type character
2623// fix for ambiguity in data_ref allows it to match T_LPAREN substring_range
2624// T_RPAREN, so required T_LPAREN substring_range T_RPAREN made optional
2625// ERR_CHK 609 ensure final () is (substring-range)
2626substring
2627@init{boolean hasSubstringRange = false;}
2628 : data_ref (T_LPAREN substring_range {hasSubstringRange=true;} T_RPAREN)?
2629 { action.substring(hasSubstringRange); }
2630 | char_literal_constant T_LPAREN substring_range T_RPAREN
2631 { action.substring(true); }
2632 ;
2633
2634// R610 parent_string inlined in R609 as (data_ref | char_literal_constant)
2635// T_IDENT inlined for scalar_variable_name
2636// data_ref inlined for scalar_structure_component and array_element
2637// data_ref isa T_IDENT so T_IDENT deleted
2638// scalar_constant replaced by char_literal_constant as data_ref isa T_IDENT
2639// and must be character
2640
2641// R611
2642// ERR_CHK 611 scalar_int_expr replaced by expr
2643substring_range
2644@init{
2645 boolean hasLowerBound = false;
2646 boolean hasUpperBound = false;
2647}
2648 : (expr {hasLowerBound = true;})? T_COLON (expr {hasUpperBound = true;})?
2649 { action.substring_range(hasLowerBound, hasUpperBound); }
2650 ;
2651
2652// R612
2653data_ref
2654@init{int numPartRefs = 0;}
2655 : part_ref {numPartRefs += 1;} ( T_PERCENT part_ref {numPartRefs += 1;})*
2656 {action.data_ref(numPartRefs);}
2657 ;
2658
2659/**
2660 * R612-F08 part-ref
2661 * is part-name [ ( section-subscript-list ) ] [ image-selector]
2662 */
2663
2664////////////
2665// R612-F08, R613-F03
2666//
2667// This rule is implemented in the FortranParserExtras grammar
2668//
2669part_ref
2670 : T_IDENT
2671 {System.err.println("ERROR: part_ref implemented in FortranParserExtras.java");}
2672 ;
2673
2674
2675// R614 structure_component inlined as data_ref
2676
2677// R615 type_param_inquiry inlined in R701 then deleted as can be designator
2678// T_IDENT inlined for type_param_name
2679
2680// R616 array_element inlined as data_ref
2681
2682// R617 array_section inlined in R603
2683
2684// R618 subscript inlined as expr
2685// ERR_CHK 618 scalar_int_expr replaced by expr
2686
2687
2688/**
2689 * R620-F08 section-subscript
2690 * is subscript
2691 * or subscript-triplet
2692 * or vector-subscript
2693 */
2694
2695////////////
2696// R620-F08, R619-F03
2697//
2698// This rule is implemented in FortranParserExtras grammar
2699
2700
2701// R620 subscript_triplet inlined in R619
2702// inlined expr as subscript and stride in subscript_triplet
2703
2704// R621 stride inlined as expr
2705// ERR_CHK 621 scalar_int_expr replaced by expr
2706
2707// R622
2708// ERR_CHK 622 int_expr replaced by expr
2709vector_subscript
2710 : expr
2711 { action.vector_subscript(); }
2712 ;
2713
2714// R622 inlined vector_subscript as expr in R619
2715// ERR_CHK 622 int_expr replaced by expr
2716
2717// R623
2718// modified to remove backtracking by looking for the token inserted during
2719// the lexical prepass if a :: was found (which required alt1 below).
2720allocate_stmt
2721@init {Token lbl = null;
2722 boolean hasTypeSpec = false;
2723 boolean hasAllocOptList = false;}
2724@after{checkForInclude();}
2725 : (label {lbl=$label.tk;})? T_ALLOCATE_STMT_1 T_ALLOCATE T_LPAREN
2726 type_spec T_COLON_COLON
2727 allocation_list
2728 ( T_COMMA alloc_opt_list {hasAllocOptList=true;} )? T_RPAREN
2729 end_of_stmt
2730 {
2731 hasTypeSpec = true;
2732 action.allocate_stmt(lbl, $T_ALLOCATE, $end_of_stmt.tk,
2733 hasTypeSpec, hasAllocOptList);
2734 }
2735 | (label {lbl=$label.tk;})? T_ALLOCATE T_LPAREN
2736 allocation_list
2737 ( T_COMMA alloc_opt_list {hasAllocOptList=true;} )? T_RPAREN
2738 end_of_stmt
2739 {
2740 action.allocate_stmt(lbl, $T_ALLOCATE, $end_of_stmt.tk,
2741 hasTypeSpec, hasAllocOptList);
2742 }
2743 ;
2744
2745// R624
2746// ERR_CHK 624 source_expr replaced by expr
2747// stat_variable and errmsg_variable replaced by designator
2748alloc_opt
2749 : T_IDENT T_EQUALS expr
2750 /* {'STAT','ERRMSG'} are variables {SOURCE'} is expr */
2751 { action.alloc_opt($T_IDENT); }
2752 ;
2753
2754alloc_opt_list
2755@init{ int count=0;}
2756 : {action.alloc_opt_list__begin();}
2757 alloc_opt {count++;} ( T_COMMA alloc_opt {count++;} )*
2758 {action.alloc_opt_list(count);}
2759 ;
2760
2761// R625 stat_variable was scalar_int_variable inlined in R624 and R636
2762// R626 errmsg_variable was scalar_default_char_variable inlined in R624
2763// and R636
2764// R627 inlined source_expr was expr
2765
2766////////////
2767// R631-F08, R628-F03
2768//
2769// This rule is implemented in the FortranParserExtras grammar
2770//
2771allocation
2772 : T_IDENT
2773 {System.err.println("ERROR: allocation implemented in FortranParserExtras.java");}
2774 ;
2775
2776allocation_list
2777@init{ int count=0;}
2778 : {action.allocation_list__begin();}
2779 allocation {count++;} ( T_COMMA allocation {count++;} )*
2780 {action.allocation_list(count);}
2781 ;
2782
2783/**
2784 * R632-F08 allocate-object
2785 * is variable-name
2786 * structure-component
2787 */
2788
2789////////////
2790// R636-F08, R629-F03
2791//
2792// This rule is implemented in the FortranParserExtras grammar
2793//
2794allocate_object
2795 : T_IDENT
2796 {System.err.println("ERROR: allocate_object implemented in FortranParserExtras.java");}
2797 ;
2798
2799allocate_object_list
2800@init{ int count=0;}
2801 : {action.allocate_object_list__begin();}
2802 allocate_object {count++;} ( T_COMMA allocate_object {count++;} )*
2803 {action.allocate_object_list(count);}
2804 ;
2805
2806// R630
2807// ERR_CHK 630a lower_bound_expr replaced by expr
2808// ERR_CHK 630b upper_bound_expr replaced by expr
2809allocate_shape_spec
2810@init{boolean hasLowerBound = false; boolean hasUpperBound = true;}
2811 : expr (T_COLON expr)?
2812 { // note, allocate-shape-spec always has upper bound
2813 // grammar was refactored to remove left recursion,
2814 // looks deceptive
2815 action.allocate_shape_spec(hasLowerBound, hasUpperBound);
2816 }
2817 ;
2818
2819allocate_shape_spec_list
2820@init{ int count=0;}
2821 : {action.allocate_shape_spec_list__begin();}
2822 allocate_shape_spec {count++;}
2823 ( T_COMMA allocate_shape_spec {count++;} )*
2824 {action.allocate_shape_spec_list(count);}
2825 ;
2826
2827// R631 inlined lower_bound_expr was scalar_int_expr
2828
2829// R632 inlined upper_bound_expr was scalar_int_expr
2830
2831
2832/*
2833 * R636-F08 allocate-coarray-spec
2834 * is [ allocate-coshape-spec-list , ] [ lower-bound-expr : ] *
2835 */
2836
2837////////////
2838// R636-F08
2839//
2840// This rule is implemented in FortranParserExtras grammar
2841
2842
2843/*
2844 * R637-F08 allocate-coshape-spec
2845 * is [ lower-bound-expr : ] upper-bound-expr
2846 */
2847
2848////////////
2849// R637-F08
2850//
2851allocate_coshape_spec
2852@init { boolean hasExpr = false; }
2853 : expr ( T_COLON expr { hasExpr = true; })?
2854 { action.allocate_coshape_spec(hasExpr); }
2855 ;
2856
2857allocate_coshape_spec_list
2858@init{ int count=0;}
2859 : {action.allocate_coshape_spec_list__begin();}
2860 allocate_coshape_spec {count++;} ( T_COMMA allocate_coshape_spec {count++;} )*
2861 {action.allocate_coshape_spec_list(count);}
2862 ;
2863
2864
2865// R633
2866nullify_stmt
2867@init {Token lbl = null;} // @init{INIT_TOKEN_NULL(lbl);}
2868@after{checkForInclude();}
2869 : (label {lbl=$label.tk;})?
2870 T_NULLIFY T_LPAREN pointer_object_list T_RPAREN end_of_stmt
2871 { action.nullify_stmt(lbl, $T_NULLIFY, $end_of_stmt.tk); }
2872 ;
2873
2874// R634
2875// T_IDENT inlined for variable_name and proc_pointer_name
2876// data_ref inlined for structure_component
2877// data_ref can be a T_IDENT so T_IDENT deleted
2878pointer_object
2879 : data_ref
2880 { action.pointer_object(); }
2881 ;
2882
2883pointer_object_list
2884@init{ int count=0;}
2885 : {action.pointer_object_list__begin();}
2886 pointer_object {count++;} ( T_COMMA pointer_object {count++;} )*
2887 {action.pointer_object_list(count);}
2888 ;
2889
2890// R635
2891deallocate_stmt
2892@init {Token lbl = null; boolean hasDeallocOptList=false;}
2893@after{checkForInclude();}
2894 : (label {lbl=$label.tk;})? T_DEALLOCATE T_LPAREN allocate_object_list
2895 ( T_COMMA dealloc_opt_list {hasDeallocOptList=true;})?
2896 T_RPAREN end_of_stmt
2897 {action.deallocate_stmt(lbl, $T_DEALLOCATE, $end_of_stmt.tk,
2898 hasDeallocOptList);}
2899 ;
2900
2901// R636
2902// stat_variable and errmsg_variable replaced by designator
2903dealloc_opt
2904 : T_IDENT /* {'STAT','ERRMSG'} */ T_EQUALS designator
2905 { action.dealloc_opt($T_IDENT); }
2906 ;
2907
2908dealloc_opt_list
2909@init{ int count=0;}
2910 : {action.dealloc_opt_list__begin();}
2911 dealloc_opt {count++;} ( T_COMMA dealloc_opt {count++;} )*
2912 {action.dealloc_opt_list(count);}
2913 ;
2914
2915/**
2916 * Section/Clause 7: Expressions and assignment
2917 */
2918
2919// R701
2920// constant replaced by literal_constant as T_IDENT can be designator
2921// T_IDENT inlined for type_param_name
2922// data_ref in designator can be a T_IDENT so T_IDENT deleted
2923// type_param_inquiry is designator T_PERCENT T_IDENT can be designator so
2924// deleted
2925// function_reference integrated with designator (was ambiguous) and
2926// deleted (to reduce backtracking)
2927primary
2928options {backtrack=true;} // alt 1,4 ambiguous
2929@after {action.primary();}
2930 : designator_or_func_ref
2931 | literal_constant
2932 | array_constructor
2933 | structure_constructor
2934 | T_LPAREN expr T_RPAREN
2935 ;
2936
2937// R702
2938level_1_expr
2939@init{Token tk = null;} //@init{INIT_TOKEN_NULL(tk);}
2940 : (defined_unary_op {tk = $defined_unary_op.tk;})? primary
2941 {action.level_1_expr(tk);}
2942 ;
2943
2944// R703
2945defined_unary_op returns [Token tk]
2946 : T_DEFINED_OP {tk = $T_DEFINED_OP;}
2947 { action.defined_unary_op($T_DEFINED_OP); }
2948 ;
2949
2950// inserted as R704 functionality
2951power_operand
2952@init{boolean hasPowerOperand = false;}
2953 : level_1_expr (power_op power_operand {hasPowerOperand = true;})?
2954 {action.power_operand(hasPowerOperand);}
2955 ;
2956
2957// R704
2958// see power_operand
2959mult_operand
2960@init{int numMultOps = 0;}
2961// : level_1_expr ( power_op mult_operand )?
2962// : power_operand
2963 : power_operand (mult_op power_operand
2964 { action.mult_operand__mult_op($mult_op.tk); numMultOps += 1; })*
2965 { action.mult_operand(numMultOps); }
2966 ;
2967
2968// R705-addition
2969// This rule has been added so the unary plus/minus has the correct
2970// precedence when actions are fired.
2971signed_operand
2972@init{int numAddOps = 0;}
2973 : (tk=add_op)? mult_operand
2974 {action.signed_operand(tk);}
2975 ;
2976
2977// R705
2978// moved leading optionals to mult_operand
2979add_operand
2980@init{int numAddOps = 0;}
2981@after{action.add_operand(numAddOps);}
2982// : ( add_operand mult_op )? mult_operand
2983// : ( mult_operand mult_op )* mult_operand
2984 : signed_operand
2985 ( tk=add_op mult_operand
2986 {action.add_operand__add_op(tk); numAddOps += 1;}
2987 )*
2988 ;
2989
2990// R706
2991// moved leading optionals to add_operand
2992level_2_expr
2993@init{int numConcatOps = 0;}
2994// : ( ( level_2_expr )? add_op )? add_operand
2995// check notes on how to remove this left recursion
2996// (WARNING something like the following)
2997// : (add_op)? ( add_operand add_op )* add_operand
2998 : add_operand ( concat_op add_operand {numConcatOps += 1;})*
2999 {action.level_2_expr(numConcatOps);}
3000 ;
3001
3002// R707
3003power_op returns [Token tk]
3004 : T_POWER {tk = $T_POWER;}
3005 { action.power_op($T_POWER); }
3006 ;
3007
3008// R708
3009mult_op returns [Token tk]
3010 : T_ASTERISK { tk = $T_ASTERISK; action.mult_op(tk); }
3011 | T_SLASH { tk = $T_SLASH; action.mult_op(tk); }
3012 ;
3013
3014// R709
3015add_op returns [Token tk]
3016 : T_PLUS { tk = $T_PLUS; action.add_op(tk); }
3017 | T_MINUS { tk = $T_MINUS; action.add_op(tk); }
3018 ;
3019
3020// R710
3021// moved leading optional to level_2_expr
3022level_3_expr
3023@init{Token relOp = null;} //@init{INIT_TOKEN_NULL(relOp);}
3024// : ( level_3_expr concat_op )? level_2_expr
3025// : ( level_2_expr concat_op )* level_2_expr
3026 : level_2_expr (rel_op level_2_expr {relOp = $rel_op.tk;})?
3027 {action.level_3_expr(relOp);}
3028 ;
3029
3030// R711
3031concat_op returns [Token tk]
3032 : T_SLASH_SLASH { tk = $T_SLASH_SLASH; action.concat_op(tk); }
3033 ;
3034
3035// R712
3036// moved leading optional to level_3_expr
3037// inlined level_3_expr for level_4_expr in R714
3038//level_4_expr
3039// : ( level_3_expr rel_op )? level_3_expr
3040// : level_3_expr
3041// ;
3042
3043// R713
3044rel_op returns [Token tk]
3045@after {
3046 action.rel_op(tk);
3047}
3048 : T_EQ {tk=$T_EQ;}
3049 | T_NE {tk=$T_NE;}
3050 | T_LT {tk=$T_LT;}
3051 | T_LE {tk=$T_LE;}
3052 | T_GT {tk=$T_GT;}
3053 | T_GE {tk=$T_GE;}
3054 | T_EQ_EQ {tk=$T_EQ_EQ;}
3055 | T_SLASH_EQ {tk=$T_SLASH_EQ;}
3056 | T_LESSTHAN {tk=$T_LESSTHAN;}
3057 | T_LESSTHAN_EQ {tk=$T_LESSTHAN_EQ;}
3058 | T_GREATERTHAN {tk=$T_GREATERTHAN;}
3059 | T_GREATERTHAN_EQ {tk=$T_GREATERTHAN_EQ;}
3060 ;
3061
3062// R714
3063// level_4_expr inlined as level_3_expr
3064and_operand
3065@init {
3066 boolean hasNotOp0 = false; // @init{INIT_BOOL_FALSE(hasNotOp0);
3067 boolean hasNotOp1 = false; // @init{INIT_BOOL_FALSE(hasNotOp1);
3068 int numAndOps = 0;
3069}
3070// : ( not_op )? level_3_expr
3071 : (not_op {hasNotOp0=true;})?
3072 level_3_expr
3073 (and_op {hasNotOp1=false;} (not_op {hasNotOp1=true;})? level_3_expr
3074 {action.and_operand__not_op(hasNotOp1); numAndOps += 1;}
3075 )*
3076 {action.and_operand(hasNotOp0, numAndOps);}
3077 ;
3078
3079// R715
3080// moved leading optional to or_operand
3081or_operand
3082@init{int numOrOps = 0;}
3083// : ( or_operand and_op )? and_operand
3084// : ( and_operand and_op )* and_operand
3085 : and_operand (or_op and_operand {numOrOps += 1;})*
3086 { action.or_operand(numOrOps); }
3087 ;
3088
3089// R716
3090// moved leading optional to or_operand
3091// TODO - action for equiv_op token
3092equiv_operand
3093@init{int numEquivOps = 0;}
3094// : ( equiv_operand or_op )? or_operand
3095// : ( or_operand or_op )* or_operand
3096 : or_operand
3097 (equiv_op or_operand
3098 {action.equiv_operand__equiv_op($equiv_op.tk); numEquivOps += 1;}
3099 )*
3100 {action.equiv_operand(numEquivOps);}
3101 ;
3102
3103// R717
3104// moved leading optional to equiv_operand
3105level_5_expr
3106@init{int numDefinedBinaryOps = 0;}
3107// : ( level_5_expr equiv_op )? equiv_operand
3108// : ( equiv_operand equiv_op )* equiv_operand
3109 : equiv_operand (defined_binary_op equiv_operand
3110 {action.level_5_expr__defined_binary_op($defined_binary_op.tk);
3111 numDefinedBinaryOps += 1;} )*
3112 {action.level_5_expr(numDefinedBinaryOps);}
3113 ;
3114
3115// R718
3116not_op returns [Token tk]
3117 : T_NOT { tk = $T_NOT; action.not_op(tk); }
3118 ;
3119
3120// R719
3121and_op returns [Token tk]
3122 : T_AND { tk = $T_AND; action.and_op(tk); }
3123 ;
3124
3125// R720
3126or_op returns [Token tk]
3127 : T_OR { tk = $T_OR; action.or_op(tk); }
3128 ;
3129
3130// R721
3131equiv_op returns [Token tk]
3132 : T_EQV { tk = $T_EQV; action.equiv_op(tk); }
3133 | T_NEQV { tk = $T_NEQV; action.equiv_op(tk); }
3134 ;
3135
3136// R722
3137// moved leading optional to level_5_expr
3138expr
3139// : ( expr defined_binary_op )? level_5_expr
3140// : ( level_5_expr defined_binary_op )* level_5_expr
3141 : level_5_expr
3142 {action.expr();}
3143 ;
3144
3145// R723
3146defined_binary_op returns [Token tk]
3147 : T_DEFINED_OP { tk = $T_DEFINED_OP; action.defined_binary_op(tk); }
3148 ;
3149
3150// R724 inlined logical_expr was expr
3151
3152// R725 inlined char_expr was expr
3153
3154// R726 inlined default_char_expr
3155
3156// R727 inlined int_expr
3157
3158// R728 inlined numeric_expr was expr
3159
3160// inlined scalar_numeric_expr was expr
3161
3162// R729 inlined specification_expr was scalar_int_expr
3163
3164// R730 inlined initialization_expr
3165
3166// R731 inlined char_initialization_expr was char_expr
3167
3168// inlined scalar_char_initialization_expr was char_expr
3169
3170// R732 inlined int_initialization_expr was int_expr
3171
3172// inlined scalar_int_initialization_expr was int_initialization_expr
3173
3174// R733 inlined logical_initialization_expr was logical_expr
3175
3176// inlined scalar_logical_initialization_expr was logical_expr
3177
3178// R734
3179assignment_stmt
3180@init {Token lbl = null;}
3181@after{checkForInclude();}
3182 : (label {lbl=$label.tk;})? T_ASSIGNMENT_STMT variable
3183 T_EQUALS expr end_of_stmt
3184 {action.assignment_stmt(lbl, $end_of_stmt.tk);}
3185 ;
3186
3187// R735
3188// ERR_TEST 735 ensure that part_ref in data_ref doesn't capture the T_LPAREN
3189// data_pointer_object and proc_pointer_object replaced by designator
3190// data_target and proc_target replaced by expr
3191// third alt covered by first alt so proc_pointer_object assignment deleted
3192// designator (R603), minus the substring part is data_ref, so designator
3193// replaced by data_ref,
3194// see NOTE 6.10 for why array-section does not have pointer attribute
3195// TODO: alt1 and alt3 require the backtracking. if find a way to disambiguate
3196// them, should be able to remove backtracking.
3197pointer_assignment_stmt
3198options {backtrack=true;}
3199@init {Token lbl = null;}
3200@after{checkForInclude();}
3201 : (label {lbl=$label.tk;})? T_PTR_ASSIGNMENT_STMT data_ref T_EQ_GT
3202 expr end_of_stmt
3203 {action.pointer_assignment_stmt(lbl, $end_of_stmt.tk,false,false);}
3204 | (label {lbl=$label.tk;})? T_PTR_ASSIGNMENT_STMT data_ref T_LPAREN
3205 bounds_spec_list T_RPAREN T_EQ_GT expr end_of_stmt
3206 {action.pointer_assignment_stmt(lbl, $end_of_stmt.tk, true,false);}
3207 | (label {lbl=$label.tk;})? T_PTR_ASSIGNMENT_STMT data_ref T_LPAREN
3208 bounds_remapping_list T_RPAREN T_EQ_GT expr end_of_stmt
3209 {action.pointer_assignment_stmt(lbl, $end_of_stmt.tk, false,true);}
3210 ;
3211
3212// R736
3213// ERR_CHK 736 ensure ( T_IDENT | designator ending in T_PERCENT T_IDENT)
3214// T_IDENT inlined for variable_name and data_pointer_component_name
3215// variable replaced by designator
3216data_pointer_object
3217 : designator
3218 { action.data_pointer_object(); }
3219 ;
3220
3221// R737
3222// ERR_CHK 737 lower_bound_expr replaced by expr
3223bounds_spec
3224 : expr T_COLON
3225 { action.bounds_spec(); }
3226 ;
3227
3228bounds_spec_list
3229@init{ int count=0;}
3230 : {action.bounds_spec_list__begin();}
3231 bounds_spec {count++;} ( T_COMMA bounds_spec {count++;} )*
3232 {action.bounds_spec_list(count);}
3233 ;
3234
3235// R738
3236// ERR_CHK 738a lower_bound_expr replaced by expr
3237// ERR_CHK 738b upper_bound_expr replaced by expr
3238bounds_remapping
3239 : expr T_COLON expr
3240 { action.bounds_remapping(); }
3241 ;
3242
3243bounds_remapping_list
3244@init{ int count=0;}
3245 : {action.bounds_remapping_list__begin();}
3246 bounds_remapping {count++;} ( T_COMMA bounds_remapping {count++;} )*
3247 {action.bounds_remapping_list(count);}
3248 ;
3249
3250// R739 data_target inlined as expr in R459 and R735
3251// expr can be designator (via primary) so variable deleted
3252
3253// R740
3254// ERR_CHK 740 ensure ( T_IDENT | ends in T_PERCENT T_IDENT )
3255// T_IDENT inlined for proc_pointer_name
3256// proc_component_ref replaced by designator T_PERCENT T_IDENT replaced
3257// by designator
3258proc_pointer_object
3259 : designator
3260 { action.proc_pointer_object(); }
3261 ;
3262
3263// R741 proc_component_ref inlined as designator T_PERCENT T_IDENT in R740,
3264// R742, R1219, and R1221
3265// T_IDENT inlined for procedure_component_name
3266// designator inlined for variable
3267
3268// R742 proc_target inlined as expr in R459 and R735
3269// ERR_CHK 736 ensure ( expr | designator ending in T_PERCENT T_IDENT)
3270// T_IDENT inlined for procedure_name
3271// T_IDENT isa expr so T_IDENT deleted
3272// proc_component_ref is variable T_PERCENT T_IDENT can be designator
3273// so deleted
3274
3275// R743
3276// ERR_CHK 743 mask_expr replaced by expr
3277// assignment_stmt inlined for where_assignment_stmt
3278where_stmt
3279@init {
3280 Token lbl = null;
3281 action.where_stmt__begin();
3282}
3283@after{checkForInclude();}
3284 :
3285 (label {lbl=$label.tk;})? T_WHERE_STMT T_WHERE
3286 T_LPAREN expr T_RPAREN assignment_stmt
3287 {action.where_stmt(lbl, $T_WHERE);}
3288 ;
3289
3290// R744
3291where_construct
3292@init {
3293 int numConstructs = 0;
3294 int numMaskedConstructs = 0;
3295 boolean hasMaskedElsewhere = false;
3296 int numElsewhereConstructs = 0;
3297 boolean hasElsewhere = false;
3298}
3299 : where_construct_stmt ( where_body_construct {numConstructs += 1;} )*
3300 ( masked_elsewhere_stmt ( where_body_construct
3301 {numMaskedConstructs += 1;} )*
3302 {hasMaskedElsewhere = true;
3303 action.masked_elsewhere_stmt__end(numMaskedConstructs);}
3304 )*
3305 ( elsewhere_stmt ( where_body_construct
3306 {numElsewhereConstructs += 1;} )*
3307 {hasElsewhere = true;
3308 action.elsewhere_stmt__end(numElsewhereConstructs);}
3309 )?
3310 end_where_stmt
3311 {action.where_construct(numConstructs, hasMaskedElsewhere,
3312 hasElsewhere);}
3313 ;
3314
3315// R745
3316// ERR_CHK 745 mask_expr replaced by expr
3317where_construct_stmt
3318@init {Token id=null;}
3319@after{checkForInclude();}
3320 : ( T_IDENT T_COLON {id=$T_IDENT;})? T_WHERE_CONSTRUCT_STMT T_WHERE
3321 T_LPAREN expr T_RPAREN end_of_stmt
3322 {action.where_construct_stmt(id, $T_WHERE, $end_of_stmt.tk);}
3323 ;
3324
3325// R746
3326// assignment_stmt inlined for where_assignment_stmt
3327where_body_construct
3328@after {
3329 action.where_body_construct();
3330}
3331 : assignment_stmt
3332 | where_stmt
3333 | where_construct
3334 ;
3335
3336// R747 where_assignment_stmt inlined as assignment_stmt in R743 and R746
3337
3338// R748 inlined mask_expr was logical_expr
3339
3340// inlined scalar_mask_expr was scalar_logical_expr
3341
3342// inlined scalar_logical_expr was logical_expr
3343
3344// R749
3345// ERR_CHK 749 mask_expr replaced by expr
3346masked_elsewhere_stmt
3347@init {Token lbl = null;Token id=null;}
3348@after{checkForInclude();}
3349 : (label {lbl=$label.tk;})? T_ELSE T_WHERE T_LPAREN expr T_RPAREN
3350 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
3351 {action.masked_elsewhere_stmt(lbl, $T_ELSE, $T_WHERE, id,
3352 $end_of_stmt.tk);}
3353 | (label {lbl=$label.tk;})? T_ELSEWHERE T_LPAREN expr T_RPAREN
3354 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
3355 {action.masked_elsewhere_stmt(lbl, $T_ELSEWHERE, null,id,
3356 $end_of_stmt.tk);}
3357 ;
3358
3359// R750
3360elsewhere_stmt
3361@init { Token lbl = null; Token id=null;}
3362@after{checkForInclude();}
3363 : (label {lbl=$label.tk;})? T_ELSE T_WHERE
3364 (T_IDENT {id=$T_IDENT;})? end_of_stmt
3365 {action.elsewhere_stmt(lbl, $T_ELSE, $T_WHERE, id,
3366 $end_of_stmt.tk);}
3367 | (label {lbl=$label.tk;})? T_ELSEWHERE (T_IDENT {id=$T_IDENT;})?
3368 end_of_stmt
3369 {action.elsewhere_stmt(lbl, $T_ELSEWHERE, null, id,
3370 $end_of_stmt.tk);}
3371 ;
3372
3373// R751
3374end_where_stmt
3375@init {Token lbl = null; Token id=null;} // @init{INIT_TOKEN_NULL(lbl);}
3376@after{checkForInclude();}
3377 : (label {lbl=$label.tk;})? T_END T_WHERE ( T_IDENT {id=$T_IDENT;} )?
3378 end_of_stmt
3379 {action.end_where_stmt(lbl, $T_END, $T_WHERE, id, $end_of_stmt.tk);}
3380 | (label {lbl=$label.tk;})? T_ENDWHERE ( T_IDENT {id=$T_IDENT;} )?
3381 end_of_stmt
3382 {action.end_where_stmt(lbl, $T_ENDWHERE, null, id, $end_of_stmt.tk);}
3383 ;
3384
3385// R752
3386forall_construct
3387@after {
3388 action.forall_construct();
3389}
3390 : forall_construct_stmt
3391 ( forall_body_construct )*
3392 end_forall_stmt
3393 ;
3394
3395// R753
3396forall_construct_stmt
3397@init {Token lbl = null; Token id = null;}
3398@after{checkForInclude();}
3399 : (label {lbl=$label.tk;})? ( T_IDENT T_COLON {id=$T_IDENT;})?
3400 T_FORALL_CONSTRUCT_STMT T_FORALL
3401 forall_header end_of_stmt
3402 {action.forall_construct_stmt(lbl, id, $T_FORALL,
3403 $end_of_stmt.tk);}
3404 ;
3405
3406// R754
3407// ERR_CHK 754 scalar_mask_expr replaced by expr
3408forall_header
3409@after {
3410 action.forall_header();
3411}
3412 : T_LPAREN forall_triplet_spec_list ( T_COMMA expr )? T_RPAREN
3413 ;
3414
3415// R755
3416// T_IDENT inlined for index_name
3417// expr inlined for subscript and stride
3418forall_triplet_spec
3419@init{boolean hasStride=false;}
3420 : T_IDENT T_EQUALS expr T_COLON expr ( T_COLON expr {hasStride=true;})?
3421 {action.forall_triplet_spec($T_IDENT,hasStride);}
3422 ;
3423
3424
3425forall_triplet_spec_list
3426@init{ int count=0;}
3427 : {action.forall_triplet_spec_list__begin();}
3428 forall_triplet_spec {count++;}
3429 ( T_COMMA forall_triplet_spec {count++;} )*
3430 {action.forall_triplet_spec_list(count);}
3431 ;
3432
3433// R756
3434forall_body_construct
3435@after {
3436 action.forall_body_construct();
3437}
3438 : forall_assignment_stmt
3439 | where_stmt
3440 | where_construct
3441 | forall_construct
3442 | forall_stmt
3443 ;
3444
3445// R757
3446forall_assignment_stmt
3447@after{checkForInclude();}
3448 : assignment_stmt
3449 {action.forall_assignment_stmt(false);}
3450 | pointer_assignment_stmt
3451 {action.forall_assignment_stmt(true);}
3452 ;
3453
3454// R758
3455end_forall_stmt
3456@init {Token lbl = null; Token id=null;}
3457@after{checkForInclude();}
3458 : (label {lbl=$label.tk;})? T_END T_FORALL ( T_IDENT {id=$T_IDENT;})?
3459 end_of_stmt
3460 {action.end_forall_stmt(lbl, $T_END, $T_FORALL, id, $end_of_stmt.tk);}
3461 | (label {lbl=$label.tk;})? T_ENDFORALL ( T_IDENT {id=$T_IDENT;})?
3462 end_of_stmt
3463 {action.end_forall_stmt(lbl, $T_ENDFORALL, null, id, $end_of_stmt.tk);}
3464 ;
3465
3466// R759
3467// T_FORALL_STMT token is inserted by scanner to remove need for backtracking
3468forall_stmt
3469@init {
3470 Token lbl = null;
3471 action.forall_stmt__begin();
3472}
3473@after{checkForInclude();}
3474 : (label {lbl=$label.tk;})? T_FORALL_STMT T_FORALL
3475 forall_header
3476 forall_assignment_stmt
3477 {action.forall_stmt(lbl, $T_FORALL);}
3478 ;
3479
3480
3481/**
3482 * Section/Clause 8: Execution control
3483 */
3484
3485
3486// R801
3487block
3488@after {
3489 action.block();
3490}
3491 : ( execution_part_construct )*
3492 ;
3493
3494// R802
3495if_construct
3496@after {
3497 action.if_construct();
3498}
3499 : if_then_stmt block ( else_if_stmt block )* ( else_stmt block )?
3500 end_if_stmt
3501 ;
3502
3503// R803
3504// ERR_CHK 803 scalar_logical_expr replaced by expr
3505if_then_stmt
3506@init {Token lbl = null; Token id=null;}
3507@after{checkForInclude();}
3508 : (label {lbl=$label.tk;})? ( T_IDENT T_COLON {id=$T_IDENT;} )? T_IF
3509 T_LPAREN expr T_RPAREN T_THEN end_of_stmt
3510 {action.if_then_stmt(lbl, id, $T_IF, $T_THEN, $end_of_stmt.tk);}
3511 ;
3512
3513// R804
3514// ERR_CHK 804 scalar_logical_expr replaced by expr
3515else_if_stmt
3516@init {Token lbl = null; Token id=null;}
3517@after{checkForInclude();}
3518 : (label {lbl=$label.tk;})? T_ELSE T_IF
3519 T_LPAREN expr T_RPAREN T_THEN ( T_IDENT {id=$T_IDENT;} )? end_of_stmt
3520 {action.else_if_stmt(lbl, $T_ELSE, $T_IF, $T_THEN, id,
3521 $end_of_stmt.tk);}
3522 | (label {lbl=$label.tk;})? T_ELSEIF
3523 T_LPAREN expr T_RPAREN T_THEN ( T_IDENT {id=$T_IDENT;} )? end_of_stmt
3524 {action.else_if_stmt(lbl, $T_ELSEIF, null, $T_THEN, id,
3525 $end_of_stmt.tk);}
3526 ;
3527
3528// R805
3529else_stmt
3530@init {Token lbl = null; Token id=null;}
3531@after{checkForInclude();}
3532 : (label {lbl=$label.tk;})? T_ELSE ( T_IDENT {id=$T_IDENT;} )?
3533 end_of_stmt
3534 {action.else_stmt(lbl, $T_ELSE, id, $end_of_stmt.tk);}
3535 ;
3536
3537// R806
3538end_if_stmt
3539@init {Token lbl = null; Token id=null;}
3540@after{checkForInclude();}
3541 : (label {lbl=$label.tk;})? T_END T_IF ( T_IDENT {id=$T_IDENT;} )?
3542 end_of_stmt
3543 {action.end_if_stmt(lbl, $T_END, $T_IF, id, $end_of_stmt.tk);}
3544 | (label {lbl=$label.tk;})? T_ENDIF ( T_IDENT {id=$T_IDENT;} )?
3545 end_of_stmt
3546 {action.end_if_stmt(lbl, $T_ENDIF, null, id, $end_of_stmt.tk);}
3547 ;
3548
3549// R807
3550// ERR_CHK 807 scalar_logical_expr replaced by expr
3551// T_IF_STMT inserted by scanner to remove need for backtracking
3552if_stmt
3553@init {
3554 Token lbl = null;
3555 action.if_stmt__begin();
3556}
3557@after{checkForInclude();}
3558 : (label {lbl=$label.tk;})? T_IF_STMT T_IF T_LPAREN expr T_RPAREN
3559 action_stmt
3560 {action.if_stmt(lbl, $T_IF);}
3561 ;
3562
3563/*
3564 * R807-F08 block-construct
3565 * is block-stmt
3566 * [ specification-part ]
3567 * block
3568 * end-block-stmt
3569 *
3570 * C806-F08 (R807-F08) The specification-part of a BLOCK construct shall not contain a
3571 * COMMON, EQUIVALENCE, IMPLICIT, INTENT, NAMELIST, OPTIONAL, statement function, or
3572 * VALUE statement.
3573 *
3574 * C806-F08 means that the implicit-part in specification-part can be removed
3575 */
3576
3577////////////
3578// R807-F08
3579//
3580block_construct
3581@after{action.block_construct();}
3582 : block_stmt
3583 specification_part_and_block
3584 end_block_stmt
3585 ;
3586
3587specification_part_and_block
3588@init{int numUseStmts=0; int numImportStmts=0; gCount1=0;}
3589 : ( use_stmt {numUseStmts++;} )*
3590 ( import_stmt {numImportStmts++;} )*
3591 declaration_construct_and_block
3592 {action.specification_part_and_block(numUseStmts, numImportStmts, gCount1);}
3593 ;
3594
3595declaration_construct_and_block
3596@init{gCount1++;}
3597 : ((label)? T_ENTRY) => entry_stmt declaration_construct_and_block
3598 | ((label)? T_ENUM) => enum_def declaration_construct_and_block
3599 | ((label)? T_FORMAT) => format_stmt declaration_construct_and_block
3600 | ((label)? T_INTERFACE) => interface_block declaration_construct_and_block
3601 | ((label)? T_PARAMETER) => parameter_stmt declaration_construct_and_block
3602 | ((label)? T_PROCEDURE) => procedure_declaration_stmt
3603 declaration_construct_and_block
3604 | (derived_type_stmt) => derived_type_def declaration_construct_and_block
3605 | (type_declaration_stmt) => type_declaration_stmt declaration_construct_and_block
3606
3607 // the following are from other_specification_stmt
3608
3609 | ((label)? access_spec) => access_stmt declaration_construct_and_block
3610 | ((label)? T_ALLOCATABLE) => allocatable_stmt declaration_construct_and_block
3611 | ((label)? T_ASYNCHRONOUS) => asynchronous_stmt declaration_construct_and_block
3612 | ((label)? T_BIND) => bind_stmt declaration_construct_and_block
3613 | ((label)? T_CODIMENSION) => codimension_stmt declaration_construct_and_block
3614 | ((label)? T_DATA) => data_stmt declaration_construct_and_block
3615 | ((label)? T_DIMENSION) => dimension_stmt declaration_construct_and_block
3616 | ((label)? T_EXTERNAL) => external_stmt declaration_construct_and_block
3617 | ((label)? T_INTRINSIC) => intrinsic_stmt declaration_construct_and_block
3618 | ((label)? T_POINTER) => pointer_stmt declaration_construct_and_block
3619 | ((label)? T_PROTECTED) => protected_stmt declaration_construct_and_block
3620 | ((label)? T_SAVE) => save_stmt declaration_construct_and_block
3621 | ((label)? T_TARGET) => target_stmt declaration_construct_and_block
3622 | ((label)? T_VOLATILE) => volatile_stmt declaration_construct_and_block
3623 | block {gCount1--; /* decrement extra count as this isn't a declConstruct */}
3624 ;
3625
3626/*
3627 * R808-F08 block-stmt
3628 * is [ block-construct-name : ] BLOCK
3629 */
3630
3631////////////
3632// R808-F08
3633//
3634block_stmt
3635@init {Token lbl = null; Token name = null;}
3636@after{checkForInclude();}
3637 : (label {lbl=$label.tk;})?
3638 (T_IDENT T_COLON {name=$T_IDENT;})?
3639 T_BLOCK end_of_stmt
3640 {action.block_stmt(lbl, name, $T_BLOCK, $end_of_stmt.tk);}
3641 ;
3642
3643/*
3644 * R809-F08 end-block-stmt
3645 * is END BLOCK [ block-construct-name ]
3646 */
3647
3648////////////
3649// R809-F08
3650//
3651end_block_stmt
3652@init {Token lbl = null; Token name = null;}
3653@after{checkForInclude();}
3654 : (label {lbl=$label.tk;})?
3655 T_END T_BLOCK (T_IDENT {name=$T_IDENT;})? end_of_stmt
3656 {action.end_block_stmt(lbl, name, $T_END, $T_BLOCK, $end_of_stmt.tk);}
3657 | (label {lbl=$label.tk;})?
3658 T_ENDBLOCK (T_IDENT {name=$T_IDENT;})? end_of_stmt
3659 {action.end_block_stmt(lbl, name, $T_ENDBLOCK, null, $end_of_stmt.tk);}
3660 ;
3661
3662/*
3663 * R810-F08 critical-construct
3664 * is critical-stmt
3665 * block
3666 * end-critical-stmt
3667 */
3668
3669////////////
3670// R810-F08
3671//
3672critical_construct
3673 : critical_stmt block end_critical_stmt
3674 {action.critical_construct();}
3675 ;
3676
3677/*
3678 * R811-F08 critical-stmt
3679 * is [ critical-construct-name : ] CRITICAL
3680 */
3681
3682////////////
3683// R811-F08
3684//
3685critical_stmt
3686@init {Token lbl = null; Token name = null;}
3687@after{checkForInclude();}
3688 : (label {lbl=$label.tk;})?
3689 (T_IDENT T_COLON {name=$T_IDENT;})?
3690 T_CRITICAL end_of_stmt
3691 {action.critical_stmt(lbl, name, $T_CRITICAL, $end_of_stmt.tk);}
3692 ;
3693
3694/*
3695 * R812-F08 end-critical-stmt
3696 * is END CRITICAL [ critical-construct-name ]
3697 */
3698
3699////////////
3700// R812-F08
3701//
3702end_critical_stmt
3703@init {Token lbl = null; Token name = null;}
3704@after{checkForInclude();}
3705 : (label {lbl=$label.tk;})?
3706 T_END T_CRITICAL (T_IDENT {name=$T_IDENT;})? end_of_stmt
3707 {action.end_critical_stmt(lbl, name, $T_END, $T_CRITICAL, $end_of_stmt.tk);}
3708 ;
3709
3710// R808
3711case_construct
3712@after {
3713 action.case_construct();
3714}
3715 : select_case_stmt ( case_stmt block )* end_select_stmt
3716 ;
3717
3718// R809
3719// ERR_CHK 809 case_expr replaced by expr
3720select_case_stmt
3721@init {Token lbl = null; Token id=null; Token tk1 = null; Token tk2 = null;}
3722@after{checkForInclude();}
3723 : (label {lbl=$label.tk;})? ( T_IDENT T_COLON {id=$T_IDENT;})?
3724 (T_SELECT T_CASE {tk1=$T_SELECT; tk2=$T_CASE;}
3725 | T_SELECTCASE {tk1=$T_SELECTCASE; tk2=null;} )
3726 T_LPAREN expr T_RPAREN end_of_stmt
3727 {action.select_case_stmt(lbl, id, tk1, tk2, $end_of_stmt.tk);}
3728 ;
3729
3730// R810
3731case_stmt
3732@init {Token lbl = null; Token id=null;}
3733@after{checkForInclude();}
3734 : (label {lbl=$label.tk;})? T_CASE case_selector
3735 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
3736 { action.case_stmt(lbl, $T_CASE, id, $end_of_stmt.tk);}
3737 ;
3738
3739// R811
3740end_select_stmt
3741@init {Token lbl = null; Token id=null;}
3742@after{checkForInclude();}
3743 : (label {lbl=$label.tk;})? T_END T_SELECT (T_IDENT {id=$T_IDENT;})?
3744 end_of_stmt
3745 {action.end_select_stmt(lbl, $T_END, $T_SELECT, id,
3746 $end_of_stmt.tk);}
3747 | (label {lbl=$label.tk;})? T_ENDSELECT (T_IDENT {id=$T_IDENT;})?
3748 end_of_stmt
3749 {action.end_select_stmt(lbl, $T_ENDSELECT, null, id,
3750 $end_of_stmt.tk);}
3751 ;
3752
3753// R812 inlined case_expr with expr was either scalar_int_expr
3754// scalar_char_expr scalar_logical_expr
3755
3756// inlined scalar_char_expr with expr was char_expr
3757
3758// R813
3759case_selector
3760 : T_LPAREN
3761 case_value_range_list
3762 T_RPAREN
3763 { action.case_selector(null); }
3764 | T_DEFAULT
3765 { action.case_selector($T_DEFAULT); }
3766 ;
3767
3768// R814
3769case_value_range
3770@after {
3771 action.case_value_range();
3772}
3773 : T_COLON case_value
3774 | case_value case_value_range_suffix
3775 ;
3776
3777case_value_range_suffix
3778@after {
3779 action.case_value_range_suffix();
3780}
3781 : T_COLON ( case_value )?
3782 | { /* empty */ }
3783 ;
3784
3785case_value_range_list
3786@init{ int count=0;}
3787 : {action.case_value_range_list__begin();}
3788 case_value_range {count++;} ( T_COMMA case_value_range {count++;} )*
3789 {action.case_value_range_list(count);}
3790 ;
3791
3792// R815
3793// ERR_CHK 815 expr either scalar_int_initialization_expr
3794// scalar_char_initialization_expr scalar_logical_initialization_expr
3795case_value
3796 : expr
3797 { action.case_value(); }
3798 ;
3799
3800// R816
3801associate_construct
3802 : associate_stmt
3803 block
3804 end_associate_stmt
3805 { action.associate_construct(); }
3806 ;
3807
3808// R817
3809associate_stmt
3810@init {Token lbl = null; Token id=null;}
3811@after{checkForInclude();}
3812 : (label {lbl=$label.tk;})? ( T_IDENT T_COLON {id=$T_IDENT;})?
3813 T_ASSOCIATE T_LPAREN association_list T_RPAREN end_of_stmt
3814 {action.associate_stmt(lbl, id, $T_ASSOCIATE, $end_of_stmt.tk);}
3815 ;
3816
3817association_list
3818@init{ int count=0;}
3819 : {action.association_list__begin();}
3820 association {count++;} ( T_COMMA association {count++;} )*
3821 {action.association_list(count);}
3822 ;
3823
3824/*
3825 * R818-08 loop-control
3826 * is [ , ] do-variable = scalar-int-expr , scalar-int-expr [ , scalar-int-expr ]
3827 * or [ , ] WHILE ( scalar-logical-expr )
3828 * or [ , ] CONCURRENT forall-header
3829 */
3830
3831////////////
3832// R818-F08, R830-F03
3833//
3834// ERR_CHK 818 scalar_int_expr replaced by expr
3835// ERR_CHK 818 scalar_logical_expr replaced by expr
3836loop_control
3837@init {boolean hasOptExpr = false;}
3838 : ( T_COMMA )? do_variable T_EQUALS expr T_COMMA expr
3839 ( T_COMMA expr {hasOptExpr=true;})?
3840 {action.loop_control(null, IActionEnums.DoConstruct_variable, hasOptExpr);}
3841 | ( T_COMMA )? T_WHILE T_LPAREN expr T_RPAREN
3842 {action.loop_control($T_WHILE, IActionEnums.DoConstruct_while, hasOptExpr);}
3843 | ( T_COMMA )? T_CONCURRENT forall_header
3844 {action.loop_control($T_CONCURRENT,
3845 IActionEnums.DoConstruct_concurrent, hasOptExpr);}
3846 ;
3847
3848// R818
3849// T_IDENT inlined for associate_name
3850association
3851 : T_IDENT T_EQ_GT selector
3852 { action.association($T_IDENT); }
3853 ;
3854
3855// R819
3856// expr can be designator (via primary) so variable deleted
3857selector
3858 : expr
3859 { action.selector(); }
3860 ;
3861
3862// R820
3863end_associate_stmt
3864@init {Token lbl = null; Token id=null;}
3865@after{checkForInclude();}
3866 : (label {lbl=$label.tk;})? T_END T_ASSOCIATE
3867 (T_IDENT {id=$T_IDENT;})? end_of_stmt
3868 {action.end_associate_stmt(lbl, $T_END, $T_ASSOCIATE, id,
3869 $end_of_stmt.tk);}
3870 | (label {lbl=$label.tk;})? T_ENDASSOCIATE
3871 (T_IDENT {id=$T_IDENT;})? end_of_stmt
3872 {action.end_associate_stmt(lbl, $T_ENDASSOCIATE, null, id,
3873 $end_of_stmt.tk);}
3874 ;
3875
3876// R821
3877select_type_construct
3878 : select_type_stmt ( type_guard_stmt block )* end_select_type_stmt
3879 { action.select_type_construct(); }
3880 ;
3881
3882// R822
3883// T_IDENT inlined for select_construct_name and associate_name
3884select_type_stmt
3885@init {Token lbl = null; Token selectConstructName=null;
3886 Token associateName=null;}
3887@after{checkForInclude();}
3888 : (label {lbl=$label.tk;})?
3889 ( idTmp=T_IDENT T_COLON {selectConstructName=idTmp;})? select_type
3890 T_LPAREN ( idTmpx=T_IDENT T_EQ_GT {associateName=idTmpx;} )?
3891 selector T_RPAREN end_of_stmt
3892 {action.select_type_stmt(lbl, selectConstructName, associateName,
3893 $end_of_stmt.tk);}
3894 ;
3895
3896select_type
3897 : T_SELECT T_TYPE { action.select_type($T_SELECT, $T_TYPE); }
3898 | T_SELECTTYPE { action.select_type($T_SELECTTYPE, null); }
3899 ;
3900
3901// R823
3902// T_IDENT inlined for select_construct_name
3903// TODO - FIXME - have to remove T_TYPE_IS and T_CLASS_IS because the
3904// lexer never matches the sequences. lexer now matches a T_IDENT for
3905// the 'IS'. this rule should be fixed (see test_select_stmts.f03)
3906// TODO - The temporary token seems convoluted, but I couldn't figure out
3907// how to prevent ambiguous use of T_IDENT otherwise. -BMR
3908type_guard_stmt
3909@init {Token lbl = null; Token selectConstructName=null;}
3910@after{checkForInclude();}
3911 : (label {lbl=$label.tk;})? T_TYPE id1=T_IDENT
3912 T_LPAREN type_spec T_RPAREN
3913 ( idTmp=T_IDENT {selectConstructName=idTmp;})? end_of_stmt
3914 {action.type_guard_stmt(lbl, $T_TYPE, id1, selectConstructName,
3915 $end_of_stmt.tk);}
3916 | (label {lbl=$label.tk;})? T_CLASS id1=T_IDENT
3917 T_LPAREN type_spec T_RPAREN
3918 ( idTmp=T_IDENT {selectConstructName=idTmp;})? end_of_stmt
3919 {action.type_guard_stmt(lbl, $T_CLASS, id1, selectConstructName,
3920 $end_of_stmt.tk);}
3921 | (label {lbl=$label.tk;})? T_CLASS T_DEFAULT
3922 ( idTmp=T_IDENT {selectConstructName=idTmp;})? end_of_stmt
3923 {action.type_guard_stmt(lbl, $T_CLASS, $T_DEFAULT,
3924 selectConstructName, $end_of_stmt.tk);}
3925 ;
3926
3927// R824
3928// T_IDENT inlined for select_construct_name
3929end_select_type_stmt
3930@init {Token lbl = null; Token id = null;}
3931@after{checkForInclude();}
3932 : (label {lbl=$label.tk;})? T_END T_SELECT
3933 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
3934 {action.end_select_type_stmt(lbl, $T_END, $T_SELECT, id,
3935 $end_of_stmt.tk);}
3936 | (label {lbl=$label.tk;})? T_ENDSELECT
3937 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
3938 {action.end_select_type_stmt(lbl, $T_ENDSELECT, null, id,
3939 $end_of_stmt.tk);}
3940 ;
3941
3942// R825
3943// deleted second alternative, nonblock_do_construct, to reduce backtracking, see comments for R835 on how
3944// termination of nested loops must be handled.
3945do_construct
3946 : block_do_construct
3947 { action.do_construct(); }
3948 ;
3949
3950// R826
3951// do_block replaced by block
3952block_do_construct
3953 : do_stmt
3954 block
3955 end_do
3956 { action.block_do_construct(); }
3957 ;
3958
3959// R827
3960// label_do_stmt and nonlabel_do_stmt inlined
3961do_stmt
3962@init {Token lbl=null;
3963 Token id=null;
3964 Token digitString=null;
3965 boolean hasLoopControl=false;}
3966@after{checkForInclude();}
3967 : (label {lbl=$label.tk;})? ( T_IDENT T_COLON {id=$T_IDENT;})? T_DO
3968 ( T_DIGIT_STRING {digitString=$T_DIGIT_STRING;})?
3969 ( loop_control {hasLoopControl=true;})? end_of_stmt
3970 {action.do_stmt(lbl, id, $T_DO, digitString, $end_of_stmt.tk,
3971 hasLoopControl);}
3972 ;
3973
3974// R828
3975// T_IDENT inlined for do_construct_name
3976// T_DIGIT_STRING inlined for label
3977label_do_stmt
3978@init {Token lbl = null; Token id=null; boolean hasLoopControl=false;}
3979@after{checkForInclude();}
3980 : (label {lbl=$label.tk;})? ( T_IDENT T_COLON {id=$T_IDENT;} )?
3981 T_DO T_DIGIT_STRING ( loop_control {hasLoopControl=true;})?
3982 end_of_stmt
3983 {action.label_do_stmt(lbl, id, $T_DO, $T_DIGIT_STRING,
3984 $end_of_stmt.tk, hasLoopControl);}
3985 ;
3986
3987// R829 inlined in R827
3988// T_IDENT inlined for do_construct_name
3989
3990// R831
3991// do_variable is scalar-int-variable-name
3992do_variable
3993 : T_IDENT
3994 { action.do_variable($T_IDENT); }
3995 ;
3996
3997// R832 do_block was block inlined in R826
3998
3999// R833
4000// TODO continue-stmt is ambiguous with same in action statement, check
4001// there for label and if
4002// label matches do-stmt label, then match end-do
4003// do_term_action_stmt added to allow block_do_construct to cover
4004// nonblock_do_construct as well
4005end_do
4006@after {
4007 action.end_do();
4008}
4009 : end_do_stmt
4010 | do_term_action_stmt
4011 ;
4012
4013// R834
4014// T_IDENT inlined for do_construct_name
4015end_do_stmt
4016@init {Token lbl = null; Token id=null;}
4017@after{checkForInclude();}
4018 : (label {lbl=$label.tk;})? T_END T_DO ( T_IDENT {id=$T_IDENT;})?
4019 end_of_stmt
4020 {action.end_do_stmt(lbl, $T_END, $T_DO, id, $end_of_stmt.tk);}
4021 | (label {lbl=$label.tk;})? T_ENDDO ( T_IDENT {id=$T_IDENT;})?
4022 end_of_stmt
4023 {action.end_do_stmt(lbl, $T_ENDDO, null, id, $end_of_stmt.tk);}
4024 ;
4025
4026// R835 nonblock_do_construct deleted as it was combined with
4027// block_do_construct to reduce backtracking
4028// Second alternative, outer_shared_do_construct (nested loops sharing a
4029// termination label) is ambiguous
4030// with do_construct in do_body, so deleted. Loop termination will have to
4031// be coordinated with
4032// the scanner to unwind nested loops sharing a common termination statement
4033// (see do_term_action_stmt).
4034
4035// R836 action_term_do_construct deleted because nonblock_do_construct
4036// combined with block_do_construct to reduce backtracking
4037
4038// R837 do_body deleted because nonblock_do_construct combined with
4039// block_do_construct to reduce backtracking
4040
4041// R838
4042// C826 (R842) A do-term-shared-stmt shall not be a goto-stmt, a return-stmt,
4043// a stop-stmt, an exit-stmt, a cyle-stmt, an end-function-stmt, an
4044// end-subroutine-stmt, an end-program-stmt, or an arithmetic-if-stmt.
4045// TODO need interaction with scanner to have this extra terminal emitted
4046// when do label matched
4047// TODO need interaction with scanner to terminate shared terminal action
4048// statements (see R835).
4049do_term_action_stmt
4050@init { Token id=null; Token endToken = null; Token doToken = null;}
4051@after{checkForInclude();}
4052 // try requiring an action_stmt and then we can simply insert the new
4053 // T_LABEL_DO_TERMINAL during the Sale's prepass. T_EOS is in action_stmt.
4054 // added the T_END T_DO and T_ENDDO options to this rule because of the
4055 // token T_LABEL_DO_TERMINAL that is inserted if they end a labeled DO.
4056 : label T_LABEL_DO_TERMINAL
4057 (action_stmt | ( (T_END T_DO {endToken=$T_END; doToken=$T_DO;}
4058 | T_ENDDO {endToken=$T_ENDDO; doToken=null;})
4059 (T_IDENT {id=$T_IDENT;})?) end_of_stmt)
4060 // BMR- Has to massage the rule a little bit to convince Antlr that thre aren't potentially two identifiers here. Original is below.
4061 // (action_stmt | ( (T_END T_DO (T_IDENT {id=$T_IDENT;})?) | (T_ENDDO) (T_IDENT {id=$T_IDENT;})? ) T_EOS)
4062 {action.do_term_action_stmt($label.tk, endToken, doToken, id,
4063 $end_of_stmt.tk);}
4064// : T_LABEL_DO_TERMINAL action_stmt
4065// : T_LABEL_DO_TERMINAL action_or_cont_stmt
4066 ;
4067
4068// R839 outer_shared_do_construct removed because it caused ambiguity in
4069// R835 (see comment in R835)
4070
4071// R840 shared_term_do_construct deleted (see comments for R839 and R835)
4072
4073// R841 inner_shared_do_construct deleted (see comments for R839 and R835)
4074
4075// R842 do_term_shared_stmt deleted (see comments for R839 and R835)
4076
4077// R843
4078// T_IDENT inlined for do_construct_name
4079cycle_stmt
4080@init {Token lbl = null; Token id = null;}
4081@after{checkForInclude();}
4082 : (label {lbl=$label.tk;})? T_CYCLE (T_IDENT {id=$T_IDENT;})? end_of_stmt
4083 { action.cycle_stmt(lbl, $T_CYCLE, id, $end_of_stmt.tk); }
4084 ;
4085
4086// R844
4087// T_IDENT inlined for do_construct_name
4088exit_stmt
4089@init {Token lbl = null; Token id = null;}
4090@after{checkForInclude();}
4091 : (label {lbl=$label.tk;})? T_EXIT (T_IDENT {id=$T_IDENT;})? end_of_stmt
4092 { action.exit_stmt(lbl, $T_EXIT, id, $end_of_stmt.tk); }
4093 ;
4094
4095// R845
4096goto_stmt
4097@init {Token lbl=null;
4098 Token goto_target=null;
4099 Token goKeyword=null;
4100 Token toKeyword=null;}
4101@after{checkForInclude();}
4102 : (label {lbl=$label.tk;})?
4103 ( T_GO T_TO { goKeyword=$T_GO; toKeyword=$T_TO;}
4104 | T_GOTO { goKeyword=$T_GOTO; toKeyword=null;}
4105 )
4106 T_DIGIT_STRING {goto_target=$T_DIGIT_STRING;} end_of_stmt
4107 { action.goto_stmt(lbl, goKeyword, toKeyword, goto_target, $end_of_stmt.tk); }
4108 ;
4109
4110// R846
4111// ERR_CHK 846 scalar_int_expr replaced by expr
4112computed_goto_stmt
4113@init {Token lbl = null; Token goKeyword=null; Token toKeyword=null;}
4114@after{checkForInclude();}
4115 : (label {lbl=$label.tk;})?
4116 (T_GO T_TO {goKeyword=$T_GO; toKeyword=$T_TO;}
4117 | T_GOTO {goKeyword=$T_GOTO; toKeyword=null;})
4118 T_LPAREN label_list T_RPAREN ( T_COMMA )? expr end_of_stmt
4119 { action.computed_goto_stmt(lbl, goKeyword, toKeyword,
4120 $end_of_stmt.tk); }
4121 ;
4122
4123// The ASSIGN statement is a deleted feature.
4124assign_stmt
4125@after{checkForInclude();}
4126 : (lbl1=label)? T_ASSIGN lbl2=label T_TO name end_of_stmt
4127 { action.assign_stmt(lbl1, $T_ASSIGN, lbl2, $T_TO, $name.tk,
4128 $end_of_stmt.tk); }
4129 ;
4130
4131// The assigned GOTO statement is a deleted feature.
4132assigned_goto_stmt
4133@init {Token goKeyword=null; Token toKeyword=null;}
4134@after{checkForInclude();}
4135 : (label)? ( T_GOTO {goKeyword=$T_GOTO; toKeyword=null;}
4136 | T_GO T_TO {goKeyword=$T_GO; toKeyword=$T_TO;} )
4137 name (T_COMMA stmt_label_list)? end_of_stmt
4138 { action.assigned_goto_stmt($label.tk, goKeyword, toKeyword,
4139 $name.tk, $end_of_stmt.tk); }
4140 ;
4141
4142// Used with assigned_goto_stmt (deleted feature)
4143stmt_label_list
4144 : T_LPAREN label ( T_COMMA label )* T_RPAREN
4145 { action.stmt_label_list(); }
4146 ;
4147
4148// The PAUSE statement is a deleted feature.
4149pause_stmt
4150@init {Token tmpToken=null;}
4151@after{checkForInclude();}
4152 : (lbl1=label)? T_PAUSE (lbl2=label {tmpToken=lbl2;}
4153 | char_literal_constant {tmpToken=null;})? end_of_stmt
4154 { action.pause_stmt(lbl1, $T_PAUSE, tmpToken,
4155 $end_of_stmt.tk); }
4156 ;
4157
4158// R847
4159// ERR_CHK 847 scalar_numeric_expr replaced by expr
4160arithmetic_if_stmt
4161@after{checkForInclude();}
4162 : (lbl=label)? T_ARITHMETIC_IF_STMT T_IF
4163 T_LPAREN expr T_RPAREN label1=label
4164 T_COMMA label2=label
4165 T_COMMA label3=label end_of_stmt
4166 { action.arithmetic_if_stmt(lbl, $T_IF, label1, label2, label3,
4167 $end_of_stmt.tk); }
4168 ;
4169
4170// R848 continue_stmt
4171continue_stmt
4172@init {Token lbl = null;}
4173@after{checkForInclude();}
4174 : (label {lbl=$label.tk;})? T_CONTINUE end_of_stmt
4175 { action.continue_stmt(lbl, $T_CONTINUE, $end_of_stmt.tk); }
4176 ;
4177
4178// R849
4179stop_stmt
4180@init {Token lbl = null; boolean hasStopCode = false;}
4181@after{checkForInclude();}
4182 : (label {lbl=$label.tk;})? T_STOP (stop_code {hasStopCode=true;})?
4183 end_of_stmt
4184 { action.stop_stmt(lbl, $T_STOP, $end_of_stmt.tk, hasStopCode); }
4185 ;
4186
4187// R850
4188// ERR_CHK 850 T_DIGIT_STRING must be 5 digits or less
4189stop_code
4190 : scalar_char_constant
4191 { action.stop_code(null); }
4192// | Digit ( Digit ( Digit ( Digit ( Digit )? )? )? )?
4193 | T_DIGIT_STRING
4194 { action.stop_code($T_DIGIT_STRING); }
4195 ;
4196
4197/*
4198 * R856-F08 errorstop-stmt
4199 * is ERROR STOP [ stop-code ]
4200 */
4201
4202////////////
4203// R856-F08
4204//
4205errorstop_stmt
4206@init {Token lbl = null; boolean hasStopCode = false;}
4207@after{checkForInclude();}
4208 : (label {lbl=$label.tk;})? T_ERROR T_STOP (stop_code {hasStopCode=true;})?
4209 end_of_stmt
4210 { action.errorstop_stmt(lbl, $T_ERROR, $T_STOP, $end_of_stmt.tk, hasStopCode); }
4211 ;
4212
4213/*
4214 * R858-F08 sync-all-stmt
4215 * is SYNC ALL [([ sync-stat-list ])]
4216 */
4217
4218////////////
4219// R858-F08
4220//
4221sync_all_stmt
4222@init {Token lbl = null; boolean hasSyncStatList = false;}
4223@after{checkForInclude();}
4224 : (label {lbl=$label.tk;})? T_SYNC T_ALL
4225 (T_LPAREN T_RPAREN)? end_of_stmt
4226 { action.sync_all_stmt(lbl, $T_SYNC, $T_ALL, $end_of_stmt.tk, hasSyncStatList); }
4227 | (label {lbl=$label.tk;})? T_SYNC T_ALL
4228 T_LPAREN sync_stat_list T_RPAREN end_of_stmt
4229 { action.sync_all_stmt(lbl, $T_SYNC, $T_ALL, $end_of_stmt.tk, true); }
4230 ;
4231
4232
4233/*
4234 * R859-F08 sync-stat
4235 * is STAT = stat-variable
4236 * or ERRMSG = errmsg-variable
4237 */
4238
4239////////////
4240// R859-F08
4241//
4242sync_stat
4243 : T_IDENT T_EQUALS expr // expr is a stat-variable or an errmsg-variable
4244 /* {'STAT','ERRMSG'} exprs are variables */
4245 { action.sync_stat($T_IDENT); }
4246 ;
4247
4248sync_stat_list
4249@init{int count=0;}
4250 : {action.sync_stat_list__begin();}
4251 sync_stat {count++;} ( T_COMMA sync_stat {count++;} )*
4252 {action.sync_stat_list(count);}
4253 ;
4254
4255
4256/*
4257 * R860-F08 sync-images-stmt
4258 * is SYNC IMAGES ( image-set [, sync-stat-list ] )
4259 */
4260
4261////////////
4262// R860-F08
4263//
4264sync_images_stmt
4265@init {Token lbl = null; boolean hasSyncStatList = false;}
4266@after{checkForInclude();}
4267 : (label {lbl=$label.tk;})? T_SYNC T_IMAGES
4268 T_LPAREN image_set (T_COMMA sync_stat_list {hasSyncStatList=true;})? T_RPAREN
4269 end_of_stmt
4270 { action.sync_images_stmt(lbl, $T_SYNC, $T_IMAGES, $end_of_stmt.tk, hasSyncStatList); }
4271 ;
4272
4273
4274/*
4275 * R861-F08 image-set
4276 * is int-expr
4277 * or *
4278 */
4279
4280////////////
4281// R861-F08
4282//
4283image_set
4284@init {Token asterisk = null; boolean hasIntExpr = false;}
4285 : expr
4286 { hasIntExpr = true; action.image_set(asterisk, hasIntExpr); }
4287 | T_ASTERISK
4288 { asterisk = $T_ASTERISK; action.image_set(asterisk, hasIntExpr); }
4289 ;
4290
4291
4292/*
4293 * R862-F08 sync-memory-stmt
4294 * is SYNC MEMORY [([ sync-stat-list ])]
4295 */
4296
4297////////////
4298// R862-F08
4299//
4300sync_memory_stmt
4301@init {Token lbl = null; boolean hasSyncStatList = false;}
4302@after{checkForInclude();}
4303 : (label {lbl=$label.tk;})? T_SYNC T_MEMORY
4304 (T_LPAREN T_RPAREN)? end_of_stmt
4305 { action.sync_memory_stmt(lbl, $T_SYNC, $T_MEMORY, $end_of_stmt.tk, hasSyncStatList); }
4306 | (label {lbl=$label.tk;})? T_SYNC T_MEMORY
4307 T_LPAREN sync_stat_list T_RPAREN end_of_stmt
4308 { action.sync_memory_stmt(lbl, $T_SYNC, $T_MEMORY, $end_of_stmt.tk, true); }
4309 ;
4310
4311
4312/*
4313 * R863-F08 lock-stmt
4314 * is LOCK ( lock-variable [, lock-stat-list ] )
4315 */
4316
4317////////////
4318// R863-F08
4319//
4320// ERR_CHK 863 lock_variable replaced by variable
4321lock_stmt
4322@init {Token lbl = null; boolean hasLockStatList = false;}
4323@after{checkForInclude();}
4324 : (label {lbl=$label.tk;})? T_LOCK T_LPAREN variable
4325 (T_COMMA lock_stat_list {hasLockStatList=true;})? T_RPAREN
4326 end_of_stmt
4327 { action.lock_stmt(lbl, $T_LOCK, $end_of_stmt.tk, hasLockStatList); }
4328 ;
4329
4330/*
4331 * R864-F08 lock-stat
4332 * is ACQUIRED_LOCK = scalar-logical-variable
4333 * or sync-stat
4334 */
4335
4336////////////
4337// R864-F08
4338//
4339// TODO - replace expr with scalar_logical_variable
4340lock_stat
4341 : T_ACQUIRED_LOCK T_EQUALS expr // expr is a scalar-logical-variable
4342 { action.lock_stat($T_ACQUIRED_LOCK); }
4343 | sync_stat
4344 ;
4345
4346lock_stat_list
4347@init{int count=0;}
4348 : {action.lock_stat_list__begin();}
4349 lock_stat {count++;} ( T_COMMA lock_stat {count++;} )*
4350 {action.lock_stat_list(count);}
4351 ;
4352
4353/*
4354 * R865-F08 unlock-stmt
4355 * is UNLOCK ( lock-variable [, lock-stat-list ] )
4356 */
4357
4358////////////
4359// R865-F08
4360//
4361// ERR_CHK 865 lock_variable replaced by expr
4362unlock_stmt
4363@init {Token lbl = null; boolean hasSyncStatList = false;}
4364@after{checkForInclude();}
4365 : (label {lbl=$label.tk;})?
4366 T_UNLOCK T_LPAREN variable (T_COMMA sync_stat_list {hasSyncStatList=true;})?
4367 T_RPAREN end_of_stmt
4368 {action.unlock_stmt(lbl, $T_UNLOCK, $end_of_stmt.tk, hasSyncStatList);}
4369 ;
4370
4371scalar_char_constant
4372 : char_constant
4373 { action.scalar_char_constant(); }
4374 ;
4375
4376/**
4377 * Section/Clause 9: Input/output statements
4378 */
4379
4380// R901
4381// file_unit_number replaced by expr
4382// internal_file_variable isa expr so internal_file_variable deleted
4383io_unit
4384@after {
4385 action.io_unit();
4386}
4387 : expr
4388 | T_ASTERISK
4389 ;
4390
4391// R902
4392// ERR_CHK 902 scalar_int_expr replaced by expr
4393file_unit_number
4394@after {
4395 action.file_unit_number();
4396}
4397 : expr
4398 ;
4399
4400// R903 internal_file_variable was char_variable inlined (and then deleted)
4401// in R901
4402
4403// R904
4404open_stmt
4405@init {Token lbl = null;}
4406@after{checkForInclude();}
4407 : (label {lbl=$label.tk;})? T_OPEN T_LPAREN connect_spec_list
4408 T_RPAREN end_of_stmt
4409 {action.open_stmt(lbl, $T_OPEN, $end_of_stmt.tk);}
4410 ;
4411
4412// R905
4413// ERR_CHK 905 check expr type with identifier
4414connect_spec
4415 : expr
4416 { action.connect_spec(null); }
4417 | T_IDENT
4418 /* {'UNIT','ACCESS','ACTION','ASYNCHRONOUS','BLANK','DECIMAL', */
4419 /* 'DELIM','ENCODING'} are expr */
4420 /* {'ERR'} is T_DIGIT_STRING */
4421 /* {'FILE','FORM'} are expr */
4422 /* {'IOMSG','IOSTAT'} are variables */
4423 /* {'PAD','POSITION','RECL','ROUND','SIGN','STATUS'} are expr */
4424 T_EQUALS expr
4425 { action.connect_spec($T_IDENT); }
4426 ;
4427
4428connect_spec_list
4429@init{ int count=0;}
4430 : {action.connect_spec_list__begin();}
4431 connect_spec {count++;} ( T_COMMA connect_spec {count++;} )*
4432 {action.connect_spec_list(count);}
4433 ;
4434
4435// inlined scalar_default_char_expr
4436
4437// R906 inlined file_name_expr with expr was scalar_default_char_expr
4438
4439// R907 iomsg_variable inlined as scalar_default_char_variable in
4440// R905,R909,R913,R922,R926,R928
4441
4442// R908
4443close_stmt
4444@init {Token lbl = null;}
4445@after{checkForInclude();}
4446 : (label {lbl=$label.tk;})? T_CLOSE T_LPAREN close_spec_list
4447 T_RPAREN end_of_stmt
4448 {action.close_stmt(lbl, $T_CLOSE, $end_of_stmt.tk);}
4449 ;
4450
4451// R909
4452// file_unit_number, scalar_int_variable, iomsg_variable, label replaced
4453// by expr
4454close_spec
4455 : expr
4456 { action.close_spec(null); }
4457 | T_IDENT /* {'UNIT','IOSTAT','IOMSG','ERR','STATUS'} */ T_EQUALS expr
4458 { action.close_spec($T_IDENT); }
4459 ;
4460
4461close_spec_list
4462@init{ int count=0;}
4463 : {action.close_spec_list__begin();}
4464 close_spec {count++;} ( T_COMMA close_spec {count++;} )*
4465 {action.close_spec_list(count);}
4466 ;
4467
4468// R910
4469read_stmt
4470options {k=3;}
4471@init {Token lbl = null; boolean hasInputItemList=false;}
4472@after{checkForInclude();}
4473 : ((label)? T_READ T_LPAREN) =>
4474 (label {lbl=$label.tk;})? T_READ T_LPAREN io_control_spec_list
4475 T_RPAREN ( input_item_list {hasInputItemList=true;})? end_of_stmt
4476 {action.read_stmt(lbl, $T_READ, $end_of_stmt.tk,
4477 hasInputItemList);}
4478 | ((label)? T_READ) =>
4479 (label {lbl=$label.tk;})? T_READ format
4480 ( T_COMMA input_item_list {hasInputItemList=true;})? end_of_stmt
4481 {action.read_stmt(lbl, $T_READ, $end_of_stmt.tk,
4482 hasInputItemList);}
4483 ;
4484
4485// R911
4486write_stmt
4487@init {Token lbl = null; boolean hasOutputItemList=false;}
4488@after{checkForInclude();}
4489 : (label {lbl=$label.tk;})? T_WRITE T_LPAREN io_control_spec_list
4490 T_RPAREN ( output_item_list {hasOutputItemList=true;})? end_of_stmt
4491 { action.write_stmt(lbl, $T_WRITE, $end_of_stmt.tk,
4492 hasOutputItemList); }
4493 ;
4494
4495// R912
4496print_stmt
4497@init {Token lbl = null; boolean hasOutputItemList=false;}
4498@after{checkForInclude();}
4499 : (label {lbl=$label.tk;})? T_PRINT format
4500 ( T_COMMA output_item_list {hasOutputItemList=true;})? end_of_stmt
4501 { action.print_stmt(lbl, $T_PRINT, $end_of_stmt.tk,
4502 hasOutputItemList); }
4503 ;
4504
4505// R913
4506// ERR_CHK 913 check expr type with identifier
4507// io_unit and format are both (expr|'*') so combined
4508io_control_spec
4509 : expr
4510 // hasExpression=true
4511 { action.io_control_spec(true, null, false); }
4512 | T_ASTERISK
4513 // hasAsterisk=true
4514 { action.io_control_spec(false, null, true); }
4515 | T_IDENT /* {'UNIT','FMT'} */ T_EQUALS T_ASTERISK
4516 // hasAsterisk=true
4517 { action.io_control_spec(false, $T_IDENT, true); }
4518 | T_IDENT
4519 /* {'UNIT','FMT'} are expr 'NML' is T_IDENT} */
4520 /* {'ADVANCE','ASYNCHRONOUS','BLANK','DECIMAL','DELIM'} are expr */
4521 /* {'END','EOR','ERR'} are labels */
4522 /* {'ID','IOMSG',IOSTAT','SIZE'} are variables */
4523 /* {'PAD','POS','REC','ROUND','SIGN'} are expr */
4524 T_EQUALS expr
4525 // hasExpression=true
4526 { action.io_control_spec(true, $T_IDENT, false); }
4527 ;
4528
4529
4530io_control_spec_list
4531@init{ int count=0;}
4532 : {action.io_control_spec_list__begin();}
4533 io_control_spec {count++;} ( T_COMMA io_control_spec {count++;} )*
4534 {action.io_control_spec_list(count);}
4535 ;
4536
4537// R914
4538// ERR_CHK 914 default_char_expr replaced by expr
4539// label replaced by T_DIGIT_STRING is expr so deleted
4540format
4541@after {
4542 action.format();
4543}
4544 : expr
4545 | T_ASTERISK
4546 ;
4547
4548// R915
4549input_item
4550@after {
4551 action.input_item();
4552}
4553 : variable
4554 | io_implied_do
4555 ;
4556
4557input_item_list
4558@init{ int count=0;}
4559 : {action.input_item_list__begin();}
4560 input_item {count++;} ( T_COMMA input_item {count++;} )*
4561 {action.input_item_list(count);}
4562 ;
4563
4564// R916
4565output_item
4566options {backtrack=true;}
4567@after {
4568 action.output_item();
4569}
4570 : expr
4571 | io_implied_do
4572 ;
4573
4574
4575output_item_list
4576@init{ int count=0;}
4577 : {action.output_item_list__begin();}
4578 output_item {count++;} ( T_COMMA output_item {count++;} )*
4579 {action.output_item_list(count);}
4580 ;
4581
4582// R917
4583io_implied_do
4584 : T_LPAREN io_implied_do_object io_implied_do_suffix T_RPAREN
4585 { action.io_implied_do(); }
4586 ;
4587
4588// R918
4589// expr in output_item can be variable in input_item so input_item deleted
4590io_implied_do_object
4591 : output_item
4592 { action.io_implied_do_object(); }
4593 ;
4594
4595io_implied_do_suffix
4596options {backtrack=true;}
4597 : T_COMMA io_implied_do_object io_implied_do_suffix
4598 | T_COMMA io_implied_do_control
4599 ;
4600
4601// R919
4602// ERR_CHK 919 scalar_int_expr replaced by expr
4603io_implied_do_control
4604@init{boolean hasStride=false;}
4605 : do_variable T_EQUALS expr T_COMMA expr ( T_COMMA expr {hasStride=true;})?
4606 { action.io_implied_do_control(hasStride); }
4607 ;
4608
4609// R920
4610// TODO: remove this? it is never called.
4611dtv_type_spec
4612 : T_TYPE
4613 T_LPAREN
4614 derived_type_spec
4615 T_RPAREN
4616 { action.dtv_type_spec($T_TYPE); }
4617 | T_CLASS
4618 T_LPAREN
4619 derived_type_spec
4620 T_RPAREN
4621 { action.dtv_type_spec($T_CLASS); }
4622 ;
4623
4624// R921
4625wait_stmt
4626@init {Token lbl = null;}
4627@after{checkForInclude();}
4628 : (label {lbl=$label.tk;})? T_WAIT T_LPAREN wait_spec_list T_RPAREN
4629 end_of_stmt
4630 {action.wait_stmt(lbl, $T_WAIT, $end_of_stmt.tk);}
4631 ;
4632
4633// R922
4634// file_unit_number, scalar_int_variable, iomsg_variable, label replaced
4635// by expr
4636wait_spec
4637 : expr
4638 { action.wait_spec(null); }
4639 | T_IDENT /* {'UNIT','END','EOR','ERR','ID','IOMSG','IOSTAT'} */
4640 T_EQUALS expr
4641 { action.wait_spec($T_IDENT); }
4642 ;
4643
4644
4645wait_spec_list
4646@init{ int count=0;}
4647 : {action.wait_spec_list__begin();}
4648 wait_spec {count++;} ( T_COMMA wait_spec {count++;} )*
4649 {action.wait_spec_list(count);}
4650 ;
4651
4652// R923
4653backspace_stmt
4654options {k=3;}
4655@init {Token lbl = null;}
4656@after{checkForInclude();}
4657 : ((label)? T_BACKSPACE T_LPAREN) =>
4658 (label {lbl=$label.tk;})? T_BACKSPACE T_LPAREN position_spec_list
4659 T_RPAREN end_of_stmt
4660 {action.backspace_stmt(lbl, $T_BACKSPACE, $end_of_stmt.tk, true);}
4661 | ((label)? T_BACKSPACE) =>
4662 (label {lbl=$label.tk;})? T_BACKSPACE file_unit_number end_of_stmt
4663 {action.backspace_stmt(lbl, $T_BACKSPACE, $end_of_stmt.tk, false);}
4664 ;
4665
4666// R924
4667endfile_stmt
4668options {k=3;}
4669@init {Token lbl = null;}
4670@after{checkForInclude();}
4671 : ((label)? T_END T_FILE T_LPAREN) =>
4672 (label {lbl=$label.tk;})? T_END T_FILE T_LPAREN position_spec_list
4673 T_RPAREN end_of_stmt
4674 {action.endfile_stmt(lbl, $T_END, $T_FILE, $end_of_stmt.tk, true);}
4675 | ((label)? T_ENDFILE T_LPAREN) =>
4676 (label {lbl=$label.tk;})? T_ENDFILE T_LPAREN position_spec_list
4677 T_RPAREN end_of_stmt
4678 {action.endfile_stmt(lbl, $T_ENDFILE, null, $end_of_stmt.tk,
4679 true);}
4680 | ((label)? T_END T_FILE) =>
4681 (label {lbl=$label.tk;})? T_END T_FILE file_unit_number end_of_stmt
4682 {action.endfile_stmt(lbl, $T_END, $T_FILE, $end_of_stmt.tk,
4683 false);}
4684 | ((label)? T_ENDFILE) =>
4685 (label {lbl=$label.tk;})? T_ENDFILE file_unit_number end_of_stmt
4686 {action.endfile_stmt(lbl, $T_ENDFILE, null, $end_of_stmt.tk,
4687 false);}
4688 ;
4689
4690// R925
4691rewind_stmt
4692options {k=3;}
4693@init {Token lbl = null;}
4694@after{checkForInclude();}
4695 : ((label)? T_REWIND T_LPAREN) =>
4696 (label {lbl=$label.tk;})? T_REWIND T_LPAREN position_spec_list
4697 T_RPAREN end_of_stmt
4698 {action.rewind_stmt(lbl, $T_REWIND, $end_of_stmt.tk, true);}
4699 | ((label)? T_REWIND) =>
4700 (label {lbl=$label.tk;})? T_REWIND file_unit_number end_of_stmt
4701 {action.rewind_stmt(lbl, $T_REWIND, $end_of_stmt.tk, false);}
4702 ;
4703
4704// R926
4705// file_unit_number, scalar_int_variable, iomsg_variable, label replaced
4706// by expr
4707position_spec
4708 : expr
4709 { action.position_spec(null); }
4710 | T_IDENT /* {'UNIT','IOSTAT','IOMSG','ERR'} */ T_EQUALS expr
4711 { action.position_spec($T_IDENT); }
4712 ;
4713
4714position_spec_list
4715@init{ int count=0;}
4716 : {action.position_spec_list__begin();}
4717 position_spec {count++;} ( T_COMMA position_spec {count++;} )*
4718 {action.position_spec_list(count);}
4719 ;
4720
4721// R927
4722flush_stmt
4723options {k=3;}
4724@init {Token lbl = null;}
4725@after{checkForInclude();}
4726 : ((label)? T_FLUSH T_LPAREN) =>
4727 (label {lbl=$label.tk;})? T_FLUSH T_LPAREN flush_spec_list
4728 T_RPAREN end_of_stmt
4729 {action.flush_stmt(lbl, $T_FLUSH, $end_of_stmt.tk, true);}
4730 | ((label)? T_FLUSH) =>
4731 (label {lbl=$label.tk;})? T_FLUSH file_unit_number end_of_stmt
4732 {action.flush_stmt(lbl, $T_FLUSH, $end_of_stmt.tk, false);}
4733 ;
4734
4735// R928
4736// file_unit_number, scalar_int_variable, iomsg_variable, label replaced
4737// by expr
4738flush_spec
4739 : expr
4740 { action.flush_spec(null); }
4741 | T_IDENT /* {'UNIT','IOSTAT','IOMSG','ERR'} */ T_EQUALS expr
4742 { action.flush_spec($T_IDENT); }
4743 ;
4744
4745flush_spec_list
4746@init{ int count=0;}
4747 : {action.flush_spec_list__begin();}
4748 flush_spec {count++;} ( T_COMMA flush_spec {count++;} )*
4749 {action.flush_spec_list(count);}
4750 ;
4751
4752// R929
4753inquire_stmt
4754@init {Token lbl = null;}
4755@after{checkForInclude();}
4756 : (label {lbl=$label.tk;})? T_INQUIRE T_LPAREN inquire_spec_list
4757 T_RPAREN end_of_stmt
4758 {action.inquire_stmt(lbl, $T_INQUIRE, null, $end_of_stmt.tk,
4759 false);}
4760 | (label {lbl=$label.tk;})? T_INQUIRE_STMT_2
4761 T_INQUIRE T_LPAREN T_IDENT /* 'IOLENGTH' */ T_EQUALS
4762 scalar_int_variable T_RPAREN output_item_list end_of_stmt
4763 {action.inquire_stmt(lbl, $T_INQUIRE, $T_IDENT,
4764 $end_of_stmt.tk, true);}
4765 ;
4766
4767
4768// R930
4769// ERR_CHK 930 file_name_expr replaced by expr
4770// file_unit_number replaced by expr
4771// scalar_default_char_variable replaced by designator
4772inquire_spec
4773 : expr
4774 { action.inquire_spec(null); }
4775 | T_IDENT
4776 /* {'UNIT','FILE'} '=' expr portion, '=' designator portion below
4777 {'ACCESS','ACTION','ASYNCHRONOUS','BLANK','DECIMAL',DELIM','DIRECT'}
4778 {'ENCODING','ERR','EXIST','FORM','FORMATTED','ID','IOMSG','IOSTAT'}
4779 {'NAME','NAMED','NEXTREC','NUMBER',OPENED','PAD','PENDING','POS'}
4780 {'POSITION','READ','READWRITE','RECL','ROUND','SEQUENTIAL','SIGN'}
4781 {'SIZE','STREAM','UNFORMATTED','WRITE'} */
4782 T_EQUALS expr
4783 { action.inquire_spec($T_IDENT); }
4784 ;
4785
4786inquire_spec_list
4787@init{ int count=0;}
4788 : {action.inquire_spec_list__begin();}
4789 inquire_spec {count++;} ( T_COMMA inquire_spec {count++;} )*
4790 {action.inquire_spec_list(count);}
4791 ;
4792
4793/**
4794 * Section/Clause 10: Input/output editing
4795 */
4796
4797// R1001
4798// TODO: error checking: label is required. accept as optional so we can
4799// report the error to the user.
4800format_stmt
4801@init {Token lbl = null;}
4802@after{checkForInclude();}
4803 : (label {lbl=$label.tk;})? T_FORMAT format_specification end_of_stmt
4804 {action.format_stmt(lbl, $T_FORMAT, $end_of_stmt.tk);}
4805 ;
4806
4807// R1002
4808format_specification
4809@init{ boolean hasFormatItemList=false; }
4810 : T_LPAREN ( format_item_list {hasFormatItemList=true;})? T_RPAREN
4811 {action.format_specification(hasFormatItemList);}
4812 ;
4813
4814// R1003
4815// r replaced by int_literal_constant replaced by char_literal_constant
4816// replaced by T_CHAR_CONSTANT
4817// char_string_edit_desc replaced by T_CHAR_CONSTANT
4818format_item
4819@init{ Token descOrDigit=null; boolean hasFormatItemList=false; }
4820 : T_DATA_EDIT_DESC
4821 {action.format_item($T_DATA_EDIT_DESC,hasFormatItemList);}
4822 | T_CONTROL_EDIT_DESC
4823 {action.format_item($T_CONTROL_EDIT_DESC,hasFormatItemList);}
4824 | T_CHAR_STRING_EDIT_DESC
4825 {action.format_item($T_CHAR_STRING_EDIT_DESC,hasFormatItemList);}
4826 | (T_DIGIT_STRING {descOrDigit=$T_DIGIT_STRING;} )? T_LPAREN
4827 format_item_list T_RPAREN
4828 {action.format_item(descOrDigit,hasFormatItemList);}
4829 ;
4830
4831// the comma is not always required. see J3/04-007, pg. 221, lines
4832// 17-22
4833// ERR_CHK
4834format_item_list
4835@init{ int count=1;}
4836 : {action.format_item_list__begin();}
4837 format_item ( (T_COMMA)? format_item {count++;} )*
4838 {action.format_item_list(count);}
4839 ;
4840
4841
4842// the following rules, from here to the v_list, are the originals. modifying
4843// to try and simplify and make match up with the standard.
4844// original rules. 02.01.07
4845// // R1003
4846// // r replaced by int_literal_constant replaced by char_literal_constant replaced by T_CHAR_CONSTANT
4847// // char_string_edit_desc replaced by T_CHAR_CONSTANT
4848// format_item
4849// : T_DIGIT_STRING data_edit_desc
4850// | data_plus_control_edit_desc
4851// | T_CHAR_CONSTANT
4852// | (T_DIGIT_STRING)? T_LPAREN format_item_list T_RPAREN
4853// ;
4854
4855// format_item_list
4856// : format_item ( T_COMMA format_item )*
4857// ;
4858
4859// // R1004 r inlined in R1003 and R1011 as int_literal_constant (then as DIGIT_STRING)
4860// // C1004 (R1004) r shall not have a kind parameter associated with it
4861
4862// // R1005
4863// // w,m,d,e replaced by int_literal_constant replaced by T_DIGIT_STRING
4864// // char_literal_constant replaced by T_CHAR_CONSTANT
4865// // ERR_CHK 1005 matching T_ID_OR_OTHER with alternatives will have to be done here
4866// data_edit_desc
4867// : T_ID_OR_OTHER /* {'I','B','O','Z','F','E','EN','ES','G','L','A','D'} */
4868// T_DIGIT_STRING ( T_PERIOD T_DIGIT_STRING )?
4869// ( T_ID_OR_OTHER /* is 'E' */ T_DIGIT_STRING )?
4870// | T_ID_OR_OTHER /* is 'DT' */ T_CHAR_CONSTANT ( T_LPAREN v_list T_RPAREN )?
4871// | T_ID_OR_OTHER /* {'A','DT'},{'X','P' from control_edit_desc} */
4872// ;
4873
4874// data_plus_control_edit_desc
4875// : T_ID_OR_OTHER /* {'I','B','O','Z','F','E','EN','ES','G','L','A','D'},{T','TL','TR'} */
4876// T_DIGIT_STRING ( T_PERIOD T_DIGIT_STRING )?
4877// ( T_ID_OR_OTHER /* is 'E' */ T_DIGIT_STRING )?
4878// | T_ID_OR_OTHER /* is 'DT' */ T_CHAR_CONSTANT ( T_LPAREN v_list T_RPAREN )?
4879// | T_ID_OR_OTHER /* {'A','DT'},{'BN','BZ','RU','RD','RZ','RN','RC','RP','DC','DP'} */
4880// // following only from control_edit_desc
4881// | ( T_DIGIT_STRING )? T_SLASH
4882// | T_COLON
4883// | (T_PLUS|T_MINUS) T_DIGIT_STRING T_ID_OR_OTHER /* is 'P' */
4884// ;
4885
4886// R1006 w inlined in R1005 as int_literal_constant replaced by T_DIGIT_STRING
4887
4888// R1007 m inlined in R1005 as int_literal_constant replaced by T_DIGIT_STRING
4889
4890// R1008 d inlined in R1005 as int_literal_constant replaced by T_DIGIT_STRING
4891
4892// R1009 e inlined in R1005 as int_literal_constant replaced by T_DIGIT_STRING
4893
4894// R1010 v inlined as signed_int_literal_constant in v_list replaced by (T_PLUS or T_MINUS) T_DIGIT_STRING
4895
4896v_list
4897@init{int count=0;}
4898 : {action.v_list__begin();}
4899 (pm=T_PLUS|T_MINUS)? ds=T_DIGIT_STRING
4900 {
4901 count++;
4902 action.v_list_part(pm, ds);
4903 }
4904 ( T_COMMA (pm=T_PLUS|T_MINUS)? ds=T_DIGIT_STRING
4905 {
4906 count++;
4907 action.v_list_part(pm, ds);
4908 }
4909 )*
4910 {action.v_list(count);}
4911 ;
4912
4913// R1011 control_edit_desc inlined/combined in R1005 and data_plus_control_edit_desc
4914// r replaced by int_literal_constant replaced by T_DIGIT_STRING
4915// k replaced by signed_int_literal_constant replaced by (T_PLUS|T_MINUS)? T_DIGIT_STRING
4916// position_edit_desc inlined
4917// sign_edit_desc replaced by T_ID_OR_OTHER was {'SS','SP','S'}
4918// blank_interp_edit_desc replaced by T_ID_OR_OTHER was {'BN','BZ'}
4919// round_edit_desc replaced by T_ID_OR_OTHER was {'RU','RD','RZ','RN','RC','RP'}
4920// decimal_edit_desc replaced by T_ID_OR_OTHER was {'DC','DP'}
4921// leading T_ID_OR_OTHER alternates combined with data_edit_desc in data_plus_control_edit_desc
4922
4923// R1012 k inlined in R1011 as signed_int_literal_constant
4924// C1009 (R1012) k shall not have a kind parameter specified for it
4925
4926// R1013 position_edit_desc inlined in R1011
4927// n in R1013 was replaced by int_literal_constant replaced by T_DIGIT_STRING
4928
4929// R1014 n inlined in R1013 as int_literal_constant (is T_DIGIT_STRING, see C1010)
4930// C1010 (R1014) n shall not have a kind parameter specified for it
4931
4932// R1015 sign_edit_desc inlined in R1011 as T_ID_OR_OTHER was {'SS','SP','S'}
4933
4934// R1016 blank_interp_edit_desc inlined in R1011 as T_ID_OR_OTHER was {'BN','BZ'}
4935
4936// R1017 round_edit_desc inlined in R1011 as T_ID_OR_OTHER was {'RU','RD','RZ','RN','RC','RP'}
4937
4938// R1018 decimal_edit_desc inlined in R1011 as T_ID_OR_OTHER was {'DC','DP'}
4939
4940// R1019 char_string_edit_desc was char_literal_constant inlined in R1003 as T_CHAR_CONSTANT
4941
4942
4943/**
4944 * Section/Clause 11: Program units
4945 */
4946
4947
4948// R1102
4949// T_IDENT inlined for program_name
4950program_stmt
4951@init {Token lbl = null;} // @init{INIT_TOKEN_NULL(lbl);}
4952@after{checkForInclude();}
4953 : (label {lbl=$label.tk;})? T_PROGRAM T_IDENT end_of_stmt
4954 { action.program_stmt(lbl, $T_PROGRAM, $T_IDENT, $end_of_stmt.tk); }
4955 ;
4956
4957// R1103
4958// T_IDENT inlined for program_name
4959end_program_stmt
4960@init {Token lbl = null; Token id = null;}
4961@after {checkForInclude();}
4962 : (label {lbl=$label.tk;})? T_END T_PROGRAM (T_IDENT {id=$T_IDENT;})?
4963 end_of_stmt
4964 { action.end_program_stmt(lbl, $T_END, $T_PROGRAM, id,
4965 $end_of_stmt.tk); }
4966 | (label {lbl=$label.tk;})? T_ENDPROGRAM (T_IDENT {id=$T_IDENT;})?
4967 end_of_stmt
4968 { action.end_program_stmt(lbl, $T_ENDPROGRAM, null, id,
4969 $end_of_stmt.tk); }
4970 | (label {lbl=$label.tk;})? T_END end_of_stmt
4971 { action.end_program_stmt(lbl, $T_END, null, null,
4972 $end_of_stmt.tk); }
4973 ;
4974
4975
4976// R1104
4977// C1104 (R1104) A module specification-part shall not contain a
4978// stmt-function-stmt, an entry-stmt or a format-stmt
4979// specification_part made non-optional to remove END ambiguity (as can
4980// be empty)
4981module
4982@after {
4983 action.module();
4984}
4985 : module_stmt
4986 specification_part
4987 ( module_subprogram_part )?
4988 end_module_stmt
4989 ;
4990
4991// R1105
4992module_stmt
4993@init {Token lbl = null; Token id = null;}
4994@after{checkForInclude();}
4995 : {action.module_stmt__begin();}
4996 (label {lbl=$label.tk;})? T_MODULE ( T_IDENT {id=$T_IDENT;} )?
4997 end_of_stmt
4998 {action.module_stmt(lbl, $T_MODULE, id, $end_of_stmt.tk);}
4999 ;
5000
5001
5002// R1106
5003end_module_stmt
5004@init {Token lbl = null; Token id = null;}
5005@after{checkForInclude();}
5006 : (label {lbl=$label.tk;})? T_END T_MODULE (T_IDENT {id=$T_IDENT;})?
5007 end_of_stmt
5008 {action.end_module_stmt(lbl, $T_END, $T_MODULE, id,
5009 $end_of_stmt.tk);}
5010 | (label {lbl=$label.tk;})? T_ENDMODULE (T_IDENT {id=$T_IDENT;})?
5011 end_of_stmt
5012 {action.end_module_stmt(lbl, $T_ENDMODULE, null, id,
5013 $end_of_stmt.tk);}
5014 | (label {lbl=$label.tk;})? T_END end_of_stmt
5015 {action.end_module_stmt(lbl, $T_END, null, id, $end_of_stmt.tk);}
5016 ;
5017
5018
5019/*
5020 * R1107-F08 module-subprogram-part
5021 * is contains-stmt
5022 * [ module-subprogram ] ...
5023 */
5024
5025////////////
5026// R1107-F08
5027//
5028module_subprogram_part
5029@init {int count = 0;}
5030 : contains_stmt
5031 ( module_subprogram {count += 1;} )*
5032 { action.module_subprogram_part(count); }
5033 ;
5034
5035
5036/*
5037 * R1108-F08 module-subprogram
5038 * is function-subprogram
5039 * or subroutine-subprogram
5040 * or separate-module-subprogram // NEW_TO_F2008
5041 */
5042
5043////////////
5044// R1108-F08
5045//
5046// modified to factor optional prefix
5047//
5048module_subprogram
5049@init {boolean hasPrefix = false;}
5050@after{action.module_subprogram(hasPrefix);}
5051 : (prefix {hasPrefix=true;})? function_subprogram
5052 | subroutine_subprogram
5053 | separate_module_subprogram
5054 ;
5055
5056
5057// R1109
5058use_stmt
5059@init {
5060 Token lbl=null;
5061 boolean hasModuleNature=false;
5062 boolean hasRenameList=false;
5063}
5064@after{checkForInclude();}
5065 : (label {lbl=$label.tk;})? T_USE
5066 ( (T_COMMA module_nature {hasModuleNature=true;})?
5067 T_COLON_COLON )? T_IDENT ( T_COMMA
5068 rename_list {hasRenameList=true;})? end_of_stmt
5069 {action.use_stmt(lbl, $T_USE, $T_IDENT, null, $end_of_stmt.tk,
5070 hasModuleNature, hasRenameList, false);}
5071 | (label {lbl=$label.tk;})? T_USE
5072 ( ( T_COMMA module_nature {hasModuleNature=true;})?
5073 T_COLON_COLON )? T_IDENT T_COMMA T_ONLY T_COLON ( only_list )?
5074 end_of_stmt
5075 {action.use_stmt(lbl, $T_USE, $T_IDENT, $T_ONLY, $end_of_stmt.tk,
5076 hasModuleNature,hasRenameList,true);}
5077 ;
5078
5079// R1110
5080module_nature
5081 : T_INTRINSIC
5082 { action.module_nature($T_INTRINSIC); }
5083 | T_NON_INTRINSIC
5084 { action.module_nature($T_NON_INTRINSIC); }
5085 ;
5086
5087// R1111
5088// T_DEFINED_OP inlined for local_defined_operator and use_defined_operator
5089// T_IDENT inlined for local_name and use_name
5090rename
5091 : id1=T_IDENT T_EQ_GT id2=T_IDENT
5092 { action.rename(id1, id2, null, null, null, null); }
5093 | op1=T_OPERATOR T_LPAREN defOp1=T_DEFINED_OP T_RPAREN T_EQ_GT
5094 op2=T_OPERATOR T_LPAREN defOp2=T_DEFINED_OP T_RPAREN
5095 { action.rename(null, null, op1, defOp1, op2, defOp2); }
5096 ;
5097
5098rename_list
5099@init{ int count=0;}
5100 : {action.rename_list__begin();}
5101 rename {count++;} ( T_COMMA rename {count++;} )*
5102 {action.rename_list(count);}
5103 ;
5104
5105// R1112
5106// T_IDENT inlined for only_use_name
5107// generic_spec can be T_IDENT so T_IDENT deleted
5108only
5109@init{ boolean hasGenericSpec=false;
5110 boolean hasRename=false;
5111 boolean hasOnlyUseName=false;}
5112@after {
5113 action.only(hasGenericSpec, hasRename, hasOnlyUseName);
5114}
5115 : generic_spec {hasGenericSpec=true;}
5116 | rename {hasRename=true;}
5117 ;
5118
5119only_list
5120@init{ int count=0;}
5121 : {action.only_list__begin();}
5122 only {count++;} ( T_COMMA only {count++;} )*
5123 {action.only_list(count);}
5124 ;
5125
5126// R1113 only_use_name was use_name inlined as T_IDENT
5127
5128// R1114 inlined local_defined_operator in R1111 as T_DEFINED_OP
5129
5130// R1115 inlined use_defined_operator in R1111 as T_DEFINED_OP
5131
5132/*
5133 * R1116-F08 submodule
5134 * is submodule-stmt
5135 * [ specification-part ]
5136 * [ module-subprogram-part ]
5137 * end-submodule-stmt
5138 */
5139
5140////////////
5141// R1116-F08
5142//
5143submodule
5144@init {boolean hasModuleSubprogramPart = false;}
5145@after{action.submodule(hasModuleSubprogramPart);}
5146 : submodule_stmt
5147 specification_part // non-optional as can be empty
5148 ( module_subprogram_part {hasModuleSubprogramPart=true;} )?
5149 end_submodule_stmt
5150 ;
5151
5152/*
5153 * R1117-F08 submodule-stmt
5154 * is SUBMODULE ( parent-identifier ) submodule-name
5155 */
5156
5157////////////
5158// R1117-F08
5159//
5160submodule_stmt
5161@init {Token lbl = null; Token t_subname = null;}
5162@after{checkForInclude();}
5163 : {action.submodule_stmt__begin();}
5164 (label {lbl=$label.tk;})?
5165 T_SUBMODULE T_LPAREN parent_identifier T_RPAREN
5166 name {t_subname=$name.tk;} end_of_stmt
5167 {action.submodule_stmt(lbl, $T_SUBMODULE, t_subname, $end_of_stmt.tk);}
5168 ;
5169
5170
5171/*
5172 * R1118-F08 parent-identifier
5173 * is ancestor-module-name [ : parent-submodule-name ]
5174 */
5175
5176////////////
5177// R1118-F08
5178//
5179parent_identifier
5180@init {Token ancestor = null; Token parent = null;}
5181 : name {ancestor=$name.tk;}
5182 ( : T_IDENT {parent=$T_IDENT;} )?
5183 {action.parent_identifier(ancestor, parent);}
5184 ;
5185
5186
5187/*
5188 * R1119-F08 end-submodule-stmt
5189 * is END [ SUBMODULE [ submodule-name ] ]
5190 */
5191
5192////////////
5193// R1119-F08
5194//
5195end_submodule_stmt
5196@init {Token lbl = null; Token t_submod = null; Token t_name = null;}
5197@after{checkForInclude();}
5198 : (label {lbl=$label.tk;})?
5199 T_END (T_SUBMODULE (name {t_name=$name.tk;})? {t_submod=$T_SUBMODULE;})?
5200 end_of_stmt
5201 {action.end_submodule_stmt(lbl, $T_END, t_submod, t_name, $end_of_stmt.tk);}
5202 ;
5203
5204// R1116
5205// specification_part made non-optional to remove END ambiguity (as can
5206// be empty).
5207block_data
5208@after {
5209 action.block_data();
5210}
5211 : block_data_stmt
5212 specification_part
5213 end_block_data_stmt
5214 ;
5215
5216// R1117
5217block_data_stmt
5218@init
5219 {
5220 Token lbl = null; Token id = null;
5221 action.block_data_stmt__begin();
5222 }
5223@after{checkForInclude();}
5224 : (label {lbl=$label.tk;})?
5225 T_BLOCK T_DATA (T_IDENT {id=$T_IDENT;})? end_of_stmt
5226 {action.block_data_stmt(lbl, $T_BLOCK, $T_DATA, id, $end_of_stmt.tk);}
5227 | (label {lbl=$label.tk;})?
5228 T_BLOCKDATA (T_IDENT {id=$T_IDENT;})? end_of_stmt
5229 {action.block_data_stmt(lbl, $T_BLOCKDATA, null, id, $end_of_stmt.tk);}
5230 ;
5231
5232// R1118
5233end_block_data_stmt
5234@init {Token lbl = null; Token id = null;}
5235@after{checkForInclude();}
5236 : (label {lbl=$label.tk;})? T_END T_BLOCK T_DATA
5237 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
5238 {action.end_block_data_stmt(lbl, $T_END, $T_BLOCK, $T_DATA, id,
5239 $end_of_stmt.tk);}
5240 | (label {lbl=$label.tk;})? T_ENDBLOCK T_DATA
5241 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
5242 {action.end_block_data_stmt(lbl, $T_ENDBLOCK, null, $T_DATA, id,
5243 $end_of_stmt.tk);}
5244 | (label {lbl=$label.tk;})? T_END T_BLOCKDATA
5245 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
5246 {action.end_block_data_stmt(lbl, $T_END, $T_BLOCKDATA, null, id,
5247 $end_of_stmt.tk);}
5248 | (label {lbl=$label.tk;})? T_ENDBLOCKDATA
5249 ( T_IDENT {id=$T_IDENT;})? end_of_stmt
5250 {action.end_block_data_stmt(lbl, $T_ENDBLOCKDATA, null, null, id,
5251 $end_of_stmt.tk);}
5252 | (label {lbl=$label.tk;})? T_END end_of_stmt
5253 {action.end_block_data_stmt(lbl, $T_END, null, null, id,
5254 $end_of_stmt.tk);}
5255 ;
5256
5257/**
5258 * Section/Clause 12: Procedures
5259 */
5260
5261// R1201
5262interface_block
5263@after {
5264 action.interface_block();
5265}
5266 : interface_stmt
5267 ( interface_specification )*
5268 end_interface_stmt
5269 ;
5270
5271// R1202
5272interface_specification
5273@after {
5274 action.interface_specification();
5275}
5276 : interface_body
5277 | procedure_stmt
5278 ;
5279
5280// R1203 Note that the last argument to the action specifies whether this
5281// is an abstract interface or not.
5282interface_stmt
5283@init {Token lbl = null; boolean hasGenericSpec=false;}
5284@after{checkForInclude();}
5285 : {action.interface_stmt__begin();}
5286 (label {lbl=$label.tk;})? T_INTERFACE ( generic_spec
5287 {hasGenericSpec=true;})? end_of_stmt
5288 {action.interface_stmt(lbl, null, $T_INTERFACE, $end_of_stmt.tk,
5289 hasGenericSpec);}
5290 | (label {lbl=$label.tk;})? T_ABSTRACT T_INTERFACE end_of_stmt
5291 {action.interface_stmt(lbl, $T_ABSTRACT, $T_INTERFACE,
5292 $end_of_stmt.tk, hasGenericSpec);}
5293 ;
5294
5295// R1204
5296end_interface_stmt
5297@init {Token lbl = null; boolean hasGenericSpec=false;}
5298@after{checkForInclude();}
5299 : (label {lbl=$label.tk;})? T_END T_INTERFACE ( generic_spec
5300 {hasGenericSpec=true;})? end_of_stmt
5301 {action.end_interface_stmt(lbl, $T_END, $T_INTERFACE,
5302 $end_of_stmt.tk, hasGenericSpec);}
5303 | (label {lbl=$label.tk;})? T_ENDINTERFACE ( generic_spec
5304 {hasGenericSpec=true;})? end_of_stmt
5305 {action.end_interface_stmt(lbl, $T_ENDINTERFACE, null,
5306 $end_of_stmt.tk, hasGenericSpec);}
5307 ;
5308
5309// R1205
5310// specification_part made non-optional to remove END ambiguity (as can
5311// be empty)
5312interface_body
5313 : (prefix)? function_stmt specification_part end_function_stmt
5314 { action.interface_body(true); /* true for hasPrefix */ }
5315 | subroutine_stmt specification_part end_subroutine_stmt
5316 { action.interface_body(false); /* false for hasPrefix */ }
5317 ;
5318
5319// R1206
5320// generic_name_list substituted for procedure_name_list
5321procedure_stmt
5322@init {Token lbl = null; Token module=null;}
5323@after{checkForInclude();}
5324 : (label {lbl=$label.tk;})? ( T_MODULE {module=$T_MODULE;})?
5325 T_PROCEDURE generic_name_list end_of_stmt
5326 {action.procedure_stmt(lbl, module, $T_PROCEDURE,
5327 $end_of_stmt.tk);}
5328 ;
5329
5330// R1207
5331// T_IDENT inlined for generic_name
5332generic_spec
5333 : T_IDENT
5334 {action.generic_spec(null, $T_IDENT,
5335 IActionEnums.GenericSpec_generic_name);}
5336 | T_OPERATOR T_LPAREN defined_operator T_RPAREN
5337 {action.generic_spec($T_OPERATOR, null,
5338 IActionEnums.GenericSpec_OPERATOR);}
5339 | T_ASSIGNMENT T_LPAREN T_EQUALS T_RPAREN
5340 {action.generic_spec($T_ASSIGNMENT, null,
5341 IActionEnums.GenericSpec_ASSIGNMENT);}
5342 | defined_io_generic_spec
5343 { action.generic_spec(null, null,
5344 IActionEnums.GenericSpec_dtio_generic_spec); }
5345 ;
5346
5347// R1208
5348// TODO - the name has been changed from dtio_generic_spec to defined_io_generic_spec
5349// change the actions and enums as well
5350defined_io_generic_spec
5351 : T_READ T_LPAREN T_FORMATTED T_RPAREN
5352 {action.dtio_generic_spec($T_READ, $T_FORMATTED,
5353 IActionEnums.
5354 DTIOGenericSpec_READ_FORMATTED);}
5355 | T_READ T_LPAREN T_UNFORMATTED T_RPAREN
5356 {action.dtio_generic_spec($T_READ, $T_UNFORMATTED,
5357 IActionEnums.
5358 DTIOGenericSpec_READ_UNFORMATTED);}
5359 | T_WRITE T_LPAREN T_FORMATTED T_RPAREN
5360 {action.dtio_generic_spec($T_WRITE, $T_FORMATTED,
5361 IActionEnums.
5362 DTIOGenericSpec_WRITE_FORMATTED);}
5363 | T_WRITE T_LPAREN T_UNFORMATTED T_RPAREN
5364 {action.dtio_generic_spec($T_WRITE, $T_UNFORMATTED,
5365 IActionEnums.
5366 DTIOGenericSpec_WRITE_UNFORMATTED);}
5367 ;
5368
5369// R1209
5370// generic_name_list substituted for import_name_list
5371import_stmt
5372@init {Token lbl = null; boolean hasGenericNameList=false;}
5373@after{checkForInclude();}
5374 : (label {lbl=$label.tk;})? T_IMPORT ( ( T_COLON_COLON )?
5375 generic_name_list {hasGenericNameList=true;})? end_of_stmt
5376 {action.import_stmt(lbl, $T_IMPORT, $end_of_stmt.tk,
5377 hasGenericNameList);}
5378 ;
5379
5380// R1210
5381// generic_name_list substituted for external_name_list
5382external_stmt
5383@init {Token lbl = null;} // @init{INIT_TOKEN_NULL(lbl);}
5384@after{checkForInclude();}
5385 : (label {lbl=$label.tk;})? T_EXTERNAL ( T_COLON_COLON )?
5386 generic_name_list end_of_stmt
5387 {action.external_stmt(lbl, $T_EXTERNAL, $end_of_stmt.tk);}
5388 ;
5389
5390// R1211
5391procedure_declaration_stmt
5392@init {Token lbl = null; boolean hasProcInterface=false; int count=0;}
5393@after{checkForInclude();}
5394 : (label {lbl=$label.tk;})? T_PROCEDURE T_LPAREN
5395 ( proc_interface {hasProcInterface=true;})? T_RPAREN
5396 ( ( T_COMMA proc_attr_spec {count++;})* T_COLON_COLON )?
5397 proc_decl_list end_of_stmt
5398 {action.procedure_declaration_stmt(lbl, $T_PROCEDURE,
5399 $end_of_stmt.tk, hasProcInterface, count);}
5400 ;
5401
5402// R1212
5403// T_IDENT inlined for interface_name
5404proc_interface
5405 : T_IDENT { action.proc_interface($T_IDENT); }
5406 | declaration_type_spec { action.proc_interface(null); }
5407 ;
5408
5409// R1213
5410proc_attr_spec
5411 : access_spec
5412 { action.proc_attr_spec(null, null, IActionEnums.AttrSpec_none); }
5413 | proc_language_binding_spec
5414 { action.proc_attr_spec(null, null, IActionEnums.AttrSpec_none); }
5415 | T_INTENT T_LPAREN intent_spec T_RPAREN
5416 { action.proc_attr_spec($T_INTENT, null,
5417 IActionEnums.AttrSpec_INTENT); }
5418 | T_OPTIONAL
5419 { action.proc_attr_spec($T_OPTIONAL, null,
5420 IActionEnums.AttrSpec_OPTIONAL); }
5421 | T_POINTER
5422 { action.proc_attr_spec($T_POINTER, null,
5423 IActionEnums.AttrSpec_POINTER); }
5424 | T_SAVE
5425 { action.proc_attr_spec($T_SAVE, null,
5426 IActionEnums.AttrSpec_SAVE); }
5427// TODO: are T_PASS, T_NOPASS, and T_DEFERRED correct?
5428// From R453 binding-attr
5429 | T_PASS ( T_LPAREN T_IDENT T_RPAREN)?
5430 { action.proc_attr_spec($T_PASS, $T_IDENT,
5431 IActionEnums.AttrSpec_PASS); }
5432 | T_NOPASS
5433 { action.proc_attr_spec($T_NOPASS, null,
5434 IActionEnums.AttrSpec_NOPASS); }
5435 | T_DEFERRED
5436 { action.proc_attr_spec($T_DEFERRED, null,
5437 IActionEnums.AttrSpec_DEFERRED); }
5438 | proc_attr_spec_extension
5439 ;
5440
5441// language extension point
5442proc_attr_spec_extension : T_NO_LANGUAGE_EXTENSION ;
5443
5444// R1214
5445// T_IDENT inlined for procedure_entity_name
5446proc_decl
5447@init{boolean hasNullInit = false;}
5448 : T_IDENT ( T_EQ_GT null_init {hasNullInit=true;} )?
5449 { action.proc_decl($T_IDENT, hasNullInit); }
5450 ;
5451
5452proc_decl_list
5453@init{ int count=0;}
5454 : {action.proc_decl_list__begin();}
5455 proc_decl {count++;} ( T_COMMA proc_decl {count++;} )*
5456 {action.proc_decl_list(count);}
5457 ;
5458
5459// R1215 interface_name was name inlined as T_IDENT
5460
5461// R1216
5462// generic_name_list substituted for intrinsic_procedure_name_list
5463intrinsic_stmt
5464@init {Token lbl = null;}
5465@after{checkForInclude();}
5466 : (label {lbl=$label.tk;})? T_INTRINSIC
5467 ( T_COLON_COLON )?
5468 generic_name_list end_of_stmt
5469 {action.intrinsic_stmt(lbl, $T_INTRINSIC, $end_of_stmt.tk);}
5470 ;
5471
5472// R1217 function_reference replaced by designator_or_func_ref to reduce
5473// backtracking
5474
5475// R1218
5476// C1222 (R1218) The procedure-designator shall designate a subroutine.
5477call_stmt
5478@init {Token lbl = null; boolean hasActualArgSpecList = false;}
5479@after{checkForInclude();}
5480 : (label {lbl=$label.tk;})? T_CALL procedure_designator
5481 ( T_LPAREN (actual_arg_spec_list {hasActualArgSpecList=true;})?
5482 T_RPAREN )? end_of_stmt
5483 { action.call_stmt(lbl, $T_CALL, $end_of_stmt.tk,
5484 hasActualArgSpecList); }
5485 ;
5486
5487// R1219
5488// ERR_CHK 1219 must be (T_IDENT | designator T_PERCENT T_IDENT)
5489// T_IDENT inlined for procedure_name and binding_name
5490// proc_component_ref is variable T_PERCENT T_IDENT (variable is designator)
5491// data_ref subset of designator so data_ref T_PERCENT T_IDENT deleted
5492// designator (R603), minus the substring part is data_ref, so designator
5493// replaced by data_ref
5494//R1219 procedure-designator is procedure-name
5495// or proc-component-ref
5496// or data-ref % binding-name
5497procedure_designator
5498 : data_ref
5499 { action.procedure_designator(); }
5500 ;
5501
5502// R1220
5503actual_arg_spec
5504@init{Token keyword = null;}
5505 : (T_IDENT T_EQUALS {keyword=$T_IDENT;})? actual_arg
5506 { action.actual_arg_spec(keyword); }
5507 ;
5508
5509// TODO - delete greedy?
5510actual_arg_spec_list
5511options{greedy=false;}
5512@init{int count = 0;}
5513 : { action.actual_arg_spec_list__begin(); }
5514 actual_arg_spec {count++;} ( T_COMMA actual_arg_spec {count++;} )*
5515 { action.actual_arg_spec_list(count); }
5516 ;
5517
5518// R1221
5519// ERR_CHK 1221 ensure ( expr | designator ending in T_PERCENT T_IDENT)
5520// T_IDENT inlined for procedure_name
5521// expr isa designator (via primary) so variable deleted
5522// designator isa T_IDENT so T_IDENT deleted
5523// proc_component_ref is variable T_PERCENT T_IDENT can be designator so
5524// deleted
5525actual_arg
5526@init{boolean hasExpr = false;}
5527 : expr
5528 { hasExpr=true; action.actual_arg(hasExpr, null); }
5529 | T_ASTERISK label
5530 { action.actual_arg(hasExpr, $label.tk); }
5531 ;
5532
5533// R1222 alt_return_spec inlined as T_ASTERISK label in R1221
5534
5535// R1223
5536// 1. left factored optional prefix in function_stmt from function_subprogram
5537// 2. specification_part made non-optional to remove END ambiguity (as can
5538// be empty)
5539function_subprogram
5540@init {
5541 boolean hasExePart = false;
5542 boolean hasIntSubProg = false;
5543}
5544 : function_stmt
5545 specification_part
5546 ( execution_part { hasExePart=true; })?
5547 ( internal_subprogram_part { hasIntSubProg=true; })?
5548 end_function_stmt
5549 { action.function_subprogram(hasExePart, hasIntSubProg); }
5550 ;
5551
5552// R1224
5553// left factored optional prefix from function_stmt
5554// generic_name_list substituted for dummy_arg_name_list
5555function_stmt
5556@init {
5557 Token lbl = null;
5558 boolean hasGenericNameList=false;
5559 boolean hasSuffix=false;
5560}
5561@after{checkForInclude();}
5562 : {action.function_stmt__begin();}
5563 (label {lbl=$label.tk;})? T_FUNCTION T_IDENT
5564 T_LPAREN ( generic_name_list {hasGenericNameList=true;})? T_RPAREN
5565 ( suffix {hasSuffix=true;})? end_of_stmt
5566 {action.function_stmt(lbl, $T_FUNCTION, $T_IDENT, $end_of_stmt.tk,
5567 hasGenericNameList,hasSuffix);}
5568 ;
5569
5570// R1225
5571proc_language_binding_spec
5572 : language_binding_spec
5573 { action.proc_language_binding_spec(); }
5574 ;
5575
5576// R1226 dummy_arg_name was name inlined as T_IDENT
5577
5578// R1227
5579// C1240 (R1227) A prefix shall contain at most one of each prefix-spec
5580// C1241 (R1227) A prefix shall not specify both ELEMENTAL AND RECURSIVE
5581prefix
5582@init{int specCount=1;}
5583 : prefix_spec ( prefix_spec{specCount++;}
5584 (prefix_spec{specCount++;} )? )?
5585 {action.prefix(specCount);}
5586 ;
5587
5588t_prefix
5589@init{int specCount=1;}
5590 : t_prefix_spec ( t_prefix_spec {specCount++;})?
5591 {action.t_prefix(specCount);}
5592 ;
5593
5594// R1228
5595prefix_spec
5596 : declaration_type_spec
5597 {action.prefix_spec(true);}
5598 | t_prefix_spec
5599 {action.prefix_spec(false);}
5600 ;
5601
5602t_prefix_spec
5603 : T_RECURSIVE {action.t_prefix_spec($T_RECURSIVE);}
5604 | T_PURE {action.t_prefix_spec($T_PURE);}
5605 | T_ELEMENTAL {action.t_prefix_spec($T_ELEMENTAL);}
5606 ;
5607
5608// R1229
5609suffix
5610@init {
5611 Token result = null;
5612 boolean hasProcLangBindSpec = false;
5613}
5614 : proc_language_binding_spec ( T_RESULT T_LPAREN result_name
5615 T_RPAREN { result=$T_RESULT; })?
5616 { action.suffix(result, true); }
5617 | T_RESULT T_LPAREN result_name T_RPAREN
5618 ( proc_language_binding_spec { hasProcLangBindSpec = true; })?
5619 { action.suffix($T_RESULT, hasProcLangBindSpec); }
5620 ;
5621
5622result_name
5623 : name
5624 { action.result_name(); }
5625 ;
5626
5627// R1230
5628end_function_stmt
5629@init {Token lbl = null; Token id = null;}
5630@after{checkForInclude();}
5631 : (label {lbl=$label.tk;})? T_END T_FUNCTION ( T_IDENT {id=$T_IDENT;})?
5632 end_of_stmt
5633 {action.end_function_stmt(lbl, $T_END, $T_FUNCTION, id,
5634 $end_of_stmt.tk);}
5635 | (label {lbl=$label.tk;})? T_ENDFUNCTION ( T_IDENT {id=$T_IDENT;})?
5636 end_of_stmt
5637 {action.end_function_stmt(lbl, $T_ENDFUNCTION, null, id,
5638 $end_of_stmt.tk);}
5639 | (label {lbl=$label.tk;})? T_END end_of_stmt
5640 {action.end_function_stmt(lbl, $T_END, null, id, $end_of_stmt.tk);}
5641 ;
5642
5643// R1231
5644// specification_part made non-optional to remove END ambiguity (as can
5645// be empty)
5646subroutine_subprogram
5647 : subroutine_stmt
5648 specification_part
5649 ( execution_part )?
5650 ( internal_subprogram_part )?
5651 end_subroutine_stmt
5652 ;
5653
5654// R1232
5655subroutine_stmt
5656@init {Token lbl = null; boolean hasPrefix=false;
5657 boolean hasDummyArgList=false;
5658 boolean hasBindingSpec=false;
5659 boolean hasArgSpecifier=false;}
5660@after{checkForInclude();}
5661 : {action.subroutine_stmt__begin();}
5662 (label {lbl=$label.tk;})? (t_prefix {hasPrefix=true;})? T_SUBROUTINE
5663 T_IDENT ( T_LPAREN ( dummy_arg_list {hasDummyArgList=true;})?
5664 T_RPAREN ( proc_language_binding_spec {hasBindingSpec=true;})?
5665 {hasArgSpecifier=true;})? end_of_stmt
5666 {action.subroutine_stmt(lbl, $T_SUBROUTINE, $T_IDENT,
5667 $end_of_stmt.tk,
5668 hasPrefix, hasDummyArgList,
5669 hasBindingSpec, hasArgSpecifier);}
5670 ;
5671
5672// R1233
5673// T_IDENT inlined for dummy_arg_name
5674dummy_arg
5675options{greedy=false; memoize=false;}
5676 : T_IDENT { action.dummy_arg($T_IDENT); }
5677 | T_ASTERISK { action.dummy_arg($T_ASTERISK); }
5678 ;
5679
5680dummy_arg_list
5681@init{ int count=0;}
5682 : {action.dummy_arg_list__begin();}
5683 dummy_arg {count++;} ( T_COMMA dummy_arg {count++;} )*
5684 {action.dummy_arg_list(count);}
5685 ;
5686
5687// R1234
5688end_subroutine_stmt
5689@init {Token lbl = null; Token id=null;}
5690@after{checkForInclude();}
5691 : (label {lbl=$label.tk;})? T_END T_SUBROUTINE ( T_IDENT {id=$T_IDENT;})?
5692 end_of_stmt
5693 {action.end_subroutine_stmt(lbl, $T_END, $T_SUBROUTINE, id,
5694 $end_of_stmt.tk);}
5695 | (label {lbl=$label.tk;})? T_ENDSUBROUTINE ( T_IDENT {id=$T_IDENT;})?
5696 end_of_stmt
5697 {action.end_subroutine_stmt(lbl, $T_ENDSUBROUTINE, null, id,
5698 $end_of_stmt.tk);}
5699 | (label {lbl=$label.tk;})? T_END end_of_stmt
5700 {action.end_subroutine_stmt(lbl, $T_END, null, id, $end_of_stmt.tk);}
5701 ;
5702
5703// R1235
5704// T_INDENT inlined for entry_name
5705entry_stmt
5706@init {
5707 Token lbl = null;
5708 boolean hasDummyArgList=false;
5709 boolean hasSuffix=false;
5710}
5711@after{checkForInclude();}
5712 : (label {lbl=$label.tk;})? T_ENTRY T_IDENT
5713 ( T_LPAREN ( dummy_arg_list {hasDummyArgList=true;} )? T_RPAREN
5714 ( suffix {hasSuffix=true;})? )? end_of_stmt
5715 {action.entry_stmt(lbl, $T_ENTRY, $T_IDENT, $end_of_stmt.tk,
5716 hasDummyArgList, hasSuffix);}
5717 ;
5718
5719// R1236
5720// ERR_CHK 1236 scalar_int_expr replaced by expr
5721return_stmt
5722@init {Token lbl = null; boolean hasScalarIntExpr=false;}
5723@after{checkForInclude();}
5724 : (label {lbl=$label.tk;})? T_RETURN ( expr {hasScalarIntExpr=true;})?
5725 end_of_stmt
5726 {action.return_stmt(lbl, $T_RETURN, $end_of_stmt.tk,
5727 hasScalarIntExpr);}
5728 ;
5729
5730
5731/*
5732 * R1237-F08 separate-module-subprogram
5733 * is mp-subprogram-stmt // NEW_TO_F2008
5734 * [ specification-part ]
5735 * [ execution-part ]
5736 * [ internal-subprogram-part ]
5737 * end-mp-subprogram
5738 */
5739
5740////////////
5741// R1237-F08
5742//
5743separate_module_subprogram
5744@init{
5745 boolean hasExecutionPart = false; boolean hasInternalSubprogramPart = false;
5746 action.separate_module_subprogram__begin();
5747}
5748@after{action.separate_module_subprogram(hasExecutionPart, hasInternalSubprogramPart);}
5749 : mp_subprogram_stmt
5750 specification_part // non-optional as can be empty
5751 ( execution_part {hasExecutionPart=true;} )?
5752 ( internal_subprogram_part {hasInternalSubprogramPart=true;} )?
5753 end_mp_subprogram_stmt
5754 ;
5755
5756
5757/*
5758 * R1238-F08 mp-subprogram-stmt
5759 * is MODULE PROCEDURE procedure-name
5760 */
5761
5762////////////
5763// R1238-F08
5764//
5765mp_subprogram_stmt
5766@init {Token lbl = null;}
5767@after{checkForInclude();}
5768 : (label {lbl=$label.tk;})? T_MODULE T_PROCEDURE name end_of_stmt
5769 {
5770 action.mp_subprogram_stmt(lbl, $T_MODULE,
5771 $T_PROCEDURE, $name.tk, $end_of_stmt.tk);
5772 }
5773 ;
5774
5775
5776/*
5777 * R1239-F08 end-mp-subprogram-stmt
5778 * is END [ PROCEDURE [ procedure-name ] ]
5779 */
5780
5781////////////
5782// R1239-F08
5783//
5784end_mp_subprogram_stmt
5785@init {Token lbl = null; Token t_proc = null; Token t_name = null;}
5786@after{checkForInclude();}
5787 : (label {lbl=$label.tk;})?
5788 T_END (T_PROCEDURE (name {t_name=$name.tk;})? {t_proc=$T_PROCEDURE;})?
5789 end_of_stmt
5790 {action.end_mp_subprogram_stmt(lbl, $T_END, t_proc, t_name, $end_of_stmt.tk);}
5791 | (label {lbl=$label.tk;})?
5792 T_ENDPROCEDURE (name {t_name=$name.tk;})?
5793 end_of_stmt
5794 {
5795 action.end_mp_subprogram_stmt(lbl, $T_ENDPROCEDURE, null,
5796 t_name, $end_of_stmt.tk);
5797 }
5798 ;
5799
5800
5801// R1237
5802contains_stmt
5803@init {Token lbl = null;}
5804@after{checkForInclude();}
5805 : (label {lbl=$label.tk;})? T_CONTAINS end_of_stmt
5806 {action.contains_stmt(lbl, $T_CONTAINS, $end_of_stmt.tk);}
5807 ;
5808
5809
5810// R1238
5811// ERR_CHK 1239 scalar_expr replaced by expr
5812// generic_name_list substituted for dummy_arg_name_list
5813// TODO Hopefully scanner and parser can help work together here to work
5814// around ambiguity.
5815// why can't this be accepted as an assignment statement and then the parser
5816// look up the symbol for the T_IDENT to see if it is a function??
5817// Need scanner to send special token if it sees what?
5818// TODO - won't do a(b==3,c) = 2
5819stmt_function_stmt
5820@init {Token lbl = null; boolean hasGenericNameList=false;}
5821@after{checkForInclude();}
5822 : (label {lbl=$label.tk;})? T_STMT_FUNCTION T_IDENT T_LPAREN
5823 ( generic_name_list {hasGenericNameList=true;})? T_RPAREN
5824 T_EQUALS expr end_of_stmt
5825 {action.stmt_function_stmt(lbl, $T_IDENT, $end_of_stmt.tk,
5826 hasGenericNameList);}
5827 ;
5828
5829// added this to have a way to match the T_EOS and EOF combinations
5830end_of_stmt returns [Token tk]
5831 : T_EOS
5832 {
5833 CivlcToken eos = (CivlcToken)$T_EOS;
5834 tk = $T_EOS;
5835 action.end_of_stmt($T_EOS);
5836 }
5837 // the (EOF) => EOF is done with lookahead because if it's not there,
5838 // then antlr will crash with an internal error while trying to
5839 // generate the java code. (as of 12.11.06)
5840 | (EOF) => EOF
5841 {
5842 tk = $EOF; action.end_of_stmt($EOF);
5843 // don't call action.end_of_file() here or the action will be
5844 // called before end_of_program action called
5845 // action.end_of_file(eofToken.getText());
5846 }
5847 ;
Note: See TracBrowser for help on using the repository browser.