关于中文编程的一些思考( 三 )


[ opcode结构 ]
为什么说 , 类似于汇编码呢?通过上面结构体可以看到几个关键字段:
操作数:op1、op2
返回值:result
操作数类型:op1_type、op2_type
返回值类型:result_type
操作动作:handler指针指向具体的操作动作处理方法
3.2 PHP中间代码与C汇编下面分别使用解释型语言PHP、编译型语言C来实现相同的加法功能 , 并查看其中间码(下图显示的是简化之后的中间码) , 进行对比分析 。
关于中文编程的一些思考文章插图
[ 实现加法功能的PHP源码与中间码opcode ]
这里获取PHP中间码opcode(可以结合3.2中zend_op结构体来分析) , 使用的是vld扩展 。
关于中文编程的一些思考文章插图
这里获取C的中间码汇编 , 使用的是objdump命令 。
通过对比可以发现 , PHP的中间码与C语言的中间码具有某种相似性 。
例如 , 实现a+b的操作:
// 汇编add%edx,%eax// opcodeADD~4!0, !11.都有对应的操作指令
2.都有两个操作数
3.都有存储结果的位置
看到这里 , 是不是感觉发现了什么不得了的东西 。
解释型语言的虚拟机 , 对应着的是编译型语言更底层执行逻辑的抽象 。 解释型语言的中间码 , 对应着的是编译型语言中间码的抽象 。
各种语言的实现方式可能不太一样 , 但是实现原理是类似的 。 有些比较也可能看似有点牵强 , 但是采用这种方式却更容易理解 。
3.3 自定义词法规则笔者本次所用php源码版本为 php-7.4.10 。
词法分析规则文件:php-7.4.10/Zend/zend_language_scanner.l
关于中文编程的一些思考文章插图
[ PHP原生词法规则 ]
关于中文编程的一些思考文章插图
[ 原生词法规则与token的映射 ]
为了实现1.2示例中的代码 , 添加了几个自定义了词法规则 。
关于中文编程的一些思考文章插图
[ 添加自定义词法规则 ]
关于中文编程的一些思考文章插图
[ 添加的自定义词法规则与token的映射 ]
词法分析器遇到一个词汇 , 就去查询一本词典(词法规则) 。 如果查到了该词汇的话 , 则会得到一个合规的token , 接下来把token传递给语法分析器进行后续处理 。
在这里 , 笔者只是在词法分析器的词典中多添加了几个条目 , 把新增的几个条目映射到原有的合法token上去 , 也正是这几个条目使得1.2处代码可以正确的执行(虽然是中文编写的 , 但是词法分析器可以正确的识别其含义) 。
3.4 自定义词法验证俗话说 , 无图无真相 。 下面来验证自定义的词法所产生的token是否是预期的 。
关于中文编程的一些思考文章插图
[ 获取1.2示例代码的token ]
关于中文编程的一些思考文章插图
[ 1.2示例代码对应的token ]
从获取的token序列中可以看到 , 添加的词法规则被识别成了正确的对应token:
'如果' -> T_IF
'否则' -> T_ELSE
'输出' -> T_ECHO
也正是这一步操作 , 使得1.2示例中的中文代码demo可以被PHP程序正确执行 。
4. 添加自定义词法规则步骤这里详细记录一下 , 笔者添加自定义词法规则以及编译的过程 。