3v4l.org

run code in 300+ PHP versions simultaneously
<?php const TK_WHITESPACES = 0, TK_OPENING_PARENTHESIS = 2, // 0b00000010 TK_CLOSING_PARENTHESIS = 4, // 0b00000100 TK_LOGICAL_CONJUNCTION = 8, // 0b00001000 TK_LOGICAL_DISJUNCTION = 16, // 0b00010000 TK_LOGICAL_NEGATION = 32, // etc. TK_STRING = 64, TK_EQUAL = 128, TK_NOT_EQUAL = 256, TK_COLUMN_NAME = 512, TK_END = 1024; const ERR_NONE = 0, ERROR = 1; // 0b00000001 const TOKENIZATION_ERROR = 3, // 0b00000011 ERR_UNEXPECTED_CHAR = 7, // 0b00000111 ERR_UNCLOSED_STRING = 11, // 0b00001011 ERR_BAD_UTF8 = 19, // 0b00010011 ERR_EMPTY_STRING = 35; // TE const LOGIC_ERROR = 129, // 0b10000001 ERR_UNEXPECTED_TOKEN = 133, // 0b10000101 ERR_UNEXPECTED_CLOSING_PARENTHESIS = 137, // 0b10001001 ERR_MISSING_CLOSING_PARENTHESIS = 145, // 0b10010001 ERR_UNKNOW_COLUMN_NAME = 161, // 0b10100001 ERR_EMPTY_QUERY = 193; // L E const RULES = [ TK_COLUMN_NAME => TK_EQUAL | TK_NOT_EQUAL, TK_EQUAL => TK_STRING, TK_NOT_EQUAL => TK_STRING, TK_STRING => TK_END | TK_CLOSING_PARENTHESIS | TK_LOGICAL_DISJUNCTION | TK_LOGICAL_CONJUNCTION, TK_CLOSING_PARENTHESIS => TK_END | TK_CLOSING_PARENTHESIS | TK_LOGICAL_DISJUNCTION | TK_LOGICAL_CONJUNCTION, TK_LOGICAL_DISJUNCTION => TK_LOGICAL_NEGATION | TK_OPENING_PARENTHESIS | TK_COLUMN_NAME, TK_LOGICAL_CONJUNCTION => TK_LOGICAL_NEGATION | TK_OPENING_PARENTHESIS | TK_COLUMN_NAME, TK_LOGICAL_NEGATION => TK_OPENING_PARENTHESIS | TK_COLUMN_NAME, TK_OPENING_PARENTHESIS => TK_OPENING_PARENTHESIS | TK_COLUMN_NAME ]; const COLUMN_NAMES = ['family', 'conditions_of_use', 'taxonomical_group']; const ERROR_MESSAGES = [ ERR_UNEXPECTED_CHAR => 'caractère inattendu à la position %d.', ERR_UNCLOSED_STRING => 'chaîne de caractères non fermée à la position %d.', ERR_BAD_UTF8 => 'erreur d\'encodage UTF-8 à la position %d.', ERR_EMPTY_STRING => 'chaîne vide à la position %d.', // ***** ERR_UNEXPECTED_TOKEN => 'élément inattendu à la position %d.', ERR_UNEXPECTED_CLOSING_PARENTHESIS => 'parenthèse fermante inattendue à la position %d.', ERR_MISSING_CLOSING_PARENTHESIS => 'parenthèse fermante manquante à la position %d.', ERR_UNKNOW_COLUMN_NAME => 'nom de colonne inconnu à la position %d.', ERR_EMPTY_QUERY => 'requête vide à la position %d.' ]; const TOKEN2SQL = [ TK_EQUAL => ' = ', TK_NOT_EQUAL => ' <> ', TK_CLOSING_PARENTHESIS => ')', TK_OPENING_PARENTHESIS => '(', TK_LOGICAL_DISJUNCTION => ' OR ', TK_LOGICAL_CONJUNCTION => ' AND ', TK_LOGICAL_NEGATION => 'NOT ', TK_STRING => '?' // placeholder ]; function tokenize(string $str) { $pattern = <<<'REGEX' ~ \s+ (*:TK_WHITESPACES) | \( (*:TK_OPENING_PARENTHESIS) | \) (*:TK_CLOSING_PARENTHESIS) | \b ET \b (*:TK_LOGICAL_CONJUNCTION) | \b OU \b (*:TK_LOGICAL_DISJUNCTION) | \b NON \b (*:TK_LOGICAL_NEGATION) | \B " [^"\\]* (?s: \\ . [^"\\]* )* (?: " \B (*:TK_STRING) | " (*:ERR_UNEXPECTED_CHAR) | \z (*:ERR_UNCLOSED_STRING) ) | \b \w+ (*:TK_COLUMN_NAME) | = (*:TK_EQUAL) | (?: != | <> ) (*:TK_NOT_EQUAL) | \z (*:TK_END) | (*COMMIT) (*FAIL) # UNEXPECTED CHARACTER ⮕ tokenization aborted ~xu REGEX; $count = preg_match_all($pattern, $str, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); if ( preg_last_error() === PREG_BAD_UTF8_ERROR ) { preg_match('~(?: # séquences UTF-8 valides [\x00-\x7F] | [\xC2-\xDF][\x80-\xBF] | \xE0[\xA0-\xBF][\x80-\xBF] | \xED[\x80-\x9F][\x80-\xBF] | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} | \xF0[\x90-\xBF][\x80-\xBF]{2} | \xF4[\x80-\x8F][\x80-\xBF]{2} | [\xF1-\xF3][\x80-\xBF]{3} )*~x', $str, $m); return [ 'error' => ['type' => ERR_BAD_UTF8, 'offset' => strlen($m[0])] ]; } if ( $count === 0 ) // (*COMMIT) (*FAIL) a été atteint dés la première position return [ 'error' => ['type' => ERR_UNEXPECTED_CHAR, 'offset' => 0] ]; $errors = array_filter($matches, fn($m) => constant($m['MARK']) & ERROR); if ( !empty($errors) ) { // la fin a été atteinte mais il y a des marqueurs d'erreurs parmi les tokens $error = array_shift($errors); list($match, $offset) = $error[0]; return [ 'error' => ['type' => constant($error['MARK']), 'offset' => $offset + strlen($match)] ]; } $lastMatch = end($matches); if ( constant($lastMatch['MARK']) !== TK_END ) { // (*COMMIT) (*FAIL) a été atteint avant la fin list($match, $offset) = $lastMatch[0]; return [ 'error' => ['type' => ERR_UNEXPECTED_CHAR, 'offset' => $offset + strlen($match)] ]; } if ( $count === 1 ) // l'unique token est TK_END, la chaîne est vide return [ 'error' => ['type' => ERR_EMPTY_STRING, 'offset' => 0] ]; return [ 'error' => ERR_NONE, 'tokens' => array_map( fn($m) => [ 'value' => $m[0][0], 'offset' => $m[0][1], 'type' => constant($m['MARK']) ], $matches ) ]; } function checkLogic($tokens) { $parenthesis = 0; $current = current($tokens); if ( $current['type'] === TK_END ) return [ 'type' => ERR_EMPTY_QUERY, 'offset' => $current['offset'] ]; do { if ( $current['type'] === TK_COLUMN_NAME && !in_array($current['value'], COLUMN_NAMES) ) return [ 'type' => ERR_UNKNOW_COLUMN_NAME, 'offset' => $current['offset'] ]; if ( $current['type'] === TK_OPENING_PARENTHESIS ) $parenthesis++; elseif ( $current['type'] === TK_CLOSING_PARENTHESIS && --$parenthesis < 0 ) return [ 'type' => ERR_UNEXPECTED_CLOSING_PARENTHESIS, 'offset' => $current['offset'] ]; $next = next($tokens); if ( RULES[$current['type']] & $next['type'] ) // le token courant est suivi par un token autorisé $current = $next; else return [ 'type' => ERR_UNEXPECTED_TOKEN, 'offset' => $next['offset'] ]; } while ( $next['type'] !== TK_END ); return $parenthesis ? [ 'type' => ERR_MISSING_CLOSING_PARENTHESIS, 'offset' => $current['offset'] ] : true ; } function displayError($error, $query) { $position = grapheme_strlen(substr($query, 0, $error['offset'])); $format = ERROR_MESSAGES[$error['type']]."\n%s\n" . str_repeat(' ', $position) . '^'; printf($format, $position, $query); } function buildQuery($tokens, $prefix = '') { $SQLQuery = $prefix; $params = []; foreach ($tokens as $token) { switch($token['type']) { case TK_COLUMN_NAME: $SQLQuery .= $token['value']; break; case TK_END: break; case TK_STRING: $param = substr($token['value'], 1, -1); $params[] = strtr($param, ['\\\\' => '\\\\', '\\"' => '"']); default: $SQLQuery .= TOKEN2SQL[$token['type']]; } } return [$SQLQuery, $params]; } $query = "".'family="_\\"bîd'."u\xCC\x8A".'le\\"_" OU (((taxonomical_group="machin")))'; $tokenization = tokenize($query); $error = $tokenization['error']; if ( $error !== ERR_NONE ) { displayError($error, $query); } else { $tokens = array_filter($tokenization['tokens'], fn($token) => $token['type'] !== TK_WHITESPACES); if ( true !== $error = checkLogic($tokens) ) { displayError($error, $query); } else { $prefix = 'SELECT * FROM matable WHERE '; list($SQLQuery, $params) = buildQuery($tokens, $prefix); echo "requête: $query", PHP_EOL, "requête préparée: $SQLQuery", PHP_EOL, 'paramètres: ', print_r($params, true); // $sth = $dbh->prepare($SQLQuery); // $sth->execute($params); } }
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 38, Position 2 = 43
Branch analysis from position: 38
1 jumps found. (Code = 42) Position 1 = 85
Branch analysis from position: 85
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 43
2 jumps found. (Code = 43) Position 1 = 56, Position 2 = 61
Branch analysis from position: 56
1 jumps found. (Code = 42) Position 1 = 85
Branch analysis from position: 85
Branch analysis from position: 61
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/ZRaDC
function name:  (null)
number of ops:  86
compiled vars:  !0 = $query, !1 = $tokenization, !2 = $error, !3 = $tokens, !4 = $prefix, !5 = $SQLQuery, !6 = $params
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    3     0  E >   DECLARE_CONST                                            'TK_WHITESPACES', 0
          1        DECLARE_CONST                                            'TK_OPENING_PARENTHESIS', 2
          2        DECLARE_CONST                                            'TK_CLOSING_PARENTHESIS', 4
          3        DECLARE_CONST                                            'TK_LOGICAL_CONJUNCTION', 8
          4        DECLARE_CONST                                            'TK_LOGICAL_DISJUNCTION', 16
          5        DECLARE_CONST                                            'TK_LOGICAL_NEGATION', 32
          6        DECLARE_CONST                                            'TK_STRING', 64
          7        DECLARE_CONST                                            'TK_EQUAL', 128
          8        DECLARE_CONST                                            'TK_NOT_EQUAL', 256
          9        DECLARE_CONST                                            'TK_COLUMN_NAME', 512
         10        DECLARE_CONST                                            'TK_END', 1024
   15    11        DECLARE_CONST                                            'ERR_NONE', 0
         12        DECLARE_CONST                                            'ERROR', 1
   18    13        DECLARE_CONST                                            'TOKENIZATION_ERROR', 3
         14        DECLARE_CONST                                            'ERR_UNEXPECTED_CHAR', 7
         15        DECLARE_CONST                                            'ERR_UNCLOSED_STRING', 11
         16        DECLARE_CONST                                            'ERR_BAD_UTF8', 19
         17        DECLARE_CONST                                            'ERR_EMPTY_STRING', 35
   24    18        DECLARE_CONST                                            'LOGIC_ERROR', 129
         19        DECLARE_CONST                                            'ERR_UNEXPECTED_TOKEN', 133
         20        DECLARE_CONST                                            'ERR_UNEXPECTED_CLOSING_PARENTHESIS', 137
         21        DECLARE_CONST                                            'ERR_MISSING_CLOSING_PARENTHESIS', 145
         22        DECLARE_CONST                                            'ERR_UNKNOW_COLUMN_NAME', 161
         23        DECLARE_CONST                                            'ERR_EMPTY_QUERY', 193
   40    24        DECLARE_CONST                                            'RULES', <const ast>
   43    25        DECLARE_CONST                                            'COLUMN_NAMES', <array>
   54    26        DECLARE_CONST                                            'ERROR_MESSAGES', <const ast>
   65    27        DECLARE_CONST                                            'TOKEN2SQL', <const ast>
  197    28        ASSIGN                                                   !0, 'family%3D%22_%5C%22b%C3%AEdu%CC%8Ale%5C%22_%22+OU+%28%28%28taxonomical_group%3D%22machin%22%29%29%29'
  199    29        INIT_FCALL                                               'tokenize'
         30        SEND_VAR                                                 !0
         31        DO_FCALL                                      0  $8      
         32        ASSIGN                                                   !1, $8
  200    33        FETCH_DIM_R                                      ~10     !1, 'error'
         34        ASSIGN                                                   !2, ~10
  202    35        FETCH_CONSTANT                                   ~12     'ERR_NONE'
         36        IS_NOT_IDENTICAL                                         !2, ~12
         37      > JMPZ                                                     ~13, ->43
  203    38    >   INIT_FCALL                                               'displayerror'
         39        SEND_VAR                                                 !2
         40        SEND_VAR                                                 !0
         41        DO_FCALL                                      0          
  202    42      > JMP                                                      ->85
  205    43    >   INIT_FCALL                                               'array_filter'
         44        FETCH_DIM_R                                      ~15     !1, 'tokens'
         45        SEND_VAL                                                 ~15
         46        DECLARE_LAMBDA_FUNCTION                          ~16     [0]
         47        SEND_VAL                                                 ~16
         48        DO_ICALL                                         $17     
         49        ASSIGN                                                   !3, $17
  207    50        INIT_FCALL                                               'checklogic'
         51        SEND_VAR                                                 !3
         52        DO_FCALL                                      0  $19     
         53        ASSIGN                                           ~20     !2, $19
         54        TYPE_CHECK                                  1014          ~20
         55      > JMPZ                                                     ~21, ->61
  208    56    >   INIT_FCALL                                               'displayerror'
         57        SEND_VAR                                                 !2
         58        SEND_VAR                                                 !0
         59        DO_FCALL                                      0          
  207    60      > JMP                                                      ->85
  210    61    >   ASSIGN                                                   !4, 'SELECT+%2A+FROM+matable+WHERE+'
  211    62        INIT_FCALL                                               'buildquery'
         63        SEND_VAR                                                 !3
         64        SEND_VAR                                                 !4
         65        DO_FCALL                                      0  $24     
         66        FETCH_LIST_R                                     $25     $24, 0
         67        ASSIGN                                                   !5, $25
         68        FETCH_LIST_R                                     $27     $24, 1
         69        ASSIGN                                                   !6, $27
         70        FREE                                                     $24
  213    71        NOP                                                      
         72        FAST_CONCAT                                      ~29     'requ%C3%AAte%3A+', !0
         73        ECHO                                                     ~29
         74        ECHO                                                     '%0A'
  214    75        NOP                                                      
         76        FAST_CONCAT                                      ~30     'requ%C3%AAte+pr%C3%A9par%C3%A9e%3A+', !5
         77        ECHO                                                     ~30
         78        ECHO                                                     '%0A'
  215    79        ECHO                                                     'param%C3%A8tres%3A+'
         80        INIT_FCALL                                               'print_r'
         81        SEND_VAR                                                 !6
         82        SEND_VAL                                                 <true>
         83        DO_ICALL                                         $31     
         84        ECHO                                                     $31
  220    85    > > RETURN                                                   1


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/ZRaDC
function name:  {closure}
number of ops:  6
compiled vars:  !0 = $token
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  205     0  E >   RECV                                             !0      
          1        FETCH_DIM_R                                      ~1      !0, 'type'
          2        FETCH_CONSTANT                                   ~2      'TK_WHITESPACES'
          3        IS_NOT_IDENTICAL                                 ~3      ~1, ~2
          4      > RETURN                                                   ~3
          5*     > RETURN                                                   null

