root/ext/json/json_parser.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_json_parser_init
  2. php_json_parser_error_code
  3. php_json_parser_object_init
  4. php_json_parser_object_update
  5. php_json_parser_array_init
  6. php_json_parser_array_append
  7. php_json_yylex
  8. php_json_yyerror

   1 %code top {
   2 /*
   3   +----------------------------------------------------------------------+
   4   | PHP Version 7                                                        |
   5   +----------------------------------------------------------------------+
   6   | Copyright (c) 1997-2016 The PHP Group                                |
   7   +----------------------------------------------------------------------+
   8   | This source file is subject to version 3.01 of the PHP license,      |
   9   | that is bundled with this package in the file LICENSE, and is        |
  10   | available through the world-wide-web at the following url:           |
  11   | http://www.php.net/license/3_01.txt                                  |
  12   | If you did not receive a copy of the PHP license and are unable to   |
  13   | obtain it through the world-wide-web, please send a note to          |
  14   | license@php.net so we can mail you a copy immediately.               |
  15   +----------------------------------------------------------------------+
  16   | Author: Jakub Zelenka <bukka@php.net>                                |
  17   +----------------------------------------------------------------------+
  18 */
  19 
  20 #include "php.h"
  21 #include "php_json.h"
  22 #include "php_json_parser.h"
  23 
  24 #define YYDEBUG 0
  25 
  26 #if YYDEBUG
  27 int json_yydebug = 1;
  28 #endif
  29 
  30 #ifdef _MSC_VER
  31 #define YYMALLOC malloc
  32 #define YYFREE free
  33 #endif
  34 
  35 #define PHP_JSON_USE(uv) ((void) (uv))
  36 #define PHP_JSON_USE_1(uvr, uv1) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1)
  37 #define PHP_JSON_USE_2(uvr, uv1, uv2) PHP_JSON_USE(uvr); PHP_JSON_USE(uv1); PHP_JSON_USE(uv2)
  38 
  39 }
  40 
  41 %pure-parser
  42 %name-prefix "php_json_yy"
  43 %lex-param  { php_json_parser *parser  }
  44 %parse-param { php_json_parser *parser }
  45 
  46 %union {
  47         zval value;
  48         struct {
  49                 zend_string *key;
  50                 zval val;
  51         } pair;
  52 }
  53 
  54 
  55 %token <value> PHP_JSON_T_NUL
  56 %token <value> PHP_JSON_T_TRUE
  57 %token <value> PHP_JSON_T_FALSE
  58 %token <value> PHP_JSON_T_INT
  59 %token <value> PHP_JSON_T_DOUBLE
  60 %token <value> PHP_JSON_T_STRING
  61 %token <value> PHP_JSON_T_ESTRING
  62 %token <value> PHP_JSON_T_EOI
  63 %token <value> PHP_JSON_T_ERROR
  64 
  65 %type <value> start object key value array errlex
  66 %type <value> members member elements element
  67 %type <pair> pair
  68 
  69 %destructor { zval_dtor(&$$); } <value>
  70 %destructor { zend_string_release($$.key); zval_dtor(&$$.val); } <pair>
  71 
  72 %code {
  73 int php_json_yylex(union YYSTYPE *value, php_json_parser *parser);
  74 void php_json_yyerror(php_json_parser *parser, char const *msg);
  75 void php_json_parser_object_init(php_json_parser *parser, zval *object);
  76 int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue);
  77 void php_json_parser_array_init(zval *object);
  78 void php_json_parser_array_append(zval *array, zval *zvalue);
  79 
  80 #define PHP_JSON_DEPTH_DEC --parser->depth
  81 #define PHP_JSON_DEPTH_INC \
  82         if (parser->max_depth && parser->depth >= parser->max_depth) { \
  83                 parser->scanner.errcode = PHP_JSON_ERROR_DEPTH; \
  84                 YYERROR; \
  85         } \
  86         ++parser->depth
  87 }
  88 
  89 %% /* Rules */
  90 
  91 start:
  92                 value PHP_JSON_T_EOI
  93                         {
  94                                 ZVAL_COPY_VALUE(&$$, &$1);
  95                                 ZVAL_COPY_VALUE(parser->return_value, &$1);
  96                                 PHP_JSON_USE($2); YYACCEPT;
  97                         }
  98         |       value errlex
  99                         {
 100                                 PHP_JSON_USE_2($$, $1, $2);
 101                         }
 102 ;
 103 
 104 object:
 105                 '{' { PHP_JSON_DEPTH_INC; } members object_end
 106                         {
 107                                 PHP_JSON_DEPTH_DEC;
 108                                 $$ = $3;
 109                         }
 110 ;
 111 
 112 object_end:
 113                 '}'
 114         |       ']'
 115                         {
 116                                 parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
 117                                 YYERROR;
 118                         }
 119 ;
 120 
 121 members:
 122                 /* empty */
 123                         {
 124                                 php_json_parser_object_init(parser, &$$);
 125                         }
 126         |       member
 127 ;
 128 
 129 member:
 130                 pair
 131                         {
 132                                 php_json_parser_object_init(parser, &$$);
 133                                 if (php_json_parser_object_update(parser, &$$, $1.key, &$1.val) == FAILURE)
 134                                         YYERROR;
 135                         }
 136         |       member ',' pair
 137                         {
 138                                 if (php_json_parser_object_update(parser, &$1, $3.key, &$3.val) == FAILURE)
 139                                         YYERROR;
 140                                 ZVAL_COPY_VALUE(&$$, &$1);
 141                         }
 142         |       member errlex
 143                         {
 144                                 PHP_JSON_USE_2($$, $1, $2);
 145                         }
 146 ;
 147 
 148 pair:
 149                 key ':' value
 150                         {
 151                                 $$.key = Z_STR($1);
 152                                 ZVAL_COPY_VALUE(&$$.val, &$3);
 153                         }
 154         |       key errlex
 155                         {
 156                                 PHP_JSON_USE_2($$, $1, $2);
 157                         }
 158 ;
 159 
 160 array:
 161                 '[' { PHP_JSON_DEPTH_INC; } elements array_end
 162                         {
 163                                 PHP_JSON_DEPTH_DEC;
 164                                 ZVAL_COPY_VALUE(&$$, &$3);
 165                         }
 166 ;
 167 
 168 array_end:
 169                 ']'
 170         |       '}'
 171                         {
 172                                 parser->scanner.errcode = PHP_JSON_ERROR_STATE_MISMATCH;
 173                                 YYERROR;
 174                         }
 175 ;
 176 
 177 elements:
 178                 /* empty */
 179                         {
 180                                 php_json_parser_array_init(&$$);
 181                         }
 182         |       element
 183 ;
 184 
 185 element:
 186                 value
 187                         {
 188                                 php_json_parser_array_init(&$$);
 189                                 php_json_parser_array_append(&$$, &$1);
 190                         }
 191         |       element ',' value
 192                         {
 193                                 php_json_parser_array_append(&$1, &$3);
 194                                 ZVAL_COPY_VALUE(&$$, &$1);
 195                         }
 196         |       element errlex
 197                         {
 198                                 PHP_JSON_USE_2($$, $1, $2);
 199                         }
 200 ;
 201 
 202 key:
 203                 PHP_JSON_T_STRING
 204         |       PHP_JSON_T_ESTRING
 205 ;
 206 
 207 value:
 208                 object
 209         |       array
 210         |       PHP_JSON_T_STRING
 211         |       PHP_JSON_T_ESTRING
 212         |       PHP_JSON_T_INT
 213         |       PHP_JSON_T_DOUBLE
 214         |       PHP_JSON_T_NUL
 215         |       PHP_JSON_T_TRUE
 216         |       PHP_JSON_T_FALSE
 217         |       errlex
 218 ;
 219 
 220 errlex:
 221                 PHP_JSON_T_ERROR
 222                         {
 223                                 PHP_JSON_USE_1($$, $1);
 224                                 YYERROR;
 225                         }
 226 ;
 227         
 228 %% /* Functions */
 229 
 230 void php_json_parser_init(php_json_parser *parser, zval *return_value, char *str, size_t str_len, int options, int max_depth)
 231 {
 232         memset(parser, 0, sizeof(php_json_parser));
 233         php_json_scanner_init(&parser->scanner, str, str_len, options);
 234         parser->depth = 1;
 235         parser->max_depth = max_depth;
 236         parser->return_value = return_value;
 237 }
 238 
 239 php_json_error_code php_json_parser_error_code(php_json_parser *parser)
 240 {
 241         return parser->scanner.errcode;
 242 }
 243 
 244 void php_json_parser_object_init(php_json_parser *parser, zval *object)
 245 {
 246         if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) {
 247                 array_init(object);
 248         } else {
 249                 object_init(object);
 250         }
 251 }
 252 
 253 int php_json_parser_object_update(php_json_parser *parser, zval *object, zend_string *key, zval *zvalue)
 254 {
 255         /* if JSON_OBJECT_AS_ARRAY is set */
 256         if (Z_TYPE_P(object) == IS_ARRAY) {
 257                 zend_symtable_update(Z_ARRVAL_P(object), key, zvalue);
 258         } else {
 259                 zval zkey;
 260                 if (ZSTR_LEN(key) == 0) {
 261                         zend_string_release(key);
 262                         key = zend_string_init("_empty_", sizeof("_empty_") - 1, 0);
 263                 } else if (ZSTR_VAL(key)[0] == '\0') {
 264                         parser->scanner.errcode = PHP_JSON_ERROR_INVALID_PROPERTY_NAME;
 265                         zend_string_release(key);
 266                         zval_dtor(zvalue);
 267                         zval_dtor(object);
 268                         return FAILURE;
 269                 }
 270                 ZVAL_NEW_STR(&zkey, key);
 271                 zend_std_write_property(object, &zkey, zvalue, NULL); 
 272 
 273                 if (Z_REFCOUNTED_P(zvalue)) {
 274                         Z_DELREF_P(zvalue);
 275                 }
 276         }
 277         zend_string_release(key);
 278 
 279         return SUCCESS;
 280 }
 281 
 282 void php_json_parser_array_init(zval *array)
 283 {
 284         array_init(array);
 285 }
 286 
 287 void php_json_parser_array_append(zval *array, zval *zvalue)
 288 {
 289         zend_hash_next_index_insert(Z_ARRVAL_P(array), zvalue);
 290 }
 291         
 292 int php_json_yylex(union YYSTYPE *value, php_json_parser *parser)
 293 {
 294         int token = php_json_scan(&parser->scanner);
 295         value->value = parser->scanner.value;
 296         return token;
 297 }
 298 
 299 void php_json_yyerror(php_json_parser *parser, char const *msg)
 300 {
 301         if (!parser->scanner.errcode) {
 302                 parser->scanner.errcode = PHP_JSON_ERROR_SYNTAX;
 303         }
 304 }

/* [<][>][^][v][top][bottom][index][help] */