text: 
  /*
   +--------------------------------------------------------------------------+
   | Zephir Language                                                          |
   +--------------------------------------------------------------------------+
   | Copyright (c) 2013-2016 Zephir Team and contributors                          |
   +--------------------------------------------------------------------------+
   | This source file is subject the MIT license, that is bundled with        |
   | this package in the file LICENSE, and is available through the           |
   | world-wide-web at the following url:                                     |
   | http://zephir-lang.com/license.html                                      |
   |                                                                          |
   | If you did not receive a copy of the MIT license and are unable          |
   | to obtain it through the world-wide-web, please send a note to           |
   | license@zephir-lang.com so we can mail you a copy immediately.           |
   +--------------------------------------------------------------------------+
  */
  
  #define SUCCESS 1
  #define FAILURE 0
  
  const xx_token_names xx_tokens[] =
  {
  	{ XX_T_INTEGER,             "INTEGER" },
  	{ XX_T_DOUBLE,              "DOUBLE" },
  	{ XX_T_STRING,              "STRING" },
  	{ XX_T_IDENTIFIER,    		"IDENTIFIER" },
  	{ XX_T_AT,                  "@" },
  	{ XX_T_COMMA,               "," },
  	{ XX_T_ASSIGN,              "=" },
  	{ XX_T_COLON,               ":" },
  	{ XX_T_PARENTHESES_OPEN,    "(" },
  	{ XX_T_PARENTHESES_CLOSE,   ")" },
  	{ XX_T_BRACKET_OPEN,        "{" },
  	{ XX_T_BRACKET_CLOSE,       "}" },
   	{ XX_T_SBRACKET_OPEN,       "[" },
  	{ XX_T_SBRACKET_CLOSE,      "]" },
  	{  0, NULL }
  };
  
  #if !defined HAVE_STRNDUP && !defined __USE_XOPEN2K8
  char *strndup(const char *s, size_t len)
  {
      if (s) {
          char *ns = malloc(len + 1);
          if (ns) {
              ns[len] = 0;
              return strncpy(ns, s, len);
          }
      }
  
      return NULL;
  }
  #endif
  
  /**
   * Wrapper to alloc memory within the parser
   */
  static void *xx_wrapper_alloc(size_t bytes){
  	return malloc(bytes);
  }
  
  /**
   * Wrapper to free memory within the parser
   */
  static void xx_wrapper_free(void *pointer){
  	//free(pointer);
  }
  
  /**
   * Creates a parser_token to be passed to the parser
   */
  static void xx_parse_with_token(void* xx_parser, int opcode, int parsercode, xx_scanner_token *token, xx_parser_status *parser_status){
  
  	xx_parser_token *pToken;
  
  	pToken = malloc(sizeof(xx_parser_token));
  	pToken->opcode = opcode;
  	pToken->token = token->value;
  	pToken->token_len = token->len;
  	pToken->free_flag = 1;
  
  	xx_(xx_parser, parsercode, pToken, parser_status);
  
  	token->value = NULL;
  	token->len = 0;
  }
  
  /**
   * Creates an error message when it's triggered by the scanner
   */
  static void xx_scanner_error_msg(xx_parser_status *parser_status){
  
  	/*char *error, *error_part;
  	XX_scanner_state *state = parser_status->scanner_state;
  
  	ALLOC_INIT_ZVAL(*error_msg);
  	if (state->start) {
  		error = emalloc(sizeof(char) * (128 + state->start_length +  Z_STRLEN_P(state->active_file)));
  		if (state->start_length > 16) {
  			error_part = estrndup(state->start, 16);
  			sprintf(error, "Parsing error before '%s...' in %s on line %d", error_part, Z_STRVAL_P(state->active_file), state->active_line);
  			efree(error_part);
  		} else {
  			sprintf(error, "Parsing error before '%s' in %s on line %d", state->start, Z_STRVAL_P(state->active_file), state->active_line);
  		}
  		ZVAL_STRING(*error_msg, error, 1);
  	} else {
  		error = emalloc(sizeof(char) * (64 + Z_STRLEN_P(state->active_file)));
  		sprintf(error, "Parsing error near to EOF in %s", Z_STRVAL_P(state->active_file));
  		ZVAL_STRING(*error_msg, error, 1);
  	}
  	efree(error);*/
  }
  
  /**
   * Parses a comment returning an intermediate array representation
   */
  zval *xx_parse_program(char *program, size_t program_length, char *file_path) {
  
  	char *error;
  	xx_scanner_state *state;
  	xx_scanner_token token;
  	int scanner_status, status = SUCCESS, start_lines;
  	xx_parser_status *parser_status = NULL;
  	void* xx_parser;
  
  	/**
  	 * Check if the program has any length
  	 */
  	if (program_length < 2) {
  		return NULL;
  	}
  
  	/**
  	 * Start the reentrant parser
  	 */
  	xx_parser = xx_Alloc(xx_wrapper_alloc);
  
  	parser_status = malloc(sizeof(xx_parser_status));
  	state = malloc(sizeof(xx_scanner_state));
  
  	parser_status->status = XX_PARSING_OK;
  	parser_status->scanner_state = state;
  	parser_status->ret = NULL;
  	parser_status->token = &token;
  	parser_status->syntax_error = NULL;
  	parser_status->number_brackets = 0;
  
  	/**
  	 * Initialize the scanner state
  	 */
  	state->active_token = 0;
  	state->start = program;
  	state->start_length = 0;
  	state->active_file = file_path;
  	state->active_line = 1;
  	state->active_char = 1;
  	state->class_line = 0;
  	state->class_char = 0;
  	state->method_line = 0;
  	state->method_char = 0;
  
  	state->end = state->start;
  
  	while (0 <= (scanner_status = xx_get_token(state, &token))) {
  
  		state->active_token = token.opcode;
  
  		state->start_length = (program + program_length - state->start);
  
  		switch (token.opcode) {
  
  			case XX_T_IGNORE:
  				break;
  
  			case XX_T_NAMESPACE:
  				xx_(xx_parser, XX_NAMESPACE, NULL, parser_status);
  				break;
  			case XX_T_ABSTRACT:
  				xx_(xx_parser, XX_ABSTRACT, NULL, parser_status);
  				break;
  			case XX_T_CLASS:
  				xx_(xx_parser, XX_CLASS, NULL, parser_status);
  				break;
  			case XX_T_INTERFACE:
  				xx_(xx_parser, XX_INTERFACE, NULL, parser_status);
  				break;
  			case XX_T_EXTENDS:
  				xx_(xx_parser, XX_EXTENDS, NULL, parser_status);
  				break;
  			case XX_T_IMPLEMENTS:
  				xx_(xx_parser, XX_IMPLEMENTS, NULL, parser_status);
  				break;
  			case XX_T_PUBLIC:
  				xx_(xx_parser, XX_PUBLIC, NULL, parser_status);
  				break;
  			case XX_T_PROTECTED:
  				xx_(xx_parser, XX_PROTECTED, NULL, parser_status);
  				break;
  			case XX_T_PRIVATE:
  				xx_(xx_parser, XX_PRIVATE, NULL, parser_status);
  				break;
  			case XX_T_STATIC:
  				xx_(xx_parser, XX_STATIC, NULL, parser_status);
  				break;
  			case XX_T_INLINE:
  				xx_(xx_parser, XX_INLINE, NULL, parser_status);
  				break;
  			case XX_T_DEPRECATED:
  				xx_(xx_parser, XX_DEPRECATED, NULL, parser_status);
  				break;
  			case XX_T_FINAL:
  				xx_(xx_parser, XX_FINAL, NULL, parser_status);
  				break;
  			case XX_T_INTERNAL:
  				xx_(xx_parser, XX_INTERNAL, NULL, parser_status);
  				break;
  			case XX_T_FUNCTION:
  				xx_(xx_parser, XX_FUNCTION, NULL, parser_status);
  				break;
  			case XX_T_LET:
  				xx_(xx_parser, XX_LET, NULL, parser_status);
  				break;
  			case XX_T_ECHO:
  				xx_(xx_parser, XX_ECHO, NULL, parser_status);
  				break;
  			case XX_T_RETURN:
  				xx_(xx_parser, XX_RETURN, NULL, parser_status);
  				break;
  			case XX_T_REQUIRE:
  				xx_(xx_parser, XX_REQUIRE, NULL, parser_status);
  				break;
  			case XX_T_CLONE:
  				xx_(xx_parser, XX_CLONE, NULL, parser_status);
  				break;
  			case XX_T_EMPTY:
  				xx_(xx_parser, XX_EMPTY, NULL, parser_status);
  				break;
  			case XX_T_IF:
  				xx_(xx_parser, XX_IF, NULL, parser_status);
  				break;
  			case XX_T_ELSE:
  				xx_(xx_parser, XX_ELSE, NULL, parser_status);
  				break;
  			case XX_T_ELSEIF:
  				xx_(xx_parser, XX_ELSEIF, NULL, parser_status);
  				break;
  			case XX_T_LOOP:
  				xx_(xx_parser, XX_LOOP, NULL, parser_status);
  				break;
  			case XX_T_CONTINUE:
  				xx_(xx_parser, XX_CONTINUE, NULL, parser_status);
  				break;
  			case XX_T_BREAK:
  				xx_(xx_parser, XX_BREAK, NULL, parser_status);
  				break;
  			case XX_T_WHILE:
  				xx_(xx_parser, XX_WHILE, NULL, parser_status);
  				break;
  			case XX_T_DO:
  				xx_(xx_parser, XX_DO, NULL, parser_status);
  				break;
  			case XX_T_NEW:
  				xx_(xx_parser, XX_NEW, NULL, parser_status);
  				break;
  			case XX_T_CONST:
  				xx_(xx_parser, XX_CONST, NULL, parser_status);
  				break;
  			case XX_T_TYPEOF:
  				xx_(xx_parser, XX_TYPEOF, NULL, parser_status);
  				break;
  			case XX_T_INSTANCEOF:
  				xx_(xx_parser, XX_INSTANCEOF, NULL, parser_status);
  				break;
  			case XX_T_ISSET:
  				xx_(xx_parser, XX_ISSET, NULL, parser_status);
  				break;
  			case XX_T_UNSET:
  				xx_(xx_parser, XX_UNSET, NULL, parser_status);
  				break;
  			case XX_T_THROW:
  				xx_(xx_parser, XX_THROW, NULL, parser_status);
  				break;
  			case XX_T_FOR:
  				xx_(xx_parser, XX_FOR, NULL, parser_status);
  				break;
  			case XX_T_IN:
  				xx_(xx_parser, XX_IN, NULL, parser_status);
  				break;
  			case XX_T_REVERSE:
  				xx_(xx_parser, XX_REVERSE, NULL, parser_status);
  				break;
  			case XX_T_USE:
  				xx_(xx_parser, XX_USE, NULL, parser_status);
  				break;
  			case XX_T_AS:
  				xx_(xx_parser, XX_AS, NULL, parser_status);
  				break;
  			case XX_T_TRY:
  				xx_(xx_parser, XX_TRY, NULL, parser_status);
  				break;
  			case XX_T_CATCH:
  				xx_(xx_parser, XX_CATCH, NULL, parser_status);
  				break;
  
  			case XX_T_DOTCOMMA:
  				xx_(xx_parser, XX_DOTCOMMA, NULL, parser_status);
  				break;
  			case XX_T_COMMA:
  				xx_(xx_parser, XX_COMMA, NULL, parser_status);
  				break;
  			case XX_T_ASSIGN:
  				xx_(xx_parser, XX_ASSIGN, NULL, parser_status);
  				break;
  			case XX_T_ADDASSIGN:
  				xx_(xx_parser, XX_ADDASSIGN, NULL, parser_status);
  				break;
  			case XX_T_SUBASSIGN:
  				xx_(xx_parser, XX_SUBASSIGN, NULL, parser_status);
  				break;
  			case XX_T_DIVASSIGN:
  				xx_(xx_parser, XX_DIVASSIGN, NULL, parser_status);
  				break;
  			case XX_T_MULASSIGN:
  				xx_(xx_parser, XX_MULASSIGN, NULL, parser_status);
  				break;
  			case XX_T_CONCATASSIGN:
  				xx_(xx_parser, XX_CONCATASSIGN, NULL, parser_status);
  				break;
  			case XX_T_MODASSIGN:
  				xx_(xx_parser, XX_MODASSIGN, NULL, parser_status);
  				break;
  			case XX_T_EQUALS:
  				xx_(xx_parser, XX_EQUALS, NULL, parser_status);
  				break;
  			case XX_T_NOTEQUALS:
  				xx_(xx_parser, XX_NOTEQUALS, NULL, parser_status);
  				break;
  			case XX_T_IDENTICAL:
  				xx_(xx_parser, XX_IDENTICAL, NULL, parser_status);
  				break;
  			case XX_T_NOTIDENTICAL:
  				xx_(xx_parser, XX_NOTIDENTICAL, NULL, parser_status);
  				break;
  			case XX_T_LESS:
  				xx_(xx_parser, XX_LESS, NULL, parser_status);
  				break;
  			case XX_T_GREATER:
  				xx_(xx_parser, XX_GREATER, NULL, parser_status);
  				break;
  			case XX_T_LESSEQUAL:
  				xx_(xx_parser, XX_LESSEQUAL, NULL, parser_status);
  				break;
  			case XX_T_GREATEREQUAL:
  				xx_(xx_parser, XX_GREATEREQUAL, NULL, parser_status);
  				break;
  			case XX_T_QUESTION:
  				xx_(xx_parser, XX_QUESTION, NULL, parser_status);
  				break;
  			case XX_T_COLON:
  				xx_(xx_parser, XX_COLON, NULL, parser_status);
  				break;
  			case XX_T_ARROW:
  				xx_(xx_parser, XX_ARROW, NULL, parser_status);
  				break;
  			case XX_T_DOUBLEARROW:
  				xx_(xx_parser, XX_DOUBLEARROW, NULL, parser_status);
  				break;
  			case XX_T_DOUBLECOLON:
  				xx_(xx_parser, XX_DOUBLECOLON, NULL, parser_status);
  				break;
  			case XX_T_INCLUSIVE_RANGE:
  				xx_(xx_parser, XX_INCLUSIVE_RANGE, NULL, parser_status);
  				break;
  			case XX_T_EXCLUSIVE_RANGE:
  				xx_(xx_parser, XX_EXCLUSIVE_RANGE, NULL, parser_status);
  				break;
  			case XX_T_NOT:
  				xx_(xx_parser, XX_NOT, NULL, parser_status);
  				break;
  			case XX_T_BITWISE_NOT:
  				xx_(xx_parser, XX_BITWISE_NOT, NULL, parser_status);
  				break;
  			case XX_T_FETCH:
  				xx_(xx_parser, XX_FETCH, NULL, parser_status);
  				break;
  			case XX_T_SWITCH:
  				xx_(xx_parser, XX_SWITCH, NULL, parser_status);
  				break;
  			case XX_T_CASE:
  				xx_(xx_parser, XX_CASE, NULL, parser_status);
  				break;
  			case XX_T_DEFAULT:
  				xx_(xx_parser, XX_DEFAULT, NULL, parser_status);
  				break;
  
  			case XX_T_PARENTHESES_OPEN:
  				xx_(xx_parser, XX_PARENTHESES_OPEN, NULL, parser_status);
  				break;
  			case XX_T_PARENTHESES_CLOSE:
  				xx_(xx_parser, XX_PARENTHESES_CLOSE, NULL, parser_status);
  				break;
  
  			case XX_T_BRACKET_OPEN:
  				parser_status->number_brackets++;
  				xx_(xx_parser, XX_BRACKET_OPEN, NULL, parser_status);
  				break;
  			case XX_T_BRACKET_CLOSE:
  				parser_status->number_brackets--;
  				xx_(xx_parser, XX_BRACKET_CLOSE, NULL, parser_status);
  				break;
  
  			case XX_T_SBRACKET_OPEN:
  				xx_(xx_parser, XX_SBRACKET_OPEN, NULL, parser_status);
  				break;
  			case XX_T_SBRACKET_CLOSE:
  				xx_(xx_parser, XX_SBRACKET_CLOSE, NULL, parser_status);
  				break;
  
  			case XX_T_NULL:
  				xx_(xx_parser, XX_NULL, NULL, parser_status);
  				break;
  			case XX_T_TRUE:
  				xx_(xx_parser, XX_TRUE, NULL, parser_status);
  				break;
  			case XX_T_FALSE:
  				xx_(xx_parser, XX_FALSE, NULL, parser_status);
  				break;
  			case XX_T_COMMENT:
  				if (parser_status->number_brackets <= 1) {
  					xx_parse_with_token(xx_parser, XX_T_COMMENT, XX_COMMENT, &token, parser_status);
  				}
  				break;
  			case XX_T_CBLOCK:
  				xx_parse_with_token(xx_parser, XX_T_CBLOCK, XX_CBLOCK, &token, parser_status);
  				break;
  			case XX_T_TYPE_INTEGER:
  				xx_(xx_parser, XX_TYPE_INTEGER, NULL, parser_status);
  				break;
  			case XX_T_TYPE_UINTEGER:
  				xx_(xx_parser, XX_TYPE_UINTEGER, NULL, parser_status);
  				break;
  			case XX_T_TYPE_CHAR:
  				xx_(xx_parser, XX_TYPE_CHAR, NULL, parser_status);
  				break;
  			case XX_T_TYPE_UCHAR:
  				xx_(xx_parser, XX_TYPE_UCHAR, NULL, parser_status);
  				break;
  			case XX_T_TYPE_LONG:
  				xx_(xx_parser, XX_TYPE_LONG, NULL, parser_status);
  				break;
  			case XX_T_TYPE_ULONG:
  				xx_(xx_parser, XX_TYPE_ULONG, NULL, parser_status);
  				break;
  			case XX_T_TYPE_DOUBLE:
  				xx_(xx_parser, XX_TYPE_DOUBLE, NULL, parser_status);
  				break;
  			case XX_T_TYPE_STRING:
  				xx_(xx_parser, XX_TYPE_STRING, NULL, parser_status);
  				break;
  			case XX_T_TYPE_BOOL:
  				xx_(xx_parser, XX_TYPE_BOOL, NULL, parser_status);
  				break;
  			case XX_T_TYPE_ARRAY:
  				xx_(xx_parser, XX_TYPE_ARRAY, NULL, parser_status);
  				break;
  			case XX_T_TYPE_VAR:
  				xx_(xx_parser, XX_TYPE_VAR, NULL, parser_status);
  				break;
  		    case XX_T_TYPE_OBJECT:
                  xx_(xx_parser, XX_TYPE_OBJECT, NULL, parser_status);
                  break;
  		    case XX_T_TYPE_RESOURCE:
                  xx_(xx_parser, XX_TYPE_RESOURCE, NULL, parser_status);
                  break;
              case XX_T_TYPE_CALLABLE:
                  xx_(xx_parser, XX_TYPE_CALLABLE, NULL, parser_status);
                  break;
  
  			case XX_T_ADD:
  				xx_(xx_parser, XX_ADD, NULL, parser_status);
  				break;
  			case XX_T_SUB:
  				xx_(xx_parser, XX_SUB, NULL, parser_status);
  				break;
  			case XX_T_MUL:
  				xx_(xx_parser, XX_MUL, NULL, parser_status);
  				break;
  			case XX_T_DIV:
  				xx_(xx_parser, XX_DIV, NULL, parser_status);
  				break;
  			case XX_T_MOD:
  				xx_(xx_parser, XX_MOD, NULL, parser_status);
  				break;
  			case XX_T_DOT:
  				xx_(xx_parser, XX_CONCAT, NULL, parser_status);
  				break;
  			case XX_T_INCR:
  				xx_(xx_parser, XX_INCR, NULL, parser_status);
  				break;
  			case XX_T_DECR:
  				xx_(xx_parser, XX_DECR, NULL, parser_status);
  				break;
  			case XX_T_AND:
  				xx_(xx_parser, XX_AND, NULL, parser_status);
  				break;
  			case XX_T_OR:
  				xx_(xx_parser, XX_OR, NULL, parser_status);
  				break;
  			case XX_T_BITWISE_AND:
  				xx_(xx_parser, XX_BITWISE_AND, NULL, parser_status);
  				break;
  			case XX_T_BITWISE_OR:
  				xx_(xx_parser, XX_BITWISE_OR, NULL, parser_status);
  				break;
  			case XX_T_BITWISE_XOR:
  				xx_(xx_parser, XX_BITWISE_XOR, NULL, parser_status);
  				break;
  			case XX_T_BITWISE_SHIFTLEFT:
  				xx_(xx_parser, XX_BITWISE_SHIFTLEFT, NULL, parser_status);
  				break;
  			case XX_T_BITWISE_SHIFTRIGHT:
  				xx_(xx_parser, XX_BITWISE_SHIFTRIGHT, NULL, parser_status);
  				break;
  			case XX_T_INTEGER:
  				xx_parse_with_token(xx_parser, XX_T_INTEGER, XX_INTEGER, &token, parser_status);
  				break;
  			case XX_T_DOUBLE:
  				xx_parse_with_token(xx_parser, XX_T_DOUBLE, XX_DOUBLE, &token, parser_status);
  				break;
  			case XX_T_STRING:
  				xx_parse_with_token(xx_parser, XX_T_STRING, XX_STRING, &token, parser_status);
  				break;
  			case XX_T_ISTRING:
  				xx_parse_with_token(xx_parser, XX_T_ISTRING, XX_ISTRING, &token, parser_status);
  				break;
  			case XX_T_CHAR:
  				xx_parse_with_token(xx_parser, XX_T_CHAR, XX_CHAR, &token, parser_status);
  				break;
  			case XX_T_IDENTIFIER:
  				xx_parse_with_token(xx_parser, XX_T_IDENTIFIER, XX_IDENTIFIER, &token, parser_status);
  				break;
  			case XX_T_CONSTANT:
  				xx_parse_with_token(xx_parser, XX_T_CONSTANT, XX_CONSTANT, &token, parser_status);
  				break;
  
  			case XX_T_VOID:
  				xx_(xx_parser, XX_VOID, NULL, parser_status);
  				break;
  			case XX_T_LIKELY:
  				xx_(xx_parser, XX_LIKELY, NULL, parser_status);
  				break;
  			case XX_T_UNLIKELY:
  				xx_(xx_parser, XX_UNLIKELY, NULL, parser_status);
  				break;
  
  			default:
  				parser_status->status = XX_PARSING_FAILED;
  				fprintf(stderr, "Scanner: unknown opcode %d\n", token.opcode);
  				/*if (!*error_msg) {
  					error = emalloc(sizeof(char) * (48 + Z_STRLEN_P(state->active_file)));
  					sprintf(error, "Scanner: unknown opcode %d on in %s line %d", token.opcode, Z_STRVAL_P(state->active_file), state->active_line);
  					ALLOC_INIT_ZVAL(*error_msg);
  					ZVAL_STRING(*error_msg, error, 1);
  					efree(error);
  				}*/
  				break;
  		}
  
  		if (parser_status->status != XX_PARSING_OK) {
  			status = FAILURE;
  			break;
  		}
  
  		state->end = state->start;
  	}
  
  	if (status != FAILURE) {
  		switch (scanner_status) {
  			case XX_SCANNER_RETCODE_ERR:
  			case XX_SCANNER_RETCODE_IMPOSSIBLE:
  				{
  					char *x = malloc(sizeof(char) * 1024);
  					if (state->start) {
  						sprintf(x, "Scanner error: %d %s", scanner_status, state->start);
  					} else {
  						sprintf(x, "Scanner error: %d", scanner_status);
  					}
  					fprintf(stderr, "%s\n", x);
  					free(x);
  					status = FAILURE;
  				}
  				break;
  			default:
  				xx_(xx_parser, 0, NULL, parser_status);
  		}
  	}
  
  	state->active_token = 0;
  	state->start = NULL;
  
  	if (parser_status->status != XX_PARSING_OK) {
  		status = FAILURE;
  		/*if (parser_status->syntax_error) {
  			if (!*error_msg) {
  				ALLOC_INIT_ZVAL(*error_msg);
  				ZVAL_STRING(*error_msg, parser_status->syntax_error, 1);
  			}
  			efree(parser_status->syntax_error);
  		}*/
  		//fprintf(stderr, "error!\n");
  	}
  
  	xx_Free(xx_parser, xx_wrapper_free);
  
  	if (status != FAILURE) {
  		if (parser_status->status == XX_PARSING_OK) {
  			//printf("%s\n", json_object_to_json_string(parser_status->ret));
  			/*if (parser_status->ret) {
  				ZVAL_ZVAL(*result, parser_status->ret, 0, 0);
  				ZVAL_NULL(parser_status->ret);
  				zval_ptr_dtor(&parser_status->ret);
  			} else {
  				array_init(*result);
  			}*/
  		}
  	}
  
  	if (parser_status->ret) {
  		zval *ret_ptr = parser_status->ret;
  		free(parser_status);
  		free(state);
  		return ret_ptr;
  	}
  	free(parser_status);
  	free(state);
  	return NULL;
  }
  