到目前为止,我们已经实现了yaphp
源代码到AST
的生成工作。但是,我们对echo
语句的实现还是简单处理了,之前的实现如下:
1 | statement: |
可以看到,这里实际上我们没有体现出T_ECHO
的功能,我们仅仅处理了expr
。所以,这里我们需要去处理一下。
有了前面的基础之后,我们可以非常轻松的来实现这个AST
的生成。
我们修改后的规则如下:
1 | statement: |
可以看到,我们加了一个echo_expr
,用来创建一个ZEND_AST_ECHO
类型的AST
。这里,我们的语法和php-src
的有点不同,php-src
的语法功能更加的丰富一点,它支持echo
后面跟一个ZEND_AST_STMT_LIST
,这个的实现也是比较简单的,和我们之前创建top_statement_list
的思路是一致的。这里小伙伴们可以自己去实现一下,我们的yaphp
就不支持这种可有可无的语法了。
其中,zend_ast_create_1
的实现如下:
1 | zend_ast *zend_ast_create_1(zend_ast_kind kind, zend_ast_attr attr, zend_ast *child) { |
然后,我们需要在_zend_ast_kind
中增加一个ZEND_AST_ECHO
:
1 | /* 1 child node */ |
最后,我们再修改一下我们的dump_compiler_globals
函数:
1 | else if (ast->kind > ZEND_AST_0_NODE_END && ast->kind < ZEND_AST_1_NODE_END) { |
其中,ZEND_AST_0_NODE_END
, ZEND_AST_1_NODE_END
, ZEND_AST_2_NODE_END
这三个zend_ast
节点类型php-src
是没有的,这里是为了方便调试给加上的,否则,我们每次增加一个zend_ast
节点类型,就需要写一个if
语句。
现在,让我们来编译一下yaphp
,并且运行,结果如下:
1 | create * zend_ast |
符合我们的预期。