示例#1
0
/*
 * Exported JSON decoding interface
 */
JX9_PRIVATE int jx9JsonDecode(jx9_context *pCtx,const char *zJSON,int nByte)
{
	jx9_vm *pVm = pCtx->pVm;
	json_decoder sDecoder;
	SySet sToken;
	SyLex sLex;
	sxi32 rc;
	/* Tokenize the input */
	SySetInit(&sToken, &pVm->sAllocator, sizeof(SyToken));
	rc = SXRET_OK;
	SyLexInit(&sLex, &sToken, VmJsonTokenize, &rc);
	SyLexTokenizeInput(&sLex,zJSON,(sxu32)nByte, 0, 0, 0);
	if( rc != SXRET_OK ){
		/* Something goes wrong while tokenizing input. [i.e: Unexpected token] */
		SyLexRelease(&sLex);
		SySetRelease(&sToken);
		/* return NULL */
		jx9_result_null(pCtx);
		return JX9_OK;
	}
	/* Fill the decoder */
	sDecoder.pCtx = pCtx;
	sDecoder.pErr = &rc;
	sDecoder.pIn = (SyToken *)SySetBasePtr(&sToken);
	sDecoder.pEnd = &sDecoder.pIn[SySetUsed(&sToken)];
	sDecoder.iFlags = 0;
	sDecoder.rec_count = 0;
	/* Set a default consumer */
	sDecoder.xConsumer = VmJsonDefaultDecoder;
	sDecoder.pUserData = 0;
	/* Decode the raw JSON input */
	rc = VmJsonDecode(&sDecoder, 0);
	if( rc == SXERR_ABORT ){
		/* 
		 * Something goes wrong while decoding JSON input.Return NULL.
		 */
		jx9_result_null(pCtx);
	}
	/* Clean-up the mess left behind */
	SyLexRelease(&sLex);
	SySetRelease(&sToken);
	/* All done */
	return JX9_OK;
}
示例#2
0
文件: parse.c 项目: buaabyl/pyUnQLite
/*
 * Extract a single expression node from the input.
 * On success store the freshly extractd node in ppNode.
 * When errors, JX9 take care of generating the appropriate error message.
 * An expression node can be a variable [i.e: $var], an operator [i.e: ++] 
 * an annonymous function [i.e: function(){ return "Hello"; }, a double/single
 * quoted string, a heredoc/nowdoc, a literal [i.e: JX9_EOL], a namespace path
 * [i.e: namespaces\path\to..], a array/list [i.e: array(4, 5, 6)] and so on.
 */
