This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- parser/Parser.h --------------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2008-2010, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #ifndef COMMA_PARSER_PARSER_HDR_GUARD 00010 #define COMMA_PARSER_PARSER_HDR_GUARD 00011 00012 #include "comma/basic/IdentifierPool.h" 00013 #include "comma/basic/ParameterModes.h" 00014 #include "comma/parser/Lexer.h" 00015 #include "comma/parser/ParseClient.h" 00016 #include "llvm/ADT/SmallVector.h" 00017 #include <iosfwd> 00018 #include <stack> 00019 00020 namespace llvm { 00021 00022 class APInt; 00023 00024 } // end llvm namespace. 00025 00026 namespace comma { 00027 00028 class Parser { 00029 00030 public: 00031 Parser(TextProvider &txtProvider, 00032 IdentifierPool &idPool, 00033 ParseClient &client, 00034 Diagnostic &diag); 00035 00036 // Generic pointer to a parse method. 00037 typedef void (Parser::*parseFn)(); 00038 00039 // Generic pointer to a parse method returning a Node. 00040 typedef Node (Parser::*parseNodeFn)(); 00041 00042 void parseModel(); 00043 00044 void parseGenericFormalParams(); 00045 void parseGenericFormalDomain(); 00046 00047 void parseSignatureProfile(); 00048 void parseSupersignatureProfile(); 00049 void parseWithComponents(); 00050 00051 bool parseSubroutineParameter(); 00052 void parseSubroutineParameters(); 00053 00054 Node parseFunctionDeclaration(bool parsingSignatureProfile = false); 00055 Node parseProcedureDeclaration(bool parsingSignatureProfile = false); 00056 void parseFunctionDeclOrDefinition(); 00057 void parseProcedureDeclOrDefinition(); 00058 00063 void parseSubroutineBody(Node declarationNode); 00064 00065 bool parseDeclaration(); 00066 bool parseObjectDeclaration(); 00067 bool parseImportDeclaration(); 00068 00069 void parseCarrier(); 00070 void parseAddComponents(); 00071 00072 Node parseStatement(); 00073 Node parseIfStmt(); 00074 Node parseReturnStmt(); 00075 Node parseAssignmentStmt(); 00076 Node parseBlockStmt(); 00077 Node parseWhileStmt(); 00078 Node parseLoopStmt(); 00079 Node parseForStmt(); 00080 Node parsePragmaStmt(); 00081 Node parseProcedureCallStatement(); 00082 Node parseRaiseStmt(); 00083 00084 void parseExceptionStmt(Node context); 00085 00086 Node parseExpr(); 00087 Node parsePrimaryExpr(); 00088 Node parseParenExpr(); 00089 Node parseOperatorExpr(); 00090 Node parseIntegerLiteral(); 00091 Node parseStringLiteral(); 00092 Node parseQualifiedExpr(Node qualifier); 00093 Node parseAllocatorExpr(); 00094 00096 enum NameOption { 00098 No_Option, 00099 00102 Statement_Name, 00103 00106 Accept_Range_Attribute, 00107 }; 00108 00109 Node parseName(NameOption option = No_Option); 00110 Node parseDirectName(NameOption option); 00111 Node parseSelectedComponent(Node prefix, NameOption option); 00112 Node parseApplication(Node prefix); 00113 Node parseParameterAssociation(); 00114 Node parseAttribute(Node prefix, NameOption option); 00115 Node parseInj(); 00116 Node parsePrj(); 00117 00118 bool parseType(); 00119 bool parseSubtype(); 00120 void parseEnumerationList(); 00121 bool parseIntegerRange(IdentifierInfo *name, Location loc); 00122 00123 void parseArrayIndexProfile(NodeVector &indices); 00124 bool parseArrayTypeDecl(IdentifierInfo *name, Location loc); 00125 bool parseRecordTypeDecl(IdentifierInfo *name, Location loc); 00126 bool parseAccessTypeDecl(IdentifierInfo *name, Location loc); 00127 00130 bool parseTopLevelDeclaration(); 00131 00134 bool parseSuccessful() const { return diagnostic.numErrors() == 0; } 00135 00136 private: 00137 TextProvider &txtProvider; 00138 IdentifierPool &idPool; 00139 ParseClient &client; 00140 Diagnostic &diagnostic; 00141 Lexer lexer; 00142 00143 Lexer::Token token; 00144 00145 // The kind of end tag which is expected. This enumeration will be 00146 // expanded. 00147 enum EndTagKind { 00148 NAMED_TAG 00149 }; 00150 00151 // As the parser encounters constructs which must be matched by an end tag 00152 // an EndTagEntry is pushed onto the EndTagStack. 00153 struct EndTagEntry { 00154 00155 EndTagEntry(EndTagKind kind, Location loc, IdentifierInfo *tag = 0) 00156 : kind(kind), location(loc), tag(tag) { } 00157 00158 // The kind of end tag expected. 00159 EndTagKind kind; 00160 00161 // Location of the construct introducing this scope. Used for reporting 00162 // nesting errors or tag missmatches. 00163 Location location; 00164 00165 // The expected tag or NULL if no tag is required. 00166 IdentifierInfo *tag; 00167 }; 00168 00169 std::stack<EndTagEntry> endTagStack; 00170 00171 // Generic vector type to accumulate locations. 00172 typedef llvm::SmallVector<Location, 4> LocationVector; 00173 00174 // Accumulation of IdentifierInfo nodes. 00175 typedef llvm::SmallVector<IdentifierInfo*, 4> IdInfoVector; 00176 00177 unsigned currentLine(); 00178 unsigned currentColumn(); 00179 Location currentLocation(); 00180 00181 IdentifierInfo *getIdentifierInfo(const Lexer::Token &tkn); 00182 00183 Lexer::Token &nextToken(); 00184 Lexer::Token ¤tToken(); 00185 Lexer::Token peekToken(); 00186 void setCurrentToken(Lexer::Token &tkn); 00187 00188 // Ignores the current token and returns the location of the token skipped. 00189 // This method is used to support the idiom of skipping reserved words and 00190 // saving the location of the construct. 00191 Location ignoreToken(); 00192 00193 Lexer::Code currentTokenCode(); 00194 Lexer::Code peekTokenCode(); 00195 00196 bool currentTokenIs(Lexer::Code code); 00197 bool nextTokenIs(Lexer::Code code); 00198 bool expectToken(Lexer::Code code); 00199 bool reduceToken(Lexer::Code code); 00200 bool requireToken(Lexer::Code code); 00201 00202 // Matches a right paren assuming that the opening paren has already been 00203 // consumed, keeping track of nested pairs. Consumes the closing 00204 // paren. Note that this method does not save the state of the token stream. 00205 bool seekCloseParen(); 00206 00207 // Assuming an 'if' token has been consumed, moves the token stream past a 00208 // matching 'end if' sequence (taking into account inner 'if' expressions. 00209 bool seekEndIf(); 00210 00211 // Moves the token stream past an 'end loop' sequence, taking into account 00212 // inner loop statmement. 00213 bool seekEndLoop(); 00214 00215 bool seekToken(Lexer::Code code); 00216 bool seekAndConsumeToken(Lexer::Code code); 00217 00218 bool seekTokens(Lexer::Code code0, 00219 Lexer::Code code1 = Lexer::UNUSED_ID, 00220 Lexer::Code code2 = Lexer::UNUSED_ID, 00221 Lexer::Code code3 = Lexer::UNUSED_ID, 00222 Lexer::Code code4 = Lexer::UNUSED_ID, 00223 Lexer::Code code5 = Lexer::UNUSED_ID); 00224 00225 00226 bool seekAndConsumeTokens(Lexer::Code code0, 00227 Lexer::Code code1 = Lexer::UNUSED_ID, 00228 Lexer::Code code2 = Lexer::UNUSED_ID, 00229 Lexer::Code code3 = Lexer::UNUSED_ID, 00230 Lexer::Code code4 = Lexer::UNUSED_ID); 00231 00232 // Seeks a terminating semicolon. This method skips all semicolons which 00233 // appear nested within braces. It trys to find a semicolon at the same 00234 // syntatic level it was envoked at. Note that this method does not save 00235 // the state of the token stream. 00236 bool seekSemi(); 00237 00238 std::string currentTokenString() { 00239 return currentToken().getString(); 00240 } 00241 00242 DiagnosticStream &report(Location loc, diag::Kind kind) { 00243 SourceLocation sloc = txtProvider.getSourceLocation(loc); 00244 return diagnostic.report(sloc, kind); 00245 } 00246 00247 DiagnosticStream &report(SourceLocation sloc, diag::Kind kind) { 00248 return diagnostic.report(sloc, kind); 00249 } 00250 00251 DiagnosticStream &report(diag::Kind kind) { 00252 SourceLocation sloc = txtProvider.getSourceLocation(currentLocation()); 00253 return diagnostic.report(sloc, kind); 00254 } 00255 00256 IdentifierInfo *parseIdentifier(); 00257 IdentifierInfo *parseFunctionIdentifier(); 00258 IdentifierInfo *parseCharacter(); 00259 IdentifierInfo *parseIdentifierOrCharacter(); 00260 IdentifierInfo *parseAnyIdentifier(); 00261 00262 PM::ParameterMode parseParameterMode(); 00263 00264 // Parses the argument list of a subroutine call. The current token must be 00265 // a TKN_LPAREN. If the parsing succeeds, dst is populated with the nodes 00266 // for each argument and true is returned. Otherwise, false is returned and 00267 // the token stream has been adjusted such that the closing paren of the 00268 // argument list has been consumed. 00269 bool parseSubroutineArgumentList(NodeVector &dst); 00270 00271 bool seekEndTag(IdentifierInfo *tag); 00272 00273 bool seekAndConsumeEndTag(IdentifierInfo *tag); 00274 00275 // Parses an end tag. If expectedTag is non-null, parse "end <tag>", otherwise 00276 // parse "end". Returns true if tokens were consumed (which can happen when the 00277 // parse fails due to a missing or unexpected end tag) and false otherwise. 00278 bool parseEndTag(IdentifierInfo *expectedTag = 0); 00279 00280 // Seeks to the end of a Comma name. 00281 void seekNameEnd(); 00282 00283 // If a name follows on the token stream, consume it and return true 00284 // (without invoking any client callbacks). This method is useful for 00285 // tentative parsing. However, it is not full parser. For example, it 00286 // skips over mathing pairs of parenthesis. 00287 bool consumeName(); 00288 00289 // Returns true if a matching pair of parens "()" is next on the stream of 00290 // tokens. 00291 bool unitExprFollows(); 00292 00293 // Returns true if an assignment statement is next on the stream of tokens. 00294 bool assignmentFollows(); 00295 00296 // Returns true if a keyword selection expression follows: That is, if 00297 // the token stream admits an IdentifierInfo followed by a '=>' token. 00298 bool keywordSelectionFollows(); 00299 00300 // Returns true if a selected component (a name followed by a '.') is 00301 // upcoming on the token stream. 00302 bool selectedComponentFollows(); 00303 00310 bool aggregateFollows(); 00311 00313 Node parseAggregate(); 00314 00324 bool parseAggregateComponent(bool &seenKeyedComponent); 00325 00335 bool blockStmtFollows(); 00336 00342 bool qualificationFollows(); 00343 00349 bool attributeFollows(); 00350 00351 Node parseExponentialOperator(); 00352 Node parseMultiplicativeOperator(); 00353 Node parseBinaryAdditiveOperator(Node lhs); 00354 Node parseAdditiveOperator(); 00355 Node parseRelationalOperator(); 00356 Node parseLogicalOperator(Lexer::Code expectedKind, Node lhs); 00357 00361 Node parseDSTDefinition(bool acceptDiamond); 00362 00370 Node parseOthersExpr(); 00371 00372 Node parsePragmaAssert(IdentifierInfo *name, Location loc); 00373 00374 // Parses a pragma in a declaration context. 00375 void parseDeclarationPragma(); 00376 void parsePragmaImport(Location pragmaLoc); 00377 00378 // Convenience function for obtaining null nodes. 00379 Node getNullNode() { return client.getNullNode(); } 00380 00381 // Convenience function for obtaining invalid nodes. 00382 Node getInvalidNode() { return client.getInvalidNode(); } 00383 00384 // Converts a character array representing a Comma integer literal into an 00385 // llvm::APInt. The bit width of the resulting APInt is always set to the 00386 // minimal number of bits needed to represent the given number. 00387 void decimalLiteralToAPInt(const char *start, unsigned length, 00388 llvm::APInt &value); 00389 }; 00390 00391 } // End comma namespace 00392 00393 #endif