End of Dynamic Function 0

Function tokenize:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 13, Position 2 = 25
Branch analysis from position: 13
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 25
2 jumps found. (Code = 43) Position 1 = 27, Position 2 = 32
Branch analysis from position: 27
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 32
2 jumps found. (Code = 43) Position 1 = 41, Position 2 = 61
Branch analysis from position: 41
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 61
2 jumps found. (Code = 43) Position 1 = 72, Position 2 = 85
Branch analysis from position: 72
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 85
2 jumps found. (Code = 43) Position 1 = 87, Position 2 = 92
Branch analysis from position: 87
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 92
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/ZRaDC
function name:  tokenize
number of ops:  102
compiled vars:  !0 = $str, !1 = $pattern, !2 = $count, !3 = $matches, !4 = $m, !5 = $errors, !6 = $error, !7 = $match, !8 = $offset, !9 = $lastMatch
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   68     0  E >   RECV                                             !0      
   69     1        ASSIGN                                                   !1, '++++%7E%0A++++++++%5Cs%2B+%28%2A%3ATK_WHITESPACES%29%0A%0A++++++%7C+%5C%28++%28%2A%3ATK_OPENING_PARENTHESIS%29%0A++++++%7C+%5C%29++%28%2A%3ATK_CLOSING_PARENTHESIS%29%0A%0A++++++%7C+%5Cb+ET+%5Cb++++%28%2A%3ATK_LOGICAL_CONJUNCTION%29%0A++++++%7C+%5Cb+OU+%5Cb++++%28%2A%3ATK_LOGICAL_DISJUNCTION%29%0A++++++%7C+%5Cb+NON+%5Cb+++%28%2A%3ATK_LOGICAL_NEGATION%29%0A%0A++++++%7C+%5CB+%22+%5B%5E%22%5C%5C%5D%2A+%28%3Fs%3A+%5C%5C+.+%5B%5E%22%5C%5C%5D%2A+%29%2A%0A++++++++%28%3F%3A+%22+%5CB+%28%2A%3ATK_STRING%29+%7C+%22+%28%2A%3AERR_UNEXPECTED_CHAR%29+%7C+%5Cz+%28%2A%3AERR_UNCLOSED_STRING%29+%29%0A++++++%7C+%5Cb+%5Cw%2B++%28%2A%3ATK_COLUMN_NAME%29%0A%0A++++++%7C+%3D+++%28%2A%3ATK_EQUAL%29%0A++++++%7C+%28%3F%3A+%21%3D+%7C+%3C%3E+%29+++%28%2A%3ATK_NOT_EQUAL%29%0A%0A++++++%7C+%5Cz++%28%2A%3ATK_END%29%0A++++++%7C+%28%2ACOMMIT%29+%28%2AFAIL%29+%23+UNEXPECTED+CHARACTER+%E2%AE%95+tokenization+aborted%0A++++%7Exu'
   92     2        INIT_FCALL                                               'preg_match_all'
          3        SEND_VAR                                                 !1
          4        SEND_VAR                                                 !0
          5        SEND_REF                                                 !3
          6        SEND_VAL                                                 258
          7        DO_ICALL                                         $11     
          8        ASSIGN                                                   !2, $11
   94     9        INIT_FCALL                                               'preg_last_error'
         10        DO_ICALL                                         $13     
         11        IS_IDENTICAL                                             $13, 4
         12      > JMPZ                                                     ~14, ->25
   95    13    >   INIT_FCALL                                               'preg_match'
         14        SEND_VAL                                                 '%7E%28%3F%3A+%23+s%C3%A9quences+UTF-8+valides%0A++++++++++++%5B%5Cx00-%5Cx7F%5D%0A++++++++++%7C+%5B%5CxC2-%5CxDF%5D%5B%5Cx80-%5CxBF%5D%0A++++++++++%7C+%5CxE0%5B%5CxA0-%5CxBF%5D%5B%5Cx80-%5CxBF%5D%0A++++++++++%7C+%5CxED%5B%5Cx80-%5Cx9F%5D%5B%5Cx80-%5CxBF%5D%0A++++++++++%7C+%5B%5CxE1-%5CxEC%5CxEE%5CxEF%5D%5B%5Cx80-%5CxBF%5D%7B2%7D%0A++++++++++%7C+%5CxF0%5B%5Cx90-%5CxBF%5D%5B%5Cx80-%5CxBF%5D%7B2%7D%0A++++++++++%7C+%5CxF4%5B%5Cx80-%5Cx8F%5D%5B%5Cx80-%5CxBF%5D%7B2%7D%0A++++++++++%7C+%5B%5CxF1-%5CxF3%5D%5B%5Cx80-%5CxBF%5D%7B3%7D%0A++++++++++%29%2A%7Ex'
  104    15        SEND_VAR                                                 !0
         16        SEND_REF                                                 !4
   95    17        DO_ICALL                                                 
  106    18        FETCH_CONSTANT                                   ~16     'ERR_BAD_UTF8'
         19        INIT_ARRAY                                       ~17     ~16, 'type'
         20        FETCH_DIM_R                                      ~18     !4, 0
         21        STRLEN                                           ~19     ~18
         22        ADD_ARRAY_ELEMENT                                ~17     ~19, 'offset'
         23        INIT_ARRAY                                       ~20     ~17, 'error'
         24      > RETURN                                                   ~20
  109    25    >   IS_IDENTICAL                                             !2, 0
         26      > JMPZ                                                     ~21, ->32
  110    27    >   FETCH_CONSTANT                                   ~22     'ERR_UNEXPECTED_CHAR'
         28        INIT_ARRAY                                       ~23     ~22, 'type'
         29        ADD_ARRAY_ELEMENT                                ~23     0, 'offset'
         30        INIT_ARRAY                                       ~24     ~23, 'error'
         31      > RETURN                                                   ~24
  112    32    >   INIT_FCALL                                               'array_filter'
         33        SEND_VAR                                                 !3
         34        DECLARE_LAMBDA_FUNCTION                          ~25     [0]
         35        SEND_VAL                                                 ~25
         36        DO_ICALL                                         $26     
         37        ASSIGN                                                   !5, $26
  114    38        ISSET_ISEMPTY_CV                                 ~28     !5
         39        BOOL_NOT                                         ~29     ~28
         40      > JMPZ                                                     ~29, ->61
  115    41    >   INIT_FCALL                                               'array_shift'
         42        SEND_REF                                                 !5
         43        DO_ICALL                                         $30     
         44        ASSIGN                                                   !6, $30
  116    45        FETCH_DIM_R                                      ~32     !6, 0
         46        FETCH_LIST_R                                     $33     ~32, 0
         47        ASSIGN                                                   !7, $33
         48        FETCH_LIST_R                                     $35     ~32, 1
         49        ASSIGN                                                   !8, $35
         50        FREE                                                     ~32
  117    51        INIT_FCALL                                               'constant'
         52        FETCH_DIM_R                                      ~37     !6, 'MARK'
         53        SEND_VAL                                                 ~37
         54        DO_ICALL                                         $38     
         55        INIT_ARRAY                                       ~39     $38, 'type'
         56        STRLEN                                           ~40     !7
         57        ADD                                              ~41     !8, ~40
         58        ADD_ARRAY_ELEMENT                                ~39     ~41, 'offset'
         59        INIT_ARRAY                                       ~42     ~39, 'error'
         60      > RETURN                                                   ~42
  120    61    >   INIT_FCALL                                               'end'
         62        SEND_REF                                                 !3
         63        DO_ICALL                                         $43     
         64        ASSIGN                                                   !9, $43
  122    65        INIT_FCALL                                               'constant'
         66        FETCH_DIM_R                                      ~45     !9, 'MARK'
         67        SEND_VAL                                                 ~45
         68        DO_ICALL                                         $46     
         69        FETCH_CONSTANT                                   ~47     'TK_END'
         70        IS_NOT_IDENTICAL                                         $46, ~47
         71      > JMPZ                                                     ~48, ->85
  123    72    >   FETCH_DIM_R                                      ~49     !9, 0
         73        FETCH_LIST_R                                     $50     ~49, 0
         74        ASSIGN                                                   !7, $50
         75        FETCH_LIST_R                                     $52     ~49, 1
         76        ASSIGN                                                   !8, $52
         77        FREE                                                     ~49
  124    78        FETCH_CONSTANT                                   ~54     'ERR_UNEXPECTED_CHAR'
         79        INIT_ARRAY                                       ~55     ~54, 'type'
         80        STRLEN                                           ~56     !7
         81        ADD                                              ~57     !8, ~56
         82        ADD_ARRAY_ELEMENT                                ~55     ~57, 'offset'
         83        INIT_ARRAY                                       ~58     ~55, 'error'
         84      > RETURN                                                   ~58
  127    85    >   IS_IDENTICAL                                             !2, 1
         86      > JMPZ                                                     ~59, ->92
  128    87    >   FETCH_CONSTANT                                   ~60     'ERR_EMPTY_STRING'
         88        INIT_ARRAY                                       ~61     ~60, 'type'
         89        ADD_ARRAY_ELEMENT                                ~61     0, 'offset'
         90        INIT_ARRAY                                       ~62     ~61, 'error'
         91      > RETURN                                                   ~62
  131    92    >   FETCH_CONSTANT                                   ~63     'ERR_NONE'
         93        INIT_ARRAY                                       ~64     ~63, 'error'
  132    94        INIT_FCALL                                               'array_map'
  133    95        DECLARE_LAMBDA_FUNCTION                          ~65     [1]
         96        SEND_VAL                                                 ~65
  134    97        SEND_VAR                                                 !3
  132    98        DO_ICALL                                         $66     
  134    99        ADD_ARRAY_ELEMENT                                ~64     $66, 'tokens'
        100      > RETURN                                                   ~64
  137   101*     > RETURN                                                   null


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/ZRaDC
function name:  {closure}
number of ops:  9
compiled vars:  !0 = $m
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  112     0  E >   RECV                                             !0      
          1        INIT_FCALL                                               'constant'
          2        FETCH_DIM_R                                      ~1      !0, 'MARK'
          3        SEND_VAL                                                 ~1
          4        DO_ICALL                                         $2      
          5        FETCH_CONSTANT                                   ~3      'ERROR'
          6        BW_AND                                           ~4      $2, ~3
          7      > RETURN                                                   ~4
          8*     > RETURN                                                   null

