1 /*
2 * phpdbg_lexer.l
3 */
4
5 #include "phpdbg.h"
6 #include "phpdbg_cmd.h"
7
8 #include "phpdbg_parser.h"
9
10 #define LEX(v) (PHPDBG_G(lexer).v)
11
12 #define YYCTYPE unsigned char
13 #define YYSETCONDITION(x) LEX(state) = x;
14 #define YYGETCONDITION() LEX(state)
15 #define YYCURSOR LEX(cursor)
16 #define YYMARKER LEX(marker)
17 #define YYCTXMARKER LEX(ctxmarker)
18 #define yyleng LEX(len)
19 #define yytext ((char*) LEX(text))
20 #undef YYDEBUG
21 #define YYDEBUG(a, b)
22 #define YYFILL(n)
23
24 #define NORMAL 0
25 #define PRE_RAW 1
26 #define RAW 2
27 #define INITIAL 3
28
ZEND_EXTERN_MODULE_GLOBALS(phpdbg)29 ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
30
31 void phpdbg_init_lexer (phpdbg_param_t *stack, char *input) {
32 PHPDBG_G(parser_stack) = stack;
33
34 YYSETCONDITION(INITIAL);
35
36 LEX(text) = YYCURSOR = (unsigned char *) input;
37 LEX(len) = strlen(input);
38 }
39
unescape_string(char * s)40 static int unescape_string(char *s) {
41 switch (*s) {
42 case '\'':
43 case '\"': {
44 char start = *s;
45 size_t off = 1;
46 do {
47 if (s[off] == '\\') {
48 off++;
49 }
50 *s = s[off];
51 } while ((++s)[off] != start);
52 return off + 1;
53 }
54 }
55
56 return 0;
57 }
58
phpdbg_lex(phpdbg_param_t * yylval)59 int phpdbg_lex (phpdbg_param_t* yylval) {
60
61 restart:
62 LEX(text) = YYCURSOR;
63
64 /*!re2c
65 re2c:yyfill:check = 0;
66 T_TRUE 'true'
67 T_YES 'yes'
68 T_ON 'on'
69 T_ENABLED 'enabled'
70 T_FALSE 'false'
71 T_NO 'no'
72 T_OFF 'off'
73 T_DISABLED 'disabled'
74 T_EVAL 'ev'
75 T_SHELL 'sh'
76 T_IF 'if'
77 T_RUN 'run'
78 T_RUN_SHORT "r"
79 WS [ \r\t]+
80 DIGITS [-]?[0-9\.]+
81 ID [^ \r\n\t:#\000]+
82 GENERIC_ID ([^ \r\n\t:#\000"']|":\\")+|["]([^\n\000"\\]|"\\\\"|"\\"["])+["]|[']([^\n\000'\\]|"\\\\"|"\\"['])+[']
83 ADDR [0][x][a-fA-F0-9]+
84 OPCODE (ZEND_|zend_)([A-Z_a-z])+
85 INPUT ("\\"[#"']|["]("\\\\"|"\\"["]|[^\n\000"])*["]|[']("\\"[']|"\\\\"|[^\n\000'])*[']|[^\n\000#"'])+
86
87 <!*> := yyleng = (size_t) YYCURSOR - (size_t) yytext;
88
89 <*>[\n\000] {
90 return 0;
91 }
92
93 <PRE_RAW, NORMAL>"-r"{WS}?{DIGITS} {
94 char *text = yytext + 2;
95 while (*++text < '0');
96 yylval->num = atoi(text);
97 return T_REQ_ID;
98 }
99
100 <NORMAL>{T_IF}{WS} {
101 YYSETCONDITION(RAW);
102 phpdbg_init_param(yylval, EMPTY_PARAM);
103 return T_IF;
104 }
105
106 <NORMAL>"#"/{DIGITS} {
107 return T_POUND;
108 }
109
110 <*>"#" {
111 YYSETCONDITION(INITIAL);
112 return T_SEPARATOR;
113 }
114
115 <NORMAL>"::" {
116 return T_DCOLON;
117 }
118
119 <NORMAL>":"/[^\\] {
120 return T_COLON;
121 }
122
123 <NORMAL>{ID}"://" {
124 phpdbg_init_param(yylval, STR_PARAM);
125 yylval->str = estrndup(yytext, yyleng);
126 yylval->len = yyleng;
127 return T_PROTO;
128 }
129
130 <NORMAL>({T_YES}|{T_ON}|{T_ENABLED}|{T_TRUE})/[ \r\t\n\000] {
131 phpdbg_init_param(yylval, NUMERIC_PARAM);
132 yylval->num = 1;
133 return T_TRUTHY;
134 }
135
136 <NORMAL>({T_NO}|{T_OFF}|{T_DISABLED}|{T_FALSE})/[ \r\t\n\000] {
137 phpdbg_init_param(yylval, NUMERIC_PARAM);
138 yylval->num = 0;
139 return T_FALSY;
140 }
141
142 <NORMAL>{DIGITS} {
143 phpdbg_init_param(yylval, NUMERIC_PARAM);
144 yylval->num = atoi(yytext);
145 return T_DIGITS;
146 }
147
148 <NORMAL>{ADDR} {
149 phpdbg_init_param(yylval, ADDR_PARAM);
150 yylval->addr = strtoul(yytext, 0, 16);
151 return T_ADDR;
152 }
153
154 <NORMAL>{OPCODE} {
155 phpdbg_init_param(yylval, OP_PARAM);
156 yylval->str = estrndup(yytext, yyleng);
157 yylval->len = yyleng;
158 return T_OPCODE;
159 }
160
161 <NORMAL>{GENERIC_ID} {
162 phpdbg_init_param(yylval, STR_PARAM);
163 yylval->str = estrndup(yytext, yyleng - unescape_string(yytext));
164 yylval->len = yyleng;
165 return T_ID;
166 }
167
168 <RAW>{INPUT} {
169 phpdbg_init_param(yylval, STR_PARAM);
170 yylval->str = estrdup(yytext);
171 yylval->len = yyleng;
172 return T_INPUT;
173 }
174
175 <*>{WS} {
176 /* ignore whitespace */
177
178 goto restart;
179 }
180
181 <INITIAL>{T_EVAL}{WS} {
182 YYSETCONDITION(PRE_RAW);
183 phpdbg_init_param(yylval, EMPTY_PARAM);
184 return T_EVAL;
185 }
186
187 <INITIAL>{T_SHELL}{WS} {
188 YYSETCONDITION(PRE_RAW);
189 phpdbg_init_param(yylval, EMPTY_PARAM);
190 return T_SHELL;
191 }
192
193 <INITIAL>({T_RUN}|{T_RUN_SHORT}){WS} {
194 YYSETCONDITION(PRE_RAW);
195 phpdbg_init_param(yylval, EMPTY_PARAM);
196 return T_RUN;
197 }
198
199 <PRE_RAW>[^ ] {
200 YYSETCONDITION(RAW);
201
202 YYCURSOR = LEX(text);
203 goto restart;
204 }
205
206 <INITIAL>[^ ] {
207 YYSETCONDITION(NORMAL);
208
209 YYCURSOR = LEX(text);
210 goto restart;
211 }
212
213 */
214 }
215