php[022]re2c
coding
re2c 测试运行示例
$ ./integer 1024
decimal
$ ./integer sda
error
$ ./integer 0b10
binary
Re2c 是一个免费的开源词典生成器,适用于 C 和C++。其主要目标是生成与仔细优化的手写代码的速度相匹配或超过速度的快速词典。Re2c 使用有限状态机的直接编码,而不是表驱动的方法,并优化生成的代码。re2c 的另一个显著功能是异常灵活的用户界面:re2c 将接口代码的定义留给用户,而不是假设一个固定的程序模板。这为用户提供了为特定环境和输入模型自定义 lexer 的自由。Re2c 支持使用 POSIX 或最左侧贪婪语义的快速和轻量级子匹配提取。Re2c被许多其他项目使用(如php),旨在完全向后兼容。另一方面,它是一个研究项目和一个游乐场,在正式语法和自动机领域开发新的算法
re2c运行来源参考php源码学习d10 词法分析
https://github.com/skvadrik/re2c
安装
$git clone https://github.com/skvadrik/re2c.git
$cd re2c
$./autogen.sh
$./configure
$ make
$ make install
re2ctest.l
#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("binary\n"); break;
case OCT: printf("octal\n"); break;
case DEC: printf("decimal\n"); break;
case HEX: printf("hexadecimal\n"); break;
}
}
}
re2c转换+g++编译
re2c re2ctest.l -o re2ctest.c && g++ re2ctest.c -o re2ctest
re2ctest
$ ./integer 1024
decimal
$ ./integer sda
error
$ ./integer 0b10
binary
查看re2ctest.c
/* Generated by re2c 1.3 on Mon Jan 20 20:53:54 2020 */
#line 1 "integer.l"
#include <stdio.h>
enum num_t { ERR, BIN, OCT, DEC, HEX};
static num_t lex(const char *YYCURSOR)
{
const char *YYMARKER;
#line 10 "integer.c"
{
char yych;
yych = *YYCURSOR;
switch (yych) {
case '0': goto yy4;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy5;
default: goto yy2;
}
yy2:
++YYCURSOR;
yy3:
#line 14 "integer.l"
{return ERR;}
#line 32 "integer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
case 0x00: goto yy6;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': goto yy8;
case 'B':
case 'b': goto yy11;
case 'X':
case 'x': goto yy12;
default: goto yy3;
}
yy5:
yych = *(YYMARKER = ++YYCURSOR);
switch (yych) {
case 0x00: goto yy13;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy15;
default: goto yy3;
}
yy6:
++YYCURSOR;
#line 16 "integer.l"
{return OCT;}
#line 71 "integer.c"
yy8:
yych = *++YYCURSOR;
switch (yych) {
case 0x00: goto yy6;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': goto yy8;
default: goto yy10;
}
yy10:
YYCURSOR = YYMARKER;
goto yy3;
yy11:
yych = *++YYCURSOR;
if (yych <= 0x00) goto yy10;
goto yy18;
yy12:
yych = *++YYCURSOR;
if (yych <= 0x00) goto yy10;
goto yy20;
yy13:
++YYCURSOR;
#line 17 "integer.l"
{return DEC;}
#line 101 "integer.c"
yy15:
yych = *++YYCURSOR;
switch (yych) {
case 0x00: goto yy13;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy15;
default: goto yy10;
}
yy17:
yych = *++YYCURSOR;
yy18:
switch (yych) {
case 0x00: goto yy21;
case '0':
case '1': goto yy17;
default: goto yy10;
}
yy19:
yych = *++YYCURSOR;
yy20:
switch (yych) {
case 0x00: goto yy23;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f': goto yy19;
default: goto yy10;
}
yy21:
++YYCURSOR;
#line 15 "integer.l"
{return BIN;}
#line 160 "integer.c"
yy23:
++YYCURSOR;
#line 18 "integer.l"
{return HEX;}
#line 165 "integer.c"
}
#line 19 "integer.l"
}
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("binary\n"); break;
case OCT: printf("octal\n"); break;
case DEC: printf("decimal\n"); break;
case HEX: printf("hexadecimal\n"); break;
}
}
}
评论列表