コード例 #1
0
ファイル: json_scanner.cpp プロジェクト: 0vermind/NeoLoader
int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
{
  char ch;
  
  if (!m_io->isOpen()) {
    qCritical() << "JSonScanner::yylex - io device is not open";
    return -1;
  }

  yylloc->step();

  do {
    bool ret;
    if (m_io->atEnd()) {
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::END";
      return yy::json_parser::token::END;
    }
    else
      ret = m_io->getChar(&ch);

    if (!ret) {
      qCritical() << "JSonScanner::yylex - error reading from io device";
      return -1;
    }

    qjsonDebug() << "JSonScanner::yylex - got |" << ch << "|";
    
    yylloc->columns();
    
    if (ch == '\n' || ch == '\r')
      yylloc->lines();
      
  } while (m_quotmarkClosed && (isspace(ch) != 0));

  if (m_quotmarkClosed && ((ch == 't') || (ch == 'T')
      || (ch == 'n') || (ch == 'N'))) {
    // check true & null value
    const QByteArray buf = m_io->peek(3).toLower();

    if (buf.length() == 3) {
      if (buf == "rue") {
        m_io->read (3);
        yylloc->columns(3);
        qjsonDebug() << "JSonScanner::yylex - TRUE_VAL";
        return yy::json_parser::token::TRUE_VAL;
      }
      else if (buf == "ull") {
        m_io->read (3);
        yylloc->columns(3);
        qjsonDebug() << "JSonScanner::yylex - NULL_VAL";
        return yy::json_parser::token::NULL_VAL;
      }
    }
  }
  else if (m_quotmarkClosed && ((ch == 'f') || (ch == 'F'))) {
    // check false value
    const QByteArray buf = m_io->peek(4).toLower();
    if (buf.length() == 4) {
      if (buf == "alse") {
        m_io->read (4);
        yylloc->columns(4);
        qjsonDebug() << "JSonScanner::yylex - FALSE_VAL";
        return yy::json_parser::token::FALSE_VAL;
      }
    }
  }
  else if (m_quotmarkClosed && ((ch == 'e') || (ch == 'E'))) {
    QByteArray ret(1, ch);
    const QByteArray buf = m_io->peek(1);
    if (!buf.isEmpty()) {
      if ((buf[0] == '+' ) || (buf[0] == '-' )) {
        ret += m_io->read (1);  
        yylloc->columns();
      }
    }
    *yylval = QVariant(QString::fromUtf8(ret));
    return yy::json_parser::token::E;
  }
  
  if (ch != '"' && !m_quotmarkClosed) {
    // we're inside a " " block
    QByteArray raw;
    raw += ch;
    char prevCh = ch;
    bool escape_on = (ch == '\\') ? true : false;

    while ( true ) {
      char nextCh;
      qint64 ret = m_io->peek(&nextCh, 1);
      if (ret != 1) {
        if (m_io->atEnd())
          return yy::json_parser::token::END;
        else
          return -1;
      } else if ( !escape_on && nextCh == '\"' ) {
		bool ok;
		if(raw.left(15) == "@base64-b8An45:"){
		  ok = true;
		  *yylval = QByteArray::fromBase64(raw.mid(15));
		} else {
          const QString str = unescape( raw, &ok );
		  *yylval = ok ? str : QString();
		}
        return ok ? yy::json_parser::token::STRING : -1;
      }
#if 0
      if ( prevCh == '\\' && nextCh != '"' && nextCh != '\\' && nextCh != '/' &&
           nextCh != 'b' && nextCh != 'f' && nextCh != 'n' &&
           nextCh != 'r' && nextCh != 't' && nextCh != 'u') {
        qjsonDebug() << "Just read" << nextCh;
        qjsonDebug() << "JSonScanner::yylex - error decoding escaped sequence";
        return -1;
       }
#endif
      m_io->read(1); // consume
      raw += nextCh;
      prevCh = nextCh;
      if (escape_on)
        escape_on = false;
      else
        escape_on = (prevCh == '\\') ? true : false;
#if 0
      if (nextCh == '\\') {
        char buf;
        if (m_io->getChar (&buf)) {
          yylloc->columns();
          if (((buf != '"') && (buf != '\\') && (buf != '/') &&
              (buf != 'b') && (buf != 'f') && (buf != 'n') &&
              (buf != 'r') && (buf != 't') && (buf != 'u'))) {
                qjsonDebug() << "Just read" << buf;
                qjsonDebug() << "JSonScanner::yylex - error decoding escaped sequence";
                return -1;
          }
        } else {
          qCritical() << "JSonScanner::yylex - error decoding escaped sequence : io error";
          return -1;
        }
      }
#endif
    }
  }
  else if (isdigit(ch) != 0 && m_quotmarkClosed) {
    *yylval = QVariant(QString::fromLatin1(QByteArray(&ch,1)));
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DIGIT";
    return yy::json_parser::token::DIGIT;
  }
  else if (isalnum(ch) != 0) {
    *yylval = QVariant(QString(QChar::fromLatin1(ch)));
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::WORD ("
             << ch << ")";
    return yy::json_parser::token::STRING;
  }
  else if (ch == ':') {
    // set yylval
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::COLON";
    return yy::json_parser::token::COLON;
  }
  else if (ch == '"') {
    // yy::json_parser::token::QUOTMARK (")

    // set yylval
    m_quotmarkCount++;
    if (m_quotmarkCount %2 == 0) {
      m_quotmarkClosed = true;
      m_quotmarkCount = 0;
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::QUOTMARKCLOSE";
      return yy::json_parser::token::QUOTMARKCLOSE;
    }
    else {
      m_quotmarkClosed = false;
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::QUOTMARKOPEN";
      return yy::json_parser::token::QUOTMARKOPEN;
    }
  }
  else if (ch == ',') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::COMMA";
    return yy::json_parser::token::COMMA;
  }
  else if (ch == '.') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DOT";
    return yy::json_parser::token::DOT;
  }
  else if (ch == '-') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::MINUS";
    return yy::json_parser::token::MINUS;
  }
  else if (ch == '[') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::SQUARE_BRACKET_OPEN";
    return yy::json_parser::token::SQUARE_BRACKET_OPEN;
  }
  else if (ch == ']') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::SQUARE_BRACKET_CLOSE";
    return yy::json_parser::token::SQUARE_BRACKET_CLOSE;
  }
  else if (ch == '{') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::CURLY_BRACKET_OPEN";
    return yy::json_parser::token::CURLY_BRACKET_OPEN;
  }
  else if (ch == '}') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::CURLY_BRACKET_CLOSE";
    return yy::json_parser::token::CURLY_BRACKET_CLOSE;
  }

  //unknown char!
  //TODO yyerror?
  qCritical() << "JSonScanner::yylex - unknown char, returning -1";
  return -1;
}
コード例 #2
0
ファイル: json_scanner.cpp プロジェクト: LosYear/Ferriage
int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
{
  char ch;

  if (!m_io->isOpen()) {
    qCritical() << "JSonScanner::yylex - io device is not open";
    return -1;
  }

  yylloc->step();

  do {
    bool ret;
    if (m_io->atEnd()) {
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::END";
      return yy::json_parser::token::END;
    }
    else
      ret = m_io->getChar(&ch);

    if (!ret) {
      qCritical() << "JSonScanner::yylex - error reading from io device";
      return -1;
    }

    qjsonDebug() << "JSonScanner::yylex - got |" << ch << "|";
    yylloc->columns();

    if (ch == '\n' || ch == '\r')
      yylloc->lines();
  } while (m_quotmarkClosed && (isspace(ch) != 0));

  if (m_quotmarkClosed && ((ch == 't') || (ch == 'T'))) {
    const QByteArray buf = m_io->peek(3).toLower();
    if (buf == "rue") {
      m_io->read (3);
      yylloc->columns(3);
      qjsonDebug() << "JSonScanner::yylex - TRUE_VAL";
      return yy::json_parser::token::TRUE_VAL;
    }
  }
  else if (m_quotmarkClosed && ((ch == 'n') || (ch == 'N'))) {
    const QByteArray buf = m_io->peek(3).toLower();
    if (buf == "ull") {
      m_io->read (3);
      yylloc->columns(3);
      qjsonDebug() << "JSonScanner::yylex - NULL_VAL";
      return yy::json_parser::token::NULL_VAL;
    } else if (buf.startsWith("an") && m_allowSpecialNumbers) {
      m_io->read(2);
      yylloc->columns(2);
      qjsonDebug() << "JSonScanner::yylex - NAN_VAL";
      return yy::json_parser::token::NAN_VAL;

    }
  }
  else if (m_quotmarkClosed && ((ch == 'f') || (ch == 'F'))) {
    // check false value
    const QByteArray buf = m_io->peek(4).toLower();
    if (buf.length() == 4) {
      if (buf == "alse") {
        m_io->read (4);
        yylloc->columns(4);
        qjsonDebug() << "JSonScanner::yylex - FALSE_VAL";
        return yy::json_parser::token::FALSE_VAL;
      }
    }
  }
  else if (m_quotmarkClosed && ((ch == 'e') || (ch == 'E'))) {
    QByteArray ret(1, ch);
    const QByteArray buf = m_io->peek(1);
    if (!buf.isEmpty()) {
      if ((buf[0] == '+' ) || (buf[0] == '-' )) {
        ret += m_io->read (1);
        yylloc->columns();
      }
    }
    *yylval = QVariant(QString::fromUtf8(ret));
    return yy::json_parser::token::E;
  }
  else if (m_allowSpecialNumbers && m_quotmarkClosed && ((ch == 'I') || (ch == 'i'))) {
    QByteArray ret(1, ch);
    const QByteArray buf = m_io->peek(7);
    if (buf == "nfinity") {
      m_io->read(7);
      yylloc->columns(7);
      qjsonDebug() << "JSonScanner::yylex - INFINITY_VAL";
      return yy::json_parser::token::INFINITY_VAL;
    }
  }

  if (ch != '"' && !m_quotmarkClosed) {
    // we're inside a " " block
    QByteArray raw;
    raw += ch;
    char prevCh = ch;
    bool escape_on = (ch == '\\') ? true : false;

    while ( true ) {
      char nextCh;
      qint64 ret = m_io->peek(&nextCh, 1);
      if (ret != 1) {
        if (m_io->atEnd())
          return yy::json_parser::token::END;
        else
          return -1;
      } else if ( !escape_on && nextCh == '\"' ) {
        bool ok;
        const QString str = unescape( raw, &ok );
        *yylval = ok ? str : QString();
        return ok ? yy::json_parser::token::STRING : -1;
      }
#if 0
      if ( prevCh == '\\' && nextCh != '"' && nextCh != '\\' && nextCh != '/' &&
           nextCh != 'b' && nextCh != 'f' && nextCh != 'n' &&
           nextCh != 'r' && nextCh != 't' && nextCh != 'u') {
        qjsonDebug() << "Just read" << nextCh;
        qjsonDebug() << "JSonScanner::yylex - error decoding escaped sequence";
        return -1;
       }
#endif
      m_io->read(1); // consume
      raw += nextCh;
      prevCh = nextCh;
      if (escape_on)
        escape_on = false;
      else
        escape_on = (prevCh == '\\') ? true : false;
#if 0
      if (nextCh == '\\') {
        char buf;
        if (m_io->getChar (&buf)) {
          yylloc->columns();
          if (((buf != '"') && (buf != '\\') && (buf != '/') &&
              (buf != 'b') && (buf != 'f') && (buf != 'n') &&
              (buf != 'r') && (buf != 't') && (buf != 'u'))) {
                qjsonDebug() << "Just read" << buf;
                qjsonDebug() << "JSonScanner::yylex - error decoding escaped sequence";
                return -1;
          }
        } else {
          qCritical() << "JSonScanner::yylex - error decoding escaped sequence : io error";
          return -1;
        }
      }
#endif
    }
  }
  else if (isdigit(ch) != 0 && m_quotmarkClosed) {
    bool ok;
    QByteArray numArray = QByteArray::fromRawData( &ch, 1 * sizeof(char) );
    qulonglong number = numArray.toULongLong(&ok);
    if (!ok) {
      //This shouldn't happen
      qCritical() << "JSonScanner::yylex - error while converting char to ulonglong, returning -1";
      return -1;
    }
    if (number == 0) {
      // we have to return immediately otherwise numbers like
      // 2.04 will be converted to 2.4
      *yylval = QVariant(number);
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DIGIT";
      return yy::json_parser::token::DIGIT;
    }

    char nextCh;
    qint64 ret = m_io->peek(&nextCh, 1);
    while (ret == 1 && isdigit(nextCh)) {
      m_io->read(1); //consume
      yylloc->columns(1);
      numArray = QByteArray::fromRawData( &nextCh, 1 * sizeof(char) );
      number = number * 10 + numArray.toULongLong(&ok);
      if (!ok) {
        //This shouldn't happen
        qCritical() << "JSonScanner::yylex - error while converting char to ulonglong, returning -1";
        return -1;
      }
      ret = m_io->peek(&nextCh, 1);
    }

    *yylval = QVariant(number);
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DIGIT";
    return yy::json_parser::token::DIGIT;
  }
  else if (isalnum(ch) != 0) {
    *yylval = QVariant(QString(QChar::fromLatin1(ch)));
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::WORD ("
             << ch << ")";
    return yy::json_parser::token::STRING;
  }
  else if (ch == ':') {
    // set yylval
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::COLON";
    return yy::json_parser::token::COLON;
  }
  else if (ch == '"') {
    // yy::json_parser::token::QUOTMARK (")

    // set yylval
    m_quotmarkCount++;
    if (m_quotmarkCount %2 == 0) {
      m_quotmarkClosed = true;
      m_quotmarkCount = 0;
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::QUOTMARKCLOSE";
      return yy::json_parser::token::QUOTMARKCLOSE;
    }
    else {
      m_quotmarkClosed = false;
      qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::QUOTMARKOPEN";
      return yy::json_parser::token::QUOTMARKOPEN;
    }
  }
  else if (ch == ',') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::COMMA";
    return yy::json_parser::token::COMMA;
  }
  else if (ch == '.') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DOT";
    return yy::json_parser::token::DOT;
  }
  else if (ch == '-') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::MINUS";
    return yy::json_parser::token::MINUS;
  }
  else if (ch == '[') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::SQUARE_BRACKET_OPEN";
    return yy::json_parser::token::SQUARE_BRACKET_OPEN;
  }
  else if (ch == ']') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::SQUARE_BRACKET_CLOSE";
    return yy::json_parser::token::SQUARE_BRACKET_CLOSE;
  }
  else if (ch == '{') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::CURLY_BRACKET_OPEN";
    return yy::json_parser::token::CURLY_BRACKET_OPEN;
  }
  else if (ch == '}') {
    qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::CURLY_BRACKET_CLOSE";
    return yy::json_parser::token::CURLY_BRACKET_CLOSE;
  }

  //unknown char!
  //TODO yyerror?
  qCritical() << "JSonScanner::yylex - unknown char, returning -1";
  return -1;
}