1

最小示例代码:

<?php

    $avarname = 'a var value';

    function a_function_name($a_parameter = true)
    {
        // a comment
    }

    a_function_name();

使用 token_get_all() 的结构:

T_OPEN_TAG: <?php
T_WHITESPACE:
T_VARIABLE: $avarname
T_WHITESPACE:
T_WHITESPACE:
T_CONSTANT_ENCAPSED_STRING: 'a var value'
T_WHITESPACE:
T_FUNCTION: function
T_WHITESPACE:
T_STRING: a_function_name
T_VARIABLE: $a_parameter
T_WHITESPACE:
T_WHITESPACE:
T_STRING: true
T_WHITESPACE:
T_WHITESPACE:
T_COMMENT: // a comment
T_WHITESPACE:
T_WHITESPACE:
T_STRING: a_function_name
T_WHITESPACE:

如您所见,可以通过检查T_STRING、前面是T_WHITESPACE和前面的T_FUNCTION来检测函数定义。到目前为止,一切都很好。

但是,函数调用只是一个T_STRING,就像许多其他事物一样,例如参数的“真实”常量,在它之前或之后都没有特殊符号。

如果在 T_STRING 之前没有符号告诉我的解释器下一个 T_STRING 应该指什么,我怎么知道它指函数名还是其他东西

如果您的回答是我需要检查是否存在名称为 T_STRING 值的函数,这是否意味着不存在名为 true() 的函数?因为那会与“真实”常数冲突?如果我需要进行这样的检查,它会以许多不同的方式使事情复杂化......

4

1 回答 1

2

token_get_all 实际返回的是这个(已经后处理的令牌名称):

  ...,
  [26]=>
  array(3) {
    [0]=>
    string(8) "T_STRING"
    [1]=>
    string(15) "a_function_name"
    [2]=>
    int(10)
  }
  [27]=>
  string(1) "("
  [28]=>
  string(1) ")"

token_get_all仅进行标记化,它不会将部分解析为逻辑 AST。之后的下一步是查看令牌如何组合在一起以及它们形成的逻辑单元。在这里,您需要将三个连续的标记“ a_function_name”、“ (”和“ )”解析为函数调用

您可能希望使用现有的PHP Parser,而不是从头开始重新设计这一步。

于 2020-03-10T08:10:48.467 回答