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/ParseName.cpp ---------------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #include "comma/parser/Parser.h" 00010 00011 using namespace comma; 00012 00013 //===----------------------------------------------------------------------===// 00014 // Name Parsing. 00015 00016 Node Parser::parseDirectName(NameOption option) 00017 { 00018 Location loc = currentLocation(); 00019 00020 switch (currentTokenCode()) { 00021 default: 00022 report(diag::UNEXPECTED_TOKEN) << currentTokenString(); 00023 seekNameEnd(); 00024 break; 00025 00026 case Lexer::TKN_IDENTIFIER: 00027 if (IdentifierInfo *name = parseIdentifier()) 00028 return client.acceptDirectName(name, loc, option); 00029 break; 00030 00031 case Lexer::TKN_CHARACTER: 00032 if (IdentifierInfo *name = parseCharacter()) 00033 return client.acceptCharacterLiteral(name, loc); 00034 break; 00035 00036 case Lexer::TKN_PERCENT: 00037 return client.acceptPercent(ignoreToken()); 00038 00039 case Lexer::TKN_INJ: 00040 return parseInj(); 00041 00042 case Lexer::TKN_PRJ: 00043 return parsePrj(); 00044 }; 00045 00046 return getInvalidNode(); 00047 } 00048 00049 Node Parser::parseInj() 00050 { 00051 assert(currentTokenIs(Lexer::TKN_INJ)); 00052 Location loc = ignoreToken(); 00053 00054 if (!requireToken(Lexer::TKN_LPAREN)) 00055 return getInvalidNode(); 00056 00057 Node expr = parseExpr(); 00058 00059 if (expr.isInvalid() || !requireToken(Lexer::TKN_RPAREN)) 00060 return getInvalidNode(); 00061 00062 return client.acceptInj(loc, expr); 00063 } 00064 00065 Node Parser::parsePrj() 00066 { 00067 assert(currentTokenIs(Lexer::TKN_PRJ)); 00068 Location loc = ignoreToken(); 00069 00070 if (!requireToken(Lexer::TKN_LPAREN)) 00071 return getInvalidNode(); 00072 00073 Node expr = parseExpr(); 00074 00075 if (expr.isInvalid() || !requireToken(Lexer::TKN_RPAREN)) { 00076 seekCloseParen(); 00077 return getInvalidNode(); 00078 } 00079 00080 return client.acceptPrj(loc, expr); 00081 } 00082 00083 Node Parser::parseSelectedComponent(Node prefix, NameOption option) 00084 { 00085 Location loc = currentLocation(); 00086 00087 if (reduceToken(Lexer::TKN_ALL)) 00088 return client.acceptDereference(prefix, loc); 00089 00090 IdentifierInfo *name = parseAnyIdentifier(); 00091 00092 if (name) { 00093 bool forStatement = (option == Statement_Name); 00094 return client.acceptSelectedComponent(prefix, name, loc, forStatement); 00095 } 00096 00097 seekNameEnd(); 00098 return getInvalidNode(); 00099 } 00100 00101 Node Parser::parseApplication(Node prefix) 00102 { 00103 assert(currentTokenIs(Lexer::TKN_LPAREN)); 00104 00105 if (unitExprFollows()) { 00106 Location loc = ignoreToken(); // Ignore the opening paren; 00107 ignoreToken(); // Ingore the close paren; 00108 Node result = client.finishName(prefix); 00109 if (result.isValid()) 00110 report(loc, diag::EMPTY_PARAMS); 00111 return result; 00112 } 00113 00114 ignoreToken(); // Ignore the opening paren. 00115 NodeVector arguments; 00116 bool seenSelector = false; 00117 00118 do { 00119 Node arg = getInvalidNode(); 00120 if (keywordSelectionFollows()) { 00121 arg = parseParameterAssociation(); 00122 seenSelector = true; 00123 } 00124 else if (seenSelector) { 00125 report(diag::POSITIONAL_FOLLOWING_SELECTED_PARAMETER); 00126 seekCloseParen(); 00127 return getInvalidNode(); 00128 } 00129 else 00130 arg = parseExpr(); 00131 00132 if (arg.isValid()) 00133 arguments.push_back(arg); 00134 else { 00135 seekCloseParen(); 00136 return getInvalidNode(); 00137 } 00138 } while (reduceToken(Lexer::TKN_COMMA)); 00139 00140 if (!requireToken(Lexer::TKN_RPAREN)) { 00141 seekCloseParen(); 00142 return getInvalidNode(); 00143 } 00144 return client.acceptApplication(prefix, arguments); 00145 } 00146 00147 Node Parser::parseParameterAssociation() 00148 { 00149 assert(keywordSelectionFollows()); 00150 00151 Location loc = currentLocation(); 00152 IdentifierInfo *key = parseIdentifier(); 00153 00154 ignoreToken(); // Ignore the =>. 00155 00156 Node rhs = parseExpr(); 00157 00158 if (rhs.isValid()) 00159 return client.acceptParameterAssociation(key, loc, rhs); 00160 else 00161 return getInvalidNode(); 00162 } 00163 00164 Node Parser::parseAttribute(Node prefix, NameOption option) 00165 { 00166 assert(attributeFollows()); 00167 ignoreToken(); // Ignore the quote. 00168 00169 Location loc = currentLocation(); 00170 IdentifierInfo *name = parseIdentifier(); 00171 00172 if (name->getAttributeID() == attrib::UNKNOWN_ATTRIBUTE) { 00173 report(loc, diag::UNKNOWN_ATTRIBUTE) << name; 00174 return getInvalidNode(); 00175 } 00176 00179 if ((name->getAttributeID() == attrib::Range) && 00180 (option != Accept_Range_Attribute)) { 00181 report(loc, diag::INVALID_ATTRIBUTE_CONTEXT) << name; 00182 return getInvalidNode(); 00183 } 00184 00185 return client.acceptAttribute(prefix, name, loc); 00186 } 00187 00188 Node Parser::parseName(NameOption option) 00189 { 00190 Location loc = currentLocation(); 00191 00192 // All names start with a direct name. 00193 Node prefix = parseDirectName(option); 00194 00195 if (prefix.isInvalid()) 00196 return prefix; 00197 00198 for ( ;; ) { 00199 if (currentTokenIs(Lexer::TKN_LPAREN)) 00200 prefix = parseApplication(prefix); 00201 else if (reduceToken(Lexer::TKN_DOT)) { 00202 prefix = client.finishName(prefix); 00203 if (prefix.isValid()) 00204 prefix = parseSelectedComponent(prefix, option); 00205 } 00206 else if (attributeFollows()) { 00207 prefix = client.finishName(prefix); 00208 if (prefix.isValid()) 00209 prefix = parseAttribute(prefix, option); 00210 } 00211 else 00212 break; 00213 00214 if (prefix.isInvalid()) 00215 break; 00216 } 00217 00218 if (prefix.isInvalid()) { 00219 seekNameEnd(); 00220 return prefix; 00221 } 00222 else 00223 return client.finishName(prefix); 00224 } 00225 00226 void Parser::seekNameEnd() 00227 { 00228 for ( ;; ) { 00229 switch(currentTokenCode()) { 00230 00231 default: 00232 return; 00233 00234 case Lexer::TKN_IDENTIFIER: 00235 case Lexer::TKN_DOT: 00236 case Lexer::TKN_CHARACTER: 00237 case Lexer::TKN_PERCENT: 00238 case Lexer::TKN_INJ: 00239 case Lexer::TKN_PRJ: 00240 case Lexer::TKN_ALL: 00241 ignoreToken(); 00242 break; 00243 00244 case Lexer::TKN_LPAREN: 00245 ignoreToken(); 00246 seekCloseParen(); 00247 }; 00248 } 00249 } 00250 00251 bool Parser::consumeName() 00252 { 00253 // Identify direct names. If we cannot consume a direct name we simply 00254 // return false. 00255 switch (currentTokenCode()) { 00256 default: 00257 return false; 00258 case Lexer::TKN_CHARACTER: 00259 case Lexer::TKN_IDENTIFIER: 00260 case Lexer::TKN_PERCENT: 00261 case Lexer::TKN_INJ: 00262 case Lexer::TKN_PRJ: 00263 break; 00264 } 00265 00266 // OK. Consume the direct name. 00267 ignoreToken(); 00268 00269 // From this point on we will invariably return true since a name was 00270 // consumed. Just drive the token stream as far as we can assuming all 00271 // tokens are valid. 00272 bool consume = true; 00273 while (consume) { 00274 if (reduceToken(Lexer::TKN_LPAREN)) 00275 consume = seekCloseParen(); 00276 else if (reduceToken(Lexer::TKN_DOT)) { 00277 switch (currentTokenCode()) { 00278 default: 00279 consume = false; 00280 break; 00281 case Lexer::TKN_IDENTIFIER: 00282 case Lexer::TKN_CHARACTER: 00283 case Lexer::TKN_ALL: 00284 ignoreToken(); 00285 break; 00286 }; 00287 } 00288 else if (attributeFollows()) { 00289 ignoreToken(); // Ignore the quote. 00290 ignoreToken(); // Ignore the attribute name. 00291 } 00292 else 00293 consume = false; 00294 } 00295 return true; 00296 } 00297