00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/parser/Parser.h"
00010 #include <cassert>
00011
00012 using namespace comma;
00013
00014 Node Parser::parseStatement()
00015 {
00016 Node node = getInvalidNode();
00017
00018 switch (currentTokenCode()) {
00019
00020 default:
00021 if (assignmentFollows())
00022 node = parseAssignmentStmt();
00023 else if (blockStmtFollows())
00024 node = parseBlockStmt();
00025 else
00026 node = parseProcedureCallStatement();
00027 break;
00028
00029 case Lexer::TKN_IF:
00030 node = parseIfStmt();
00031 break;
00032
00033 case Lexer::TKN_RETURN:
00034 node = parseReturnStmt();
00035 break;
00036 }
00037
00038 if (node.isInvalid() || !requireToken(Lexer::TKN_SEMI))
00039 seekAndConsumeToken(Lexer::TKN_SEMI);
00040
00041 return node;
00042 }
00043
00044 Node Parser::parseProcedureCallStatement()
00045 {
00046 Node qual = getNullNode();
00047 if (qualifierFollows()) {
00048 qual = parseQualifier();
00049 if (qual.isInvalid())
00050 return getInvalidNode();
00051 }
00052
00053 Location loc = currentLocation();
00054 IdentifierInfo *name = parseIdentifierInfo();
00055 if (!name) {
00056 seekToken(Lexer::TKN_SEMI);
00057 return getInvalidNode();
00058 }
00059
00060 NodeVector args;
00061 if (currentTokenIs(Lexer::TKN_LPAREN))
00062 if (!parseSubroutineArgumentList(args))
00063 return getInvalidNode();
00064
00065 Node connective = client.acceptProcedureName(name, loc, qual);
00066
00067 if (connective.isValid())
00068 return client.acceptProcedureCall(connective, loc, args);
00069 else
00070 return getInvalidNode();
00071 }
00072
00073 Node Parser::parseReturnStmt()
00074 {
00075 assert(currentTokenIs(Lexer::TKN_RETURN));
00076
00077 Location loc = ignoreToken();
00078
00079 if (currentTokenIs(Lexer::TKN_SEMI))
00080 return client.acceptEmptyReturnStmt(loc);
00081
00082 Node expr = parseExpr();
00083
00084 if (expr.isValid())
00085 return client.acceptReturnStmt(loc, expr);
00086 return expr;
00087 }
00088
00089 Node Parser::parseAssignmentStmt()
00090 {
00091 assert(assignmentFollows());
00092
00093 Location location = currentLocation();
00094 IdentifierInfo *target = parseIdentifierInfo();
00095
00096 ignoreToken();
00097 Node value = parseExpr();
00098 if (value.isValid())
00099 return client.acceptAssignmentStmt(location, target, value);
00100 return getInvalidNode();
00101 }
00102
00103 Node Parser::parseIfStmt()
00104 {
00105 assert(currentTokenIs(Lexer::TKN_IF));
00106
00107 Location loc = ignoreToken();
00108 Node condition = parseExpr();
00109 NodeVector stmts;
00110
00111 if (condition.isInvalid() || !requireToken(Lexer::TKN_THEN)) {
00112 seekEndIf();
00113 return getInvalidNode();
00114 }
00115
00116 do {
00117 Node stmt = parseStatement();
00118 if (stmt.isValid())
00119 stmts.push_back(stmt);
00120 } while (!currentTokenIs(Lexer::TKN_END) &&
00121 !currentTokenIs(Lexer::TKN_ELSE) &&
00122 !currentTokenIs(Lexer::TKN_ELSIF) &&
00123 !currentTokenIs(Lexer::TKN_EOT));
00124
00125 Node result = client.acceptIfStmt(loc, condition, &stmts[0], stmts.size());
00126 if (result.isInvalid()) {
00127 seekEndIf();
00128 return getInvalidNode();
00129 }
00130
00131 while (currentTokenIs(Lexer::TKN_ELSIF)) {
00132 loc = ignoreToken();
00133 condition = parseExpr();
00134 if (condition.isInvalid() || !requireToken(Lexer::TKN_THEN)) {
00135 seekEndIf();
00136 return getInvalidNode();
00137 }
00138
00139 stmts.clear();
00140 do {
00141 Node stmt = parseStatement();
00142 if (stmt.isValid())
00143 stmts.push_back(stmt);
00144 } while (!currentTokenIs(Lexer::TKN_END) &&
00145 !currentTokenIs(Lexer::TKN_ELSE) &&
00146 !currentTokenIs(Lexer::TKN_ELSIF) &&
00147 !currentTokenIs(Lexer::TKN_EOT));
00148
00149 result = client.acceptElsifStmt(loc, result, condition,
00150 &stmts[0], stmts.size());
00151
00152 if (result.isInvalid()) {
00153 seekEndIf();
00154 return getInvalidNode();
00155 }
00156 }
00157
00158 if (currentTokenIs(Lexer::TKN_ELSE)) {
00159 loc = ignoreToken();
00160 stmts.clear();
00161 do {
00162 Node stmt = parseStatement();
00163 if (stmt.isValid())
00164 stmts.push_back(stmt);
00165 } while (!currentTokenIs(Lexer::TKN_END) &&
00166 !currentTokenIs(Lexer::TKN_EOT));
00167
00168 result = client.acceptElseStmt(loc, result, &stmts[0], stmts.size());
00169 }
00170
00171 if (!requireToken(Lexer::TKN_END) || !requireToken(Lexer::TKN_IF))
00172 return getInvalidNode();
00173
00174 return Node(result);
00175 }
00176
00177 Node Parser::parseBlockStmt()
00178 {
00179 Location loc = currentLocation();
00180 IdentifierInfo *label = 0;
00181
00182 assert(blockStmtFollows());
00183
00184
00185 if (currentTokenIs(Lexer::TKN_IDENTIFIER)) {
00186 label = parseIdentifierInfo();
00187 ignoreToken();
00188 }
00189
00190 Node block = client.beginBlockStmt(loc, label);
00191
00192 if (reduceToken(Lexer::TKN_DECLARE)) {
00193 while (!currentTokenIs(Lexer::TKN_BEGIN) &&
00194 !currentTokenIs(Lexer::TKN_EOT)) {
00195 parseDeclaration();
00196 requireToken(Lexer::TKN_SEMI);
00197 }
00198 }
00199
00200 if (requireToken(Lexer::TKN_BEGIN)) {
00201 while (!currentTokenIs(Lexer::TKN_END) &&
00202 !currentTokenIs(Lexer::TKN_EOT)) {
00203 Node stmt = parseStatement();
00204 if (stmt.isValid())
00205 client.acceptBlockStmt(block, stmt);
00206 }
00207 if (parseEndTag(label)) {
00208 client.endBlockStmt(block);
00209 return block;
00210 }
00211 }
00212
00213 seekAndConsumeEndTag(label);
00214 return getInvalidNode();
00215 }