Logo Search packages:      
Sourcecode: jaula version File versions

Value * JAULA::Parser::Value_Parser::parseValue ( Lexan lexan,
unsigned int  token 
) throw (Exception) [static]

reads a single JSON value

Parameters:
lexan Reference to the lexical analysis instance that reads from the input.
token Token read from the upper level. * If this token does not belong to an starting value token, an error condition will arise.
Returns:
a pointer to memory taken from the heap containing the value read. If this value belongs to a complex type, all the items that it contains have been recursively parsed.
Exceptions:
Exception An exception will be thrown as soon as a lexical or syntax error is found analyzing the stream. The result of printing the exception retrurned through a stream is a human readable text explaining the error found and an approximation of the error line where it occurred.
Description
This method fully reads a whole value from the input or until a syntax or lexical error is found. Upon execution input stream is positioned so that a new token or EOF can be read from the input.

Definition at line 117 of file jaula_parse.cc.

References JAULA::Exception::addOrigin(), array_addItem, array_nextItem, END, EOFError(), JAULA::Value_String::getData(), property_begin, property_name, property_next, property_value, and START.

Referenced by JAULA::Parser::parseStream().

  {
    try
    {
      std::auto_ptr<Value_Array>  pArray;
      std::auto_ptr<Value_Object> pObject;
      std::string                 propName;
      for (parser_states  state = START
        ; (state != END)
        ; token = lexan.yylex())
      {                          // main state for

        switch (state)
        {                        // main state switch

          case START :
            switch (token)
            {                    // START state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for a value"
                  , errAct.str()));
              }
              break;

              case '[' :
                pArray.reset(new Value_Array());
                state = array_addItem;
                break;

              case NULL_VALUE :
                return new Value_Null();

              case FALSE_VALUE :
                return new Value_Boolean(false);

              case TRUE_VALUE :
                return new Value_Boolean(true);

              case NUMBER_VALUE :
              {
                char *resto;
                double  val = strtod(lexan.getTokenData().c_str(), &resto);
                if ((resto) && (*resto))
                {
                  std::ostringstream  errDet;
                  errDet << "Value " << lexan.getTokenData()
                    << " contains a non-numerical value and is not enclosed"
                    << " between double quotes";
                  std::ostringstream  errAct;
                  errAct << "analyzing line "
                    << lexan.lineno()
                    << " from input stream.";
                  throw Syntax_Error(errDet.str(), errAct.str());
                }
                return new Value_Number(val);
              }

              case NUMBER_INT_VALUE :
              {
                char *resto;
                long  val = strtol(lexan.getTokenData().c_str(), &resto, 0);
                if ((resto) && (*resto))
                {
                  std::ostringstream  errDet;
                  errDet << "Value "
                    << lexan.getTokenData()
                    << " contains a non-numerical value and is not enclosed"
                    << " between double quotes";
                  std::ostringstream  errAct;
                  errAct << "analyzing line "
                    << lexan.lineno()
                    << " from input stream.";
                  throw Syntax_Error(errDet.str(), errAct.str());
                }
                return new Value_Number_Int(val);
              }

              case STRING_VALUE :
                return new Value_String(lexan.getTokenData());

              case '{' :
                pObject.reset(new Value_Object());
                state = property_begin;
                break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for a value or the beginning of an"
                  << " array or object";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // START state switch
            break;

          case array_addItem :
            switch (token)
            {                    // array_addItem state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for a value"
                  " or a closing array symbol"
                  , errAct.str()));
              }
              break;

              case ']' :
                return pArray.release();

              case '[' :
              case '{' :
              case NULL_VALUE :
              case FALSE_VALUE :
              case TRUE_VALUE :
              case NUMBER_VALUE :
              case NUMBER_INT_VALUE :
              case STRING_VALUE :
              {
                std::auto_ptr<Value>    pItem(parseValue(lexan, token));
                pArray->addItem(*(pItem.get()));
              }
              state = array_nextItem;
              break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for a value or the end of an array";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // array_addItem state switch
            break;

          case array_nextItem :
            switch (token)
            {                    // array_nextItem state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for an item"
                  " delimiter or a closing array symbol"
                  , errAct.str()));
              }
              break;

              case ']' :
                return pArray.release();

              case ',' :
                state = array_addItem;
                break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for an item delimiter or the end of"
                  << " an array";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // array_nextItem state switch
            break;

          case property_begin :
            switch (token)
            {                    // property_begin state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for a"
                  " property name or a closing object symbol"
                  , errAct.str()));
              }
              break;

              case '}' :
                return pObject.release();

              case STRING_VALUE :
              {
                std::auto_ptr<Value> pVal(parseValue(lexan, token));
                Value_String *pStrVal =
                  dynamic_cast<Value_String *>(pVal.get());
                if (pStrVal)
                  propName = pStrVal->getData();
                else
                {
                  std::ostringstream  errDet;
                  errDet << "Unexpected value type ";
                  if (isprint(token))
                    errDet << "'" << static_cast<char>(token) << "'";
                  else
                    errDet << '(' << token << ')';
                  errDet << " while waiting for a property name";
                  std::ostringstream  errAct;
                  errAct << "analyzing line "
                    << lexan.lineno()
                    << " from input stream.";
                  throw Syntax_Error(errDet.str(), errAct.str());
                }
              }
              state = property_name;
              break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for a property name or the end of"
                  << " an object";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // property_begin state switch
            break;

          case property_name :
            switch (token)
            {                    // property_name state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for a"
                  " property name delimiter symbol"
                  , errAct.str()));
              }
              break;

              case ':' :
                state = property_value;
                break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for property name delimiter";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // property_name state switch
            break;

          case property_value :
            switch (token)
            {                    // property_value state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for a value"
                  " for an object property"
                  , errAct.str()));
              }
              break;

              case '[' :
              case '{' :
              case NULL_VALUE :
              case FALSE_VALUE :
              case TRUE_VALUE :
              case NUMBER_VALUE :
              case NUMBER_INT_VALUE :
              case STRING_VALUE :
              {
                std::auto_ptr<Value>    pItemVal(parseValue(lexan, token));
                pObject->insertItem(propName, *(pItemVal.get()));
              }
              state = property_next;
              break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for a value for an object property";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // property_value state switch
            break;

          case property_next :
            switch (token)
            {                    // property_next state switch
              case 0 :
              {
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                EOFError(lexan
                  , Syntax_Error("Unexpected EOF while waiting for an item"
                  " delimiter or a closing object symbol"
                  , errAct.str()));
              }
              break;

              case '}' :
                return pObject.release();

              case ',' :
                state = property_begin;
                break;

              default :
              {
                std::ostringstream  errDet;
                errDet << "Unexpected symbol ";
                if (isprint(token))
                  errDet << "'" << static_cast<char>(token) << "'";
                else
                  errDet << '(' << token << ')';
                errDet << " while waiting for an item delimiter or the end of"
                  << " an object";
                std::ostringstream  errAct;
                errAct << "analyzing line "
                  << lexan.lineno()
                  << " from input stream.";
                throw Syntax_Error(errDet.str(), errAct.str());
              }
              break;

            }                    // property_next state switch
            break;

          default:
          {
            std::ostringstream  errAct;
            errAct << "analyzing line "
              << lexan.lineno()
              << " from input stream.";
            throw Syntax_Error("The parser state machine reached an unknown"
              " value. Internal error"
              , errAct.str());
          }
          break;

        }                        // main state switch

      }                          // main state for
      {
        std::ostringstream  errAct;
        errAct << "analyzing line "
          << lexan.lineno()
          << " from input stream.";
        throw Syntax_Error("The parser state machine flow reached to an"
          " unexpected point. Internal error"
          , errAct.str());
      }
      return 0;                  // Flow control will never reach this point
    }
    catch(Exception &ex)
    {
      ex.addOrigin("Parser::Value_Parser::parseValue(Lexan &, unsigned int)");
      throw ex;
    }
  }


Generated by  Doxygen 1.6.0   Back to index