XmlReader::attribElems XmlReader::attributes() { _attributes.clear(); if(_tag.compare("?xml")==0 || _tag.compare("!--")==0) return _attributes; localposition = _position; // move past tag extractIdentifier(localposition); // find attributes size_t locpos = _xml.find('>',localposition); while(true) { std::string name = extractIdentifier(localposition); if(locpos < localposition) return _attributes; std::string value = extractIdentifier(localposition); if(locpos < localposition) throw std::exception("malformed XML"); std::pair<std::string,std::string> elem; elem.first = name; elem.second = value; _attributes.push_back(elem); } return _attributes; }
std::string XmlReader::element() { // find tag - assumes _position points to character after // opening "<" on entry localposition = _position; _tag = extractIdentifier(localposition); // is declaration? std::string decTag = "?xml"; if(_tag.compare("?xml") == 0) { size_t locpos = _xml.find("?>"); return _xml.substr(_position-1,locpos-_position+3); } // is comment? if(_tag.compare("!--") == 0) { size_t locpos = _xml.find("-->"); return _xml.substr(_position-1,locpos-_position+4); } // find end of element </tag> size_t locpos1 = localposition; // note: tracks element scope with tagStack, so will correctly // return nested elements with the same tag name std::stack<std::string> tagStack; tagStack.push(_tag); while(true) { locpos1 = _xml.find(_tag,locpos1); if(locpos1 >= _xml.size()) break; if(_xml[locpos1-1]=='/' && _xml[locpos1 + _tag.size()] == '>') // modified 2/15/2012 tagStack.pop(); else if(_xml[locpos1-1]=='<') tagStack.push(_tag); if(tagStack.size() == 0) break; ++locpos1; } // find end element of self-closing tag, e.g., <tag /> size_t locpos2 = _xml.find(">",localposition); if(_xml[locpos2-1] != '/') locpos2 = _xml.size(); // find end element </tag> localposition = std::min(locpos1,locpos2); if(localposition >= _xml.size()) throw std::exception("malformed XML"); if(localposition == locpos1) { localposition = _xml.find('>',localposition); return _xml.substr(_position-1, localposition - _position +2); } return _xml.substr(_position-1, localposition - _position + 2); }
TObject* Scanner::get(){ //first extract the first character from the sourcereader char c = getChar(); if(c==END_OF_BUFFER) { //FIXME please update this, better handling return new TObject(new string(1, char(0)), NULL_TOKEN, line, char_line); } //next determine the type switch(TOKEN_TYPE type = token_type(c)){ case WHITESPACE: { //skip the whitespace and return something skipWS(c); //return the next token return get(); } case COMMENT: { skipCMT(c); return get(); } case NUMERIC: case DOT: { //extracts all the numbers return extractNumber(c); } case UNDERSCORE: case IDENTIFIER: { TObject* tok = extractIdentifier(c); TOKEN_TYPE key = is_keyword(*tok->str); //then check if that is a keyword if(key!=UNKNOWN){ //then change the format tok->type = key; tok->special = true; } return tok; } case GREATER_THAN: case LESS_THAN: case EQUAL_SIGN: { //check if we have an = comming return extractComparator(c); } case OPERATOR: { //get the next char ch = getChar(); if(ch=='='){ switch(c){ case '-': return new TObject(0, MINUS_EQUALS, line, char_line); case '+': return new TObject(0, PLUS_EQUALS, line, char_line); case '*': return new TObject(0, TIMES_EQUALS, line, char_line); case '/': return new TObject(0, DIVIDE_EQUALS, line, char_line); case '%': return new TObject(0, MODULO_EQUALS, line, char_line); case '^': return new TObject(0, EXPO_EQUALS, line, char_line); default: break; } }else{ putback(); } return new TObject(new string(1, c), type, line, char_line); } case UNKNOWN: { string error= ERROR_MSG[6]+"\""; error.append(getLine().append("\"")); throw new YottaError(SYNTAX_ERROR, error, line, char_line); } default: { return new TObject(new string(1, c), type, line, char_line); } } }
std::string XmlReader::tag() { localposition = _position; return extractIdentifier(localposition); }