00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/basic/Pragmas.h"
00010 #include "comma/parser/Parser.h"
00011
00012 #include <cassert>
00013 #include <cstring>
00014
00015 using namespace comma;
00016
00017 Node Parser::parseStatement()
00018 {
00019 Node node = getInvalidNode();
00020
00021 switch (currentTokenCode()) {
00022
00023 default:
00024 if (assignmentFollows())
00025 node = parseAssignmentStmt();
00026 else if (blockStmtFollows())
00027 node = parseBlockStmt();
00028 else
00029 node = parseProcedureCallStatement();
00030 break;
00031
00032 case Lexer::TKN_IF:
00033 node = parseIfStmt();
00034 break;
00035
00036 case Lexer::TKN_WHILE:
00037 node = parseWhileStmt();
00038 break;
00039
00040 case Lexer::TKN_FOR:
00041 node = parseForStmt();
00042 break;
00043
00044 case Lexer::TKN_LOOP:
00045 node = parseLoopStmt();
00046 break;
00047
00048 case Lexer::TKN_RETURN:
00049 node = parseReturnStmt();
00050 break;
00051
00052 case Lexer::TKN_RAISE:
00053 node = parseRaiseStmt();
00054 break;
00055
00056 case Lexer::TKN_PRAGMA:
00057 node = parsePragmaStmt();
00058 break;
00059
00060 case Lexer::TKN_NULL:
00061 node = client.acceptNullStmt(ignoreToken());
00062 break;
00063 }
00064
00065 if (!requireToken(Lexer::TKN_SEMI))
00066 seekAndConsumeToken(Lexer::TKN_SEMI);
00067 return node;
00068 }
00069
00070 Node Parser::parseProcedureCallStatement()
00071 {
00072 Node name = parseName(Statement_Name);
00073 if (name.isValid())
00074 return client.acceptProcedureCall(name);
00075 return getInvalidNode();
00076 }
00077
00078 Node Parser::parseReturnStmt()
00079 {
00080 assert(currentTokenIs(Lexer::TKN_RETURN));
00081
00082 Location loc = ignoreToken();
00083
00084 if (currentTokenIs(Lexer::TKN_SEMI))
00085 return client.acceptEmptyReturnStmt(loc);
00086
00087 Node expr = parseExpr();
00088
00089 if (expr.isValid())
00090 return client.acceptReturnStmt(loc, expr);
00091
00092 seekSemi();
00093 return getInvalidNode();
00094 }
00095
00096 Node Parser::parseAssignmentStmt()
00097 {
00098 assert(assignmentFollows());
00099
00100 Node target = parseName();
00101
00102 if (target.isInvalid()) {
00103 seekSemi();
00104 return getInvalidNode();
00105 }
00106
00107 ignoreToken();
00108
00109 Node value = parseExpr();
00110
00111 if (value.isValid())
00112 return client.acceptAssignmentStmt(target, value);
00113 else {
00114 seekSemi();
00115 return getInvalidNode();
00116 }
00117 }
00118
00119 Node Parser::parseIfStmt()
00120 {
00121 assert(currentTokenIs(Lexer::TKN_IF));
00122
00123 Location loc = ignoreToken();
00124 Node condition = parseExpr();
00125 NodeVector stmts;
00126
00127 if (condition.isInvalid() || !requireToken(Lexer::TKN_THEN)) {
00128 seekEndIf();
00129 return getInvalidNode();
00130 }
00131
00132 do {
00133 Node stmt = parseStatement();
00134 if (stmt.isValid())
00135 stmts.push_back(stmt);
00136 } while (!currentTokenIs(Lexer::TKN_END) &&
00137 !currentTokenIs(Lexer::TKN_ELSE) &&
00138 !currentTokenIs(Lexer::TKN_ELSIF) &&
00139 !currentTokenIs(Lexer::TKN_EOT));
00140
00141 Node result = client.acceptIfStmt(loc, condition, stmts);
00142 if (result.isInvalid()) {
00143 seekEndIf();
00144 return getInvalidNode();
00145 }
00146
00147 while (currentTokenIs(Lexer::TKN_ELSIF)) {
00148 loc = ignoreToken();
00149 condition = parseExpr();
00150 if (condition.isInvalid() || !requireToken(Lexer::TKN_THEN)) {
00151 seekEndIf();
00152 return getInvalidNode();
00153 }
00154
00155 stmts.clear();
00156 do {
00157 Node stmt = parseStatement();
00158 if (stmt.isValid())
00159 stmts.push_back(stmt);
00160 } while (!currentTokenIs(Lexer::TKN_END) &&
00161 !currentTokenIs(Lexer::TKN_ELSE) &&
00162 !currentTokenIs(Lexer::TKN_ELSIF) &&
00163 !currentTokenIs(Lexer::TKN_EOT));
00164
00165 result = client.acceptElsifStmt(loc, result, condition, stmts);
00166
00167 if (result.isInvalid()) {
00168 seekEndIf();
00169 return getInvalidNode();
00170 }
00171 }
00172
00173 if (currentTokenIs(Lexer::TKN_ELSE)) {
00174 loc = ignoreToken();
00175 stmts.clear();
00176 do {
00177 Node stmt = parseStatement();
00178 if (stmt.isValid())
00179 stmts.push_back(stmt);
00180 } while (!currentTokenIs(Lexer::TKN_END) &&
00181 !currentTokenIs(Lexer::TKN_EOT));
00182
00183 result = client.acceptElseStmt(loc, result, stmts);
00184 }
00185
00186 if (!requireToken(Lexer::TKN_END) || !requireToken(Lexer::TKN_IF))
00187 return getInvalidNode();
00188
00189 return Node(result);
00190 }
00191
00192 Node Parser::parseBlockStmt()
00193 {
00194 Location loc = currentLocation();
00195 IdentifierInfo *label = 0;
00196
00197 assert(blockStmtFollows());
00198
00199
00200 if (currentTokenIs(Lexer::TKN_IDENTIFIER)) {
00201 label = parseIdentifier();
00202 ignoreToken();
00203 }
00204
00205 Node block = client.beginBlockStmt(loc, label);
00206
00207 if (reduceToken(Lexer::TKN_DECLARE)) {
00208 while (!currentTokenIs(Lexer::TKN_BEGIN) &&
00209 !currentTokenIs(Lexer::TKN_EOT)) {
00210 parseDeclaration();
00211 requireToken(Lexer::TKN_SEMI);
00212 }
00213 }
00214
00215 if (!requireToken(Lexer::TKN_BEGIN)) {
00216 client.endBlockStmt(block);
00217 seekAndConsumeEndTag(label);
00218 return getInvalidNode();
00219 }
00220
00221
00222 while (!currentTokenIs(Lexer::TKN_END) &&
00223 !currentTokenIs(Lexer::TKN_EXCEPTION) &&
00224 !currentTokenIs(Lexer::TKN_EOT)) {
00225 Node stmt = parseStatement();
00226 if (stmt.isValid())
00227 client.acceptStmt(block, stmt);
00228 }
00229
00230
00231 client.endBlockStmt(block);
00232
00233
00234 if (currentTokenIs(Lexer::TKN_EXCEPTION))
00235 parseExceptionStmt(block);
00236
00237
00238 if (!parseEndTag(label))
00239 seekAndConsumeEndTag(label);
00240 return block;
00241 }
00242
00243 Node Parser::parseWhileStmt()
00244 {
00245 assert(currentTokenIs(Lexer::TKN_WHILE));
00246
00247 Location loc = ignoreToken();
00248 Node condition = parseExpr();
00249 NodeVector stmts;
00250
00251 if (condition.isInvalid() || !requireToken(Lexer::TKN_LOOP)) {
00252 seekEndLoop();
00253 return getInvalidNode();
00254 }
00255
00256 do {
00257 Node stmt = parseStatement();
00258 if (stmt.isValid())
00259 stmts.push_back(stmt);
00260 } while (!currentTokenIs(Lexer::TKN_END) &&
00261 !currentTokenIs(Lexer::TKN_EOT));
00262
00263 if (!requireToken(Lexer::TKN_END) || !requireToken(Lexer::TKN_LOOP))
00264 return getInvalidNode();
00265
00266 return client.acceptWhileStmt(loc, condition, stmts);
00267 }
00268
00269 Node Parser::parseLoopStmt()
00270 {
00271 assert(currentTokenIs(Lexer::TKN_LOOP));
00272
00273 Location loc = ignoreToken();
00274 NodeVector stmts;
00275
00276 do {
00277 Node stmt = parseStatement();
00278 if (stmt.isValid())
00279 stmts.push_back(stmt);
00280 } while (!currentTokenIs(Lexer::TKN_END) &&
00281 !currentTokenIs(Lexer::TKN_EOT));
00282
00283 if (!requireToken(Lexer::TKN_END) || !requireToken(Lexer::TKN_LOOP))
00284 return getInvalidNode();
00285
00286 return client.acceptLoopStmt(loc, stmts);
00287 }
00288
00289 Node Parser::parseForStmt()
00290 {
00291 assert(currentTokenIs(Lexer::TKN_FOR));
00292 Location forLoc = ignoreToken();
00293
00294 Location iterLoc = currentLocation();
00295 IdentifierInfo *iterName = parseIdentifier();
00296
00297 if (!iterName || !requireToken(Lexer::TKN_IN)) {
00298 seekEndLoop();
00299 return getInvalidNode();
00300 }
00301
00302 bool isReversed = reduceToken(Lexer::TKN_REVERSE);
00303 Node DST = parseDSTDefinition(false);
00304 if (DST.isInvalid() || !requireToken(Lexer::TKN_LOOP)) {
00305 seekEndLoop();
00306 return getInvalidNode();
00307 }
00308
00309 Node forNode = client.beginForStmt(
00310 forLoc, iterName, iterLoc, DST, isReversed);
00311
00312 NodeVector stmts;
00313 do {
00314 Node stmt = parseStatement();
00315 if (stmt.isValid())
00316 stmts.push_back(stmt);
00317 } while (!currentTokenIs(Lexer::TKN_END) &&
00318 !currentTokenIs(Lexer::TKN_EOT));
00319
00320
00321
00322
00323 forNode = client.endForStmt(forNode, stmts);
00324
00325 if (!requireToken(Lexer::TKN_END) || !requireToken(Lexer::TKN_LOOP))
00326 return getInvalidNode();
00327
00328 return forNode;
00329 }
00330
00331 Node Parser::parsePragmaStmt()
00332 {
00333 assert(currentTokenIs(Lexer::TKN_PRAGMA));
00334 ignoreToken();
00335
00336 Location loc = currentLocation();
00337 IdentifierInfo *name = parseIdentifier();
00338
00339 if (!name) {
00340 seekSemi();
00341 return getInvalidNode();
00342 }
00343
00344 llvm::StringRef ref(name->getString());
00345 pragma::PragmaID ID = pragma::getPragmaID(ref);
00346
00347 if (ID == pragma::UNKNOWN_PRAGMA) {
00348 report(loc, diag::UNKNOWN_PRAGMA) << name;
00349 seekSemi();
00350 return getInvalidNode();
00351 }
00352
00353
00354
00355
00356 switch (ID) {
00357 default:
00358 seekSemi();
00359 report(loc, diag::INVALID_PRAGMA_CONTEXT) << name;
00360 return getInvalidNode();
00361
00362 case pragma::Assert:
00363 return parsePragmaAssert(name, loc);
00364 }
00365 }
00366
00367 Node Parser::parsePragmaAssert(IdentifierInfo *name, Location loc)
00368 {
00369 if (requireToken(Lexer::TKN_LPAREN)) {
00370 NodeVector args;
00371
00372 Node condition = parseExpr();
00373 if (condition.isInvalid()) {
00374 seekToken(Lexer::TKN_RPAREN);
00375 return getInvalidNode();
00376 }
00377 args.push_back(condition);
00378
00379 if (reduceToken(Lexer::TKN_COMMA)) {
00380 Node message = parseExpr();
00381 if (message.isInvalid()) {
00382 seekToken(Lexer::TKN_RPAREN);
00383 return getInvalidNode();
00384 }
00385 args.push_back(message);
00386 }
00387
00388 if (!requireToken(Lexer::TKN_RPAREN)) {
00389 seekToken(Lexer::TKN_RPAREN);
00390 return getInvalidNode();
00391 }
00392 else
00393 return client.acceptPragmaStmt(name, loc, args);
00394 }
00395 seekSemi();
00396 return getInvalidNode();
00397 }
00398
00399 Node Parser::parseRaiseStmt()
00400 {
00401 assert(currentTokenIs(Lexer::TKN_RAISE));
00402 Location raiseLoc = ignoreToken();
00403
00404 Node exception = parseName();
00405 if (exception.isInvalid()) {
00406 seekSemi();
00407 return getInvalidNode();
00408 }
00409
00410 Node message = getNullNode();
00411 if (reduceToken(Lexer::TKN_WITH)) {
00412 message = parseExpr();
00413 if (message.isInvalid()) {
00414 seekSemi();
00415 return getInvalidNode();
00416 }
00417 }
00418 return client.acceptRaiseStmt(raiseLoc, exception, message);
00419 }
00420
00421 void Parser::parseExceptionStmt(Node context)
00422 {
00423 assert(currentTokenIs(Lexer::TKN_EXCEPTION));
00424 ignoreToken();
00425
00426
00427 bool seenOthers = false;
00428 Location othersLoc = 0;
00429 do {
00430 Location loc = currentLocation();
00431 if (!requireToken(Lexer::TKN_WHEN)) {
00432 seekToken(Lexer::TKN_END);
00433 return;
00434 }
00435
00436 if (seenOthers) {
00437 report(othersLoc, diag::OTHERS_HANDLER_NOT_FINAL);
00438 seekToken(Lexer::TKN_END);
00439 return;
00440 }
00441
00442
00443
00444 NodeVector choices;
00445 do {
00446 Location choiceLoc = currentLocation();
00447 if (reduceToken(Lexer::TKN_OTHERS)) {
00448 if (!choices.empty()) {
00449 report(choiceLoc, diag::OTHERS_HANDLER_NOT_UNIQUE);
00450 seekToken(Lexer::TKN_END);
00451 return;
00452 }
00453 seenOthers = true;
00454 othersLoc = choiceLoc;
00455 break;
00456 }
00457
00458 Node exception = parseName();
00459 if (exception.isValid())
00460 choices.push_back(exception);
00461 else {
00462 seekToken(Lexer::TKN_END);
00463 return;
00464 }
00465 } while (reduceToken(Lexer::TKN_BAR));
00466
00467 if (!requireToken(Lexer::TKN_RDARROW)) {
00468 seekToken(Lexer::TKN_END);
00469 return;
00470 }
00471
00472 Node handler = client.beginHandlerStmt(loc, choices);
00473 if (handler.isInvalid()) {
00474 seekToken(Lexer::TKN_END);
00475 return;
00476 }
00477
00478 do {
00479 Node stmt = parseStatement();
00480 if (stmt.isValid())
00481 client.acceptStmt(handler, stmt);
00482 } while (!currentTokenIs(Lexer::TKN_WHEN) &&
00483 !currentTokenIs(Lexer::TKN_END) &&
00484 !currentTokenIs(Lexer::TKN_EOT));
00485
00486 client.endHandlerStmt(context, handler);
00487 } while (currentTokenIs(Lexer::TKN_WHEN));
00488 }