PHP的抽象语法树相关解析

前段时间的自学笔记,直接转载本人印象笔记上的内容,如若侵权请联系我,如有错误请指出

抽象语法树的概念

树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

抽象语法树相关装载器与转化

在进行PHP与AST的互相转化前,需要下载官方文档中的“autoload.php”文件并引用。

将PHP代码转化为AST:

$parser = (new ParserFactory())->createForHostVersion();
try {
    $ast = $parser->parse($code);
} catch (Error $e) {
    echo 'Parse Error: ', $e->getMessage();
    return;
}

将AST转化为PHP代码:

    $prettyPrinter = new PrettyPrinter\Standard();    
    $code = $prettyPrinter->prettyPrint($ast);   
    echo $code;   
} catch (Error $e) {
    echo  $e->getMessage();
    return;
}

抽象语法树的节点分析

以最常见的一句话木马为例:
eval($_GET[pass]);

其转化为AST的结果是:

array(
    0: Stmt_Expression(
        expr: Expr_Eval(
            expr: Expr_ArrayDimFetch(
                var: Expr_Variable(
                    name: _GET
                )
                dim: Expr_ConstFetch(
                    name: Name(
                        name: pass
                    )
                )
            )
        )
    )
)

根据本段AST分析其结构。

一句或一段闭合的代码转化为AST就是一个完整的树状结构,结构的起点为stmt节点,属于stmt的节点有:

stmt_expression:表达式语句,如基础的变量定义和赋值等

stmt_function:定义方法的代码段

stmt_class:定义类的代码段

stmt_if/while/do/for/foreach/switch/case:条件语句、循环语句等

stmt_return/throw/break/continue/trycatch/catch/echo:返回值、异常处理、跳出循环等

以上是我在代码编写过程中实际遇到的,如有遗漏欢迎补充

  • 子节点中最常见的节点为expr节点,一般用stmt->expr的方式调用子节点或子节点的name、value等属性
  • 两个子节点有相同的父节点,用左右表示,多个子节点有相关父节点,用0123表示
  • 调用函数的语句一般包含expr_函数名节点,赋值语句则为expr_assign节点,调用自定义函数是,为expr_funcall节点
  • dim与expr:   scalar和expr
expr: Expr_ArrayDimFetch:数组:数组中变量名与[]中的内容是并列关系。一个为变量var: Expr_Variable,一个为常量键对键组名dim: Expr_ConstFetch或常量数字dim: Scalar_Int  
var: Expr_Variable:变量,只需申明变量名 name:xxx
dim: Expr_ConstFetch:常量键名,若键名为pass,可以理解为隐含一个name:键名;键名:pass;的语句,在表达时需要先申明name:Name,再申明name:pass
dim: Scalar_Int:整型标量,只需申明value:xx
expr: Scalar_Int:$a=0中0的代表,只需申明value
dim与expr的区别:expr指向变量、标量本身,dim指向变量/标量所指向的位置
scalar:语句本身,一般是字符串,不需要运算
expr:语句结果,需要运算 
scalar标量,包含int、string、LNumber等类型,单个字符不归为char而是归为string
非直接值,由两个及以上节点组成的值用expr进行申明,特征是括号和运算符
expr: Scalar_InterpolatedString:拼接字符串,被认为由数组拼接,会将子节点分为0、1等排序,而非左右节点,子节点中的字符串常量由value申明,变量申明的是name
  • 20
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值