From 48704ef940e2dbe0cc1a8c4e7bbea3b662ee1d92 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Fri, 20 Apr 2018 13:49:03 -0700 Subject: [PATCH] [flang] Move Parser<> to its own header. Original-commit: flang-compiler/f18@c43e8ba138546c5739cc8eaa681a9eb6e51ed657 Reviewed-on: https://github.com/flang-compiler/f18/pull/66 Tree-same-pre-rewrite: false --- flang/lib/parser/basic-parsers.h | 26 ++---- flang/lib/parser/grammar.h | 127 +----------------------------- flang/lib/parser/type-parsers.h | 131 +++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 146 deletions(-) create mode 100644 flang/lib/parser/type-parsers.h diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index b955cdd53882..2bcb541dd955 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -1048,27 +1048,11 @@ template struct construct { } }; -// If f is a function of type bool (*f)(const ParseState &), then -// StatePredicateGuardParser{f} is a parser that succeeds when f() is true -// and fails otherwise. The state is preserved. -class StatePredicateGuardParser { -public: - using resultType = Success; - constexpr StatePredicateGuardParser( - const StatePredicateGuardParser &) = default; - constexpr explicit StatePredicateGuardParser( - bool (*predicate)(const ParseState &)) - : predicate_{predicate} {} - std::optional Parse(ParseState &state) const { - if (predicate_(state)) { - return {Success{}}; - } - return {}; - } - -private: - bool (*const predicate_)(const ParseState &); -}; +// For a parser p, indirect(p) returns a parser that builds an indirect +// reference to p's return type. +template inline constexpr auto indirect(const PA &p) { + return construct>{}(p); +} // If a and b are parsers, then nonemptySeparated(a, b) returns a parser // that succeeds if a does. If a succeeds, it then applies many(b >> a). diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index c2dec7923190..13b71fef3169 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -4,7 +4,7 @@ // Top-level grammar specification for Fortran. These parsers drive // the tokenization parsers in cooked-tokens.h to consume characters, // recognize the productions of Fortran, and to construct a parse tree. -// See parser-combinators.txt for documentation on the parser combinator +// See ParserCombinators.md for documentation on the parser combinator // library used here to implement an LL recursive descent recognizer. #include "basic-parsers.h" @@ -12,6 +12,7 @@ #include "debug-parser.h" #include "parse-tree.h" #include "token-parsers.h" +#include "type-parser.h" #include "user-state.h" #include #include @@ -31,130 +32,6 @@ namespace parser { // on the definitions of symbols. The "Rxxx" numbers that appear in // comments refer to these numbered requirements in the Fortran standard. -// Many parsers in this grammar are defined as instances of this Parser<> -// template class. This usage requires that their Parse() member functions -// be defined separately, typically with a parsing expression wrapped up -// in an TYPE_PARSER() macro call. -template struct Parser { - using resultType = A; - constexpr Parser() {} - static inline std::optional Parse(ParseState &); -}; - -#define TYPE_PARSER(pexpr) \ - template<> \ - inline std::optional \ - Parser::Parse(ParseState &state) { \ - static constexpr auto parser = (pexpr); \ - return parser.Parse(state); \ - } - -#define TYPE_CONTEXT_PARSER(contextText, pexpr) \ - TYPE_PARSER(instrumented((contextText), inContext((contextText), (pexpr)))) - -// Some specializations of Parser<> are used multiple times, or are -// of some special importance, so we instantiate them once here and -// give them names rather than referencing them as anonymous Parser{} -// objects in the right-hand sides of productions. -constexpr Parser program; // R501 - the "top level" production -constexpr Parser specificationPart; // R504 -constexpr Parser implicitPart; // R505 -constexpr Parser declarationConstruct; // R507 -constexpr Parser specificationConstruct; // R508 -constexpr Parser executionPart; // R509 -constexpr Parser executionPartConstruct; // R510 -constexpr Parser internalSubprogramPart; // R511 -constexpr Parser actionStmt; // R515 -constexpr Parser name; // R603 -constexpr Parser literalConstant; // R605 -constexpr Parser namedConstant; // R606 -constexpr Parser typeParamValue; // R701 -constexpr Parser typeSpec; // R702 -constexpr Parser declarationTypeSpec; // R703 -constexpr Parser intrinsicTypeSpec; // R704 -constexpr Parser integerTypeSpec; // R705 -constexpr Parser kindSelector; // R706 -constexpr Parser signedIntLiteralConstant; // R707 -constexpr Parser intLiteralConstant; // R708 -constexpr Parser kindParam; // R709 -constexpr Parser realLiteralConstant; // R714 -constexpr Parser charLength; // R723 -constexpr Parser charLiteralConstant; // R724 -constexpr Parser initialization; // R743 & R805 -constexpr Parser derivedTypeSpec; // R754 -constexpr Parser typeDeclarationStmt; // R801 -constexpr Parser nullInit; // R806 -constexpr Parser accessSpec; // R807 -constexpr Parser languageBindingSpec; // R808, R1528 -constexpr Parser entityDecl; // R803 -constexpr Parser coarraySpec; // R809 -constexpr Parser arraySpec; // R815 -constexpr Parser explicitShapeSpec; // R816 -constexpr Parser deferredShapeSpecList; // R820 -constexpr Parser assumedImpliedSpec; // R821 -constexpr Parser intentSpec; // R826 -constexpr Parser dataStmt; // R837 -constexpr Parser dataImpliedDo; // R840 -constexpr Parser parameterStmt; // R851 -constexpr Parser oldParameterStmt; -constexpr Parser designator; // R901 -constexpr Parser variable; // R902 -constexpr Parser substring; // R908 -constexpr Parser dataRef; // R911, R914, R917 -constexpr Parser structureComponent; // R913 -constexpr Parser statVariable; // R929 -constexpr Parser statOrErrmsg; // R942 & R1165 -constexpr Parser definedOpName; // R1003, R1023, R1414, & R1415 -constexpr Parser expr; // R1022 -constexpr Parser specificationExpr; // R1028 -constexpr Parser assignmentStmt; // R1032 -constexpr Parser pointerAssignmentStmt; // R1033 -constexpr Parser whereStmt; // R1041, R1045, R1046 -constexpr Parser whereConstruct; // R1042 -constexpr Parser whereBodyConstruct; // R1044 -constexpr Parser forallConstruct; // R1050 -constexpr Parser forallAssignmentStmt; // R1053 -constexpr Parser forallStmt; // R1055 -constexpr Parser selector; // R1105 -constexpr Parser endSelectStmt; // R1143 & R1151 & R1155 -constexpr Parser loopControl; // R1123 -constexpr Parser concurrentHeader; // R1125 -constexpr Parser endDoStmt; // R1132 -constexpr Parser ioUnit; // R1201, R1203 -constexpr Parser fileUnitNumber; // R1202 -constexpr Parser ioControlSpec; // R1213, R1214 -constexpr Parser format; // R1215 -constexpr Parser inputItem; // R1216 -constexpr Parser outputItem; // R1217 -constexpr Parser inputImpliedDo; // R1218, R1219 -constexpr Parser outputImpliedDo; // R1218, R1219 -constexpr Parser positionOrFlushSpec; // R1227 & R1229 -constexpr Parser formatStmt; // R1301 -constexpr Parser interfaceBlock; // R1501 -constexpr Parser genericSpec; // R1508 -constexpr Parser procInterface; // R1513 -constexpr Parser procDecl; // R1515 -constexpr Parser functionReference; // R1520 -constexpr Parser actualArgSpec; // R1523 -constexpr Parser prefixSpec; // R1527 -constexpr Parser functionSubprogram; // R1529 -constexpr Parser functionStmt; // R1530 -constexpr Parser suffix; // R1532 -constexpr Parser endFunctionStmt; // R1533 -constexpr Parser subroutineSubprogram; // R1534 -constexpr Parser subroutineStmt; // R1535 -constexpr Parser dummyArg; // R1536 -constexpr Parser endSubroutineStmt; // R1537 -constexpr Parser entryStmt; // R1541 -constexpr Parser containsStmt; // R1543 -constexpr Parser compilerDirective; - -// For a parser p, indirect(p) returns a parser that builds an indirect -// reference to p's return type. -template inline constexpr auto indirect(const PA &p) { - return construct>{}(p); -} - // R711 digit-string -> digit [digit]... // N.B. not a token -- no space is skipped constexpr DigitString digitString; diff --git a/flang/lib/parser/type-parsers.h b/flang/lib/parser/type-parsers.h new file mode 100644 index 000000000000..128c0d26bbf2 --- /dev/null +++ b/flang/lib/parser/type-parsers.h @@ -0,0 +1,131 @@ +#ifndef FORTRAN_PARSER_TYPE_PARSERS_H_ +#define FORTRAN_PARSER_TYPE_PARSERS_H_ + +#include "basic-parsers.h" +#include "parse-tree.h" +#include + +namespace Fortran { +namespace parser { + +// Many parsers in the grammar are defined as instances of this Parser<> +// template class, i.e. as the anonymous sole parser for a given type. +// This usage requires that their Parse() member functions be defined +// separately, typically with a parsing expression wrapped up in an +// TYPE_PARSER() macro call. +template struct Parser { + using resultType = A; + constexpr Parser() {} + static inline std::optional Parse(ParseState &); +}; + +#define TYPE_PARSER(pexpr) \ + template<> \ + inline std::optional \ + Parser::Parse(ParseState &state) { \ + static constexpr auto parser = (pexpr); \ + return parser.Parse(state); \ + } + +#define TYPE_CONTEXT_PARSER(contextText, pexpr) \ + TYPE_PARSER(instrumented((contextText), inContext((contextText), (pexpr)))) + +// Some specializations of Parser<> are used multiple times, or are +// of some special importance, so we instantiate them once here and +// give them names rather than referencing them as anonymous Parser{} +// objects in the right-hand sides of productions. +constexpr Parser program; // R501 - the "top level" production +constexpr Parser specificationPart; // R504 +constexpr Parser implicitPart; // R505 +constexpr Parser declarationConstruct; // R507 +constexpr Parser specificationConstruct; // R508 +constexpr Parser executionPart; // R509 +constexpr Parser executionPartConstruct; // R510 +constexpr Parser internalSubprogramPart; // R511 +constexpr Parser actionStmt; // R515 +constexpr Parser name; // R603 +constexpr Parser literalConstant; // R605 +constexpr Parser namedConstant; // R606 +constexpr Parser typeParamValue; // R701 +constexpr Parser typeSpec; // R702 +constexpr Parser declarationTypeSpec; // R703 +constexpr Parser intrinsicTypeSpec; // R704 +constexpr Parser integerTypeSpec; // R705 +constexpr Parser kindSelector; // R706 +constexpr Parser signedIntLiteralConstant; // R707 +constexpr Parser intLiteralConstant; // R708 +constexpr Parser kindParam; // R709 +constexpr Parser realLiteralConstant; // R714 +constexpr Parser charLength; // R723 +constexpr Parser charLiteralConstant; // R724 +constexpr Parser initialization; // R743 & R805 +constexpr Parser derivedTypeSpec; // R754 +constexpr Parser typeDeclarationStmt; // R801 +constexpr Parser nullInit; // R806 +constexpr Parser accessSpec; // R807 +constexpr Parser languageBindingSpec; // R808, R1528 +constexpr Parser entityDecl; // R803 +constexpr Parser coarraySpec; // R809 +constexpr Parser arraySpec; // R815 +constexpr Parser explicitShapeSpec; // R816 +constexpr Parser deferredShapeSpecList; // R820 +constexpr Parser assumedImpliedSpec; // R821 +constexpr Parser intentSpec; // R826 +constexpr Parser dataStmt; // R837 +constexpr Parser dataImpliedDo; // R840 +constexpr Parser parameterStmt; // R851 +constexpr Parser oldParameterStmt; +constexpr Parser designator; // R901 +constexpr Parser variable; // R902 +constexpr Parser substring; // R908 +constexpr Parser dataRef; // R911, R914, R917 +constexpr Parser structureComponent; // R913 +constexpr Parser statVariable; // R929 +constexpr Parser statOrErrmsg; // R942 & R1165 +constexpr Parser definedOpName; // R1003, R1023, R1414, & R1415 +constexpr Parser expr; // R1022 +constexpr Parser specificationExpr; // R1028 +constexpr Parser assignmentStmt; // R1032 +constexpr Parser pointerAssignmentStmt; // R1033 +constexpr Parser whereStmt; // R1041, R1045, R1046 +constexpr Parser whereConstruct; // R1042 +constexpr Parser whereBodyConstruct; // R1044 +constexpr Parser forallConstruct; // R1050 +constexpr Parser forallAssignmentStmt; // R1053 +constexpr Parser forallStmt; // R1055 +constexpr Parser selector; // R1105 +constexpr Parser endSelectStmt; // R1143 & R1151 & R1155 +constexpr Parser loopControl; // R1123 +constexpr Parser concurrentHeader; // R1125 +constexpr Parser endDoStmt; // R1132 +constexpr Parser ioUnit; // R1201, R1203 +constexpr Parser fileUnitNumber; // R1202 +constexpr Parser ioControlSpec; // R1213, R1214 +constexpr Parser format; // R1215 +constexpr Parser inputItem; // R1216 +constexpr Parser outputItem; // R1217 +constexpr Parser inputImpliedDo; // R1218, R1219 +constexpr Parser outputImpliedDo; // R1218, R1219 +constexpr Parser positionOrFlushSpec; // R1227 & R1229 +constexpr Parser formatStmt; // R1301 +constexpr Parser interfaceBlock; // R1501 +constexpr Parser genericSpec; // R1508 +constexpr Parser procInterface; // R1513 +constexpr Parser procDecl; // R1515 +constexpr Parser functionReference; // R1520 +constexpr Parser actualArgSpec; // R1523 +constexpr Parser prefixSpec; // R1527 +constexpr Parser functionSubprogram; // R1529 +constexpr Parser functionStmt; // R1530 +constexpr Parser suffix; // R1532 +constexpr Parser endFunctionStmt; // R1533 +constexpr Parser subroutineSubprogram; // R1534 +constexpr Parser subroutineStmt; // R1535 +constexpr Parser dummyArg; // R1536 +constexpr Parser endSubroutineStmt; // R1537 +constexpr Parser entryStmt; // R1541 +constexpr Parser containsStmt; // R1543 +constexpr Parser compilerDirective; +} // namespace parser +} // namespace Fortran +#endif // FORTRAN_PARSER_TYPE_PARSERS_H_