3v4l.org

run code in 300+ PHP versions simultaneously
<?php class Token { public function __toString() { return get_called_class(); } } class ParensOpenToken extends Token {} class ParensCloseToken extends Token {} class SemicolonToken extends Token {} class ValueToken extends Token { public $value = ''; public function __toString() { return parent::__toString() . '("' . $this->value . '")'; } } class OtherToken extends Token { public $value = ''; public function __toString() { return parent::__toString() . '("' . $this->value . '")'; } } class Tokenizer { public function tokenize($string) { $tokensList = [ '[ \t\n]' => OtherToken::class, '\\{' => ParensOpenToken::class, '\\}' => ParensCloseToken::class, ';' => SemicolonToken::class, '[a-zA-Zа-яА-Я\-_0-9]+' => ValueToken::class ]; $tokens = []; while (mb_strlen($string) > 0) { $matched = false; foreach ($tokensList as $pattern => $token) { if (preg_match('/^(' . $pattern . ')/', $string, $out) !== FALSE) { if (isset($out[1])) { $token = new $token(); if ($token instanceof ValueToken && !is_null($out[1])) { $token->value = $out[1]; } $tokens[] = $token; $string = mb_substr($string, mb_strlen($out[1])); $matched = true; break; } } } if (!$matched) { $value = mb_substr($string, 0, 1); $otherToken = new OtherToken(); $otherToken->value = $value; $string = mb_substr($string, 1); } } return $tokens; } } class Parser { private $_tokens = []; private $_index = 0; private function isTokensAvailable() { return $this->_index < count($this->_tokens); } private function peekCurrentToken() { return $this->_tokens[$this->_index]; } private function popCurrentToken() { return $this->_tokens[$this->_index++]; } private function parsePrimary() { $peek = $this->peekCurrentToken(); if ($peek instanceof ParensOpenToken) { return $this->parseParens(); } elseif ($peek instanceof ValueToken) { return $this->parseValue(); } else { throw new \Exception('Parser error: unexpected character at index ' . $this->_index); return null; } } private function parseParens() { $token = $this->popCurrentToken(); if (!($token instanceof ParensOpenToken)) { throw new \Exception('Parser error: expected {'); } $expressions = []; while (true) { $expression = $this->parsePrimary(); $expressions[] = $expression; $token = $this->peekCurrentToken(); if ($token instanceof ParensCloseToken) { $this->popCurrentToken(); return $expressions; } elseif (!($token instanceof SemicolonToken)) { throw new \Exception('Parser error: expected semicolon after object in array'); } else { $this->popCurrentToken(); } } return $expressions; } private function parseValue() { $token = $this->popCurrentToken(); if (!($token instanceof ValueToken)) { throw new \Exception('Parser error: expected value token'); } return $token->value; } public function parse($tokens) { $result = []; $this->_tokens = $tokens; $this->_index = 0; while ($this->isTokensAvailable()) { $result[] = $this->parsePrimary(); } return $result; } } $tokenizer = new Tokenizer(); $parser = new Parser(); $string = '{{param1;{param2_array};param3;param4};{param5;{param6_array};param7;param8}}'; $tokens = $tokenizer->tokenize($string); $result = $parser->parse($tokens); print_r($result); $string2 = '{{param1;{param2_array;param2_array;param2_array};param3;param4}}'; $tokens2 = $tokenizer->tokenize($string2); $result2 = $parser->parse($tokens2); print_r($result2);
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  (null)
number of ops:  37
compiled vars:  !0 = $tokenizer, !1 = $parser, !2 = $string, !3 = $tokens, !4 = $result, !5 = $string2, !6 = $tokens2, !7 = $result2
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    3     0  E >   DECLARE_CLASS                                            'token'
    6     1        DECLARE_CLASS                                            'parensopentoken', 'token'
    7     2        DECLARE_CLASS                                            'parensclosetoken', 'token'
    8     3        DECLARE_CLASS                                            'semicolontoken', 'token'
    9     4        DECLARE_CLASS                                            'valuetoken', 'token'
   15     5        DECLARE_CLASS                                            'othertoken', 'token'
  140     6        NEW                                              $8      'Tokenizer'
          7        DO_FCALL                                      0          
          8        ASSIGN                                                   !0, $8
  141     9        NEW                                              $11     'Parser'
         10        DO_FCALL                                      0          
         11        ASSIGN                                                   !1, $11
  143    12        ASSIGN                                                   !2, '%7B%7Bparam1%3B%7Bparam2_array%7D%3Bparam3%3Bparam4%7D%3B%7Bparam5%3B%7Bparam6_array%7D%3Bparam7%3Bparam8%7D%7D'
  144    13        INIT_METHOD_CALL                                         !0, 'tokenize'
         14        SEND_VAR_EX                                              !2
         15        DO_FCALL                                      0  $15     
         16        ASSIGN                                                   !3, $15
  145    17        INIT_METHOD_CALL                                         !1, 'parse'
         18        SEND_VAR_EX                                              !3
         19        DO_FCALL                                      0  $17     
         20        ASSIGN                                                   !4, $17
  146    21        INIT_FCALL                                               'print_r'
         22        SEND_VAR                                                 !4
         23        DO_ICALL                                                 
  148    24        ASSIGN                                                   !5, '%7B%7Bparam1%3B%7Bparam2_array%3Bparam2_array%3Bparam2_array%7D%3Bparam3%3Bparam4%7D%7D'
  149    25        INIT_METHOD_CALL                                         !0, 'tokenize'
         26        SEND_VAR_EX                                              !5
         27        DO_FCALL                                      0  $21     
         28        ASSIGN                                                   !6, $21
  150    29        INIT_METHOD_CALL                                         !1, 'parse'
         30        SEND_VAR_EX                                              !6
         31        DO_FCALL                                      0  $23     
         32        ASSIGN                                                   !7, $23
  151    33        INIT_FCALL                                               'print_r'
         34        SEND_VAR                                                 !7
         35        DO_ICALL                                                 
         36      > RETURN                                                   1

