void ParserThread::HandleForWhile() { SymbolKind id; Token * tok = ConsumeToken(); //eat for or while key word id = (tok->type_id()==TKN_FOR)? tkFor:tkWhile; Symbol * sym = DoAddToken(id,*tok); ConsumeToken(); //eat the left parenthesis PushContext(); //save the old context m_Context.parentToken=sym; DoParse(); // do a parse, and should returned on an unbalanced right parenthesis PopContext(); // restore the old context tok = PeekToken(); if(tok->type_id()==TKN_L_BRACE) { ConsumeToken(); //eat { PushContext(); //save the old context m_Context.parentToken=sym; DoParse(); // do a parse, and should returned on an unbalanced right brace PopContext(); // restore the old context } else SkipStatementBlock(); }
void ParserThread::HandleEnum() { // enums have the following rough definition: // enum [xxx] { type1 name1 [= 1][, [type2 name2 [= 2]]] }; ConsumeToken(); Token * tk = ConsumeToken(); // the token after "enum" //Token * newToken = 0; if (tk->type_id() == TKN_IDENTIFIER) // enum XXX { Token *pk = PeekToken(); if(pk->type_id() == TKN_L_BRACE ) //enum XXX { { // Do Add Token of enum TRACE("find enum %s at line(%d)",tk->get_text().c_str(),tk->line_number()); DoAddToken(tkEnum, *tk); //newToken->m_ImplLineStart = pk->line_number(); ConsumeToken(); //consume { PushContext(); ReadEnumList(); PopContext(); } else { SkipStatementBlock(); //something wrong return; } } else if (tk->type_id()== TKN_L_BRACE) // enum { { // // Do Add Token of enum TRACE("find unnamed enum at line(%d)",tk->line_number()); DoAddToken(tkEnum, *tk); ConsumeToken(); //consume { PushContext(); ReadEnumList(); PopContext(); } // Token's implement End line information added tk = ConsumeToken(); //we are now after the } // if we find a ;, good, end of definition of enum // if we find an id, then this is something like enum XXX{...} A,B; // A,B were the instant of the enum tk = ConsumeToken(); if(tk->type_id() == TKN_IDENTIFIER) { //Add variables list return; } else if(tk->type_id() == TKN_SEMICOLON) { //OK, end of enum definition return; } }
void ParserThread::HandleNamespace() { ConsumeToken(); Token *pk = PeekToken(); Token name; if(pk->type_id()==TKN_IDENTIFIER) { name = *pk; ConsumeToken(); } else { //un-named namespace } pk = PeekToken(); if(pk->type_id()==TKN_L_BRACE) { ConsumeToken(); Symbol * sym = DoAddToken(tkNamespace,name); PushContext(); m_Context.parentToken = sym; DoParse(); PopContext(); TRACE("end of namespace\n"); } }
nsXFormsXPathNode* nsXFormsXPathParser::Parse(const nsAString& aExpression) { #ifdef DEBUG_XF_PARSER printf("=====================================\n"); printf("Parsing: %s\n", NS_ConvertUTF16toUTF8(aExpression).get()); printf("=====================================\n"); #endif mScanner.Init(aExpression); mAnalyzeStackPointer = 0; mPredicateLevel = 0; mHead = nsnull; PopToken(); PushContext(); nsXFormsXPathNode* root = mHead; Expr(); PopContext(); #ifdef DEBUG_XF_PARSER Dump(root); printf("-------------------------------------\n"); #endif return root; }
void ParserThread::HandleFunction() { //TRACE("HandleFunction() : %s %s()",m_Context.type.back().name.get_text().c_str(),name.c_str()); // should always at the ( , so we firstly read the parentheses if(m_Context.nameQueue.size()==0) { m_Context.nameQueue = m_Context.typeQueue; m_Context.typeQueue.clear(); } Symbol * sym = DoAddToken(tkFunction, m_Context.nameQueue.back().name); ArgumentList args; ReadFunctionArguments(args); Token * peek = PeekToken(); if(peek->type_id() == TKN_CONST) ConsumeToken(); // skip the member initialization list if(PeekToken()->type_id() == TKN_COLON) { ConsumeToken(); while(true) { if(PeekToken()->type_id()!=TKN_L_BRACE) ConsumeToken(); else break; } } peek = PeekToken(); if (peek->type_id() == TKN_L_BRACE) // function definition { TRACE("Function definition"); //SkipBrace(); ConsumeToken(); //Symbol * sym = DoAddToken(tkFunction, m_Context.nameQueue.back().name); PushContext(); m_Context.parentToken = sym; DoParse(); PopContext(); } else if (peek->type_id() == TKN_SEMICOLON) { TRACE("Function declaration"); //DoAddToken(tkFunction, m_Context.nameQueue.back().name); //newToken->m_Args = args; ConsumeToken(); } m_Context.EndStatement(); }
//-------------------------------------------------------------------------------------------------- static void ParseValue ( Parser_t* parserPtr, char c ) //-------------------------------------------------------------------------------------------------- { // Throw away whitespace until something else comes along. if (!isspace(c)) { if (c == '{') // Start of an object. { PushContext(parserPtr, LE_JSON_CONTEXT_OBJECT, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_MEMBER_OR_OBJECT_END; Report(parserPtr, LE_JSON_OBJECT_START); } else if (c == '[') // Start of an array. { PushContext(parserPtr, LE_JSON_CONTEXT_ARRAY, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_VALUE_OR_ARRAY_END; Report(parserPtr, LE_JSON_ARRAY_START); } else if (c == '"') { PushContext(parserPtr, LE_JSON_CONTEXT_STRING, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_STRING; } else if (c == 't') { PushContext(parserPtr, LE_JSON_CONTEXT_TRUE, GetEventHandler(parserPtr)); AddToBuffer(parserPtr, c); parserPtr->next = EXPECT_TRUE; } else if (c == 'f') { PushContext(parserPtr, LE_JSON_CONTEXT_FALSE, GetEventHandler(parserPtr)); AddToBuffer(parserPtr, c); parserPtr->next = EXPECT_FALSE; } else if (c == 'n') { PushContext(parserPtr, LE_JSON_CONTEXT_NULL, GetEventHandler(parserPtr)); AddToBuffer(parserPtr, c); parserPtr->next = EXPECT_NULL; } else if (isdigit(c) || (c == '-')) { PushContext(parserPtr, LE_JSON_CONTEXT_NUMBER, GetEventHandler(parserPtr)); AddToBuffer(parserPtr, c); parserPtr->next = EXPECT_NUMBER; } else { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Unexpected character at beginning of value."); } } }
nsresult RDFContentSinkImpl::OpenMember(const PRUnichar* aName, const PRUnichar** aAttributes) { // ensure that we're actually reading a member element by making // sure that the opening tag is <rdf:li>, where "rdf:" corresponds // to whatever they've declared the standard RDF namespace to be. nsresult rv; nsCOMPtr<nsIAtom> localName; const nsDependentSubstring& nameSpaceURI = SplitExpatName(aName, getter_AddRefs(localName)); if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || localName != kLiAtom) { PR_LOG(gLog, PR_LOG_ALWAYS, ("rdfxml: expected RDF:li at line %d", -1)); // XXX pass in line number return NS_ERROR_UNEXPECTED; } // The parent element is the container. nsIRDFResource* container = GetContextElement(0); if (! container) return NS_ERROR_NULL_POINTER; nsIRDFResource* resource; if (NS_SUCCEEDED(rv = GetResourceAttribute(aAttributes, &resource))) { // Okay, this node has an RDF:resource="..." attribute. That // means that it's a "referenced item," as covered in [6.29]. nsCOMPtr<nsIRDFContainer> c; NS_NewRDFContainer(getter_AddRefs(c)); c->Init(mDataSource, container); c->AppendElement(resource); // XXX Technically, we should _not_ fall through here and push // the element onto the stack: this is supposed to be a closed // node. But right now I'm lazy and the code will just Do The // Right Thing so long as the RDF is well-formed. NS_RELEASE(resource); } // Change state. Pushing a null context element is a bit weird, // but the idea is that there really is _no_ context "property". // The contained element will use nsIRDFContainer::AppendElement() to add // the element to the container, which requires only the container // and the element to be added. PushContext(nsnull, mState, mParseMode); mState = eRDFContentSinkState_InMemberElement; SetParseMode(aAttributes); return NS_OK; }
void ParserThread::ReadFunctionArguments(ArgumentList &args) { //TKN_L_PAREN args.clear(); ConsumeToken();//remove the first TKN_L_PAREN PushContext(); m_Context.parseType = FunctionParameter; DoParse(); PopContext(); }
void nsXFormsXPathParser::LocationPath() { if (DoRelative()) { PushContext(); RelativeLocationPath(); PopContext(); } else { nsXFormsXPathScanner::XPATHTOKEN t = PeekToken(); switch (t) { case nsXFormsXPathScanner::SLASH: case nsXFormsXPathScanner::SLASHSLASH: PushContext(); AbsoluteLocationPath(); PopContext(); break; default: XPathCompilerException("Not a location path", mScanner.Expression(), mScanner.Offset(), mScanner.Length()); } } }
/* * Parse the command string contained in the current context. */ void CmdStringParse( OPT_STORAGE *cmdOpts, int *itemsParsed ) /***********************************************************/ { int ch; char * filename; for( ;; ) { /*** Find the start of the next item ***/ CmdScanWhitespace(); ch = GetCharContext(); if( ch == '\0' ) break; MarkPosContext(); /* mark start of switch */ /*** Handle switches, command files, and input files ***/ if( ch == '-' || ch == '/' ) { /* switch */ if( OPT_PROCESS( cmdOpts ) != 0 ) { cmd_line_error(); } } else if( ch == '@' ) { /* command file */ filename = CmdScanFileNameWithoutQuotes(); PushContext(); if( OpenFileContext( filename ) ) { FatalError( "Cannot open '%s'.", filename ); } FreeMem( filename ); CmdStringParse( cmdOpts, itemsParsed ); PopContext(); } else if( ch == '"' ) { /* quoted option or file name */ ch = GetCharContext(); if( ch == '-' ) { Quoted = 1; if( OPT_PROCESS( cmdOpts ) != 0 ) { cmd_line_error(); } } else { UngetCharContext(); UngetCharContext(); filename = CmdScanFileName(); AddFile( TYPE_DEFAULT_FILE, filename ); FreeMem( filename ); } } else { /* input file */ UngetCharContext(); filename = CmdScanFileName(); AddFile( TYPE_DEFAULT_FILE, filename ); FreeMem( filename ); } (*itemsParsed)++; } CloseContext(); }
void nsXFormsXPathParser::PathExpr() { nsXFormsXPathScanner::XPATHTOKEN t = PeekToken(); switch (t) { case nsXFormsXPathScanner::ANCESTOR: case nsXFormsXPathScanner::ANCESTOR_OR_SELF: case nsXFormsXPathScanner::ATTRIBUTE: case nsXFormsXPathScanner::CHILD: case nsXFormsXPathScanner::DESCENDANT: case nsXFormsXPathScanner::DESCENDANT_OR_SELF: case nsXFormsXPathScanner::FOLLOWING: case nsXFormsXPathScanner::FOLLOWING_SIBLING: case nsXFormsXPathScanner::NAMESPACE: case nsXFormsXPathScanner::PARENT: case nsXFormsXPathScanner::PRECEDING: case nsXFormsXPathScanner::PRECEDING_SIBLING: case nsXFormsXPathScanner::SELF: case nsXFormsXPathScanner::AT: case nsXFormsXPathScanner::STAR: case nsXFormsXPathScanner::NCNAME: case nsXFormsXPathScanner::QNAME: case nsXFormsXPathScanner::COMMENT: case nsXFormsXPathScanner::TEXT: case nsXFormsXPathScanner::PI: case nsXFormsXPathScanner::NODE: case nsXFormsXPathScanner::DOT: case nsXFormsXPathScanner::DOTDOT: case nsXFormsXPathScanner::SLASH: case nsXFormsXPathScanner::SLASHSLASH: LocationPath(); break; default: PushContext(); FilterExpr(); t = PeekToken(); if (t == nsXFormsXPathScanner::SLASH || t == nsXFormsXPathScanner::SLASHSLASH) { PopToken(); if (DoRelative()) { RelativeLocationPath(); } else { XPathCompilerException("After / in a filter expression it is required to have a relative path expression", EmptyString()); } } PopContext(); } }
/* * Parse the command string contained in the current context. */ void CmdStringParse( OPT_STORAGE *cmdOpts, int *itemsParsed ) /***********************************************************/ { char ch; char * filename; char * str; for( ;; ) { /*** Find the start of the next item ***/ CmdScanWhitespace(); ch = GetCharContext(); if( ch == '\0' ) break; MarkPosContext(); /* mark start of switch */ /*** Handle switches, command files, and input files ***/ if( ch == '-' || ch == '/' ) { /* switch */ if( OPT_PROCESS( cmdOpts ) ) { /* * Switch didn't match, if user entered empty switch, * just be silent like MS's nmake does. */ ch = GetCharContext(); if( ch != '\0' && !isspace( ch ) ) { cmd_line_error(); } } } else if( ch == '@' ) { /* command file */ filename = CmdScanFileNameWithoutQuotes(); PushContext(); if( OpenFileContext( filename ) ) { FatalError( "Cannot open '%s'.", filename ); } FreeMem( filename ); CmdStringParse( cmdOpts, itemsParsed ); PopContext(); } else { /* targets and macros */ UngetCharContext(); str = CmdScanString(); add_string( &(cmdOpts->t010101010101_value), str, '\0' ); cmdOpts->t010101010101 = 1; } (*itemsParsed)++; } CloseContext(); }
void nsXFormsXPathParser::FunctionCall() { nsDependentSubstring fname = Substring(mScanner.Expression(), mScanner.Offset() + 1, mScanner.Length()); if (!mUsesDynamicFunc && fname.Equals(NS_LITERAL_STRING("now"))) { mUsesDynamicFunc = PR_TRUE; } PopToken(); PopToken(); nsXFormsXPathScanner::XPATHTOKEN t = PeekToken(); PRBool con = t == nsXFormsXPathScanner::RPARAN ? PR_FALSE : PR_TRUE; while (con) { if (t == nsXFormsXPathScanner::XPATHEOF) { XPathCompilerException("Expected ) got EOF", mScanner.Expression(), mScanner.Offset(), mScanner.Length()); } nsXFormsXPathNode* c = JustContext(); Expr(); if (fname.Equals(NS_LITERAL_STRING("index"))) { c->mIsIndex = PR_TRUE; } PushContext(c); t = PeekToken(); con = (t == nsXFormsXPathScanner::COMMA); if (con) { PopToken(); // Another Argument } } if (t != nsXFormsXPathScanner::RPARAN) { XPathCompilerException("Expected )", mScanner.Expression(), mScanner.Offset(), mScanner.Length()); } PopToken(); }
//-------------------------------------------------------------------------------------------------- le_json_ParsingSessionRef_t le_json_ParseString ( const char *jsonString, ///< JSON string to parse. le_json_EventHandler_t eventHandler, ///< Function to call when normal parsing events happen. le_json_ErrorHandler_t errorHandler, ///< Function to call when errors happen. void* opaquePtr ///< Opaque pointer to be fetched by handlers using le_json_GetOpaquePtr(). ) { // Create a Parser. Parser_t* parserPtr = NewParser(eventHandler, errorHandler, opaquePtr); parserPtr->fd = -1; parserPtr->jsonString = jsonString; le_event_QueueFunction((le_event_DeferredFunc_t) &StringEventHandler, parserPtr, NULL); // Create the top-level context and push it onto the context stack. PushContext(parserPtr, LE_JSON_CONTEXT_DOC, eventHandler); return parserPtr; }
//-------------------------------------------------------------------------------------------------- le_json_ParsingSessionRef_t le_json_Parse ( int fd, ///< File descriptor to read the JSON document from. le_json_EventHandler_t eventHandler, ///< Function to call when normal parsing events happen. le_json_ErrorHandler_t errorHandler, ///< Function to call when errors happen. void* opaquePtr ///< Opaque pointer to be fetched by handlers using le_json_GetOpaquePtr(). ) //-------------------------------------------------------------------------------------------------- { // Create a Parser. Parser_t* parserPtr = NewParser(eventHandler, errorHandler, opaquePtr); parserPtr->fd = fd; parserPtr->fdMonitor = le_fdMonitor_Create("le_json", fd, FdEventHandler, POLLIN); le_fdMonitor_SetContextPtr(parserPtr->fdMonitor, parserPtr); // Create the top-level context and push it onto the context stack. PushContext(parserPtr, LE_JSON_CONTEXT_DOC, eventHandler); return parserPtr; }
void nsXFormsXPathParser::PrimaryExpr() { nsXFormsXPathScanner::XPATHTOKEN t = PeekToken(); switch (t) { case nsXFormsXPathScanner::VARIABLE: PopToken(); break; case nsXFormsXPathScanner::LPARAN: { PopToken(); nsXFormsXPathNode* c = JustContext(); Expr(); PushContext(c); if (PeekToken() == nsXFormsXPathScanner::RPARAN) { PopToken(); } else { XPathCompilerException("Expected )", mScanner.Expression(), mScanner.Offset(), mScanner.Length()); } } break; case nsXFormsXPathScanner::LITERAL: mHead->mLiteral = PR_TRUE; PopToken(); break; case nsXFormsXPathScanner::NUMBER: mHead->mLiteral = PR_TRUE; PopToken(); break; case nsXFormsXPathScanner::FUNCTIONNAME: FunctionCall(); break; default: XPathCompilerException("Not a primary expression", mScanner.Expression(), mScanner.Offset(), mScanner.Length()); } }
nsresult RDFContentSinkImpl::OpenRDF(const PRUnichar* aName) { // ensure that we're actually reading RDF by making sure that the // opening tag is <rdf:RDF>, where "rdf:" corresponds to whatever // they've declared the standard RDF namespace to be. nsCOMPtr<nsIAtom> localName; const nsDependentSubstring& nameSpaceURI = SplitExpatName(aName, getter_AddRefs(localName)); if (!nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI) || localName != kRDFAtom) { // PR_LOG(gLog, PR_LOG_ALWAYS, // ("rdfxml: expected RDF:RDF at line %d", // aNode.GetSourceLineNumber())); return NS_ERROR_UNEXPECTED; } PushContext(nsnull, mState, mParseMode); mState = eRDFContentSinkState_InDocumentElement; return NS_OK; }
nsresult RDFContentSinkImpl::OpenProperty(const PRUnichar* aName, const PRUnichar** aAttributes) { nsresult rv; // an "object" non-terminal is either a "description", a "typed // node", or a "container", so this change the content sink's // state appropriately. nsCOMPtr<nsIAtom> localName; const nsDependentSubstring& nameSpaceURI = SplitExpatName(aName, getter_AddRefs(localName)); const char* attrName; localName->GetUTF8String(&attrName); NS_ConvertUTF16toUTF8 propertyStr(nameSpaceURI); propertyStr.Append(attrName); nsCOMPtr<nsIRDFResource> property; rv = gRDFService->GetResource(propertyStr, getter_AddRefs(property)); if (NS_FAILED(rv)) return rv; // See if they've specified a 'resource' attribute, in which case // they mean *that* to be the object of this property. nsCOMPtr<nsIRDFResource> target; GetResourceAttribute(aAttributes, getter_AddRefs(target)); PRBool isAnonymous = PR_FALSE; if (! target) { // See if an 'ID' attribute has been specified, in which case // this corresponds to the fourth form of [6.12]. // XXX strictly speaking, we should reject the RDF/XML as // invalid if they've specified both an 'ID' and a 'resource' // attribute. Bah. // XXX strictly speaking, 'about=' isn't allowed here, but // what the hell. GetIdAboutAttribute(aAttributes, getter_AddRefs(target), &isAnonymous); } if (target) { // They specified an inline resource for the value of this // property. Create an RDF resource for the inline resource // URI, add the properties to it, and attach the inline // resource to its parent. PRInt32 count; rv = AddProperties(aAttributes, target, &count); NS_ASSERTION(NS_SUCCEEDED(rv), "problem adding properties"); if (NS_FAILED(rv)) return rv; if (count || !isAnonymous) { // If the resource was "anonymous" (i.e., they hadn't // explicitly set an ID or resource attribute), then we'll // only assert this property from the context element *if* // there were properties specified on the anonymous // resource. rv = mDataSource->Assert(GetContextElement(0), property, target, PR_TRUE); if (NS_FAILED(rv)) return rv; } // XXX Technically, we should _not_ fall through here and push // the element onto the stack: this is supposed to be a closed // node. But right now I'm lazy and the code will just Do The // Right Thing so long as the RDF is well-formed. } // Push the element onto the context stack and change state. PushContext(property, mState, mParseMode); mState = eRDFContentSinkState_InPropertyElement; SetParseMode(aAttributes); return NS_OK; }
void ParserThread::HandleClass(EClassType ct) { // class xxx { or class { // the keyworkd "class" is already comsumed //assert(CurrentToken()->type_id()==TKN_CLASS); ConsumeToken(); Token * current = ConsumeToken(); // class name Token * next = PeekToken(); TRACE("HandleClass() : Found class '%s'", current->get_text().c_str() ); // Check current firstly if (current->type_id() == TKN_L_BRACE) // unnamed class/struct/union { // cc_string unnamedTmp; // unnamedTmp.Printf(_T("%s%s%d"), // ParserConsts::unnamed.wx_str(), // ct == ctClass ? _T("Class") : // ct == ctUnion ? _T("Union") : // _T("Struct"), ++m_pTokensTree->m_StructUnionUnnamedCount); // // Token* newToken = DoAddToken(tkClass, unnamedTmp, lineNr); // // PushContext(); // m_Context.Clear(); // m_Context.parentToken = newToken; // m_Context.accessScope = ct == ctClass ? tsPrivate : tsPublic; // struct has default public scope // // newToken->m_ImplLine = lineNr; // newToken->m_ImplLineStart = m_Tokenizer.GetLineNumber(); // // DoParse(); // // PopContext(); } else if (current->type_id() == TKN_IDENTIFIER) //OK, we need to check the next { //parser base clause if ( next->type_id() == TKN_COLON ) { //ReadType //ConsumeToken(); //remove :id ConsumeToken(); //remove : ConsumeToken(); //remove protect/public/private //ConsumeToken(); //need to read the id ParseFullIdentifer(); } next = PeekToken(); if ( next->type_id() == TKN_L_BRACE) // class AAA {, we find the "{" here { //ParserThreadContext savedContext = m_Context; //m_Context.EndStatement(); //m_Context.parentToken = newToken; ConsumeToken();// consume { Symbol * sym = DoAddToken(tkClass, *current); PushContext(); m_Context.parentToken = sym; DoParse(); // when meet a }, we should return from DoParse() PopContext(); current = ConsumeToken(); if(current->type_id()==TKN_SEMICOLON) // class A {.....}; return; else SkipStatementBlock(); //struct A {....} a b; } } else { // something wrong, should be skip to a semicolon SkipStatementBlock(); } }
//-------------------------------------------------------------------------------------------------- static void ProcessChar ( Parser_t* parserPtr, char c ) //-------------------------------------------------------------------------------------------------- { switch (parserPtr->next) { case EXPECT_OBJECT_OR_ARRAY: // Throw away whitespace characters until '{' or '[' is found. if (c == '{') { PushContext(parserPtr, LE_JSON_CONTEXT_OBJECT, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_MEMBER_OR_OBJECT_END; Report(parserPtr, LE_JSON_OBJECT_START); } else if (c == '[') { PushContext(parserPtr, LE_JSON_CONTEXT_ARRAY, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_VALUE_OR_ARRAY_END; Report(parserPtr, LE_JSON_ARRAY_START); } else if (!isspace(c)) { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Document must start with '{' or '['."); } return; case EXPECT_MEMBER_OR_OBJECT_END: // Throw away whitespace until a '"' or '}' is found. if (c == '}') // Object end found. { Report(parserPtr, LE_JSON_OBJECT_END); PopContext(parserPtr); } else if (c == '"') // Start of member name (string) found. { PushContext(parserPtr, LE_JSON_CONTEXT_MEMBER, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_STRING; } else if (!isspace(c)) { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Expected end of object (}) or beginning of object member name (\")."); } return; case EXPECT_COLON: // Throw away whitespace until a ':' is found. if (c == ':') { parserPtr->next = EXPECT_VALUE; } else if (!isspace(c)) { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Expected ':' after object member name."); } return; case EXPECT_VALUE: ParseValue(parserPtr, c); return; case EXPECT_COMMA_OR_OBJECT_END: // Throw away whitespace until a ',' or '}' is found. if (c == '}') // Object end found. { Report(parserPtr, LE_JSON_OBJECT_END); PopContext(parserPtr); } else if (c == ',') // Comma separator found. { parserPtr->next = EXPECT_MEMBER; } else if (!isspace(c)) { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Expected end of object (}) or beginning of object member name (\")."); } return; case EXPECT_MEMBER: // Throw away whitespace until a '"' is found. if (c == '"') // Start of member name (string) found. { PushContext(parserPtr, LE_JSON_CONTEXT_MEMBER, GetEventHandler(parserPtr)); parserPtr->next = EXPECT_STRING; } else if (!isspace(c)) { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Expected beginning of object member name (\")."); } return; case EXPECT_VALUE_OR_ARRAY_END: if (c == ']') { Report(parserPtr, LE_JSON_ARRAY_END); PopContext(parserPtr); } else { ParseValue(parserPtr, c); } return; case EXPECT_COMMA_OR_ARRAY_END: // Throw away whitespace until a ',' or ']' is found. if (c == ']') // Array end found. { Report(parserPtr, LE_JSON_ARRAY_END); PopContext(parserPtr); } else if (c == ',') // Comma separator found. { parserPtr->next = EXPECT_VALUE; } else if (!isspace(c)) { Error(parserPtr, LE_JSON_SYNTAX_ERROR, "Expected end of array (]) or a comma separator (,)."); } return; case EXPECT_STRING: ParseString(parserPtr, c); return; case EXPECT_NUMBER: if ((c == '.') || isdigit(c)) { AddToBuffer(parserPtr, c); } else { ProcessNumber(parserPtr); ProcessChar(parserPtr, c); } return; case EXPECT_TRUE: ParseConstant(parserPtr, c, "true"); if (strcmp(parserPtr->buffer, "true") == 0) { Report(parserPtr, LE_JSON_TRUE); PopContext(parserPtr); } return; case EXPECT_FALSE: ParseConstant(parserPtr, c, "false"); if (strcmp(parserPtr->buffer, "false") == 0) { Report(parserPtr, LE_JSON_FALSE); PopContext(parserPtr); } return; case EXPECT_NULL: ParseConstant(parserPtr, c, "null"); if (strcmp(parserPtr->buffer, "null") == 0) { Report(parserPtr, LE_JSON_NULL); PopContext(parserPtr); } return; case EXPECT_NOTHING: ///< Parsing stopped. return; } LE_FATAL("Internal error: Invalid JSON parser expectation %d.", parserPtr->next); }
nsresult RDFContentSinkImpl::OpenObject(const PRUnichar* aName, const PRUnichar** aAttributes) { // an "object" non-terminal is either a "description", a "typed // node", or a "container", so this change the content sink's // state appropriately. nsCOMPtr<nsIAtom> localName; const nsDependentSubstring& nameSpaceURI = SplitExpatName(aName, getter_AddRefs(localName)); // Figure out the URI of this object, and create an RDF node for it. nsCOMPtr<nsIRDFResource> source; GetIdAboutAttribute(aAttributes, getter_AddRefs(source)); // If there is no `ID' or `about', then there's not much we can do. if (! source) return NS_ERROR_FAILURE; // Push the element onto the context stack PushContext(source, mState, mParseMode); // Now figure out what kind of state transition we need to // make. We'll either be going into a mode where we parse a // description or a container. PRBool isaTypedNode = PR_TRUE; if (nameSpaceURI.EqualsLiteral(RDF_NAMESPACE_URI)) { isaTypedNode = PR_FALSE; if (localName == kDescriptionAtom) { // it's a description mState = eRDFContentSinkState_InDescriptionElement; } else if (localName == kBagAtom) { // it's a bag container InitContainer(kRDF_Bag, source); mState = eRDFContentSinkState_InContainerElement; } else if (localName == kSeqAtom) { // it's a seq container InitContainer(kRDF_Seq, source); mState = eRDFContentSinkState_InContainerElement; } else if (localName == kAltAtom) { // it's an alt container InitContainer(kRDF_Alt, source); mState = eRDFContentSinkState_InContainerElement; } else { // heh, that's not *in* the RDF namespace: just treat it // like a typed node isaTypedNode = PR_TRUE; } } if (isaTypedNode) { const char* attrName; localName->GetUTF8String(&attrName); NS_ConvertUTF16toUTF8 typeStr(nameSpaceURI); typeStr.Append(attrName); nsCOMPtr<nsIRDFResource> type; nsresult rv = gRDFService->GetResource(typeStr, getter_AddRefs(type)); if (NS_FAILED(rv)) return rv; rv = mDataSource->Assert(source, kRDF_type, type, PR_TRUE); if (NS_FAILED(rv)) return rv; mState = eRDFContentSinkState_InDescriptionElement; } AddProperties(aAttributes, source); return NS_OK; }