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);
}
Ejemplo n.º 3
0
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);
}