Class Token:
Function __tostring:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  __toString
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    4     0  E >   GET_CALLED_CLASS                                 ~0      
          1        VERIFY_RETURN_TYPE                                       ~0
          2      > RETURN                                                   ~0
          3*       VERIFY_RETURN_TYPE                                       
          4*     > RETURN                                                   null

End of function __tostring

End of class Token.

Class ParensOpenToken: [no user functions]
Class ParensCloseToken: [no user functions]
Class SemicolonToken: [no user functions]
Class ValueToken:
Function __tostring:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  __toString
number of ops:  10
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   12     0  E >   INIT_STATIC_METHOD_CALL                                  '__toString'
          1        DO_FCALL                                      0  $0      
          2        CONCAT                                           ~1      $0, '%28%22'
          3        FETCH_OBJ_R                                      ~2      'value'
          4        CONCAT                                           ~3      ~1, ~2
          5        CONCAT                                           ~4      ~3, '%22%29'
          6        VERIFY_RETURN_TYPE                                       ~4
          7      > RETURN                                                   ~4
   13     8*       VERIFY_RETURN_TYPE                                       
          9*     > RETURN                                                   null

End of function __tostring

End of class ValueToken.

Class OtherToken:
Function __tostring:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  __toString
number of ops:  10
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   18     0  E >   INIT_STATIC_METHOD_CALL                                  '__toString'
          1        DO_FCALL                                      0  $0      
          2        CONCAT                                           ~1      $0, '%28%22'
          3        FETCH_OBJ_R                                      ~2      'value'
          4        CONCAT                                           ~3      ~1, ~2
          5        CONCAT                                           ~4      ~3, '%22%29'
          6        VERIFY_RETURN_TYPE                                       ~4
          7      > RETURN                                                   ~4
   19     8*       VERIFY_RETURN_TYPE                                       
          9*     > RETURN                                                   null

End of function __tostring

End of class OtherToken.

