00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/parser/Parser.h"
00010
00011 using namespace comma;
00012
00013
00014
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();
00107 ignoreToken();
00108 Node result = client.finishName(prefix);
00109 if (result.isValid())
00110 report(loc, diag::EMPTY_PARAMS);
00111 return result;
00112 }
00113
00114 ignoreToken();
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();
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();
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
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
00254
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
00267 ignoreToken();
00268
00269
00270
00271
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();
00290 ignoreToken();
00291 }
00292 else
00293 consume = false;
00294 }
00295 return true;
00296 }
00297