1.树的基本知识回顾
中:左跟右
前:跟左右
后:左右跟
遍历数可采用 递归,压栈,队列(层次遍历)等方式
2.抽象语法树结构源码
enum _zend_ast_kind {
/* special nodes */
ZEND_AST_ZVAL = 1 << ZEND_AST_SPECIAL_SHIFT, // 64
ZEND_AST_ZNODE, // 65
/* declaration nodes */
ZEND_AST_FUNC_DECL, // 66
ZEND_AST_CLOSURE, // 67
ZEND_AST_METHOD, // 68
ZEND_AST_CLASS, //69
/* list nodes 对应下边_zend_ast_list*/
ZEND_AST_ARG_LIST = 1 << ZEND_AST_IS_LIST_SHIFT, // 128
ZEND_AST_ARRAY, // 129
ZEND_AST_ENCAPS_LIST, // 130
ZEND_AST_EXPR_LIST, // 131
ZEND_AST_STMT_LIST, // 132
ZEND_AST_IF, // 133
ZEND_AST_SWITCH_LIST, // 134
ZEND_AST_CATCH_LIST, // 135
ZEND_AST_PARAM_LIST, // 136
ZEND_AST_CLOSURE_USES, // 137
ZEND_AST_PROP_DECL, // 138
ZEND_AST_CONST_DECL, //139
ZEND_AST_CLASS_CONST_DECL, //140
ZEND_AST_NAME_LIST, // 141
ZEND_AST_TRAIT_ADAPTATIONS, // 142
ZEND_AST_USE, //143
/* 0 child nodes */
ZEND_AST_MAGIC_CONST = 0 << ZEND_AST_NUM_CHILDREN_SHIFT, // 0
ZEND_AST_TYPE, // 1
/* 1 child node */
ZEND_AST_VAR = 1 << ZEND_AST_NUM_CHILDREN_SHIFT, // 256
ZEND_AST_CONST, // 257
ZEND_AST_UNPACK, // 258
ZEND_AST_UNARY_PLUS, // 259
ZEND_AST_UNARY_MINUS, // 260
ZEND_AST_CAST, // 261
ZEND_AST_EMPTY, // 262
ZEND_AST_ISSET, // 263
ZEND_AST_SILENCE, // 264
ZEND_AST_SHELL_EXEC, // 265
ZEND_AST_CLONE, // 266
ZEND_AST_EXIT, // 267
ZEND_AST_PRINT, // 268
ZEND_AST_INCLUDE_OR_EVAL, // 269
ZEND_AST_UNARY_OP, // 270
ZEND_AST_PRE_INC, // 271
ZEND_AST_PRE_DEC, // 272
ZEND_AST_POST_INC, // 273
ZEND_AST_POST_DEC, // 274
ZEND_AST_YIELD_FROM, // 275
ZEND_AST_GLOBAL, // 276
ZEND_AST_UNSET, // 277
ZEND_AST_RETURN, // 278
ZEND_AST_LABEL, // 279
ZEND_AST_REF, // 280
ZEND_AST_HALT_COMPILER, // 281
ZEND_AST_ECHO, // 282
ZEND_AST_THROW, // 283
ZEND_AST_GOTO, // 284
ZEND_AST_BREAK, // 285
ZEND_AST_CONTINUE, // 286
/* 2 child nodes */
ZEND_AST_DIM = 2 << ZEND_AST_NUM_CHILDREN_SHIFT, // 512
ZEND_AST_PROP, // 513
ZEND_AST_STATIC_PROP, // 514
ZEND_AST_CALL, // 515
ZEND_AST_CLASS_CONST, // 516
ZEND_AST_ASSIGN, // 517
ZEND_AST_ASSIGN_REF, // 518
ZEND_AST_ASSIGN_OP, // 519
ZEND_AST_BINARY_OP, // 520
ZEND_AST_GREATER, // 521
ZEND_AST_GREATER_EQUAL, // 522
ZEND_AST_AND, // 523
ZEND_AST_OR, // 524
ZEND_AST_ARRAY_ELEM, // 525
ZEND_AST_NEW, // 526
ZEND_AST_INSTANCEOF, // 527
ZEND_AST_YIELD, // 528
ZEND_AST_COALESCE, // 529
ZEND_AST_STATIC, // 530
ZEND_AST_WHILE, // 531
ZEND_AST_DO_WHILE, // 532
ZEND_AST_IF_ELEM, // 533
ZEND_AST_SWITCH, // 534
ZEND_AST_SWITCH_CASE, // 535
ZEND_AST_DECLARE, // 536
ZEND_AST_USE_TRAIT, // 537
ZEND_AST_TRAIT_PRECEDENCE, // 538
ZEND_AST_METHOD_REFERENCE, // 539
ZEND_AST_NAMESPACE, // 540
ZEND_AST_USE_ELEM, // 541
ZEND_AST_TRAIT_ALIAS, // 542
ZEND_AST_GROUP_USE, // 543
/* 3 child nodes */
ZEND_AST_METHOD_CALL = 3 << ZEND_AST_NUM_CHILDREN_SHIFT, // 768
ZEND_AST_STATIC_CALL, // 769
ZEND_AST_CONDITIONAL, // 770
ZEND_AST_TRY, // 771
ZEND_AST_CATCH, // 772
ZEND_AST_PARAM, // 773
ZEND_AST_PROP_ELEM, // 774
ZEND_AST_CONST_ELEM, // 775
/* 4 child nodes */
ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT, // 1024
ZEND_AST_FOREACH, // 1025
};
struct _zend_ast {
zend_ast_kind kind; /* 类型 前119行对其细分 Type of the node (ZEND_AST_* enum constant) */
zend_ast_attr attr; /* Additional attribute, use depending on node type */
uint32_t lineno; /* 代码行数 Line number */
zend_ast *child[1]; /* Array of children (using struct hack) */
};
/* Same as zend_ast, but with children count, which is updated dynamically */
typedef struct _zend_ast_list {
zend_ast_kind kind;
zend_ast_attr attr;
uint32_t lineno;
uint32_t children;
zend_ast *child[1];
} zend_ast_list;
/* zval 存储Lineno is stored in val.u2.lineno */
typedef struct _zend_ast_zval {
zend_ast_kind kind;
zend_ast_attr attr;
zval val;
} zend_ast_zval;
/* Separate structure for function and class declaration, as they need extra information. */
typedef struct _zend_ast_decl {
zend_ast_kind kind;
zend_ast_attr attr; /* Unused - for structure compatibility */
uint32_t start_lineno;
uint32_t end_lineno;
uint32_t flags;
unsigned char *lex_pos;
zend_string *doc_comment;
zend_string *name;
zend_ast *child[4];
} zend_ast_decl;
2.抽象语法树结构示例
b zend_compile
p compiler_globals.ast(592行) init_op_array(op_array, type, INITIAL_OP_ARRAY_SIZE);
例1:
$a = 1;
$b = $a + 1;
例2:
$a = ( 1 + 2 ) * 3;
例3
$a = [1];
foreach ($a as $k => $v)
{
echo $v;
}
// 11include.php
$a = 1;
例4
include "11include.php";
$a += 2;
例5
include_once "include.php"
$a += 333;
3.笔记地址