Class Tokenizer:
Function tokenize:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 42) Position 1 = 66
Branch analysis from position: 66
2 jumps found. (Code = 44) Position 1 = 71, Position 2 = 4
Branch analysis from position: 71
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 4
2 jumps found. (Code = 77) Position 1 = 6, Position 2 = 47
Branch analysis from position: 6
2 jumps found. (Code = 78) Position 1 = 7, Position 2 = 47
Branch analysis from position: 7
2 jumps found. (Code = 43) Position 1 = 17, Position 2 = 46
Branch analysis from position: 17
2 jumps found. (Code = 43) Position 1 = 19, Position 2 = 46
Branch analysis from position: 19
2 jumps found. (Code = 46) Position 1 = 25, Position 2 = 29
Branch analysis from position: 25
2 jumps found. (Code = 43) Position 1 = 30, Position 2 = 33
Branch analysis from position: 30
1 jumps found. (Code = 42) Position 1 = 47
Branch analysis from position: 47
2 jumps found. (Code = 43) Position 1 = 50, Position 2 = 66
Branch analysis from position: 50
2 jumps found. (Code = 44) Position 1 = 71, Position 2 = 4
Branch analysis from position: 71
Branch analysis from position: 4
Branch analysis from position: 66
Branch analysis from position: 33
Branch analysis from position: 29
Branch analysis from position: 46
1 jumps found. (Code = 42) Position 1 = 6
Branch analysis from position: 6
Branch analysis from position: 46
Branch analysis from position: 47
Branch analysis from position: 47
filename:       /in/YTrNI
function name:  tokenize
number of ops:  73
compiled vars:  !0 = $string, !1 = $tokensList, !2 = $tokens, !3 = $matched, !4 = $token, !5 = $pattern, !6 = $out, !7 = $value, !8 = $otherToken
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   23     0  E >   RECV                                             !0      
   24     1        ASSIGN                                                   !1, <array>
   31     2        ASSIGN                                                   !2, <array>
   33     3      > JMP                                                      ->66
   34     4    >   ASSIGN                                                   !3, <false>
   36     5      > FE_RESET_R                                       $12     !1, ->47
          6    > > FE_FETCH_R                                       ~13     $12, !4, ->47
          7    >   ASSIGN                                                   !5, ~13
   37     8        INIT_FCALL                                               'preg_match'
          9        CONCAT                                           ~15     '%2F%5E%28', !5
         10        CONCAT                                           ~16     ~15, '%29%2F'
         11        SEND_VAL                                                 ~16
         12        SEND_VAR                                                 !0
         13        SEND_REF                                                 !6
         14        DO_ICALL                                         $17     
         15        TYPE_CHECK                                  1018          $17
         16      > JMPZ                                                     ~18, ->46
   38    17    >   ISSET_ISEMPTY_DIM_OBJ                         0          !6, 1
         18      > JMPZ                                                     ~19, ->46
   39    19    >   FETCH_CLASS                                   0  $20     !4
         20        NEW                                              $21     $20
         21        DO_FCALL                                      0          
         22        ASSIGN                                                   !4, $21
   40    23        INSTANCEOF                                       ~24     !4, 'ValueToken'
         24      > JMPZ_EX                                          ~24     ~24, ->29
         25    >   FETCH_DIM_R                                      ~25     !6, 1
         26        TYPE_CHECK                                    2  ~26     ~25
         27        BOOL_NOT                                         ~27     ~26
         28        BOOL                                             ~24     ~27
         29    > > JMPZ                                                     ~24, ->33
   41    30    >   FETCH_DIM_R                                      ~29     !6, 1
         31        ASSIGN_OBJ                                               !4, 'value'
         32        OP_DATA                                                  ~29
   43    33    >   ASSIGN_DIM                                               !2
         34        OP_DATA                                                  !4
   45    35        INIT_FCALL                                               'mb_substr'
         36        SEND_VAR                                                 !0
         37        INIT_FCALL                                               'mb_strlen'
         38        FETCH_DIM_R                                      ~31     !6, 1
         39        SEND_VAL                                                 ~31
         40        DO_ICALL                                         $32     
         41        SEND_VAR                                                 $32
         42        DO_ICALL                                         $33     
         43        ASSIGN                                                   !0, $33
   46    44        ASSIGN                                                   !3, <true>
   47    45      > JMP                                                      ->47
   36    46    > > JMP                                                      ->6
         47    >   FE_FREE                                                  $12
   52    48        BOOL_NOT                                         ~36     !3
         49      > JMPZ                                                     ~36, ->66
   53    50    >   INIT_FCALL                                               'mb_substr'
         51        SEND_VAR                                                 !0
         52        SEND_VAL                                                 0
         53        SEND_VAL                                                 1
         54        DO_ICALL                                         $37     
         55        ASSIGN                                                   !7, $37
   54    56        NEW                                              $39     'OtherToken'
         57        DO_FCALL                                      0          
         58        ASSIGN                                                   !8, $39
   55    59        ASSIGN_OBJ                                               !8, 'value'
         60        OP_DATA                                                  !7
   56    61        INIT_FCALL                                               'mb_substr'
         62        SEND_VAR                                                 !0
         63        SEND_VAL                                                 1
         64        DO_ICALL                                         $43     
         65        ASSIGN                                                   !0, $43
   33    66    >   INIT_FCALL                                               'mb_strlen'
         67        SEND_VAR                                                 !0
         68        DO_ICALL                                         $45     
         69        IS_SMALLER                                               0, $45
         70      > JMPNZ                                                    ~46, ->4
   60    71    > > RETURN                                                   !2
   61    72*     > RETURN                                                   null

