落地窗前梦残夜 2019-07-01
baiyan
原视频地址:http://replay.xesv5.com/ll/24...
之所以需要做这种从字符串到数据结构(AST)的转换,是因为编译器是无法直接操作“1+2”这样的字符串的。实际上,代码的本质根本就不是字符串,它本来就是一个具有复杂拓扑的数据结构,就像电路一样。“1+2”这个字符串只是对这种数据结构的一种“编码”,就像ZIP或者JPEG只是对它们压缩的数据的编码一样。
这种编码可以方便你把代码存到磁盘上,方便你用文本编辑器来修改它们(对人友好,方便人们编写代码,但是对编译器不友好),然而你必须知道,文本并不是代码本身。所以从磁盘读取了文本之后,你必须先“解码”,才能方便地操作代码的数据结构。比如,如果上面的Java代码生成的AST节点叫node,你就可以用node.operator来访问加号ADD,用node.left来访问1,node.right来访问2。这是很方便的。对于程序语言,这种解码的动作就叫做parsing,用于解码的那段代码就叫做parser。
<?php $lan = '<?php $a = 1; echo $a'; $tokens = token_get_all($lan); foreach ($tokens as $token) { if (is_array($token)) { echo "Line {$token[2]}: ", token_name($token[0]), " ('{$token[1]}')", PHP_EOL; } }
Line 1: T_OPEN_TAG ('<?php ') Line 1: T_VARIABLE ('$a') Line 1: T_WHITESPACE (' ') Line 1: T_WHITESPACE (' ') Line 1: T_LNUMBER ('1') Line 1: T_WHITESPACE (' ') Line 1: T_ECHO ('echo') Line 1: T_WHITESPACE (' ') Line 1: T_VARIABLE ('$a')
那么让我们你自己去设计一个算法,从一个字符串中识别并取出token,应该怎么做?
例:观察下面这个正则表达式:
(a|b)*abb
- 对于a,只能到状态0或者1,不能到达结束的3,所以不匹配 - 对于abb,第一个a可以使状态0跃迁到1,第二个b可以从1跃迁到2,最后一个b结束,所以匹配 - 对于aabb,第一个a可以选择从0跃迁到0,第二个从0跃迁到1,后面两个b同上,匹配 - 对于cabb,第一个c就无法满足,不匹配
<?php. if (!empty($_POST)) {. $data1 = $_POST["data1"];$data2 = $_POST["data2"];$fuhao = $_POST["fuh