297 self::TYPE_UN_OP => [
300 self::TYPE_INCR_OP => [
303 self::TYPE_ADD_OP => [
306 self::TYPE_BRACE_OPEN => [
310 self::TYPE_BRACE_CLOSE => [
312 self::ACTION_POP =>
true,
314 self::TYPE_PAREN_OPEN => [
318 self::TYPE_RETURN => [
327 self::TYPE_LITERAL => [
332 self::TYPE_PAREN_OPEN => [
339 self::PROPERTY_ASSIGNMENT => [
340 self::TYPE_COLON => [
343 self::TYPE_BRACE_OPEN => [
347 self::TYPE_BRACE_CLOSE => [
348 self::ACTION_POP =>
true,
351 self::EXPRESSION => [
352 self::TYPE_SEMICOLON => [
355 self::TYPE_BRACE_OPEN => [
359 self::TYPE_BRACE_CLOSE => [
360 self::ACTION_POP =>
true,
362 self::TYPE_PAREN_OPEN => [
369 self::TYPE_LITERAL => [
373 self::EXPRESSION_NO_NL => [
374 self::TYPE_SEMICOLON => [
377 self::TYPE_BRACE_OPEN => [
381 self::TYPE_BRACE_CLOSE => [
382 self::ACTION_POP =>
true,
384 self::TYPE_PAREN_OPEN => [
391 self::TYPE_LITERAL => [
395 self::EXPRESSION_OP => [
396 self::TYPE_BIN_OP => [
399 self::TYPE_ADD_OP => [
406 self::TYPE_COLON => [
409 self::TYPE_COMMA => [
412 self::TYPE_SEMICOLON => [
415 self::TYPE_PAREN_OPEN => [
419 self::TYPE_BRACE_CLOSE => [
420 self::ACTION_POP =>
true,
423 self::EXPRESSION_FUNC => [
424 self::TYPE_BRACE_OPEN => [
429 self::EXPRESSION_TERNARY => [
430 self::TYPE_BRACE_OPEN => [
434 self::TYPE_PAREN_OPEN => [
441 self::TYPE_LITERAL => [
445 self::EXPRESSION_TERNARY_OP => [
446 self::TYPE_BIN_OP => [
449 self::TYPE_ADD_OP => [
456 self::TYPE_COMMA => [
459 self::TYPE_PAREN_OPEN => [
463 self::TYPE_COLON => [
464 self::ACTION_POP =>
true,
467 self::EXPRESSION_TERNARY_FUNC => [
468 self::TYPE_BRACE_OPEN => [
473 self::PAREN_EXPRESSION => [
474 self::TYPE_BRACE_OPEN => [
478 self::TYPE_PAREN_OPEN => [
482 self::TYPE_PAREN_CLOSE => [
483 self::ACTION_POP =>
true,
488 self::TYPE_LITERAL => [
492 self::PAREN_EXPRESSION_OP => [
493 self::TYPE_BIN_OP => [
496 self::TYPE_ADD_OP => [
502 self::TYPE_COLON => [
505 self::TYPE_COMMA => [
508 self::TYPE_SEMICOLON => [
511 self::TYPE_PAREN_OPEN => [
515 self::TYPE_PAREN_CLOSE => [
516 self::ACTION_POP =>
true,
519 self::PAREN_EXPRESSION_FUNC => [
520 self::TYPE_BRACE_OPEN => [
526 self::PROPERTY_EXPRESSION => [
527 self::TYPE_BRACE_OPEN => [
531 self::TYPE_BRACE_CLOSE => [
532 self::ACTION_POP =>
true,
534 self::TYPE_PAREN_OPEN => [
541 self::TYPE_LITERAL => [
545 self::PROPERTY_EXPRESSION_OP => [
546 self::TYPE_BIN_OP => [
549 self::TYPE_ADD_OP => [
556 self::TYPE_COMMA => [
559 self::TYPE_BRACE_OPEN => [
562 self::TYPE_BRACE_CLOSE => [
563 self::ACTION_POP =>
true,
565 self::TYPE_PAREN_OPEN => [
570 self::PROPERTY_EXPRESSION_FUNC => [
571 self::TYPE_BRACE_OPEN => [
580 self::EXPRESSION_NO_NL => [
581 self::TYPE_UN_OP =>
true,
582 self::TYPE_INCR_OP =>
true,
583 self::TYPE_ADD_OP =>
true,
584 self::TYPE_BRACE_OPEN =>
true,
585 self::TYPE_PAREN_OPEN =>
true,
586 self::TYPE_RETURN =>
true,
587 self::TYPE_IF =>
true,
588 self::TYPE_DO =>
true,
589 self::TYPE_FUNC =>
true,
590 self::TYPE_LITERAL =>
true
592 self::EXPRESSION_OP => [
593 self::TYPE_UN_OP =>
true,
594 self::TYPE_INCR_OP =>
true,
595 self::TYPE_BRACE_OPEN =>
true,
596 self::TYPE_RETURN =>
true,
597 self::TYPE_IF =>
true,
598 self::TYPE_DO =>
true,
599 self::TYPE_FUNC =>
true,
600 self::TYPE_LITERAL =>
true
606 self::EXPRESSION_OP =>
true,
607 self::EXPRESSION_TERNARY_OP =>
true,
608 self::PAREN_EXPRESSION_OP =>
true,
609 self::PROPERTY_EXPRESSION_OP =>
true
616 $length = strlen(
$s );
618 $newlineFound =
true;
622 while ( $pos < $length ) {
625 $skip = strspn(
$s,
" \t\n\r\xb\xc", $pos );
628 if ( $ch ===
'/' && substr(
$s, $pos, 2 ) ===
'/*' ) {
630 $end = strpos(
$s,
'*/', $pos + 2 );
631 $skip = $end ===
false ? $length - $pos : $end - $pos + 2;
637 if ( !$newlineFound && strcspn(
$s,
"\r\n", $pos, $skip ) !== $skip ) {
638 $newlineFound =
true;
646 if ( ( $ch ===
'/' && substr(
$s, $pos, 2 ) ===
'//' )
647 || ( $ch ===
'<' && substr(
$s, $pos, 4 ) ===
'<!--' )
648 || ( $ch ===
'-' && $newlineFound && substr(
$s, $pos, 3 ) ===
'-->' )
650 $pos += strcspn(
$s,
"\r\n", $pos );
662 if ( $ch ===
"'" || $ch ===
'"' ) {
664 $search = $ch .
'\\';
670 $end += strcspn(
$s, $search, $end ) + 2;
673 }
while ( $end - 2 < $length &&
$s[$end - 2] ===
'\\' );
676 if ( $end > $length ) {
684 } elseif ( $ch ===
'/' && !isset( $divStates[$state] ) ) {
693 $end += strcspn(
$s,
'/[\\', $end ) + 2;
695 }
while ( $end - 2 < $length &&
$s[$end - 2] ===
'\\' );
698 if ( $end > $length ) {
705 if (
$s[$end - 1] ===
'/' ) {
713 $end += strcspn(
$s,
']\\', $end ) + 2;
715 }
while ( $end - 2 < $length &&
$s[$end - 2] ===
'\\' );
718 if ( $end > $length ) {
727 while ( $end < $length && ctype_alpha(
$s[$end] ) ) {
732 && ( $pos + 1 < $length ) && (
$s[$pos + 1] ===
'x' ||
$s[$pos + 1] ===
'X' )
736 $len = strspn(
$s,
'0123456789ABCDEFabcdef', $end );
741 'Expected a hexadecimal number but found ' . substr(
$s, $pos, 5 ) .
'...'
747 || ( $ch ===
'.' && $pos + 1 < $length && ctype_digit(
$s[$pos + 1] ) )
749 $end += strspn(
$s,
'0123456789', $end );
750 $decimal = strspn(
$s,
'.', $end );
752 if ( $decimal > 2 ) {
755 $end += strspn(
$s,
'0123456789', $end + 1 ) + $decimal;
757 $exponent = strspn(
$s,
'eE', $end );
759 if ( $exponent > 1 ) {
765 $end += strspn(
$s,
'-+', $end );
766 $len = strspn(
$s,
'0123456789', $end );
771 'No decimal digits after e, how many zeroes should be added?'
776 } elseif ( isset( $opChars[$ch] ) ) {
780 && isset( $tokenTypes[substr(
$s, $pos, $end - $pos + 1 )] )
787 $end += strcspn(
$s,
" \t\n.;,=<>+-{}()[]?:*/%'\"!&|^~\xb\xc\r", $end );
791 $token = substr(
$s, $pos, $end - $pos );
794 if ( $newlineFound && isset( $semicolon[$state][
$type] ) ) {
800 } elseif ( $lineLength + $end - $pos > self::$maxLineLength &&
801 !isset( $semicolon[$state][
$type] ) &&
$type !== self::TYPE_INCR_OP ) {
808 } elseif ( !isset( $opChars[$last] ) && !isset( $opChars[$ch] ) ) {
812 } elseif ( $last === $ch && ( $ch ===
'+' || $ch ===
'-' || $ch ===
'/' ) ) {
817 $type === self::TYPE_LITERAL
818 && ( $token ===
'true' || $token ===
'false' )
819 && ( $state === self::EXPRESSION || $state === self::PROPERTY_EXPRESSION )
822 $token = ( $token ===
'true' ) ?
'!0' :
'!1';
826 $lineLength += $end - $pos;
827 $last =
$s[$end - 1];
829 $newlineFound =
false;
832 if ( isset( $model[$state][
$type][self::ACTION_PUSH] ) &&
833 count( $stack ) < self::STACK_LIMIT
837 if ( $stack && isset( $model[$state][
$type][self::ACTION_POP] ) ) {
838 $state = array_pop( $stack );
839 } elseif ( isset( $model[$state][
$type][self::ACTION_GOTO] ) ) {