1 2/* 3 +------------------------------------------------------------------------+ 4 | Phalcon Framework | 5 +------------------------------------------------------------------------+ 6 | Copyright (c) 2011-present Phalcon Team (http://www.phalconphp.com) | 7 +------------------------------------------------------------------------+ 8 | This source file is subject to the New BSD License that is bundled | 9 | with this package in the file docs/LICENSE.txt. | 10 | | 11 | If you did not receive a copy of the license and are unable to | 12 | obtain it through the world-wide-web, please send an email | 13 | to license@phalconphp.com so we can send you a copy immediately. | 14 +------------------------------------------------------------------------+ 15 | Authors: Andres Gutierrez <andres@phalconphp.com> | 16 | Eduar Carvajal <eduar@phalconphp.com> | 17 +------------------------------------------------------------------------+ 18*/ 19 20%token_prefix PHVOLT_ 21%token_type {phvolt_parser_token*} 22%default_type {zval*} 23%extra_argument {phvolt_parser_status *status} 24%name phvolt_ 25 26%right OPEN_DELIMITER . 27%left COMMA . 28%left IN . 29%left QUESTION COLON . 30%left RANGE . 31%left AND OR . 32%left IS EQUALS NOTEQUALS LESS GREATER GREATEREQUAL LESSEQUAL IDENTICAL NOTIDENTICAL . 33%left DIVIDE TIMES MOD . 34%left PLUS MINUS CONCAT . 35%right SBRACKET_OPEN . 36%left PIPE . 37%right NOT . 38%left INCR DECR . 39%right PARENTHESES_OPEN . 40%left DOT . 41 42%include { 43#include "parser.php5.inc.h" 44} 45 46%syntax_error { 47 { 48 49 smart_str error_str = {0}; 50 51 char *token_name = NULL; 52 const phvolt_token_names *tokens = phvolt_tokens; 53 int token_len = 0; 54 int active_token = status->scanner_state->active_token; 55 56 if (status->scanner_state->start_length) { 57 58 if (active_token) { 59 60 do { 61 if (tokens->code == active_token) { 62 token_name = tokens->name; 63 token_len = tokens->len; 64 break; 65 } 66 ++tokens; 67 } while (tokens[0].code != 0); 68 69 } 70 71 smart_str_appendl(&error_str, "Syntax error, unexpected token ", sizeof("Syntax error, unexpected token ") - 1); 72 if (!token_name) { 73 smart_str_appendl(&error_str, "UNKNOWN", sizeof("UNKNOWN") - 1); 74 } else { 75 smart_str_appendl(&error_str, token_name, token_len); 76 } 77 78 if (status->token->value) { 79 smart_str_appendc(&error_str, '('); 80 smart_str_appendl(&error_str, status->token->value, status->token->len); 81 smart_str_appendc(&error_str, ')'); 82 } 83 84 smart_str_appendl(&error_str, " in ", sizeof(" in ") - 1); 85 smart_str_appendl(&error_str, Z_STRVAL_P(status->scanner_state->active_file), Z_STRLEN_P(status->scanner_state->active_file)); 86 smart_str_appendl(&error_str, " on line ", sizeof(" on line ") - 1); 87 88 { 89 char stmp[MAX_LENGTH_OF_LONG + 1]; 90 int str_len; 91 str_len = slprintf(stmp, sizeof(stmp), "%ld", status->scanner_state->active_line); 92 smart_str_appendl(&error_str, stmp, str_len); 93 } 94 95 } else { 96 97 smart_str_appendl(&error_str, "Syntax error, unexpected EOF in ", sizeof("Syntax error, unexpected EOF in ") - 1); 98 smart_str_appendl(&error_str, Z_STRVAL_P(status->scanner_state->active_file), Z_STRLEN_P(status->scanner_state->active_file)); 99 100 /* Report unclosed 'if' blocks */ 101 if ((status->scanner_state->if_level + status->scanner_state->old_if_level) > 0) { 102 if ((status->scanner_state->if_level + status->scanner_state->old_if_level) == 1) { 103 smart_str_appendl(&error_str, ", there is one 'if' block without close", sizeof(", there is one 'if' block without close") - 1); 104 } else { 105 smart_str_appendl(&error_str, ", there are ", sizeof(", there are ") - 1); 106 { 107 char stmp[MAX_LENGTH_OF_LONG + 1]; 108 int str_len; 109 str_len = slprintf(stmp, sizeof(stmp), "%ld", status->scanner_state->if_level + status->scanner_state->old_if_level); 110 smart_str_appendl(&error_str, stmp, str_len); 111 } 112 smart_str_appendl(&error_str, " 'if' blocks without close", sizeof(" 'if' blocks without close") - 1); 113 } 114 } 115 116 /* Report unclosed 'for' blocks */ 117 if (status->scanner_state->for_level > 0) { 118 if (status->scanner_state->for_level == 1) { 119 smart_str_appendl(&error_str, ", there is one 'for' block without close", sizeof(", there is one 'for' block without close") - 1); 120 } else { 121 smart_str_appendl(&error_str, ", there are ", sizeof(", there are ") - 1); 122 { 123 char stmp[MAX_LENGTH_OF_LONG + 1]; 124 int str_len; 125 str_len = slprintf(stmp, sizeof(stmp), "%ld", status->scanner_state->if_level); 126 smart_str_appendl(&error_str, stmp, str_len); 127 } 128 smart_str_appendl(&error_str, " 'for' blocks without close", sizeof(" 'for' blocks without close") - 1); 129 } 130 } 131 132 /* Report unclosed 'switch' blocks */ 133 if (status->scanner_state->switch_level > 0) { 134 smart_str_appendl(&error_str, ", there is a 'switch' block without 'endswitch'", sizeof(", there is a 'switch' block without 'endswitch'") - 1); 135 } 136 137 } 138 139 smart_str_0(&error_str); 140 141#if PHP_VERSION_ID < 70000 142 if (error_str.len) { 143 status->syntax_error = error_str.c; 144 status->syntax_error_len = error_str.len; 145 } else { 146 status->syntax_error = NULL; 147 } 148#else 149 if (error_str.s) { 150 status->syntax_error = estrndup(ZSTR_VAL(error_str.s), ZSTR_LEN(error_str.s)); 151 status->syntax_error_len = ZSTR_LEN(error_str.s); 152 } else { 153 status->syntax_error = NULL; 154 } 155#endif 156 } 157 158 status->status = PHVOLT_PARSING_FAILED; 159} 160 161%token_destructor { 162 if ($$) { 163 if ($$->free_flag) { 164 efree($$->token); 165 } 166 efree($$); 167 } 168} 169 170program ::= volt_language(Q) . { 171 status->ret = Q; 172} 173 174volt_language(R) ::= statement_list(L) . { 175 R = L; 176} 177 178%destructor statement_list { 179#if PHP_VERSION_ID < 70000 180 zval_ptr_dtor(&$$); 181#endif 182} 183 184statement_list(R) ::= statement_list(L) statement(S) . { 185 R = phvolt_ret_zval_list(L, S); 186} 187 188statement_list(R) ::= statement(S) . { 189 R = phvolt_ret_zval_list(NULL, S); 190} 191 192%destructor statement { 193#if PHP_VERSION_ID < 70000 194 zval_ptr_dtor(&$$); 195#endif 196} 197 198statement(R) ::= raw_fragment(F) . { 199 R = F; 200} 201 202statement(R) ::= if_statement(I) . { 203 R = I; 204} 205 206statement(R) ::= elseif_statement(E) . { 207 R = E; 208} 209 210statement(R) ::= elsefor_statement(E) . { 211 R = E; 212} 213 214statement(R) ::= for_statement(E) . { 215 R = E; 216} 217 218statement(R) ::= switch_statement(E) . { 219 R = E; 220} 221 222statement(R) ::= case_clause(E) . { 223 R = E; 224} 225 226statement(R) ::= set_statement(S) . { 227 R = S; 228} 229 230statement(R) ::= echo_statement(E) . { 231 R = E; 232} 233 234statement(R) ::= block_statement(E) . { 235 R = E; 236} 237 238statement(R) ::= cache_statement(E) . { 239 R = E; 240} 241 242statement(R) ::= extends_statement(E) . { 243 R = E; 244} 245 246statement(R) ::= include_statement(E) . { 247 R = E; 248} 249 250statement(R) ::= do_statement(E) . { 251 R = E; 252} 253 254statement(R) ::= return_statement(E) . { 255 R = E; 256} 257 258statement(R) ::= autoescape_statement(E) . { 259 R = E; 260} 261 262statement(R) ::= raw_statement(E) . { 263 R = E; 264} 265 266statement(R) ::= break_statement(E) . { 267 R = E; 268} 269 270statement(R) ::= continue_statement(E) . { 271 R = E; 272} 273 274statement(R) ::= macro_statement(E) . { 275 R = E; 276} 277 278statement(R) ::= empty_statement(E) . { 279 R = E; 280} 281 282statement(R) ::= macro_call_statement(E) . { 283 R = E; 284} 285 286%destructor if_statement { 287#if PHP_VERSION_ID < 70000 288 zval_ptr_dtor(&$$); 289#endif 290} 291 292/* {% if EXPR %} STMT {% endif %} */ 293if_statement(R) ::= OPEN_DELIMITER IF expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDIF CLOSE_DELIMITER . { 294 R = phvolt_ret_if_statement(E, T, NULL, status->scanner_state); 295} 296 297/* {% if EXPR %} {% endif %} */ 298if_statement(R) ::= OPEN_DELIMITER IF expr(E) CLOSE_DELIMITER OPEN_DELIMITER ENDIF CLOSE_DELIMITER . { 299 R = phvolt_ret_if_statement(E, NULL, NULL, status->scanner_state); 300} 301 302/* {% if EXPR %} STMT {% esle %} STMT {% endif %} */ 303if_statement(R) ::= OPEN_DELIMITER IF expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ELSE CLOSE_DELIMITER statement_list(F) OPEN_DELIMITER ENDIF CLOSE_DELIMITER . { 304 R = phvolt_ret_if_statement(E, T, F, status->scanner_state); 305} 306 307/* {% if EXPR %} STMT {% esle %} {% endif %} */ 308if_statement(R) ::= OPEN_DELIMITER IF expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ELSE CLOSE_DELIMITER OPEN_DELIMITER ENDIF CLOSE_DELIMITER . { 309 R = phvolt_ret_if_statement(E, T, NULL, status->scanner_state); 310} 311 312/* {% if EXPR %} {% esle %} {% endif %} */ 313if_statement(R) ::= OPEN_DELIMITER IF expr(E) CLOSE_DELIMITER OPEN_DELIMITER ELSE CLOSE_DELIMITER OPEN_DELIMITER ENDIF CLOSE_DELIMITER . { 314 R = phvolt_ret_if_statement(E, NULL, NULL, status->scanner_state); 315} 316 317%destructor elseif_statement { 318#if PHP_VERSION_ID < 70000 319 zval_ptr_dtor(&$$); 320#endif 321} 322 323elseif_statement(R) ::= OPEN_DELIMITER ELSEIF expr(E) CLOSE_DELIMITER . { 324 R = phvolt_ret_elseif_statement(E, status->scanner_state); 325} 326 327%destructor elsefor_statement { 328#if PHP_VERSION_ID < 70000 329 zval_ptr_dtor(&$$); 330#endif 331} 332 333elsefor_statement(R) ::= OPEN_DELIMITER ELSEFOR CLOSE_DELIMITER . { 334 R = phvolt_ret_elsefor_statement(status->scanner_state); 335} 336 337%destructor for_statement { 338#if PHP_VERSION_ID < 70000 339 zval_ptr_dtor(&$$); 340#endif 341} 342 343for_statement(R) ::= OPEN_DELIMITER FOR IDENTIFIER(I) IN expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDFOR CLOSE_DELIMITER . { 344 R = phvolt_ret_for_statement(I, NULL, E, NULL, T, status->scanner_state); 345} 346 347for_statement(R) ::= OPEN_DELIMITER FOR IDENTIFIER(I) IN expr(E) IF expr(IE) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDFOR CLOSE_DELIMITER . { 348 R = phvolt_ret_for_statement(I, NULL, E, IE, T, status->scanner_state); 349} 350 351for_statement(R) ::= OPEN_DELIMITER FOR IDENTIFIER(K) COMMA IDENTIFIER(V) IN expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDFOR CLOSE_DELIMITER . { 352 R = phvolt_ret_for_statement(V, K, E, NULL, T, status->scanner_state); 353} 354 355for_statement(R) ::= OPEN_DELIMITER FOR IDENTIFIER(K) COMMA IDENTIFIER(V) IN expr(E) IF expr(IE) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDFOR CLOSE_DELIMITER . { 356 R = phvolt_ret_for_statement(V, K, E, IE, T, status->scanner_state); 357} 358 359%destructor switch_statement { 360#if PHP_VERSION_ID < 70000 361 zval_ptr_dtor(&$$); 362#endif 363} 364 365/* {% switch EXPR %} STMT {% endswitch %} */ 366switch_statement(R) ::= OPEN_DELIMITER SWITCH expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDSWITCH CLOSE_DELIMITER . { 367 R = phvolt_ret_switch_statement(E, T, status->scanner_state); 368} 369 370/* {% switch EXPR %} {% endswitch %} */ 371switch_statement(R) ::= OPEN_DELIMITER SWITCH expr(E) CLOSE_DELIMITER OPEN_DELIMITER ENDSWITCH CLOSE_DELIMITER . { 372 R = phvolt_ret_switch_statement(E, NULL, status->scanner_state); 373} 374 375%destructor case_clause { 376#if PHP_VERSION_ID < 70000 377 zval_ptr_dtor(&$$); 378#endif 379} 380 381/* {% case EXPR %} {% endcase %} */ 382case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER . { 383 R = phvolt_ret_case_clause(E, status->scanner_state); 384} 385 386/* {% default %} */ 387case_clause(R) ::= OPEN_DELIMITER DEFAULT CLOSE_DELIMITER . { 388 R = phvolt_ret_case_clause(NULL, status->scanner_state); 389} 390 391%destructor set_statement { 392#if PHP_VERSION_ID < 70000 393 zval_ptr_dtor(&$$); 394#endif 395} 396 397set_statement(R) ::= OPEN_DELIMITER SET set_assignments(L) CLOSE_DELIMITER . { 398 R = phvolt_ret_set_statement(L); 399} 400 401%destructor set_assignments { 402#if PHP_VERSION_ID < 70000 403 zval_ptr_dtor(&$$); 404#endif 405} 406 407set_assignments(R) ::= set_assignments(L) COMMA set_assignment(S) . { 408 R = phvolt_ret_zval_list(L, S); 409} 410 411set_assignments(R) ::= set_assignment(S) . { 412 R = phvolt_ret_zval_list(NULL, S); 413} 414 415%destructor set_assignment { 416#if PHP_VERSION_ID < 70000 417 zval_ptr_dtor(&$$); 418#endif 419} 420 421set_assignment(R) ::= assignable_expr(I) ASSIGN expr(E) . { 422 R = phvolt_ret_set_assignment(I, PHVOLT_T_ASSIGN, E, status->scanner_state); 423} 424 425set_assignment(R) ::= assignable_expr(I) ADD_ASSIGN expr(E) . { 426 R = phvolt_ret_set_assignment(I, PHVOLT_T_ADD_ASSIGN, E, status->scanner_state); 427} 428 429set_assignment(R) ::= assignable_expr(I) SUB_ASSIGN expr(E) . { 430 R = phvolt_ret_set_assignment(I, PHVOLT_T_SUB_ASSIGN, E, status->scanner_state); 431} 432 433set_assignment(R) ::= assignable_expr(I) MUL_ASSIGN expr(E) . { 434 R = phvolt_ret_set_assignment(I, PHVOLT_T_MUL_ASSIGN, E, status->scanner_state); 435} 436 437set_assignment(R) ::= assignable_expr(I) DIV_ASSIGN expr(E) . { 438 R = phvolt_ret_set_assignment(I, PHVOLT_T_DIV_ASSIGN, E, status->scanner_state); 439} 440 441assignable_expr(R) ::= IDENTIFIER(I) . { 442 R = phvolt_ret_literal_zval(PHVOLT_T_IDENTIFIER, I, status->scanner_state); 443} 444 445assignable_expr(R) ::= assignable_expr(E) SBRACKET_OPEN expr(D) SBRACKET_CLOSE . { 446 R = phvolt_ret_expr(PHVOLT_T_ARRAYACCESS, E, D, NULL, status->scanner_state); 447} 448 449assignable_expr(R) ::= assignable_expr(E) DOT assignable_expr(D) . { 450 R = phvolt_ret_expr(PHVOLT_T_DOT, E, D, NULL, status->scanner_state); 451} 452 453%destructor macro_statement { 454#if PHP_VERSION_ID < 70000 455 zval_ptr_dtor(&$$); 456#endif 457} 458 459macro_statement(R) ::= OPEN_DELIMITER MACRO IDENTIFIER(I) PARENTHESES_OPEN PARENTHESES_CLOSE CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDMACRO CLOSE_DELIMITER . { 460 R = phvolt_ret_macro_statement(I, NULL, T, status->scanner_state); 461} 462 463macro_statement(R) ::= OPEN_DELIMITER MACRO IDENTIFIER(I) PARENTHESES_OPEN macro_parameters(P) PARENTHESES_CLOSE CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDMACRO CLOSE_DELIMITER . { 464 R = phvolt_ret_macro_statement(I, P, T, status->scanner_state); 465} 466 467%destructor macro_parameters { 468#if PHP_VERSION_ID < 70000 469 zval_ptr_dtor(&$$); 470#endif 471} 472 473macro_parameters(R) ::= macro_parameters(L) COMMA macro_parameter(I) . { 474 R = phvolt_ret_zval_list(L, I); 475} 476 477macro_parameters(R) ::= macro_parameter(I) . { 478 R = phvolt_ret_zval_list(NULL, I); 479} 480 481%destructor macro_parameter { 482#if PHP_VERSION_ID < 70000 483 zval_ptr_dtor(&$$); 484#endif 485} 486 487macro_parameter(R) ::= IDENTIFIER(I) . { 488 R = phvolt_ret_macro_parameter(I, NULL, status->scanner_state); 489} 490 491macro_parameter(R) ::= IDENTIFIER(I) ASSIGN macro_parameter_default(D) . { 492 R = phvolt_ret_macro_parameter(I, D, status->scanner_state); 493} 494 495macro_parameter_default(R) ::= INTEGER(I) . { 496 R = phvolt_ret_literal_zval(PHVOLT_T_INTEGER, I, status->scanner_state); 497} 498 499macro_parameter_default(R) ::= STRING(S) . { 500 R = phvolt_ret_literal_zval(PHVOLT_T_STRING, S, status->scanner_state); 501} 502 503macro_parameter_default(R) ::= DOUBLE(D) . { 504 R = phvolt_ret_literal_zval(PHVOLT_T_DOUBLE, D, status->scanner_state); 505} 506 507macro_parameter_default(R) ::= NULL . { 508 R = phvolt_ret_literal_zval(PHVOLT_T_NULL, NULL, status->scanner_state); 509} 510 511macro_parameter_default(R) ::= FALSE . { 512 R = phvolt_ret_literal_zval(PHVOLT_T_FALSE, NULL, status->scanner_state); 513} 514 515macro_parameter_default(R) ::= TRUE . { 516 R = phvolt_ret_literal_zval(PHVOLT_T_TRUE, NULL, status->scanner_state); 517} 518 519%destructor macro_call_statement { 520#if PHP_VERSION_ID < 70000 521 zval_ptr_dtor(&$$); 522#endif 523} 524 525macro_call_statement(R) ::= OPEN_DELIMITER CALL expr(E) PARENTHESES_OPEN argument_list(L) PARENTHESES_CLOSE CLOSE_DELIMITER statement_list(C) OPEN_DELIMITER ENDCALL CLOSE_DELIMITER . { 526 R = phvolt_ret_macro_call_statement(E, L, C, status->scanner_state); 527} 528 529macro_call_statement(R) ::= OPEN_DELIMITER CALL expr(E) PARENTHESES_OPEN PARENTHESES_CLOSE CLOSE_DELIMITER OPEN_DELIMITER ENDCALL CLOSE_DELIMITER . { 530 R = phvolt_ret_macro_call_statement(E, NULL, NULL, status->scanner_state); 531} 532 533%destructor empty_statement { 534#if PHP_VERSION_ID < 70000 535 zval_ptr_dtor(&$$); 536#endif 537} 538 539empty_statement(R) ::= OPEN_DELIMITER CLOSE_DELIMITER . { 540 R = phvolt_ret_empty_statement(status->scanner_state); 541} 542 543%destructor echo_statement { 544#if PHP_VERSION_ID < 70000 545 zval_ptr_dtor(&$$); 546#endif 547} 548 549echo_statement(R) ::= OPEN_EDELIMITER expr(E) CLOSE_EDELIMITER . { 550 R = phvolt_ret_echo_statement(E, status->scanner_state); 551} 552 553%destructor block_statement { 554#if PHP_VERSION_ID < 70000 555 zval_ptr_dtor(&$$); 556#endif 557} 558 559block_statement(R) ::= OPEN_DELIMITER BLOCK IDENTIFIER(I) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDBLOCK CLOSE_DELIMITER . { 560 R = phvolt_ret_block_statement(I, T, status->scanner_state); 561} 562 563block_statement(R) ::= OPEN_DELIMITER BLOCK IDENTIFIER(I) CLOSE_DELIMITER OPEN_DELIMITER ENDBLOCK CLOSE_DELIMITER . { 564 R = phvolt_ret_block_statement(I, NULL, status->scanner_state); 565} 566 567%destructor cache_statement { 568#if PHP_VERSION_ID < 70000 569 zval_ptr_dtor(&$$); 570#endif 571} 572 573cache_statement(R) ::= OPEN_DELIMITER CACHE expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDCACHE CLOSE_DELIMITER . { 574 R = phvolt_ret_cache_statement(E, NULL, T, status->scanner_state); 575} 576 577cache_statement(R) ::= OPEN_DELIMITER CACHE expr(E) cache_lifetime(N) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDCACHE CLOSE_DELIMITER . { 578 R = phvolt_ret_cache_statement(E, N, T, status->scanner_state); 579} 580 581%destructor cache_lifetime { 582#if PHP_VERSION_ID < 70000 583 zval_ptr_dtor(&$$); 584#endif 585} 586 587cache_lifetime(R) ::= INTEGER(I) . { 588 R = phvolt_ret_literal_zval(PHVOLT_T_INTEGER, I, status->scanner_state); 589} 590 591cache_lifetime(R) ::= IDENTIFIER(I) . { 592 R = phvolt_ret_literal_zval(PHVOLT_T_IDENTIFIER, I, status->scanner_state); 593} 594 595%destructor raw_statement { 596#if PHP_VERSION_ID < 70000 597 zval_ptr_dtor(&$$); 598#endif 599} 600 601raw_statement(R) ::= OPEN_DELIMITER RAW CLOSE_DELIMITER statement(T) OPEN_DELIMITER ENDRAW CLOSE_DELIMITER . { 602 R = phvolt_ret_raw_statement(T, status->scanner_state); 603} 604 605%destructor extends_statement { 606#if PHP_VERSION_ID < 70000 607 zval_ptr_dtor(&$$); 608#endif 609} 610 611extends_statement(R) ::= OPEN_DELIMITER EXTENDS expr(S) CLOSE_DELIMITER . { 612 R = phvolt_ret_extends_statement(S, status->scanner_state); 613} 614 615%destructor include_statement { 616#if PHP_VERSION_ID < 70000 617 zval_ptr_dtor(&$$); 618#endif 619} 620 621include_statement(R) ::= OPEN_DELIMITER INCLUDE expr(E) CLOSE_DELIMITER . { 622 R = phvolt_ret_include_statement(E, NULL, status->scanner_state); 623} 624 625include_statement(R) ::= OPEN_DELIMITER INCLUDE expr(E) WITH expr(P) CLOSE_DELIMITER . { 626 R = phvolt_ret_include_statement(E, P, status->scanner_state); 627} 628 629%destructor do_statement { 630#if PHP_VERSION_ID < 70000 631 zval_ptr_dtor(&$$); 632#endif 633} 634 635do_statement(R) ::= OPEN_DELIMITER DO expr(E) CLOSE_DELIMITER . { 636 R = phvolt_ret_do_statement(E, status->scanner_state); 637} 638 639%destructor return_statement { 640#if PHP_VERSION_ID < 70000 641 zval_ptr_dtor(&$$); 642#endif 643} 644 645return_statement(R) ::= OPEN_DELIMITER RETURN expr(E) CLOSE_DELIMITER . { 646 R = phvolt_ret_return_statement(E, status->scanner_state); 647} 648 649%destructor autoescape_statement { 650#if PHP_VERSION_ID < 70000 651 zval_ptr_dtor(&$$); 652#endif 653} 654 655autoescape_statement(R) ::= OPEN_DELIMITER AUTOESCAPE FALSE CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDAUTOESCAPE CLOSE_DELIMITER . { 656 R = phvolt_ret_autoescape_statement(0, T, status->scanner_state); 657} 658 659autoescape_statement(R) ::= OPEN_DELIMITER AUTOESCAPE TRUE CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDAUTOESCAPE CLOSE_DELIMITER . { 660 R = phvolt_ret_autoescape_statement(1, T, status->scanner_state); 661} 662 663%destructor break_statement { 664#if PHP_VERSION_ID < 70000 665 zval_ptr_dtor(&$$); 666#endif 667} 668 669break_statement(R) ::= OPEN_DELIMITER BREAK CLOSE_DELIMITER . { 670 R = phvolt_ret_break_statement(status->scanner_state); 671} 672 673%destructor continue_statement { 674#if PHP_VERSION_ID < 70000 675 zval_ptr_dtor(&$$); 676#endif 677} 678 679continue_statement(R) ::= OPEN_DELIMITER CONTINUE CLOSE_DELIMITER . { 680 R = phvolt_ret_continue_statement(status->scanner_state); 681} 682 683%destructor raw_fragment { 684#if PHP_VERSION_ID < 70000 685 zval_ptr_dtor(&$$); 686#endif 687} 688 689raw_fragment(R) ::= RAW_FRAGMENT(F) . { 690 R = phvolt_ret_literal_zval(PHVOLT_T_RAW_FRAGMENT, F, status->scanner_state); 691} 692 693%destructor expr { 694#if PHP_VERSION_ID < 70000 695 zval_ptr_dtor(&$$); 696#endif 697} 698 699expr(R) ::= MINUS expr(E) . { 700 R = phvolt_ret_expr(PHVOLT_T_MINUS, NULL, E, NULL, status->scanner_state); 701} 702 703expr(R) ::= PLUS expr(E) . { 704 R = phvolt_ret_expr(PHVOLT_T_PLUS, NULL, E, NULL, status->scanner_state); 705} 706 707expr(R) ::= expr(O1) MINUS expr(O2) . { 708 R = phvolt_ret_expr(PHVOLT_T_SUB, O1, O2, NULL, status->scanner_state); 709} 710 711expr(R) ::= expr(O1) PLUS expr(O2) . { 712 R = phvolt_ret_expr(PHVOLT_T_ADD, O1, O2, NULL, status->scanner_state); 713} 714 715expr(R) ::= expr(O1) TIMES expr(O2) . { 716 R = phvolt_ret_expr(PHVOLT_T_MUL, O1, O2, NULL, status->scanner_state); 717} 718 719expr(R) ::= expr(O1) TIMES TIMES expr(O2) . { 720 R = phvolt_ret_expr(PHVOLT_T_POW, O1, O2, NULL, status->scanner_state); 721} 722 723expr(R) ::= expr(O1) DIVIDE expr(O2) . { 724 R = phvolt_ret_expr(PHVOLT_T_DIV, O1, O2, NULL, status->scanner_state); 725} 726 727expr(R) ::= expr(O1) DIVIDE DIVIDE expr(O2) . { 728 R = phvolt_ret_expr(PHVOLT_T_MOD, O1, O2, NULL, status->scanner_state); 729} 730 731expr(R) ::= expr(O1) MOD expr(O2) . { 732 R = phvolt_ret_expr(PHVOLT_T_MOD, O1, O2, NULL, status->scanner_state); 733} 734 735expr(R) ::= expr(O1) AND expr(O2) . { 736 R = phvolt_ret_expr(PHVOLT_T_AND, O1, O2, NULL, status->scanner_state); 737} 738 739expr(R) ::= expr(O1) OR expr(O2) . { 740 R = phvolt_ret_expr(PHVOLT_T_OR, O1, O2, NULL, status->scanner_state); 741} 742 743expr(R) ::= expr(O1) CONCAT expr(O2) . { 744 R = phvolt_ret_expr(PHVOLT_T_CONCAT, O1, O2, NULL, status->scanner_state); 745} 746 747expr(R) ::= expr(O1) PIPE expr(O2) . { 748 R = phvolt_ret_expr(PHVOLT_T_PIPE, O1, O2, NULL, status->scanner_state); 749} 750 751expr(R) ::= expr(O1) RANGE expr(O2) . { 752 R = phvolt_ret_expr(PHVOLT_T_RANGE, O1, O2, NULL, status->scanner_state); 753} 754 755expr(R) ::= expr(O1) EQUALS expr(O2) . { 756 R = phvolt_ret_expr(PHVOLT_T_EQUALS, O1, O2, NULL, status->scanner_state); 757} 758 759expr(R) ::= expr(O1) NOTEQUALS DEFINED . { 760 R = phvolt_ret_expr(PHVOLT_T_NOT_ISSET, O1, NULL, NULL, status->scanner_state); 761} 762 763expr(R) ::= expr(O1) IS DEFINED . { 764 R = phvolt_ret_expr(PHVOLT_T_ISSET, O1, NULL, NULL, status->scanner_state); 765} 766 767expr(R) ::= expr(O1) NOTEQUALS EMPTY . { 768 R = phvolt_ret_expr(PHVOLT_T_NOT_ISEMPTY, O1, NULL, NULL, status->scanner_state); 769} 770 771expr(R) ::= expr(O1) IS EMPTY . { 772 R = phvolt_ret_expr(PHVOLT_T_ISEMPTY, O1, NULL, NULL, status->scanner_state); 773} 774 775expr(R) ::= expr(O1) NOTEQUALS EVEN . { 776 R = phvolt_ret_expr(PHVOLT_T_NOT_ISEVEN, O1, NULL, NULL, status->scanner_state); 777} 778 779expr(R) ::= expr(O1) IS EVEN . { 780 R = phvolt_ret_expr(PHVOLT_T_ISEVEN, O1, NULL, NULL, status->scanner_state); 781} 782 783expr(R) ::= expr(O1) NOTEQUALS ODD . { 784 R = phvolt_ret_expr(PHVOLT_T_NOT_ISODD, O1, NULL, NULL, status->scanner_state); 785} 786 787expr(R) ::= expr(O1) IS ODD . { 788 R = phvolt_ret_expr(PHVOLT_T_ISODD, O1, NULL, NULL, status->scanner_state); 789} 790 791expr(R) ::= expr(O1) NOTEQUALS NUMERIC . { 792 R = phvolt_ret_expr(PHVOLT_T_NOT_ISNUMERIC, O1, NULL, NULL, status->scanner_state); 793} 794 795expr(R) ::= expr(O1) IS NUMERIC . { 796 R = phvolt_ret_expr(PHVOLT_T_ISNUMERIC, O1, NULL, NULL, status->scanner_state); 797} 798 799expr(R) ::= expr(O1) NOTEQUALS SCALAR . { 800 R = phvolt_ret_expr(PHVOLT_T_NOT_ISSCALAR, O1, NULL, NULL, status->scanner_state); 801} 802 803expr(R) ::= expr(O1) IS SCALAR . { 804 R = phvolt_ret_expr(PHVOLT_T_ISSCALAR, O1, NULL, NULL, status->scanner_state); 805} 806 807expr(R) ::= expr(O1) NOTEQUALS ITERABLE . { 808 R = phvolt_ret_expr(PHVOLT_T_NOT_ISITERABLE, O1, NULL, NULL, status->scanner_state); 809} 810 811expr(R) ::= expr(O1) IS ITERABLE . { 812 R = phvolt_ret_expr(PHVOLT_T_ISITERABLE, O1, NULL, NULL, status->scanner_state); 813} 814 815expr(R) ::= expr(O1) IS expr(O2) . { 816 R = phvolt_ret_expr(PHVOLT_T_IS, O1, O2, NULL, status->scanner_state); 817} 818 819expr(R) ::= expr(O1) NOTEQUALS expr(O2) . { 820 R = phvolt_ret_expr(PHVOLT_T_NOTEQUALS, O1, O2, NULL, status->scanner_state); 821} 822 823expr(R) ::= expr(O1) IDENTICAL expr(O2) . { 824 R = phvolt_ret_expr(PHVOLT_T_IDENTICAL, O1, O2, NULL, status->scanner_state); 825} 826 827expr(R) ::= expr(O1) NOTIDENTICAL expr(O2) . { 828 R = phvolt_ret_expr(PHVOLT_T_NOTIDENTICAL, O1, O2, NULL, status->scanner_state); 829} 830 831expr(R) ::= expr(O1) LESS expr(O2) . { 832 R = phvolt_ret_expr(PHVOLT_T_LESS, O1, O2, NULL, status->scanner_state); 833} 834 835expr(R) ::= expr(O1) GREATER expr(O2) . { 836 R = phvolt_ret_expr(PHVOLT_T_GREATER, O1, O2, NULL, status->scanner_state); 837} 838 839expr(R) ::= expr(O1) GREATEREQUAL expr(O2) . { 840 R = phvolt_ret_expr(PHVOLT_T_GREATEREQUAL, O1, O2, NULL, status->scanner_state); 841} 842 843expr(R) ::= expr(O1) LESSEQUAL expr(O2) . { 844 R = phvolt_ret_expr(PHVOLT_T_LESSEQUAL, O1, O2, NULL, status->scanner_state); 845} 846 847expr(R) ::= expr(O1) DOT expr(O2) . { 848 R = phvolt_ret_expr(PHVOLT_T_DOT, O1, O2, NULL, status->scanner_state); 849} 850 851expr(R) ::= expr(O1) IN expr(O2) . { 852 R = phvolt_ret_expr(PHVOLT_T_IN, O1, O2, NULL, status->scanner_state); 853} 854 855expr(R) ::= expr(O1) NOT IN expr(O2) . { 856 R = phvolt_ret_expr(PHVOLT_T_NOT_IN, O1, O2, NULL, status->scanner_state); 857} 858 859expr(R) ::= NOT expr(E) . { 860 R = phvolt_ret_expr(PHVOLT_T_NOT, NULL, E, NULL, status->scanner_state); 861} 862 863expr(R) ::= expr(E) INCR . { 864 R = phvolt_ret_expr(PHVOLT_T_INCR, E, NULL, NULL, status->scanner_state); 865} 866 867expr(R) ::= expr(E) DECR . { 868 R = phvolt_ret_expr(PHVOLT_T_DECR, E, NULL, NULL, status->scanner_state); 869} 870 871expr(R) ::= PARENTHESES_OPEN expr(E) PARENTHESES_CLOSE . { 872 R = phvolt_ret_expr(PHVOLT_T_ENCLOSED, E, NULL, NULL, status->scanner_state); 873} 874 875expr(R) ::= SBRACKET_OPEN SBRACKET_CLOSE . { 876 R = phvolt_ret_expr(PHVOLT_T_ARRAY, NULL, NULL, NULL, status->scanner_state); 877} 878 879expr(R) ::= SBRACKET_OPEN array_list(A) SBRACKET_CLOSE . { 880 R = phvolt_ret_expr(PHVOLT_T_ARRAY, A, NULL, NULL, status->scanner_state); 881} 882 883expr(R) ::= CBRACKET_OPEN CBRACKET_CLOSE . { 884 R = phvolt_ret_expr(PHVOLT_T_ARRAY, NULL, NULL, NULL, status->scanner_state); 885} 886 887expr(R) ::= CBRACKET_OPEN array_list(A) CBRACKET_CLOSE . { 888 R = phvolt_ret_expr(PHVOLT_T_ARRAY, A, NULL, NULL, status->scanner_state); 889} 890 891expr(R) ::= expr(E) SBRACKET_OPEN expr(D) SBRACKET_CLOSE . { 892 R = phvolt_ret_expr(PHVOLT_T_ARRAYACCESS, E, D, NULL, status->scanner_state); 893} 894 895expr(R) ::= expr(E) QUESTION expr(O1) COLON expr(O2) . { 896 R = phvolt_ret_expr(PHVOLT_T_TERNARY, O1, O2, E, status->scanner_state); 897} 898 899expr(R) ::= expr(E) SBRACKET_OPEN COLON slice_offset(N) SBRACKET_CLOSE . { 900 R = phvolt_ret_slice(E, NULL, N, status->scanner_state); 901} 902 903expr(R) ::= expr(E) SBRACKET_OPEN slice_offset(S) COLON SBRACKET_CLOSE . { 904 R = phvolt_ret_slice(E, S, NULL, status->scanner_state); 905} 906 907expr(R) ::= expr(E) SBRACKET_OPEN slice_offset(S) COLON slice_offset(N) SBRACKET_CLOSE . { 908 R = phvolt_ret_slice(E, S, N, status->scanner_state); 909} 910 911%destructor slice_offset { 912#if PHP_VERSION_ID < 70000 913 zval_ptr_dtor(&$$); 914#endif 915} 916 917slice_offset(R) ::= INTEGER(I) . { 918 R = phvolt_ret_literal_zval(PHVOLT_T_INTEGER, I, status->scanner_state); 919} 920 921slice_offset(R) ::= IDENTIFIER(I) . { 922 R = phvolt_ret_literal_zval(PHVOLT_T_IDENTIFIER, I, status->scanner_state); 923} 924 925%destructor array_list { 926#if PHP_VERSION_ID < 70000 927 zval_ptr_dtor(&$$); 928#endif 929} 930 931array_list(R) ::= array_list(L) COMMA array_item(I) . { 932 R = phvolt_ret_zval_list(L, I); 933} 934 935array_list(R) ::= array_item(I) . { 936 R = phvolt_ret_zval_list(NULL, I); 937} 938 939%destructor array_item { 940#if PHP_VERSION_ID < 70000 941 zval_ptr_dtor(&$$); 942#endif 943} 944 945array_item(R) ::= STRING(S) COLON expr(E) . { 946 R = phvolt_ret_named_item(S, E, status->scanner_state); 947} 948 949array_item(R) ::= expr(E) . { 950 R = phvolt_ret_named_item(NULL, E, status->scanner_state); 951} 952 953expr(R) ::= function_call(F) . { 954 R = F; 955} 956 957%destructor function_call { 958#if PHP_VERSION_ID < 70000 959 zval_ptr_dtor(&$$); 960#endif 961} 962 963function_call(R) ::= expr(E) PARENTHESES_OPEN argument_list(L) PARENTHESES_CLOSE . { 964 R = phvolt_ret_func_call(E, L, status->scanner_state); 965} 966 967function_call(R) ::= expr(E) PARENTHESES_OPEN PARENTHESES_CLOSE . { 968 R = phvolt_ret_func_call(E, NULL, status->scanner_state); 969} 970 971%destructor argument_list { 972#if PHP_VERSION_ID < 70000 973 zval_ptr_dtor(&$$); 974#endif 975} 976 977argument_list(R) ::= argument_list(L) COMMA argument_item(I) . { 978 R = phvolt_ret_zval_list(L, I); 979} 980 981argument_list(R) ::= argument_item(I) . { 982 R = phvolt_ret_zval_list(NULL, I); 983} 984 985%destructor argument_item { 986#if PHP_VERSION_ID < 70000 987 zval_ptr_dtor(&$$); 988#endif 989} 990 991argument_item(R) ::= expr(E) . { 992 R = phvolt_ret_named_item(NULL, E, status->scanner_state); 993} 994 995argument_item(R) ::= STRING(S) COLON expr(E) . { 996 R = phvolt_ret_named_item(S, E, status->scanner_state); 997} 998 999expr(R) ::= IDENTIFIER(I) . { 1000 R = phvolt_ret_literal_zval(PHVOLT_T_IDENTIFIER, I, status->scanner_state); 1001} 1002 1003expr(R) ::= INTEGER(I) . { 1004 R = phvolt_ret_literal_zval(PHVOLT_T_INTEGER, I, status->scanner_state); 1005} 1006 1007expr(R) ::= STRING(S) . { 1008 R = phvolt_ret_literal_zval(PHVOLT_T_STRING, S, status->scanner_state); 1009} 1010 1011expr(R) ::= DOUBLE(D) . { 1012 R = phvolt_ret_literal_zval(PHVOLT_T_DOUBLE, D, status->scanner_state); 1013} 1014 1015expr(R) ::= NULL . { 1016 R = phvolt_ret_literal_zval(PHVOLT_T_NULL, NULL, status->scanner_state); 1017} 1018 1019expr(R) ::= FALSE . { 1020 R = phvolt_ret_literal_zval(PHVOLT_T_FALSE, NULL, status->scanner_state); 1021} 1022 1023expr(R) ::= TRUE . { 1024 R = phvolt_ret_literal_zval(PHVOLT_T_TRUE, NULL, status->scanner_state); 1025} 1026