19
19
20
20
namespace Fortran ::parser {
21
21
22
+ // R1530 function-stmt ->
23
+ // [prefix] FUNCTION function-name ( [dummy-arg-name-list] ) [suffix]
24
+ // R1526 prefix -> prefix-spec [prefix-spec]...
25
+ // R1531 dummy-arg-name -> name
26
+
27
+ static constexpr auto validFunctionStmt{
28
+ construct<FunctionStmt>(many (prefixSpec), " FUNCTION" >> name,
29
+ parenthesized (optionalList (name)), maybe (suffix)) /
30
+ atEndOfStmt ||
31
+ construct<FunctionStmt>(many (prefixSpec), " FUNCTION" >> name / atEndOfStmt,
32
+ // PGI & Intel accept "FUNCTION F"
33
+ extension<LanguageFeature::OmitFunctionDummies>(
34
+ " nonstandard usage: FUNCTION statement without dummy argument list" _port_en_US,
35
+ pure<std::list<Name>>()),
36
+ pure<std::optional<Suffix>>())};
37
+
38
+ // function-stmt with error recovery -- used in interfaces and internal
39
+ // subprograms, but not at the top level, where REALFUNCTIONF and
40
+ // INTEGERPUREELEMENTALFUNCTIONG(10) might appear as the first statement
41
+ // of a main program.
42
+ TYPE_PARSER (validFunctionStmt ||
43
+ construct<FunctionStmt>(many(prefixSpec), " FUNCTION" >> name,
44
+ defaulted (parenthesized(optionalList(name))), maybe(suffix)) /
45
+ checkEndOfKnownStmt)
46
+
22
47
// R502 program-unit ->
23
48
// main-program | external-subprogram | module | submodule | block-data
24
49
// R503 external-subprogram -> function-subprogram | subroutine-subprogram
@@ -36,10 +61,11 @@ namespace Fortran::parser {
36
61
// Enforcing C1547 is done in semantics.
37
62
static constexpr auto programUnit{
38
63
construct<ProgramUnit>(indirect (Parser<Module>{})) ||
39
- construct<ProgramUnit>(indirect (functionSubprogram)) ||
40
64
construct<ProgramUnit>(indirect (subroutineSubprogram)) ||
41
65
construct<ProgramUnit>(indirect (Parser<Submodule>{})) ||
42
66
construct<ProgramUnit>(indirect (Parser<BlockData>{})) ||
67
+ lookAhead (validFunctionStmt) >>
68
+ construct<ProgramUnit>(indirect (functionSubprogram)) ||
43
69
construct<ProgramUnit>(indirect (Parser<MainProgram>{}))};
44
70
static constexpr auto normalProgramUnit{StartNewSubprogram{} >> programUnit /
45
71
skipMany (" ;" _tok) / space / recovery (endOfLine, SkipPast<' \n ' >{})};
@@ -529,20 +555,6 @@ TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US,
529
555
executionPart, maybe(internalSubprogramPart),
530
556
unterminatedStatement(endFunctionStmt)))
531
557
532
- // R1530 function-stmt ->
533
- // [prefix] FUNCTION function-name ( [dummy-arg-name-list] ) [suffix]
534
- // R1526 prefix -> prefix-spec [prefix-spec]...
535
- // R1531 dummy-arg-name -> name
536
- TYPE_CONTEXT_PARSER(" FUNCTION statement" _en_US,
537
- construct<FunctionStmt>(many(prefixSpec), "FUNCTION" >> name,
538
- parenthesized(optionalList(name)), maybe(suffix)) ||
539
- extension<LanguageFeature::OmitFunctionDummies>(
540
- " nonstandard usage: FUNCTION statement without dummy argument list" _port_en_US,
541
- construct<FunctionStmt>( // PGI & Intel accept "FUNCTION F"
542
- many (prefixSpec), "FUNCTION" >> name,
543
- construct<std::list<Name>>(),
544
- construct<std::optional<Suffix>>())))
545
-
546
558
// R1532 suffix ->
547
559
// proc-language-binding-spec [RESULT ( result-name )] |
548
560
// RESULT ( result-name ) [proc-language-binding-spec]
@@ -567,11 +579,13 @@ TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_en_US,
567
579
// [prefix] SUBROUTINE subroutine-name [( [dummy-arg-list] )
568
580
// [proc-language-binding-spec]]
569
581
TYPE_PARSER(
570
- construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name,
571
- parenthesized(optionalList(dummyArg)), maybe(languageBindingSpec)) ||
572
- construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name,
573
- pure<std::list<DummyArg>>(),
574
- pure<std::optional<LanguageBindingSpec>>()))
582
+ (construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name,
583
+ !"(" _tok >> pure<std::list<DummyArg>>(),
584
+ pure<std::optional<LanguageBindingSpec>>()) ||
585
+ construct<SubroutineStmt>(many(prefixSpec), " SUBROUTINE" >> name,
586
+ defaulted(parenthesized(optionalList(dummyArg))),
587
+ maybe(languageBindingSpec))) /
588
+ checkEndOfKnownStmt)
575
589
576
590
// R1536 dummy-arg -> dummy-arg-name | *
577
591
TYPE_PARSER(construct<DummyArg>(name) || construct<DummyArg>(star))
0 commit comments