End of function tokenize

End of class Tokenizer.

Class Parser:
Function istokensavailable:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  isTokensAvailable
number of ops:  6
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   69     0  E >   FETCH_OBJ_R                                      ~0      '_index'
          1        FETCH_OBJ_R                                      ~1      '_tokens'
          2        COUNT                                            ~2      ~1
          3        IS_SMALLER                                       ~3      ~0, ~2
          4      > RETURN                                                   ~3
   70     5*     > RETURN                                                   null

End of function istokensavailable

Function peekcurrenttoken:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  peekCurrentToken
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   73     0  E >   FETCH_OBJ_R                                      ~1      '_index'
          1        FETCH_OBJ_R                                      ~0      '_tokens'
          2        FETCH_DIM_R                                      ~2      ~0, ~1
          3      > RETURN                                                   ~2
   74     4*     > RETURN                                                   null

End of function peekcurrenttoken

Function popcurrenttoken:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  popCurrentToken
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   77     0  E >   POST_INC_OBJ                                     ~1      '_index'
          1        FETCH_OBJ_R                                      ~0      '_tokens'
          2        FETCH_DIM_R                                      ~2      ~0, ~1
          3      > RETURN                                                   ~2
   78     4*     > RETURN                                                   null

End of function popcurrenttoken

Function parseprimary:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 5, Position 2 = 9
Branch analysis from position: 5
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 9
2 jumps found. (Code = 43) Position 1 = 11, Position 2 = 15
Branch analysis from position: 11
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
1 jumps found. (Code = 108) Position 1 = -2
filename:       /in/YTrNI
function name:  parsePrimary
number of ops:  23
compiled vars:  !0 = $peek
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   81     0  E >   INIT_METHOD_CALL                                         'peekCurrentToken'
          1        DO_FCALL                                      0  $1      
          2        ASSIGN                                                   !0, $1
   82     3        INSTANCEOF                                               !0, 'ParensOpenToken'
          4      > JMPZ                                                     ~3, ->9
   83     5    >   INIT_METHOD_CALL                                         'parseParens'
          6        DO_FCALL                                      0  $4      
          7      > RETURN                                                   $4
          8*       JMP                                                      ->22
   84     9    >   INSTANCEOF                                               !0, 'ValueToken'
         10      > JMPZ                                                     ~5, ->15
   85    11    >   INIT_METHOD_CALL                                         'parseValue'
         12        DO_FCALL                                      0  $6      
         13      > RETURN                                                   $6
         14*       JMP                                                      ->22
   87    15    >   NEW                                              $7      'Exception'
         16        FETCH_OBJ_R                                      ~8      '_index'
         17        CONCAT                                           ~9      'Parser+error%3A+unexpected+character+at+index+', ~8
         18        SEND_VAL_EX                                              ~9
         19        DO_FCALL                                      0          
         20      > THROW                                         0          $7
   88    21*       RETURN                                                   null
   90    22*     > RETURN                                                   null

End of function parseprimary

