ReaderChar Reader::eatWhitespace() { ReaderChar ret; uint32_t val = 0; do { val = getChar().chr; } while (!atEnd() && (tokenType(val) == TOKEN_WHITESPACE || tokenType(val) == TOKEN_NEWLINE)); return ReaderChar(val,line,column); }
Symbol tokenType(token tk) { if (!tk) return invalid; Symbol ret = type(*tk); switch(ret) { case text: if(isFunction(tk)) ret = function; else ret = identifier; break; case addop: if(*tk == '-' && strlen(tk) > 1) ret = tokenType(tk+1); break; case decimal: case digit: ret = value; break; default: break; } return ret; }
enum tokenType LL1Parsing::GetNewToken() { string buffer; char* str = new char[1024](); size_t i; if (!ifs.eof()){ getline(ifs, buffer); for (i = 0; i < buffer.size(); ++i){ if (buffer[i] == ' '){ break; } else{ str[i] = buffer[i]; } } str[i] = '\0'; } else{ delete str; return EMPTY; } char* str1 = new char[i + 1](); strcpy(str1, str); enum tokenType ret = enum tokenType(atoi(str1)); delete str, str1; return ret; }
void TSReader::handleError() { if (isComment()) return; if (hasError() && error() == CustomError) // raised by readContents return; const QString loc = QString::fromLatin1("at %3:%1:%2") .arg(lineNumber()).arg(columnNumber()).arg(m_cd.m_sourceFileName); switch (tokenType()) { case NoToken: // Cannot happen default: // likewise case Invalid: raiseError(QString::fromLatin1("Parse error %1: %2").arg(loc, errorString())); break; case StartElement: raiseError(QString::fromLatin1("Unexpected tag <%1> %2").arg(name().toString(), loc)); break; case Characters: { QString tok = text().toString(); if (tok.length() > 30) tok = tok.left(30) + QLatin1String("[...]"); raiseError(QString::fromLatin1("Unexpected characters '%1' %2").arg(tok, loc)); } break; case EntityReference: raiseError(QString::fromLatin1("Unexpected entity '&%1;' %2").arg(name().toString(), loc)); break; case ProcessingInstruction: raiseError(QString::fromLatin1("Unexpected processing instruction %1").arg(loc)); break; } }
Fraction XmlReader::readFraction() { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); int z = attribute("z", "0").toInt(); int n = attribute("n", "0").toInt(); skipCurrentElement(); return Fraction(z, n); }
QSizeF XmlReader::readSize() { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); QSizeF p; p.setWidth(doubleAttribute("w", 0.0)); p.setHeight(doubleAttribute("h", 0.0)); skipCurrentElement(); return p; }
Token Tokenizer::flush() { string text = string(mBuffer.begin(), mBuffer.end()); TokenType type = tokenType(text); mState = BufferState::EmptyState; mReady = false; return Token(type, text); }
QString MaintainingReader<TokenLookupClass, LookupKey>::readAttribute(const QString &localName, const QString &namespaceURI) const { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); Q_ASSERT_X(m_currentAttributes.hasAttribute(namespaceURI, localName), Q_FUNC_INFO, "Validation must be done before this function is called."); return m_currentAttributes.value(namespaceURI, localName).toString(); }
QColor XmlReader::readColor() { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); QColor c; c.setRed(intAttribute("r")); c.setGreen(intAttribute("g")); c.setBlue(intAttribute("b")); c.setAlpha(intAttribute("a", 255)); skipCurrentElement(); return c; }
QRectF XmlReader::readRect() { Q_ASSERT(tokenType() == XmlStreamReader::StartElement); QRectF p; p.setX(doubleAttribute("x", 0.0)); p.setY(doubleAttribute("y", 0.0)); p.setWidth(doubleAttribute("w", 0.0)); p.setHeight(doubleAttribute("h", 0.0)); skipCurrentElement(); return p; }
void evalStackPush(Stack *s, token val) { if(prefs.display.postfix) printf("\t%s\n", val); switch(tokenType(val)) { case function: { //token res; //operand = (token)stackPop(s); if (doFunc(s, val) < 0) return; //stackPush(s, res); } break; case expop: case multop: case addop: { if(stackSize(s) >= 2) { // Pop two operands // Evaluate if (doOp(s, val) < 0) return; // Push result //stackPush(s, res); } else { stackPush(s, val); } } break; case value: { stackPush(s, val); } break; default: break; } }
Fraction XmlReader::readFraction() { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); int z = attribute("z", "0").toInt(); int n = attribute("n", "1").toInt(); const QString& s(readElementText()); if (!s.isEmpty()) { int i = s.indexOf('/'); if (i == -1) qFatal("illegal fraction <%s>", qPrintable(s)); else { z = s.left(i).toInt(); n = s.mid(i+1).toInt(); } } return Fraction(z, n); }
bool leftAssoc(token op) { bool ret = false; switch(tokenType(op)) { case addop: case multop: ret = true; break; case function: case expop: ret = false; break; default: break; } return ret; }
Token Tokenizer::dispense() { ASSERT(ready()); char ch = mBuffer.at(mBuffer.size() - 1); mBuffer.pop_back(); string text = string(mBuffer.begin(), mBuffer.end()); TokenType type = tokenType(text); mState = bufferType(ch); mBuffer.clear(); mBuffer.push_back(ch); mReady = false; return Token(type, text); }
QPointF XmlReader::readPoint() { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); #ifndef NDEBUG if (!attributes().hasAttribute("x")) { QXmlStreamAttributes map = attributes(); qDebug("XmlReader::readPoint: x attribute missing: %s (%d)", name().toUtf8().data(), map.size()); for (int i = 0; i < map.size(); ++i) { const QXmlStreamAttribute& a = map.at(i); qDebug(" attr <%s> <%s>", a.name().toUtf8().data(), a.value().toUtf8().data()); } unknown(); } if (!attributes().hasAttribute("y")) { qDebug("XmlReader::readPoint: y attribute missing: %s", name().toUtf8().data()); unknown(); } #endif qreal x = doubleAttribute("x", 0.0); qreal y = doubleAttribute("y", 0.0); readNext(); return QPointF(x, y); }
bool postfix(token *tokens, int numTokens, Stack *output) { Stack operators, intermediate; int i; bool err = false; stackInit(&operators, numTokens); stackInit(&intermediate, numTokens); for(i = 0; i < numTokens; i++) { // From Wikipedia/Shunting-yard_algorithm: switch(tokenType(tokens[i])) { case value: { // If the token is a number, then add it to the output queue. //printf("Adding number %s to output stack\n", tokens[i]); evalStackPush(output, tokens[i]); } break; case function: { while(stackSize(&operators) > 0 && (tokenType(tokens[i]) != lparen) && ((precedence(tokens[i], (char*)stackTop(&operators)) <= 0))) { //printf("Moving operator %s from operator stack to output stack\n", (char*)stackTop(&operators)); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } // If the token is a function token, then push it onto the stack. //printf("Adding operator %s to operator stack\n", tokens[i]); stackPush(&operators, tokens[i]); } break; case argsep: { /* * If the token is a function argument separator (e.g., a comma): * Until the token at the top of the stack is a left * paren, pop operators off the stack onto the output * queue. If no left paren encountered, either separator * was misplaced or parens mismatched. */ while(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen && stackSize(&operators) > 1) { //printf("Moving operator from operator stack to output stack\n"); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } /*if(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen) { err = true; raise(parenMismatch); } printf("Removing left paren from operator stack\n"); stackPop(&operators); // Discard lparen*/ } break; case addop: case multop: case expop: { /* * If the token is an operator, op1, then: * while there is an operator token, op2, at the top of the stack, and * either op1 is left-associative and its precedence is less than or equal to that of op2, * or op1 is right-associative and its precedence is less than that of op2, * pop op2 off the stack, onto the output queue * push op1 onto the stack */ while(stackSize(&operators) > 0 && (tokenType((char*)stackTop(&operators)) == addop || tokenType((char*)stackTop(&operators)) == multop || tokenType((char*)stackTop(&operators)) == expop) && ((leftAssoc(tokens[i]) && precedence(tokens[i], (char*)stackTop(&operators)) <= 0) || (!leftAssoc(tokens[i]) && precedence(tokens[i], (char*)stackTop(&operators)) < 0))) { //printf("Moving operator %s from operator stack to output stack\n", (char*)stackTop(&operators)); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } //printf("Adding operator %s to operator stack\n", tokens[i]); stackPush(&operators, tokens[i]); } break; case lparen: { // If the token is a left paren, then push it onto the stack //printf("Adding left paren to operator stack\n"); if (tokenType(stackTop(&operators)) == function) stackPush(output, FUNCTIONSEPARATOR); stackPush(&operators, tokens[i]); } break; case rparen: { /* * If the token is a right paren: * Until the token at the top of the stack is a left paren, pop operators off the stack onto the output queue * Pop the left paren from the stack, but not onto the output queue * If the stack runs out without finding a left paren, then there are mismatched parens */ while(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen && stackSize(&operators) > 1) { //printf("Moving operator %s from operator stack to output stack\n", (char*)stackTop(&operators)); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } if(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen) { err = true; raise(parenMismatch); } //printf("Removing left paren from operator stack\n"); stackPop(&operators); // Discard lparen while (stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) == function) { //printf("Removing function from operator stack to output stack\n"); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } } break; default: break; } } /* * When there are no more tokens to read: * While there are still operator tokens on the stack: * If the operator token on the top of the stack is a paren, then there are mismatched parens * Pop the operator onto the output queue */ while(stackSize(&operators) > 0) { if(tokenType((token)stackTop(&operators)) == lparen) { raise(parenMismatch); err = true; } //printf("Moving operator from operator stack to output stack\n"); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } // pop result from intermediate stack stackPop(&intermediate); // free remaining intermediate results while (stackSize(&intermediate) > 0) { stackPop(&intermediate); } if (err == true) { while (stackSize(&operators) > 0) { token s = stackPop(&operators); //printf("Freeing %s from operators stack\n", s); free(s); } } stackFree(&intermediate); stackFree(&operators); return err; }
SExpression * Reader::read() { SExpression * ret = nil_symbol; ReaderChar val = eatWhitespace(); if (atEnd()) { return ret; } if (macroHint(val.chr)) { uint32_t val2 = peek().chr; uint64_t key2 = ((uint64_t)val.chr << 32) | val2; uint64_t key1 = ((uint64_t)val.chr << 32) | INVALID_CHAR; if (macros[key2]) { getChar(false); return macros[key2]->run(new List); } else if (macros[key1]) { return macros[key1]->run(new List); } else { printf("Couldn't find macro for [%c][%c]!\n", val.chr, val2); } } if (tokenType(val.chr) == TOKEN_QUOTE) { String * str = new String; ret = str; ret->begin_line = line; ret->begin_column = column; do { uint32_t val = getChar().chr; if (atEnd()) { printf("Got EOF in middle of string, %d\n", val); } if (tokenType(val) == TOKEN_QUOTE) { break; } str->append(val); } while (!atEnd()); ret->end_line = line; ret->end_column = column; } else if ( (tokenType(val.chr) == TOKEN_NUMERIC) || (tokenType(val.chr) == TOKEN_MINUS && tokenType(peek().chr) == TOKEN_NUMERIC) ) { bool is_minus = false; bool is_hex = false; int save_line = line; int save_column = column; if (tokenType(val.chr) == TOKEN_MINUS) { is_minus = true; val = getChar(); } if (val.chr == '0' && peek().chr == 'x') { is_hex = true; getChar(); } int64_t count_val = val.chr - '0'; do { val = getChar(); if (val.chr < '0' || val.chr > '9') { if (is_hex && (val.chr >= 'a' && val.chr <= 'f')) { } else { ret = new Number(is_minus ? -count_val : count_val); ret->begin_line = save_line; ret->begin_column = save_column; ret->end_line = line; ret->end_column = column; reject(val); break; } } if (is_hex) { if (val.chr >= 'a' && val.chr <= 'f') { val.chr -= ('a' - 10); } else { val.chr -= '0'; } count_val *= 16; count_val += val.chr; } else { val.chr -= '0'; count_val *= 10; count_val += val.chr; } if (atEnd()) { ret = new Number(is_minus ? -count_val : count_val); ret->begin_line = save_line; ret->begin_column = save_column; ret->end_line = line; ret->end_column = column; } } while (!atEnd()); } else if (tokenType(val.chr) == TOKEN_ALPHA) { String * str = new String; str->append(val.chr); Symbol * sym = new Symbol(str); ret = sym; ret->begin_line = line; ret->begin_column = column; do { ReaderChar val = getChar(); if (atEnd() || (tokenType(val.chr) != TOKEN_ALPHA && tokenType(val.chr) != TOKEN_MINUS && tokenType(val.chr) != TOKEN_NUMERIC)) { reject(val); break; } str->append(val.chr); } while (!atEnd()); ret->end_line = line; ret->end_column = column; } else if (tokenType(val.chr) == TOKEN_OPEN_BRACE) { List * list = new List; ret = list; ret->begin_line = line; ret->begin_column = column; do { ReaderChar next = eatWhitespace(); if (atEnd()) { printf("Got EOF in middle of list, %d\n", next.chr); break; } if (tokenType(next.chr) == TOKEN_CLOSE_BRACE) { break; } reject(next); SExpression * sep = read(); list->contents.push_back(sep); } while(!atEnd()); ret->end_line = line; ret->end_column = column; } else if (tokenType(val.chr) == TOKEN_COMMENT) { do { val = getChar(); } while (tokenType(val.chr) != TOKEN_NEWLINE && !atEnd()); } else { printf("Didn't expect %d %d!\n", val.chr, tokenType(val.chr)); } return ret; }
// return next token ExtQualModuleNames::tokenType ExtQualModuleNames::scanner() { currentToken_ = ""; if (atEnd()) { return SCANEOF; } while (!atEnd()) { const char cc = returnAdvanceChar(); if (isspace((unsigned char)cc)) { // For VS2003... continue; // do nothing } else if (isalpha(cc)) { // regular identifier currentToken_ += cc; while (isalnum(currentChar()) || currentChar() == '_') { currentToken_ += currentChar(); advanceChar(); } // convert id to internal format (ie, uppercase it) NAString id(currentToken_.c_str()); if (ToInternalIdentifier(id) != 0) { *mxCUMptr << FAIL << DgSqlCode(-2215) << DgString0(currentToken_.c_str()); } currentToken_ = id.data(); return checkReserved(); } currentToken_ += cc; switch (cc) { case '{' : case '}' : case ',' : case '.' : case '=' : return tokenType(cc); case '"': // "delimited identifier" specified by \"([^\"]|"\"\"")*\" while (!atEnd()) { const char c1 = returnAdvanceChar(); currentToken_ += c1; if (c1 == '"') { if (currentChar() == '"') { currentToken_ += currentChar(); } else { // end of delimited identifier // convert delimited id to internal format NAString id(currentToken_.c_str()); if (ToInternalIdentifier(id, FALSE, TRUE) != 0) { *mxCUMptr << FAIL << DgSqlCode(-2209) << DgString0(currentToken_.c_str()); } currentToken_ = id.data(); return ID; } } } *mxCUMptr << FAIL << DgSqlCode(-2210); // unterminated string return ID; default: advanceChar(); *mxCUMptr << FAIL << DgSqlCode(-2211) << DgString0(currentToken_.c_str()); return SCANERROR; } } return SCANEOF; }
/** This function reads a token, calls tokenType(...) to parse it to an integer, and then acts appropriately, calling the individual class methods to read a certain object. */ void Input::read() { char token[64]; OutputFormat* outList = outListHead; while (input != NULL) { while (!(*input).eof()) { token[0] = '\0'; clearIncludeComment(); *input >> token; if (strlen(token)>0) { debug(1,"Token %s = %d",token,tokenType(token)); switch (tokenType(token)) { case INTOK_GEOM: *input >> token; debug(1,"Creating new geometry object: %s.", token); inGeom = new Geometry(token); memCheck(inGeom,"Input::Input() constructor: inGeom"); break; case INTOK_MIX: debug(1,"Creating new Mixture object."); mixList = mixList->getMixture(*input); break; case INTOK_FLUX: debug(1,"Creating new Flux object."); fluxList = fluxList->getFlux(*input); break; case INTOK_PULSE: debug(1,"Creating new History object."); historyList = historyList->getHistory(*input); break; case INTOK_SCHED: debug(1,"Creating new Schedule object."); schedList = schedList->getSchedule(*input); break; case INTOK_DIM: debug(1,"Creating new Dimension object."); dimList = dimList->getDimension(*input); break; case INTOK_MINR: debug(1,"Reading Minor Radius."); *input >> token; inGeom->setMinorR(atof(token)); verbose(2,"Set torus minor radius = %g",atof(token)); break; case INTOK_MAJR: debug(1,"Reading Major Radius."); *input >> token; inGeom->setMajorR(atof(token)); verbose(2,"Set torus major radius = %g",atof(token)); break; case INTOK_COOL: debug(1,"Creating new CoolingTime object."); coolList->getCoolingTimes(*input); break; case INTOK_MAT: debug(1,"Creating new Loading object."); loadList->getMatLoading(*input); break; case INTOK_VOL: debug(1,"Reading Volume List."); volList->getVolumes(*input); break; case INTOK_MATLIB: debug(1,"Opening material library"); Component::getMatLib(*input); break; case INTOK_ELELIB: debug(1,"Opening element library"); Component::getEleLib(*input); break; case INTOK_DATALIB: debug(1,"Opening data library"); NuclearData::getDataLib(*input); break; case INTOK_LIBCONV: debug(1,"Converting data library"); DataLib::convertLib(*input); verbose(1,"Exiting after library conversion."); exit(0); case INTOK_TRUNC: debug(1,"Reading Truncation criteria."); Chain::getTruncInfo(*input); break; case INTOK_IGNORE: debug(1,"Reading relative ignore criteria."); Chain::getIgnoreInfo(*input); break; case INTOK_IMPURITY: debug(1,"Reading Impurity definition and truncation criteria."); Chain::getImpTruncInfo(*input); break; case INTOK_NORM: debug(1,"Reading interval normalizations."); normList->getNorms(*input); break; case INTOK_OUTPUT: debug(1,"Reading output formatting."); outList = outList->getOutFmts(*input); break; case INTOK_DUMPFILE: debug(1,"Openning dump filename."); *input >> token; Result::initBinDump(token); break; case INTOK_SOLVELIST: solveList->getSolveList(*input); break; case INTOK_SKIPLIST: skipList->getSolveList(*input); break; case INTOK_REFFLUX: *input >> token; VolFlux::setRefFluxType(tolower(token[0])); break; // case INTOK_CPLIBS: // int num; // *input >> num; // VolFlux::setNumCP(num); // *input >> num; // VolFlux::setNumCPEG(num); // Volume::loadRangeLib(input); // Volume::loadSpecLib(input); // break; default: error(100,"Invalid token in input file: %s",token); } } } /* delete current stream */ if (input != &cin) { debug(1,"Deleting current stream."); delete input; } debug(1,"Popping next stream."); /* end of this input stream */ streamStack >> input; }
int main(int argc, char *argv[]) { char* str = NULL; token* tokens = NULL; int numTokens = 0; Stack expr; int i; int ch, rflag = 0; prefs.precision = DEFAULTPRECISION; prefs.maxtokenlength = MAXTOKENLENGTH; while ((ch = getopt(argc, argv, "rm:")) != -1) { switch (ch) { case 'r': rflag = 1; break; case 'm': prefs.maxtokenlength = atoi(optarg); } } str = ufgets(stdin); while(str != NULL && strcmp(str, "quit") != 0) { if (strlen(str) == 0) { free(str); goto get_new_string; } if(type(*str) == text) { // Do something with command if (!execCommand(str)) goto no_command; free(str); str = NULL; } else { no_command: numTokens = tokenize(str, &tokens); free(str); str = NULL; if(prefs.display.tokens) { printf("\t%d tokens:\n", numTokens); for(i = 0; i < numTokens; i++) { printf("\t\"%s\"", tokens[i]); if(tokenType(tokens[i]) == value) printf(" = %f", buildNumber(tokens[i])); printf("\n"); } } // Convert to postfix stackInit(&expr, numTokens); if(prefs.display.postfix) printf("\tPostfix stack:\n"); postfix(tokens, numTokens, &expr); //stackReverse(&expr); /*printf("\tReversed postfix stack:\n\t"); for(i = 0; i < stackSize(&expr); i++) { printf("%s ", (token)(expr.content[i])); } printf("\n");*/ if(stackSize(&expr) != 1) { printf("\tError evaluating expression\n"); } else { if (!rflag) printf("\t= "); printf("%s\n", (char*)stackTop(&expr)); for (i=0; i< numTokens; i++) { if (tokens[i] == stackTop(&expr)) tokens[i] = NULL; } free(stackPop(&expr)); } for(i = 0; i < numTokens; i++) { if (tokens[i] != NULL) free(tokens[i]); } free(tokens); tokens = NULL; numTokens = 0; stackFree(&expr); } get_new_string: str = ufgets(stdin); } free(str); str = NULL; return EXIT_SUCCESS; }
int tokenize(char *str, char *(**tokensRef)) { int i = 0; char** tokens = NULL; char** tmp = NULL; char* ptr = str; char ch = '\0'; int numTokens = 0; char* tmpToken = malloc((prefs.maxtokenlength+1) * sizeof(char)); if (!tmpToken) { fprintf(stderr, "Malloc of temporary buffer failed\n"); return 0; } while((ch = *ptr++)) { if(type(ch) == invalid) // Stop tokenizing when we encounter an invalid character break; token newToken = NULL; tmpToken[0] = '\0'; switch(type(ch)) { case addop: { // Check if this is a negative if(ch == '-' && (numTokens == 0 || (tokenType(tokens[numTokens-1]) == addop || tokenType(tokens[numTokens-1]) == multop || tokenType(tokens[numTokens-1]) == expop || tokenType(tokens[numTokens-1]) == lparen || tokenType(tokens[numTokens-1]) == argsep))) { // Assemble an n-character (plus null-terminator) number token { int len = 1; bool hasDecimal = false; bool hasExponent = false; if(type(ch) == decimal) // Allow numbers to start with decimal { //printf("Decimal\n"); hasDecimal = true; len++; tmpToken[0] = '0'; tmpToken[1] = '.'; } else // Numbers that do not start with decimal { tmpToken[len-1] = ch; } // Assemble rest of number for(; // Don't change len *ptr // There is a next character and it is not null && len <= prefs.maxtokenlength && (type(*ptr) == digit // The next character is a digit || ((type(*ptr) == decimal // Or the next character is a decimal && hasDecimal == 0)) // But we have not added a decimal || ((*ptr == 'E' || *ptr == 'e') // Or the next character is an exponent && hasExponent == false) // But we have not added an exponent yet || ((*ptr == '+' || *ptr == '-') && hasExponent == true)); // Exponent with sign ++len) { if(type(*ptr) == decimal) hasDecimal = true; else if(*ptr == 'E' || *ptr == 'e') hasExponent = true; tmpToken[len] = *ptr++; } // Append null-terminator tmpToken[len] = '\0'; } break; } // If it's not part of a number, it's an op - fall through } case multop: case expop: case lparen: case rparen: case argsep: // Assemble a single-character (plus null-terminator) operation token { tmpToken[0] = ch; tmpToken[1] = '\0'; } break; case digit: case decimal: // Assemble an n-character (plus null-terminator) number token { int len = 1; bool hasDecimal = false; bool hasExponent = false; if(type(ch) == decimal) // Allow numbers to start with decimal { //printf("Decimal\n"); hasDecimal = true; len++; tmpToken[0] = '0'; tmpToken[1] = '.'; } else // Numbers that do not start with decimal { tmpToken[len-1] = ch; } // Assemble rest of number for(; // Don't change len *ptr // There is a next character and it is not null && len <= prefs.maxtokenlength && (type(*ptr) == digit // The next character is a digit || ((type(*ptr) == decimal // Or the next character is a decimal && hasDecimal == 0)) // But we have not added a decimal || ((*ptr == 'E' || *ptr == 'e') // Or the next character is an exponent && hasExponent == false) // But we have not added an exponent yet || ((*ptr == '+' || *ptr == '-') && hasExponent == true)); // Exponent with sign ++len) { if(type(*ptr) == decimal) hasDecimal = true; else if(*ptr == 'E' || *ptr == 'e') hasExponent = true; tmpToken[len] = *ptr++; } // Append null-terminator tmpToken[len] = '\0'; } break; case text: // Assemble an n-character (plus null-terminator) text token { int len = 1; tmpToken[0] = ch; for(len = 1; *ptr && type(*ptr) == text && len <= prefs.maxtokenlength; ++len) { tmpToken[len] = *ptr++; } tmpToken[len] = '\0'; } break; default: break; } // Add to list of tokens if(tmpToken[0] != '\0' && strlen(tmpToken) > 0) { numTokens++; /*if(tokens == NULL) // First allocation tokens = (char**)malloc(numTokens * sizeof(char*)); else*/ newToken = malloc((strlen(tmpToken)+1) * sizeof(char)); if (!newToken) { numTokens--; break; } strcpy(newToken, tmpToken); newToken[strlen(tmpToken)] = '\0'; tmp = (char**)realloc(tokens, numTokens * sizeof(char*)); if (tmp == NULL) { free(newToken); if (tokens != NULL) { for(i=0;i<numTokens-1;i++) { if (tokens[i] != NULL) free(tokens[i]); } free(tokens); } *tokensRef = NULL; free(newToken); free(tmpToken); return 0; } tokens = tmp; tmp = NULL; tokens[numTokens - 1] = newToken; } } *tokensRef = tokens; // Send back out free(tmpToken); tmpToken = NULL; return numTokens; }
int precedence(token op1, token op2) { int ret = 0; if (op2 == NULL) ret = 1; else if(tokenType(op1) == tokenType(op2)) // Equal precedence ret = 0; else if(tokenType(op1) == addop && (tokenType(op2) == multop || tokenType(op2) == expop)) // op1 has lower precedence ret = -1; else if(tokenType(op2) == addop && (tokenType(op1) == multop || tokenType(op1) == expop)) // op1 has higher precedence ret = 1; else if(tokenType(op1) == multop && tokenType(op2) == expop) // op1 has lower precedence ret = -1; else if(tokenType(op1) == expop && tokenType(op2) == multop) // op1 has higher precedence ret = 1; else if (tokenType(op1) == function && (tokenType(op2) == addop || tokenType(op2) == multop || tokenType(op2) == expop || tokenType(op2) == lparen)) ret = 1; else if ((tokenType(op1) == addop || tokenType(op1) == multop || tokenType(op1) == expop) && tokenType(op2) == function) ret = -1; return ret; }
bool MaintainingReader<TokenLookupClass, LookupKey>::hasAttribute(const QString &namespaceURI, const QString &localName) const { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); return m_currentAttributes.hasAttribute(namespaceURI, localName); }
void MaintainingReader<TokenLookupClass, LookupKey>::validateElement(const LookupKey elementName) const { Q_ASSERT(tokenType() == QXmlStreamReader::StartElement); if(m_elementDescriptions.contains(elementName)) { const ElementDescription<TokenLookupClass, LookupKey> &desc = m_elementDescriptions.value(elementName); const int attCount = m_currentAttributes.count(); QSet<typename TokenLookupClass::NodeName> encounteredXSLTAtts; for(int i = 0; i < attCount; ++i) { const QXmlStreamAttribute &attr = m_currentAttributes.at(i); if(attr.namespaceUri().isEmpty()) { const typename TokenLookupClass::NodeName attrName(TokenLookupClass::toToken(attr.name())); encounteredXSLTAtts.insert(attrName); if(!desc.requiredAttributes.contains(attrName) && !desc.optionalAttributes.contains(attrName) && !m_standardAttributes.contains(attrName) && !isAnyAttributeAllowed()) { QString translationString; QList<typename TokenLookupClass::NodeName> all(desc.requiredAttributes.toList() + desc.optionalAttributes.toList()); const int totalCount = all.count(); QStringList allowed; for(int i = 0; i < totalCount; ++i) allowed.append(formatKeyword(toString(all.at(i)))); /* Note, we can't run toString() on attrName, because we're in this branch, * the token lookup doesn't have the string(!).*/ const QString stringedName(attr.name().toString()); if(totalCount == 0) { translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only the standard attributes can appear.") .arg(formatKeyword(stringedName), formatKeyword(name())); } else if(totalCount == 1) { translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes.") .arg(formatKeyword(stringedName), formatKeyword(name()), allowed.first()); } else if(totalCount == 1) { /* Note, allowed has already had formatKeyword() applied. */ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes.") .arg(formatKeyword(stringedName), formatKeyword(name()), allowed.first(), allowed.last()); } else { /* Note, allowed has already had formatKeyword() applied. */ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes.") .arg(formatKeyword(stringedName), formatKeyword(name()), allowed.join(QLatin1String(", "))); } m_context->error(translationString, ReportContext::XTSE0090, currentLocation()); } } else if(attr.namespaceUri() == namespaceUri()) { m_context->error(QtXmlPatterns::tr("XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is.") .arg(formatKeyword(attr.name())), ReportContext::XTSE0090, currentLocation()); } /* Else, attributes in other namespaces are allowed, continue. */ } const QSet<typename TokenLookupClass::NodeName> requiredButMissing(QSet<typename TokenLookupClass::NodeName>(desc.requiredAttributes).subtract(encounteredXSLTAtts)); if(!requiredButMissing.isEmpty()) { error(QtXmlPatterns::tr("The attribute %1 must appear on element %2.") .arg(formatKeyword(toString(*requiredButMissing.constBegin())), formatKeyword(name())), ReportContext::XTSE0010); } } else { error(QtXmlPatterns::tr("The element with local name %1 does not exist in XSL-T.").arg(formatKeyword(name())), ReportContext::XTSE0010); } }