static sxi32 ExprExtractNode(jx9_gen_state *pGen, jx9_expr_node **ppNode)
{
	jx9_expr_node *pNode;
	SyToken *pCur;
	sxi32 rc;
	/* Allocate a new node */
	pNode = (jx9_expr_node *)SyMemBackendPoolAlloc(&pGen->pVm->sAllocator, sizeof(jx9_expr_node));
	if( pNode == 0 ){
		/* If the supplied memory subsystem is so sick that we are unable to allocate
		 * a tiny chunk of memory, there is no much we can do here.
		 */
		return SXERR_MEM;
	}
	/* Zero the structure */
	SyZero(pNode, sizeof(jx9_expr_node));
	SySetInit(&pNode->aNodeArgs, &pGen->pVm->sAllocator, sizeof(jx9_expr_node **));
	/* Point to the head of the token stream */
	pCur = pNode->pStart = pGen->pIn;
	/* Start collecting tokens */
	if( pCur->nType & JX9_TK_OP ){
		/* Point to the instance that describe this operator */
		pNode->pOp = (const jx9_expr_op *)pCur->pUserData;
		/* Advance the stream cursor */
		pCur++;
	}else if( pCur->nType & JX9_TK_DOLLAR ){
		/* Isolate variable */
		pCur++; /* Jump the dollar sign */
		if( pCur >= pGen->pEnd ){
			/* Syntax error */
			rc = jx9GenCompileError(pGen, E_ERROR, pNode->pStart->nLine,"Invalid variable name");
			if( rc != SXERR_ABORT ){
				rc = SXERR_SYNTAX;
			}
			SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
			return rc;
		}
		pCur++; /* Jump the variable name */
		pNode->xCode = jx9CompileVariable;
	}else if( pCur->nType & JX9_TK_OCB /* '{' */ ){
		/* JSON Object, assemble tokens */
		pCur++;
		jx9DelimitNestedTokens(pCur, pGen->pEnd, JX9_TK_OCB /* '[' */, JX9_TK_CCB /* ']' */, &pCur);
		if( pCur < pGen->pEnd ){
			pCur++;
		}else{
			/* Syntax error */
			rc = jx9GenCompileError(pGen, E_ERROR, pNode->pStart->nLine,"JSON Object: Missing closing braces '}'");
			if( rc != SXERR_ABORT ){
				rc = SXERR_SYNTAX;
			}
			SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
			return rc;
		}
		pNode->xCode = jx9CompileJsonObject;
	}else if( pCur->nType & JX9_TK_OSB /* '[' */ && !(pCur->nType & JX9_TK_OP) ){
		/* JSON Array, assemble tokens */
		pCur++;
		jx9DelimitNestedTokens(pCur, pGen->pEnd, JX9_TK_OSB /* '[' */, JX9_TK_CSB /* ']' */, &pCur);
		if( pCur < pGen->pEnd ){
			pCur++;
		}else{
			/* Syntax error */
			rc = jx9GenCompileError(pGen, E_ERROR, pNode->pStart->nLine,"JSON Array: Missing closing square bracket ']'");
			if( rc != SXERR_ABORT ){
				rc = SXERR_SYNTAX;
			}
			SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
			return rc;
		}
		pNode->xCode = jx9CompileJsonArray;
	}else if( pCur->nType & JX9_TK_KEYWORD ){
		 int nKeyword = SX_PTR_TO_INT(pCur->pUserData);
		 if( nKeyword == JX9_TKWRD_FUNCTION ){
			 /* Annonymous function */
			  if( &pCur[1] >= pGen->pEnd ){
				 /* Assume a literal */
				pCur++;
				pNode->xCode = jx9CompileLiteral;
			 }else{
				 /* Assemble annonymous functions body */
				 rc = ExprAssembleAnnon(&(*pGen), &pCur, pGen->pEnd);
				 if( rc != SXRET_OK ){
					 SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
					 return rc; 
				 }
				 pNode->xCode = jx9CompileAnnonFunc;
			  }
		 }else if( jx9IsLangConstruct(nKeyword) && &pCur[1] < pGen->pEnd ){
			 /* Language constructs [i.e: print,die...] require special handling */
			 jx9DelimitNestedTokens(pCur, pGen->pEnd, JX9_TK_LPAREN|JX9_TK_OCB|JX9_TK_OSB, JX9_TK_RPAREN|JX9_TK_CCB|JX9_TK_CSB, &pCur);
			 pNode->xCode = jx9CompileLangConstruct;
		 }else{
			 /* Assume a literal */
			 pCur++;
			 pNode->xCode = jx9CompileLiteral;
		 }
	 }else if( pCur->nType & (JX9_TK_ID) ){
		 /* Constants, function name, namespace path, object name... */
		 pCur++;
		 pNode->xCode = jx9CompileLiteral;
	 }else{
		 if( (pCur->nType & (JX9_TK_LPAREN|JX9_TK_RPAREN|JX9_TK_COMMA|JX9_TK_CSB|JX9_TK_OCB|JX9_TK_CCB|JX9_TK_COLON)) == 0 ){
			 /* Point to the code generator routine */
			 pNode->xCode = jx9GetNodeHandler(pCur->nType);
			 if( pNode->xCode == 0 ){
				 rc = jx9GenCompileError(pGen, E_ERROR, pNode->pStart->nLine, "Syntax error: Unexpected token '%z'", &pNode->pStart->sData);
				 if( rc != SXERR_ABORT ){
					 rc = SXERR_SYNTAX;
				 }
				 SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode);
				 return rc;
			 }
		 }
		/* Advance the stream cursor */
		pCur++;
	 }
	/* Point to the end of the token stream */
	pNode->pEnd = pCur;
	/* Save the node for later processing */
	*ppNode = pNode;
	/* Synchronize cursors */
	pGen->pIn = pCur;
	return SXRET_OK;
}