AstNode* Parser::parseStatement() { if (isKeyword(currentTokenValue())) { if (currentTokenValue() == "function") { return parseFunction(); } else if (currentTokenValue() == "for") { return parseFor(); } else if (currentTokenValue() == "if") { return parseIf(); } else if (currentTokenValue() == "while") { return parseWhile(); } else if (currentTokenValue() == "print") { return parsePrint(); } else if (currentTokenValue() == "int") { return parseDeclaration(VT_INT); } else if (currentTokenValue() == "double") { return parseDeclaration(VT_DOUBLE); } else if (currentTokenValue() == "string") { return parseDeclaration(VT_STRING); } else if (currentTokenValue() == "return") { return parseReturn(); } else { cout << "unhandled keyword " << currentTokenValue() << endl; assert(false); return 0; } } if (currentToken() == tLBRACE) { return parseBlock(true); } if ((currentToken() == tIDENT) && isAssignment(lookaheadToken(1))) { return parseAssignment(); } return parseExpression(); }
/*** Parse a statement ***/ Node* Parser::parseStatement() { if(hasTokens(2) && peekToken().getType() == T_IDENTIFIER && peekToken(2).getType() == T_ASSIGN) return parseAssign(); if(hasTokens(2) && peekToken().getType() == T_IDENTIFIER && peekToken(2).getType() == T_LPAREN) return parseCall(); if(hasTokens() && peekToken().getType() == T_CALL) return parseCall(); if(hasTokens() && peekToken().getType() == T_CASE) return parseCase(); if(hasTokens() && peekToken().getType() == T_DO) return parseDo(); if(hasTokens() && peekToken().getType() == T_END) return parseEnd(); if(hasTokens() && peekToken().getType() == T_EXIT) return parseExit(); if(hasTokens() && peekToken().getType() == T_FOR) return parseFor(); if(hasTokens() && peekToken().getType() == T_IF) return parseIf(); if(hasTokens() && peekToken().getType() == T_INPUT) return parseInput(); if(hasTokens() && peekToken().getType() == T_OUTPUT) return parseOutput(); if(hasTokens() && peekToken().getType() == T_REPEAT) return parseRepeat(); if(hasTokens() && peekToken().getType() == T_RETURN) return parseReturn(); if(hasTokens(2) && peekToken(1).getType() == T_IDENTIFIER && peekToken(2).getType() == T_LBRACKET) return parseSliceSelectAssign(); if(hasTokens() && peekToken().getType() == T_WHILE) return parseWhile(); throw ParserSyntaxException(getToken(), "Invalid statement!"); return 0; }
void UnwrappedLineParser::parseStructuralElement() { assert(!FormatTok->Tok.is(tok::l_brace)); switch (FormatTok->Tok.getKind()) { case tok::at: nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { parseBracedList(); break; } switch (FormatTok->Tok.getObjCKeywordID()) { case tok::objc_public: case tok::objc_protected: case tok::objc_package: case tok::objc_private: return parseAccessSpecifier(); case tok::objc_interface: case tok::objc_implementation: return parseObjCInterfaceOrImplementation(); case tok::objc_protocol: return parseObjCProtocol(); case tok::objc_end: return; // Handled by the caller. case tok::objc_optional: case tok::objc_required: nextToken(); addUnwrappedLine(); return; default: break; } break; case tok::kw_namespace: parseNamespace(); return; case tok::kw_inline: nextToken(); if (FormatTok->Tok.is(tok::kw_namespace)) { parseNamespace(); return; } break; case tok::kw_public: case tok::kw_protected: case tok::kw_private: parseAccessSpecifier(); return; case tok::kw_if: parseIfThenElse(); return; case tok::kw_for: case tok::kw_while: parseForOrWhileLoop(); return; case tok::kw_do: parseDoWhile(); return; case tok::kw_switch: parseSwitch(); return; case tok::kw_default: nextToken(); parseLabel(); return; case tok::kw_case: parseCaseLabel(); return; case tok::kw_return: parseReturn(); return; case tok::kw_extern: nextToken(); if (FormatTok->Tok.is(tok::string_literal)) { nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false); addUnwrappedLine(); return; } } // In all other cases, parse the declaration. break; default: break; } do { switch (FormatTok->Tok.getKind()) { case tok::at: nextToken(); if (FormatTok->Tok.is(tok::l_brace)) parseBracedList(); break; case tok::kw_enum: parseEnum(); break; case tok::kw_struct: case tok::kw_union: case tok::kw_class: parseRecord(); // A record declaration or definition is always the start of a structural // element. break; case tok::semi: nextToken(); addUnwrappedLine(); return; case tok::r_brace: addUnwrappedLine(); return; case tok::l_paren: parseParens(); break; case tok::caret: nextToken(); if (FormatTok->is(tok::l_brace)) { parseChildBlock(); } break; case tok::l_brace: if (!tryToParseBracedList()) { // A block outside of parentheses must be the last part of a // structural element. // FIXME: Figure out cases where this is not true, and add projections // for them (the one we know is missing are lambdas). if (Style.BreakBeforeBraces != FormatStyle::BS_Attach) addUnwrappedLine(); FormatTok->Type = TT_FunctionLBrace; parseBlock(/*MustBeDeclaration=*/false); addUnwrappedLine(); return; } // Otherwise this was a braced init list, and the structural // element continues. break; case tok::identifier: { StringRef Text = FormatTok->TokenText; nextToken(); if (Line->Tokens.size() == 1) { if (FormatTok->Tok.is(tok::colon)) { parseLabel(); return; } // Recognize function-like macro usages without trailing semicolon. if (FormatTok->Tok.is(tok::l_paren)) { parseParens(); if (FormatTok->HasUnescapedNewline && tokenCanStartNewLine(FormatTok->Tok)) { addUnwrappedLine(); return; } } else if (FormatTok->HasUnescapedNewline && Text.size() >= 5 && Text == Text.upper()) { // Recognize free-standing macros like Q_OBJECT. addUnwrappedLine(); return; } } break; } case tok::equal: nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { parseBracedList(); } break; case tok::l_square: parseSquare(); break; default: nextToken(); break; } } while (!eof()); }