放在这,没事儿了我就总结几个

1 child nodes

AST_VAR

截屏2020-07-14 下午4.07.05
1
$var

AST_ECHO

截屏2020-07-27 下午3.42.44

2 child nodes

AST_CALL

函数调用点

截屏2020-06-01 下午5.41.28

1
$a = foo('a');
  • child0: ARG_LIST - 参数列表
  • child1: 调用函数名

AST_DIM

数组引用

截屏2020-06-01 下午5.48.46

1
$a = foo['a'];
  • child0: 数组名
  • child1: 索引值

ZEND_AST_PROP

属性调用

截屏2020-06-20 下午4.39.26

1
$obj->val;
  • child0: objetct_name
  • child1: attr

ZEND_AST_WHILE

截屏2020-06-20 下午4.42.05

1
2
3
while($a==1){
[stmt_list]...
}
  • child0: condtion
  • child1: stmt_list

AST_IF_ELEMET

区别于AST_IF

截屏2020-07-14 下午4.37.36

AST_IF这个list下连接的每一个分支都由一个IF_ELEMENT进入。

  • Child0 :条件判定式
  • Child1: 代码语句块

AST_BINARY_OP

二元操作

截屏2020-07-14 下午4.51.41

控制流、数据流走判定表达式的话都是直接连这个点。代表整个二元操作表达式。

在PHP-AST这个项目中, 此点有flags字段,决定作用方法:

https://github.com/nikic/php-ast/blob/1b5d767dd326f535288786130b2215744feb2cbf/tests/metadata.phpt#L97

  • 位逻辑运算 BINARY_BITWISE_OR, BINARY_BITWISE_AND, BINARY_BITWISE_XOR,

  • 布尔逻辑运算 BINARY_BOOL_AND, BINARY_BOOL_OR, BINARY_BOOL_XOR,

  • 算术运算 BINARY_ADD, BINARY_SUB, BINARY_MUL, BINARY_DIV, BINARY_MOD, BINARY_POW,

  • 位运算 BINARY_SHIFT_LEFT, BINARY_SHIFT_RIGHT,

  • 相等关系运算 BINARY_IS_EQUAL, BINARY_IS_NOT_EQUAL,

  • 小于关系运算 BINARY_IS_SMALLER, BINARY_IS_SMALLER_OR_EQUAL,

  • 等于运算 BINARY_IS_GREATER, BINARY_IS_GREATER_OR_EQUAL,

  • 连接操作 BINARY_CONCAT,

  • 其他(就是还不懂) BINARY_COALESCE,BINARY_IS_IDENTICAL, BINARY_IS_NOT_IDENTICAL, BINARY_SPACESHIP

AST_ASSIGN

另一个非常常见的两孩子点,就是赋值语句。当然, 左值和右值。

数据流最爱连接的节点:

截屏2020-07-14 下午5.07.42

截屏2020-07-14 下午5.09.18

1
$a = foo();
  • 0child:左值(通常是变量)
  • 1child: 右值(一波操作)

追踪数据流变量在这一级上追踪。

AST_ARRAY_ELEMENT

截屏2020-07-27 下午9.26.11

1
2
3
4
5
6
$arr = array(
'a' => '1',
'b' => '2',
'c' => '3',
'd' => '4',
);

3 child nodes

AST_METHOD_CALL

截屏2020-06-20 下午4.52.15

1
$stu->getScore('math');
  • child0: var:stu //比AST_CALL多一个对象名
  • child1: name: getScore
  • child2: args:math //arg list

AST_STATIC_CALL

截屏2020-06-20 下午5.00.15

1
stu::getScore('math');
  • child0: class:stu (直接指向该类)
  • child1: name: getScore
  • child2: args: math

AST_CONDITIONAL

截屏2020-06-20 下午5.05.39

4 child nodes

AST_FOREACH

截屏2020-06-20 下午3.42.11

1
2
3
4
5
foreach($arr as $k => $v){
echo $k.$v;
}


  • child0: expr: $arr
  • child1: keyVar: $k
  • child2: valueVar: $v
  • child3: stmts: 代码块list (ZEND_AST_STMT_LIST)

ZEND_AST_FOR

截屏2020-06-20 下午3.50.18

1
2
3
4
for ($i=0; $i<=1; $i++)
{
echo $i;
}
  • child0: init: $i=0
  • child1: condtion: $i<=1
  • child2: loop: $i++
  • child3: 代码块list (ZEND_AST_STMT_LIST)

list nodes

AST_ARG_LIST = 1 //函数参数列表(实参)

AST_ARRAY //数组成员列表

截屏2020-07-27 下午9.26.11

1
2
3
4
5
6
$arr = array(
'a' => '1',
'b' => '2',
'c' => '3',
'd' => '4',
);

AST_EXPR_LIST

AST_STMT_LIST //表达式块

AST_IF //if判断条件列表

AST_SWITCH_LIST

AST_CATCH_LIST

AST_PARAM_LIST //形参

AST_CLOSURE_USES

AST_PROP_DECL

AST_CONST_DECL

AST_CLASS_CONST

AST_NAME_LIST AST_TRAIT_ADAPTATIONS AST_USE AST_TYPE_UNION AST_ATTRIBUTE_LIST

AST_STMT_LIST

最常见的块

截屏2020-07-14 下午5.30.15

儿孙满堂, 一般从这个点跳到块中各个语句中。

AST_IF_LIST

截屏2020-07-14 下午5.14.28


一个分支结构的入口, 因为分支结构是不确定的, 所以是list,从这个点可以纵览分支结构有几个。一般不连控制流边(控制流边一般练到数据操作表达式点上如BINARY_OP,ASSIGN)。

下边的每一个分支入口,都是一个AST_IF(二元):

1
2
3
4
5
6
7
8
9
AST_IF-> 0child(AST_IF_ELEMENT0)
-> 1child(AST_IFELEMENT1)
if(0child){
1child;
}
else 0child:null
{
1child;
}

注: AST没有else节点,每个分支块都是一个AST_IF。

declaration nodes

声明式语句

/* declaration nodes */
ZEND_AST_FUNC_DECL
ZEND_AST_CLOSURE
ZEND_AST_METHOD
ZEND_AST_CLASS
ZEND_AST_ARROW_FUNC

控制流起始点:

  • AST_CLASS
  • AST_FUNC