1919
2020namespace Fortran ::parser {
2121
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+
2247// R502 program-unit ->
2348// main-program | external-subprogram | module | submodule | block-data
2449// R503 external-subprogram -> function-subprogram | subroutine-subprogram
@@ -36,10 +61,11 @@ namespace Fortran::parser {
3661// Enforcing C1547 is done in semantics.
3762static constexpr auto programUnit{
3863 construct<ProgramUnit>(indirect (Parser<Module>{})) ||
39- construct<ProgramUnit>(indirect (functionSubprogram)) ||
4064 construct<ProgramUnit>(indirect (subroutineSubprogram)) ||
4165 construct<ProgramUnit>(indirect (Parser<Submodule>{})) ||
4266 construct<ProgramUnit>(indirect (Parser<BlockData>{})) ||
67+ lookAhead (validFunctionStmt) >>
68+ construct<ProgramUnit>(indirect (functionSubprogram)) ||
4369 construct<ProgramUnit>(indirect (Parser<MainProgram>{}))};
4470static constexpr auto normalProgramUnit{StartNewSubprogram{} >> programUnit /
4571 skipMany (" ;" _tok) / space / recovery (endOfLine, SkipPast<' \n ' >{})};
@@ -529,20 +555,6 @@ TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US,
529555 executionPart, maybe(internalSubprogramPart),
530556 unterminatedStatement(endFunctionStmt)))
531557
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-
546558// R1532 suffix ->
547559// proc-language-binding-spec [RESULT ( result-name )] |
548560// RESULT ( result-name ) [proc-language-binding-spec]
@@ -567,11 +579,13 @@ TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_en_US,
567579// [prefix] SUBROUTINE subroutine-name [( [dummy-arg-list] )
568580// [proc-language-binding-spec]]
569581TYPE_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)
575589
576590// R1536 dummy-arg -> dummy-arg-name | *
577591TYPE_PARSER(construct<DummyArg>(name) || construct<DummyArg>(star))
0 commit comments