1.词法分析
将代码解析成token数组,查看token数组的方法 token_get_all()
$tokens = token_get_all('<?php $a = 1; echo $a; ?>');
foreach ($tokens as $token) {
if (is_array($token)) {
echo "Line {$token[2]}: ", token_name($token[0]), " ('{$token[1]}')", PHP_EOL;
}
}
2.状态机
状态机:有开始,有结束,有中间状态,满足条件跳入其他状态。
有穷状态机:是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
不确定有穷状态机NFA :同一个动作下个状态不确定。
确定有穷状态机DFA:同一个动作下个状态唯一确定。
正则表达式(a|b)*add 的NFA(遇到第一个a不确定是往下走还是回到自己)
正则表达式(a|b)*add 的DFA:
3. re2c的安装
http://re2c.org/install/install.html
下载
git clone https://git.code.sf.net/p/re2c/code-git re2c
构建
cd re2c/
./autogen.sh
./configure --prefix=/usr/local/re2c/
make
make install
软连
ln -sf /usr/local/re2c/bin/re2c /usr/local/bin/re2c
检查
re2c -v
re2c -h
4.从正则表达式到DFA可借助工具
执行命令:
re2c xxx.l -o xxx.c
g++ xxx.c -o xxx
#include <stdio.h>
enum num_t { ERR, BIN, OCT, DEC, HEX };
static num_t lex(const char *YYCURSOR)
{
const char *YYMARKER;
/*!re2c
re2c:define:YYCTYPE = char;
re2c:yyfill:enable = 0;
end = "\x00";
bin = '0b'[01]+;
oct = "0"[0-7]*;
dec = [1-9][0-9]*;
hex = '0x'[0-9a-fA-F]+;
* { return ERR; }
bin end { return BIN; }
oct end { return OCT; }
dec end { return DEC; }
hex end { return HEX; }
*/
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
switch (lex(argv[i])) {
case ERR: printf("error\n"); break;
case BIN: printf("erjinzhi\n"); break; // 2
case OCT: printf("octal\n"); break; // 8
case DEC: printf("decimal\n"); break; // 10
case HEX: printf("hexadecimal\n"); break; // 16
}
}
return 0;
}
5.笔记地址