End of Dynamic Function 0

Dynamic Function 1
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/ZRaDC
function name:  {closure}
number of ops:  14
compiled vars:  !0 = $m
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  133     0  E >   RECV                                             !0      
          1        FETCH_DIM_R                                      ~1      !0, 0
          2        FETCH_DIM_R                                      ~2      ~1, 0
          3        INIT_ARRAY                                       ~3      ~2, 'value'
          4        FETCH_DIM_R                                      ~4      !0, 0
          5        FETCH_DIM_R                                      ~5      ~4, 1
          6        ADD_ARRAY_ELEMENT                                ~3      ~5, 'offset'
          7        INIT_FCALL                                               'constant'
          8        FETCH_DIM_R                                      ~6      !0, 'MARK'
          9        SEND_VAL                                                 ~6
         10        DO_ICALL                                         $7      
         11        ADD_ARRAY_ELEMENT                                ~3      $7, 'type'
         12      > RETURN                                                   ~3
         13*     > RETURN                                                   null

End of Dynamic Function 1

End of function tokenize

Function checklogic:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 10, Position 2 = 15
Branch analysis from position: 10
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
2 jumps found. (Code = 46) Position 1 = 19, Position 2 = 27
Branch analysis from position: 19
2 jumps found. (Code = 43) Position 1 = 28, Position 2 = 33
Branch analysis from position: 28
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 33
2 jumps found. (Code = 43) Position 1 = 37, Position 2 = 39
Branch analysis from position: 37
1 jumps found. (Code = 42) Position 1 = 52
Branch analysis from position: 52
2 jumps found. (Code = 43) Position 1 = 62, Position 2 = 64
Branch analysis from position: 62
1 jumps found. (Code = 42) Position 1 = 69
Branch analysis from position: 69
2 jumps found. (Code = 44) Position 1 = 73, Position 2 = 15
Branch analysis from position: 73
2 jumps found. (Code = 43) Position 1 = 74, Position 2 = 80
Branch analysis from position: 74
1 jumps found. (Code = 42) Position 1 = 81
Branch analysis from position: 81
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 80
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
Branch analysis from position: 64
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 39
2 jumps found. (Code = 46) Position 1 = 43, Position 2 = 46
Branch analysis from position: 43
2 jumps found. (Code = 43) Position 1 = 47, Position 2 = 52
Branch analysis from position: 47
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 52
Branch analysis from position: 46
Branch analysis from position: 27
filename:       /in/ZRaDC
function name:  checkLogic
number of ops:  83
compiled vars:  !0 = $tokens, !1 = $parenthesis, !2 = $current, !3 = $next
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  139     0  E >   RECV                                             !0      
  140     1        ASSIGN                                                   !1, 0
  141     2        INIT_FCALL                                               'current'
          3        SEND_VAR                                                 !0
          4        DO_ICALL                                         $5      
          5        ASSIGN                                                   !2, $5
  143     6        FETCH_DIM_R                                      ~7      !2, 'type'
          7        FETCH_CONSTANT                                   ~8      'TK_END'
          8        IS_IDENTICAL                                             ~7, ~8
          9      > JMPZ                                                     ~9, ->15
  144    10    >   FETCH_CONSTANT                                   ~10     'ERR_EMPTY_QUERY'
         11        INIT_ARRAY                                       ~11     ~10, 'type'
         12        FETCH_DIM_R                                      ~12     !2, 'offset'
         13        ADD_ARRAY_ELEMENT                                ~11     ~12, 'offset'
         14      > RETURN                                                   ~11
  147    15    >   FETCH_DIM_R                                      ~13     !2, 'type'
         16        FETCH_CONSTANT                                   ~14     'TK_COLUMN_NAME'
         17        IS_IDENTICAL                                     ~15     ~13, ~14
         18      > JMPZ_EX                                          ~15     ~15, ->27
         19    >   INIT_FCALL                                               'in_array'
         20        FETCH_DIM_R                                      ~16     !2, 'value'
         21        SEND_VAL                                                 ~16
         22        FETCH_CONSTANT                                   ~17     'COLUMN_NAMES'
         23        SEND_VAL                                                 ~17
         24        DO_ICALL                                         $18     
         25        BOOL_NOT                                         ~19     $18
         26        BOOL                                             ~15     ~19
         27    > > JMPZ                                                     ~15, ->33
  148    28    >   FETCH_CONSTANT                                   ~20     'ERR_UNKNOW_COLUMN_NAME'
         29        INIT_ARRAY                                       ~21     ~20, 'type'
         30        FETCH_DIM_R                                      ~22     !2, 'offset'
         31        ADD_ARRAY_ELEMENT                                ~21     ~22, 'offset'
         32      > RETURN                                                   ~21
  150    33    >   FETCH_DIM_R                                      ~23     !2, 'type'
         34        FETCH_CONSTANT                                   ~24     'TK_OPENING_PARENTHESIS'
         35        IS_IDENTICAL                                             ~23, ~24
         36      > JMPZ                                                     ~25, ->39
  151    37    >   PRE_INC                                                  !1
  150    38      > JMP                                                      ->52
  152    39    >   FETCH_DIM_R                                      ~27     !2, 'type'
         40        FETCH_CONSTANT                                   ~28     'TK_CLOSING_PARENTHESIS'
         41        IS_IDENTICAL                                     ~29     ~27, ~28
         42      > JMPZ_EX                                          ~29     ~29, ->46
         43    >   PRE_DEC                                          ~30     !1
         44        IS_SMALLER                                       ~31     ~30, 0
         45        BOOL                                             ~29     ~31
         46    > > JMPZ                                                     ~29, ->52
  153    47    >   FETCH_CONSTANT                                   ~32     'ERR_UNEXPECTED_CLOSING_PARENTHESIS'
         48        INIT_ARRAY                                       ~33     ~32, 'type'
         49        FETCH_DIM_R                                      ~34     !2, 'offset'
         50        ADD_ARRAY_ELEMENT                                ~33     ~34, 'offset'
         51      > RETURN                                                   ~33
  155    52    >   INIT_FCALL                                               'next'
         53        SEND_REF                                                 !0
         54        DO_ICALL                                         $35     
         55        ASSIGN                                                   !3, $35
  157    56        FETCH_CONSTANT                                   ~37     'RULES'
         57        FETCH_DIM_R                                      ~38     !2, 'type'
         58        FETCH_DIM_R                                      ~39     ~37, ~38
         59        FETCH_DIM_R                                      ~40     !3, 'type'
         60        BW_AND                                           ~41     ~39, ~40
         61      > JMPZ                                                     ~41, ->64
  158    62    >   ASSIGN                                                   !2, !3
  157    63      > JMP                                                      ->69
  160    64    >   FETCH_CONSTANT                                   ~43     'ERR_UNEXPECTED_TOKEN'
         65        INIT_ARRAY                                       ~44     ~43, 'type'
         66        FETCH_DIM_R                                      ~45     !3, 'offset'
         67        ADD_ARRAY_ELEMENT                                ~44     ~45, 'offset'
         68      > RETURN                                                   ~44
  162    69    >   FETCH_DIM_R                                      ~46     !3, 'type'
         70        FETCH_CONSTANT                                   ~47     'TK_END'
         71        IS_NOT_IDENTICAL                                         ~46, ~47
         72      > JMPNZ                                                    ~48, ->15
  164    73    > > JMPZ                                                     !1, ->80
         74    >   FETCH_CONSTANT                                   ~49     'ERR_MISSING_CLOSING_PARENTHESIS'
         75        INIT_ARRAY                                       ~50     ~49, 'type'
         76        FETCH_DIM_R                                      ~51     !2, 'offset'
         77        ADD_ARRAY_ELEMENT                                ~50     ~51, 'offset'
         78        QM_ASSIGN                                        ~52     ~50
         79      > JMP                                                      ->81
  165    80    >   QM_ASSIGN                                        ~52     <true>
         81    > > RETURN                                                

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
143.54 ms | 1045 KiB | 30 Q