⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tag.cpp

📁 Jabber code library, developed with c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//             printf( "adding %s to result set\n", name().c_str() );            result.push_back( this );          }        }//         else//           printf( "found %s != %s\n", token->name().c_str(), name().c_str() );        break;      }      case XTDoubleSlash:      {//         printf( "in XTDoubleSlash\n" );        Tag *t = token->clone();//         printf( "original token: %s\ncloned token: %s\n", token->xml().c_str(), n->xml().c_str() );        t->addAttribute( "type", XTElement );        add( result, evaluateTagList( t ) );        const Tag::TagList& res2 = allDescendants();        Tag::TagList::const_iterator it = res2.begin();        for( ; it != res2.end(); ++it )        {          add( result, (*it)->evaluateTagList( t ) );        }        delete t;        break;      }      case XTDot:      {        const Tag::TagList& tokenChildren = token->children();        if( !tokenChildren.empty() )        {          add( result, evaluateTagList( tokenChildren.front() ) );        }        else          result.push_back( this );        break;      }      case XTDoubleDot:      {//         printf( "in XTDoubleDot\n" );        if( m_parent )        {          const Tag::TagList& tokenChildren = token->children();          if( tokenChildren.size() )          {            Tag *testtoken = tokenChildren.front();            if( testtoken->name() == "*" )            {              add( result, m_parent->evaluateTagList( testtoken ) );            }            else            {              Tag *t = token->clone();              t->addAttribute( "type", XTElement );              t->m_name = m_parent->m_name;              add( result, m_parent->evaluateTagList( t ) );              delete t;            }          }          else          {            result.push_back( m_parent );          }        }      }      case XTInteger:      {        const Tag::TagList& l = token->children();        if( !l.size() )          break;        const Tag::TagList& res = evaluateTagList( l.front() );        int pos = atoi( token->name().c_str() );//         printf( "checking index %d\n", pos );        if( pos > 0 && pos <= (int)res.size() )        {          Tag::TagList::const_iterator it = res.begin();          while ( --pos )          {            ++it;          }          result.push_back( *it );        }        break;      }      default:        break;    }    return result;  }  bool Tag::evaluateBoolean( Tag *token )  {    if( !token )      return false;    bool result = false;    TokenType tokenType = (TokenType)atoi( token->findAttribute( "type" ).c_str() );    switch( tokenType )    {      case XTAttribute:        if( token->name() == "*" && m_attribs.size() )          result = true;        else          result = hasAttribute( token->name() );        break;      case XTOperatorEq:        result = evaluateEquals( token );        break;      case XTOperatorLt:        break;      case XTOperatorLtEq:        break;      case XTOperatorGtEq:        break;      case XTOperatorGt:        break;      case XTUnion:      case XTElement:      {        Tag *t = new Tag( "." );        t->addAttribute( "type", XTDot );        t->addChild( token );        result = !evaluateTagList( t ).empty();        t->removeChild( token );        delete t;        break;      }      default:        break;    }    return result;  }  bool Tag::evaluateEquals( Tag *token )  {    if( !token || token->children().size() != 2 )      return false;    bool result = false;    Tag::TagList::const_iterator it = token->children().begin();    Tag *ch1 = (*it);    Tag *ch2 = (*++it);    TokenType tt1 = (TokenType)atoi( ch1->findAttribute( "type" ).c_str() );    TokenType tt2 = (TokenType)atoi( ch2->findAttribute( "type" ).c_str() );    switch( tt1 )    {      case XTAttribute:        switch( tt2 )        {          case XTInteger:          case XTLiteral:            result = ( findAttribute( ch1->name() ) == ch2->name() );            break;          case XTAttribute:            result = ( hasAttribute( ch1->name() ) && hasAttribute( ch2->name() ) &&                      findAttribute( ch1->name() ) == findAttribute( ch2->name() ) );            break;          default:            break;        }        break;      case XTInteger:      case XTLiteral:        switch( tt2 )        {          case XTAttribute:            result = ( ch1->name() == findAttribute( ch2->name() ) );            break;          case XTLiteral:          case XTInteger:            result = ( ch1->name() == ch2->name() );            break;          default:            break;        }        break;      default:        break;    }    return result;  }  Tag::TagList Tag::allDescendants()  {    Tag::TagList result;    Tag::TagList::const_iterator it = m_children.begin();    for( ; it != m_children.end(); ++it )    {      result.push_back( (*it) );      add( result, (*it)->allDescendants() );    }    return result;  }  Tag::TagList Tag::evaluateUnion( Tag *token )  {    Tag::TagList result;    if( !token )      return result;    const Tag::TagList& l = token->children();    Tag::TagList::const_iterator it = l.begin();    for( ; it != l.end(); ++it )    {      add( result, evaluateTagList( (*it) ) );    }    return result;  }  void Tag::closePreviousToken( Tag** root, Tag** current, Tag::TokenType& type, std::string& tok )  {    if( !tok.empty() )    {      addToken( root, current, type, tok );      type = XTElement;      tok = "";    }  }  Tag* Tag::parse( const std::string& expression, unsigned& len, Tag::TokenType border )  {    Tag *root = 0;    Tag *current = root;    std::string token;//     XPathError error = XPNoError;//     XPathState state = Init;//     int expected = 0;//     bool run = true;//     bool ws = false;    Tag::TokenType type  = XTElement;    char c;    for( ; len < expression.length(); ++len )    {      c = expression[len];      if( type == XTLiteralInside && c != '\'' )      {        token += c;        continue;      }      switch( c )      {        case '/':          closePreviousToken( &root, &current, type, token );          if( len < expression.length()-1 && expression[len+1] == '/' )          {//             addToken( &root, &current, XTDoubleSlash, "//" );            type = XTDoubleSlash;            ++len;          }//           else//           {//             if( !current )//             addToken( &root, &current, XTSlash, "/" );//           }          break;        case ']':          closePreviousToken( &root, &current, type, token );          ++len;          return root;        case '[':        {          closePreviousToken( &root, &current, type, token );          Tag *t = parse( expression, ++len, XTRightBracket );          if( !addPredicate( &root, &current, t ) )            delete t;          break;        }        case '(':        {          closePreviousToken( &root, &current, type, token );          Tag *t = parse( expression, ++len, XTRightParenthesis );          if( current )          {//             printf( "added %s to %s\n", t->xml().c_str(), current->xml().c_str() );            t->addAttribute( "argument", "true" );            current->addChild( t );          }          else          {            root = t;//             printf( "made %s new root\n", t->xml().c_str() );          }          break;        }        case ')':          closePreviousToken( &root, &current, type, token );          ++len;          return root;        case '\'':          if( type == XTLiteralInside )            if( expression[len - 2] == '\\' )              token[token.length() - 2] = c;            else              type = XTLiteral;          else            type = XTLiteralInside;          break;        case '@':          type = XTAttribute;          break;        case '.':          token += c;          if( token.size() == 1 )          {            if( len < expression.length()-1 && expression[len+1] == '.' )            {              type = XTDoubleDot;              ++len;              token += c;            }            else            {              type = XTDot;            }          }          break;        case '*'://           if( !root || ( current && ( current->tokenType() == XTSlash//                                       || current->tokenType() == XTDoubleSlash ) ) )//           {//             addToken( &root, &current, type, "*" );//             break;//           }          addToken( &root, &current, type, "*" );          type = XTElement;          break;        case '+':        case '>':        case '<':        case '=':        case '|':        {          closePreviousToken( &root, &current, type, token );          std::string s( 1, c );          Tag::TokenType ttype = getType( s );          if( ttype <= border )            return root;          Tag *t = parse( expression, ++len, ttype );          addOperator( &root, &current, t, ttype, s );          if( border == XTRightBracket )            return root;          break;        }        default:          token += c;      }    }    if( !token.empty() )      addToken( &root, &current, type, token );//     if( error != XPNoError )//       printf( "error: %d\n", error );    return root;  }  void Tag::addToken( Tag **root, Tag **current, Tag::TokenType type,                      const std::string& token )  {    Tag *t = new Tag( token );    if( t->isNumber() && !t->children().size() )      type = XTInteger;    t->addAttribute( "type", type );    if( *root )    {//       printf( "new current %s, type: %d\n", token.c_str(), type );      (*current)->addChild( t );      *current = t;    }    else    {//       printf( "new root %s, type: %d\n", token.c_str(), type );      *current = *root = t;    }  }  void Tag::addOperator( Tag **root, Tag **current, Tag *arg,                           Tag::TokenType type, const std::string& token )  {    Tag *t = new Tag( token );    t->addAttribute( "type", type );//     printf( "new operator: %s (arg1: %s, arg2: %s)\n", t->name().c_str(), (*root)->xml().c_str(),//                                                                           arg->xml().c_str() );    t->addAttribute( "operator", "true" );    t->addChild( *root );    t->addChild( arg );    *current = *root = t;  }  bool Tag::addPredicate( Tag **root, Tag **current, Tag *token )  {    if( !*root || !*current )      return false;    if( ( token->isNumber() && !token->children().size() ) || token->name() == "+" )    {//       printf( "found Index %s, full: %s\n", token->name().c_str(), token->xml().c_str() );      if( !token->hasAttribute( "operator", "true" ) )      {        token->addAttribute( "type", XTInteger );      }      if( *root == *current )      {        *root = token;//         printf( "made Index new root\n" );      }      else      {        (*root)->removeChild( *current );        (*root)->addChild( token );//         printf( "added Index somewhere between root and current\n" );      }      token->addChild( *current );//       printf( "added Index %s, full: %s\n", token->name().c_str(), token->xml().c_str() );    }    else    {      token->addAttribute( "predicate", "true" );      (*current)->addChild( token );    }    return true;  }  Tag::TokenType Tag::getType( const std::string& c )  {    if( c == "|" )      return XTUnion;    if( c == "<" )      return XTOperatorLt;    if( c == ">" )      return XTOperatorGt;    if( c == "*" )      return XTOperatorMul;    if( c == "+" )      return XTOperatorPlus;    if( c == "=" )      return XTOperatorEq;    return XTNone;  }  bool Tag::isWhitespace( const char c )  {    return ( c == 0x09 || c == 0x0a || c == 0x0d || c == 0x20 );  }  bool Tag::isNumber()  {    if( m_name.empty() )      return false;    std::string::size_type l = m_name.length();    std::string::size_type i = 0;    while( i < l && isdigit( m_name[i] ) )      ++i;    return i == l;  }  void Tag::add( Tag::TagList& one, const Tag::TagList& two )  {    Tag::TagList::const_iterator it = two.begin();    for( ; it != two.end(); ++it )      if( std::find( one.begin(), one.end(), (*it) ) == one.end() )        one.push_back( (*it) );  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -