void UnwrappedLineParser::parseIfThenElse() { assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected"); nextToken(); parseParens(); bool NeedsUnwrappedLine = false; if (FormatTok.Tok.is(tok::l_brace)) { parseBlock(); NeedsUnwrappedLine = true; } else { addUnwrappedLine(); ++Line.Level; parseStatement(); --Line.Level; } if (FormatTok.Tok.is(tok::kw_else)) { nextToken(); if (FormatTok.Tok.is(tok::l_brace)) { parseBlock(); addUnwrappedLine(); } else if (FormatTok.Tok.is(tok::kw_if)) { parseIfThenElse(); } else { addUnwrappedLine(); ++Line.Level; parseStatement(); --Line.Level; } } else if (NeedsUnwrappedLine) { addUnwrappedLine(); } }
void UnwrappedLineParser::parseIfThenElse() { assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected"); nextToken(); if (FormatTok->Tok.is(tok::l_paren)) parseParens(); bool NeedsUnwrappedLine = false; if (FormatTok->Tok.is(tok::l_brace)) { parseBlock(/*MustBeDeclaration=*/ false); NeedsUnwrappedLine = true; } else { addUnwrappedLine(); ++Line->Level; parseStructuralElement(); --Line->Level; } if (FormatTok->Tok.is(tok::kw_else)) { nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { parseBlock(/*MustBeDeclaration=*/ false); addUnwrappedLine(); } else if (FormatTok->Tok.is(tok::kw_if)) { parseIfThenElse(); } else { addUnwrappedLine(); ++Line->Level; parseStructuralElement(); --Line->Level; } } else if (NeedsUnwrappedLine) { addUnwrappedLine(); } }
Expression::Expression(string source_, bool varyingAllowed_) { varyingAllowed = varyingAllowed_; source = source_; sourceIndex = 0; root = parseIfThenElse(); skipWhitespace(); assert(sourceIndex == source.size(), "Portion of expression not parsed: %s\n", source.c_str() + sourceIndex); }
void UnwrappedLineParser::parseIfThenElse() { assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected"); nextToken(); if (FormatTok->Tok.is(tok::l_paren)) parseParens(); bool NeedsUnwrappedLine = false; if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || Style.BreakBeforeBraces == FormatStyle::BS_GNU) { addUnwrappedLine(); } else { NeedsUnwrappedLine = true; } } else { addUnwrappedLine(); ++Line->Level; parseStructuralElement(); --Line->Level; } if (FormatTok->Tok.is(tok::kw_else)) { nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); addUnwrappedLine(); } else if (FormatTok->Tok.is(tok::kw_if)) { parseIfThenElse(); } else { addUnwrappedLine(); ++Line->Level; parseStructuralElement(); --Line->Level; } } else if (NeedsUnwrappedLine) { addUnwrappedLine(); } }
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_try: parseTryCatch(); 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; } } break; case tok::identifier: if (FormatTok->IsForEachMacro) { parseForOrWhileLoop(); 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_typedef: nextToken(); // FIXME: Use the IdentifierTable instead. if (FormatTok->TokenText == "NS_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->Tok.isAnyIdentifier() || FormatTok->isSimpleTypeSpecifier()) nextToken(); if (FormatTok->is(tok::l_paren)) parseParens(); 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::kw_try: // We arrive here when parsing function-try blocks. parseTryCatch(); return; case tok::identifier: { StringRef Text = FormatTok->TokenText; if (Style.Language == FormatStyle::LK_JavaScript && Text == "function") { tryToParseJSFunction(); break; } 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->NewlinesBefore > 0 && tokenCanStartNewLine(FormatTok->Tok) && Text == Text.upper()) { 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()); }
// Term -> Funct ( IfThenElse ) | - Term | Var | ( IfThenElse ) | Float | Sample Expression::Node *Expression::parseTerm() { //printf("parsing term\n"); Node *result; //printf("%s\n", source); if (varyingAllowed && consume("[")) { // sampling Node *coord1 = parseIfThenElse(); if (consume(",")) { Node *coord2 = parseIfThenElse(); if (consume(",")) { Node *coord3 = parseIfThenElse(); assert(consume("]"), "Sample takes at most three coordinates\n"); result = new Sample3D(coord1, coord2, coord3); } else { result = new Sample2D(coord1, coord2); assert(consume("]"), "Sample missing closing bracket\n"); } } else { result = new SampleHere(coord1); assert(consume("]"), "Sample missing closing bracket\n"); } } else if (consume("cos")) { // functions assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_cos(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("sin")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_sin(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("log")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_log(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("exp")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_exp(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("tan")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_tan(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("asin")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_asin(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("acos")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_acos(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("atan2")) { assert(consume("("), "Function call missing opening parenthesis.\n"); Node *arg1 = parseIfThenElse(); assert(consume(","), "',' expected between function call arguments.\n"); Node *arg2 = parseIfThenElse(); assert(consume(")"), "Function call missing closing parenthesis.\n"); result = new Funct_atan2(arg1, arg2); } else if (consume("atan")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_atan(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("abs")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_abs(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("floor")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_floor(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("ceil")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_ceil(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("round")) { assert(consume("("), "Function call missing opening parenthesis.\n"); result = new Funct_round(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } else if (consume("mean")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_mean0(); } else { result = new Funct_mean1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("sum")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_sum0(); } else { result = new Funct_sum1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("max")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_max0(); } else { result = new Funct_max1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("min")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_min0(); } else { result = new Funct_min1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("stddev")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_stddev0(); } else { result = new Funct_stddev1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("variance")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_variance0(); } else { result = new Funct_variance1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("skew")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_skew0(); } else { result = new Funct_skew1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("kurtosis")) { assert(consume("("), "Function call missing opening parenthesis.\n"); if (consume(")")) { result = new Funct_kurtosis0(); } else { result = new Funct_kurtosis1(parseIfThenElse()); assert(consume(")"), "Function call missing closing parenthesis.\n"); } } else if (consume("covariance")) { assert(consume("("), "Function call missing opening parenthesis.\n"); Node *arg1 = parseIfThenElse(); assert(consume(","), "',' expected between function call arguments.\n"); Node *arg2 = parseIfThenElse(); assert(consume(")"), "Function call missing closing parenthesis.\n"); result = new Funct_covariance(arg1, arg2); } else if (consume("-")) { // unary negation result = new Negation(parseTerm()); } else if (varyingAllowed && consume("x")) { // variables result = new Var_x(); } else if (varyingAllowed && consume("y")) { result = new Var_y(); } else if (varyingAllowed && consume("t")) { result = new Var_t(); } else if (varyingAllowed && consume("c")) { result = new Var_c(); } else if (varyingAllowed && consume("val")) { result = new Var_val(); } else if (consume("(")) { // a new expression bracketed result = parseIfThenElse(); assert(consume(")"), "Closing parenthesis missing on expression\n"); } else if (consume("pi")) { // constants result = new Float(3.14159265f); } else if (consume("e")) { result = new Float(2.71828183f); } else if (consume("width")) { result = new Uniform_width(); } else if (consume("height")) { result = new Uniform_height(); } else if (consume("frames")) { result = new Uniform_frames(); } else if (consume("channels")) { result = new Uniform_channels(); } else { // must be a float constant float val; int consumed = sscanf(source.c_str() + sourceIndex, "%20f", &val); if (consumed == 0) { panic("Could not parse from here: %s\n", source.c_str() + sourceIndex); } result = new Float(val); // now we must skip the constant // fortunately, a float can't sensibly be followed by . or e or a digit while (isdigit(source[sourceIndex]) || source[sourceIndex] == '.' || source[sourceIndex] == 'e') { sourceIndex++; } } //printf("done parsing term\n"); return result; }
void UnwrappedLineParser::parseStatement() { parseComments(); switch (FormatTok.Tok.getKind()) { case tok::kw_namespace: parseNamespace(); return; 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; default: break; } int TokenNumber = 0; do { ++TokenNumber; switch (FormatTok.Tok.getKind()) { case tok::kw_enum: parseEnum(); return; case tok::semi: nextToken(); addUnwrappedLine(); return; case tok::l_paren: parseParens(); break; case tok::l_brace: parseBlock(); addUnwrappedLine(); return; case tok::identifier: nextToken(); if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) { parseLabel(); return; } break; case tok::equal: nextToken(); // Skip initializers as they will be formatted by a later step. if (FormatTok.Tok.is(tok::l_brace)) nextToken(); break; default: nextToken(); break; } } while (!eof()); }