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 }