Function parseparens:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 6, Position 2 = 10
Branch analysis from position: 6
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 10
1 jumps found. (Code = 42) Position 1 = 36
Branch analysis from position: 36
2 jumps found. (Code = 44) Position 1 = 37, Position 2 = 12
Branch analysis from position: 37
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 12
2 jumps found. (Code = 43) Position 1 = 22, Position 2 = 26
Branch analysis from position: 22
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 26
2 jumps found. (Code = 43) Position 1 = 29, Position 2 = 34
Branch analysis from position: 29
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 34
2 jumps found. (Code = 44) Position 1 = 37, Position 2 = 12
Branch analysis from position: 37
Branch analysis from position: 12
filename:       /in/YTrNI
function name:  parseParens
number of ops:  39
compiled vars:  !0 = $token, !1 = $expressions, !2 = $expression
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   93     0  E >   INIT_METHOD_CALL                                         'popCurrentToken'
          1        DO_FCALL                                      0  $3      
          2        ASSIGN                                                   !0, $3
   94     3        INSTANCEOF                                       ~5      !0, 'ParensOpenToken'
          4        BOOL_NOT                                         ~6      ~5
          5      > JMPZ                                                     ~6, ->10
   95     6    >   NEW                                              $7      'Exception'
          7        SEND_VAL_EX                                              'Parser+error%3A+expected+%7B'
          8        DO_FCALL                                      0          
          9      > THROW                                         0          $7
   98    10    >   ASSIGN                                                   !1, <array>
   99    11      > JMP                                                      ->36
  100    12    >   INIT_METHOD_CALL                                         'parsePrimary'
         13        DO_FCALL                                      0  $10     
         14        ASSIGN                                                   !2, $10
  101    15        ASSIGN_DIM                                               !1
         16        OP_DATA                                                  !2
  103    17        INIT_METHOD_CALL                                         'peekCurrentToken'
         18        DO_FCALL                                      0  $13     
         19        ASSIGN                                                   !0, $13
  105    20        INSTANCEOF                                               !0, 'ParensCloseToken'
         21      > JMPZ                                                     ~15, ->26
  106    22    >   INIT_METHOD_CALL                                         'popCurrentToken'
         23        DO_FCALL                                      0          
  107    24      > RETURN                                                   !1
         25*       JMP                                                      ->36
  108    26    >   INSTANCEOF                                       ~17     !0, 'SemicolonToken'
         27        BOOL_NOT                                         ~18     ~17
         28      > JMPZ                                                     ~18, ->34
  109    29    >   NEW                                              $19     'Exception'
         30        SEND_VAL_EX                                              'Parser+error%3A+expected+semicolon+after+object+in+array'
         31        DO_FCALL                                      0          
         32      > THROW                                         0          $19
         33*       JMP                                                      ->36
  111    34    >   INIT_METHOD_CALL                                         'popCurrentToken'
         35        DO_FCALL                                      0          
   99    36    > > JMPNZ                                                    <true>, ->12
  115    37    > > RETURN                                                   !1
  116    38*     > RETURN                                                   null

End of function parseparens

Function parsevalue:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 6, Position 2 = 10
Branch analysis from position: 6
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 10
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/YTrNI
function name:  parseValue
number of ops:  13
compiled vars:  !0 = $token
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  119     0  E >   INIT_METHOD_CALL                                         'popCurrentToken'
          1        DO_FCALL                                      0  $1      
          2        ASSIGN                                                   !0, $1
  120     3        INSTANCEOF                                       ~3      !0, 'ValueToken'
          4        BOOL_NOT                                         ~4      ~3
          5      > JMPZ                                                     ~4, ->10
  121     6    >   NEW                                              $5      'Exception'
          7        SEND_VAL_EX                                              'Parser+error%3A+expected+value+token'
          8        DO_FCALL                                      0          
          9      > THROW                                         0          $5
  123    10    >   FETCH_OBJ_R                                      ~7      !0, 'value'
         11      > RETURN                                                   ~7
  124    12*     > RETURN                                                   null

End of function parsevalue

Function parse:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 42) Position 1 = 11
Branch analysis from position: 11
2 jumps found. (Code = 44) Position 1 = 14, Position 2 = 7
Branch analysis from position: 14
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 7
2 jumps found. (Code = 44) Position 1 = 14, Position 2 = 7
Branch analysis from position: 14
Branch analysis from position: 7
filename:       /in/YTrNI
function name:  parse
number of ops:  16
compiled vars:  !0 = $tokens, !1 = $result
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  126     0  E >   RECV                                             !0      
  127     1        ASSIGN                                                   !1, <array>
  128     2        ASSIGN_OBJ                                               '_tokens'
          3        OP_DATA                                                  !0
  129     4        ASSIGN_OBJ                                               '_index'
          5        OP_DATA                                                  0
  131     6      > JMP                                                      ->11
  132     7    >   INIT_METHOD_CALL                                         'parsePrimary'
          8        DO_FCALL                                      0  $6      
          9        ASSIGN_DIM                                               !1
         10        OP_DATA                                                  $6
  131    11    >   INIT_METHOD_CALL                                         'isTokensAvailable'
         12        DO_FCALL                                      0  $7      
         13      > JMPNZ                                                    $7, ->7
  135    14    > > RETURN                                                   !1
  136    15*     > RETURN                                                   null

End of function parse

End of class Parser.

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
195.64 ms | 1429 KiB | 21 Q