ExprAST *Parser::parsePrimary () { // At the top level, we have to have either an identifier of some kind, // a number, or an open paren. We might also have a unary minus sign, handle // that specially right here. switch (currentToken) { case TOKEN_IDENTIFIER_FUNCTION: return parseFunctionIdentifierExpr (); case TOKEN_IDENTIFIER_CONSTANT: return parseConstantIdentifierExpr (); case TOKEN_IDENTIFIER_VARIABLE: return parseVariableIdentifierExpr (); case TOKEN_NUMBER: return parseNumberExpr (); case TOKEN_PAREN_OPEN: return parseOpenParenExpr (); case TOKEN_OPERATOR: if (strToken == "-") return parseUnaryMinusExpr (); // Fall through for any other operator default: error (boost::format ("Expecting an expression, got %1% instead!") % formatToken ()); return NULL; } }
int main(int argc, char * argv[]) { TokenType ttype; source = stdin; listing = stdout; struct stack_t *scannerStack = newStack(); //track tags int relevant = 0; //track if current tag section is relevant to print -- 0 is relevant, > 0 is irrelevant, < 0 is no tags while((ttype=getToken()) != ENDFILE) { /* if open tag, push onto stack */ if(ttype == 1) { push(scannerStack, formatToken(ttype, tokenString)); if(relevant > 0) relevant++; //increment relevant flag for any tag inside irrelevant tag else if(!compareToken(top(scannerStack))) relevant++; //increment relevant flag on irrelevant tag } /* if close tag, check top of stack for matching open tag */ if(ttype == 2) { /* if close tag does not match top of stack, report error */ if(top(scannerStack) == NULL || strcmp(top(scannerStack), formatToken(ttype, tokenString))) { if(relevant == 0) printf("-- Error: CLOSE-TAG </%s> with no matching open tag at top of stack at line %d\n", formatToken(ttype, tokenString), lineno); continue; } /* if close tag matches top of stack, pop */ else { pop(scannerStack); /* decrement relevant tag on pop if greater than 0 */ if(relevant > 0) { relevant--; continue; } } } /* print tokens if relevant and tag is on stack */ if(relevant == 0 && top(scannerStack) != NULL) printToken(ttype, tokenString); } /* print off remaining tags in stack as errors */ while(top(scannerStack)) { printf("-- Error: OPEN-TAG <%s> with no closing tag left over in stack\n", top(scannerStack)); pop(scannerStack); } destroyStack(&scannerStack); return 0; }
ExprAST *Parser::parseBinOpRHS (int exprPrecedence, ExprAST *LHS) { while (1) { // This should be either an operator, a close-paren, comma, // or the end of the formula. if (currentToken != TOKEN_OPERATOR && currentToken != TOKEN_PAREN_CLOSE && currentToken != TOKEN_COMMA && currentToken != TOKEN_END) { error (boost::format ("Attempting to parse the RHS of a binary operator, " "and got %1%!") % formatToken ()); return NULL; } // Get the precedence int tokenPrecedence = -1; for (int i = 0 ; i < NUM_OPERATORS ; i++) { if (strToken == operators[i].name) { tokenPrecedence = operators[i].precedence; break; } } // We're done if we run into an equivalent or lower-precedence binary // operator (or, notably, something that's not an operator at all, like // the end of the formula) if (tokenPrecedence < exprPrecedence) return LHS; // Pull off the operator std::string binOp = strToken; getNextToken (); // Parse the primary after the operator ExprAST *RHS = parsePrimary (); if (!RHS) return NULL; // We've now parsed a full binary operator pair, "A op B". If the next // thing is a binary operator (which it should be, or it should be // nothing at all), we need to see whether we want "(A op B) op2 ..." or // "A op (B op2 ...)" by precedence rules. Look ahead: int nextPrecedence = -1; for (int i = 0 ; i < NUM_OPERATORS ; i++) { if (strToken == operators[i].name) { nextPrecedence = operators[i].precedence; break; } } if (tokenPrecedence < nextPrecedence) { // Next precedence is greater, we want "A op (B op2 ...)". Do that by // parsing B op2 ... into a new RHS. RHS = parseBinOpRHS (tokenPrecedence + 1, RHS); if (RHS == NULL) return NULL; } // Next precedence is lower, we want "(A op B) op2 ...", so make a new LHS LHS = new BinaryExprAST (binOp, LHS, RHS); // And loop back to the beginning } }
QString DateTime::formatDateTime(const QString &rFormat) const { if (rFormat.isEmpty()) return QString(); if (!isValid()) return QString(); const QLatin1Char null('0'); const QLatin1Char quote('\''); const QString tokens = QLatin1String("\'dMyhHmszAPapw"); const bool am_pm = hasAMPM(rFormat); QString result; QString token; QChar expected = null; QChar c; int i; for (i = 0; i < rFormat.length(); i++) { c = rFormat.at(i); // Handle literal text if (expected == quote) { if (c == quote) { Q_ASSERT_X(i > 0, "DateTime::toString()", "Found quote with status quote at i = 0"); if (i > 0 && rFormat.at(i - 1) == quote) // Second of two quotes result += quote; expected = null; } else // Next literal character result += c; } else if (c == expected) { // Extend token token += c; } else { // Close last token result += formatToken(token, am_pm); token.clear(); expected = null; // Test for valid character if (tokens.indexOf(c) >= 0) { if (c == QLatin1Char('a')) expected = QLatin1Char('p'); else if (c == QLatin1Char('A')) expected = QLatin1Char('P'); else if (c.toLower() == QLatin1Char('p')) expected = null; else expected = c; if (c != quote) token += c; } else result += c; } } result += formatToken(token, am_pm); return result; }
QString DateTime::formatToken(const QString &rToken, bool am_pm) const { if (rToken.isEmpty()) return QString(); const QChar c = rToken.at(0); QString result; int used = 0; // Qt data format strings if (rToken.startsWith(QLatin1String("dddd"))) { result = QDate::longDayName(date().dayOfWeek()); used = 4; } else if (rToken.startsWith(QLatin1String("ddd"))) { result = QDate::shortDayName(date().dayOfWeek()); used = 3; } else if (rToken.startsWith(QLatin1String("dd"))) { result = QString::number(date().day()).rightJustified(2, QLatin1Char('0'), true); used = 2; } else if (c == QLatin1Char('d')) { result = QString::number(date().day()); used = 1; } else if (rToken.startsWith(QLatin1String("MMMM"))) { result = QDate::longMonthName(date().month()); used = 4; } else if (rToken.startsWith(QLatin1String("MMM"))) { result = QDate::shortMonthName(date().month()); used = 3; } else if (rToken.startsWith(QLatin1String("MM"))) { result = QString::number(date().month()).rightJustified(2, QLatin1Char('0'), true); used = 2; } else if (c == QLatin1Char('M')) { result = QString::number(date().month()); used = 1; } else if (rToken.startsWith(QLatin1String("yyyy"))) { result = QString::number(date().year()); used = 4; } else if (rToken.startsWith(QLatin1String("yy"))) { result = QString::number(date().year() % 100).rightJustified(2, QLatin1Char('0'), true); used = 2; } // Qt time format strings else if (rToken.startsWith(QLatin1String("hh")) || rToken.startsWith(QLatin1String("HH"))) { int hour = time().hour(); if (am_pm && c == QLatin1Char('h') && hour > 12) hour -= 12; result = QString::number(hour).rightJustified(2, QLatin1Char('0'), true); used = 2; } else if (c == QLatin1Char('h') || c == QLatin1Char('H')) { int hour = time().hour(); if (am_pm && c == QLatin1Char('h') && hour > 12) hour -= 12; result = QString::number(hour); used = 2; } else if (rToken.startsWith(QLatin1String("mm"))) { result = QString::number(time().minute()).rightJustified(2, QLatin1Char('0'), true); used = 2; } else if (c == (QLatin1Char('m'))) { result = QString::number(time().minute()); used = 1; } else if (rToken.startsWith(QLatin1String("ss"))) { result = QString::number(time().second()).rightJustified(2, QLatin1Char('0'), true); used = 2; } else if (c == QLatin1Char('s')) { result = QString::number(time().second()); used = 1; } else if (rToken.startsWith(QLatin1String("zzz"))) { result = QString::number(time().msec()).rightJustified(3, QLatin1Char('0'), true); used = 3; } else if (c == QLatin1Char('z')) { result = QString::number(time().msec()); used = 1; } else if (c.toLower() == QLatin1Char('a')) { bool is_lower = c == QLatin1Char('a'); if (time().hour() < 12) result = QLatin1String("AM"); else result = QLatin1String("PM"); if (is_lower) result = result.toLower(); if (rToken.size() > 1 && ((is_lower && rToken.at(1) == QLatin1Char('p')) || (!is_lower && rToken.at(1) == QLatin1Char('P'))) ) used = 2; else used = 1; } // Extension for week number else if (rToken.startsWith(QLatin1String("ww"))) { result = QString::number(date().weekNumber()).rightJustified(2, QLatin1Char('0'), true); used = 2; } else if (c == QLatin1Char('w')) { result = QString::number(date().weekNumber()); used = 1; } if (used) return result + formatToken(rToken.mid(used), am_pm); else return result; }