php-src/sapi/phpdbg/phpdbg_lexer.l
Christoph M. Becker 95a13ca989 Revert fix for bug 76813 and re2c version bump
CentOS 7 ships with re2c 0.13.5 by default, so we should not have
bumped the required re2c version to 0.13.7.  However, 0.13.5 does not
support default rules, so we cannot use them to fix bug 76813.

This reverts commit 420184ad52 and
5e15c9c41f.

Closes GH-6593.
2021-01-11 17:19:52 +01:00

214 lines
3.8 KiB
Text

/*
* phpdbg_lexer.l
*/
#include "phpdbg.h"
#include "phpdbg_cmd.h"
#include "phpdbg_parser.h"
#define LEX(v) (PHPDBG_G(lexer).v)
#define YYCTYPE unsigned char
#define YYSETCONDITION(x) LEX(state) = x;
#define YYGETCONDITION() LEX(state)
#define YYCURSOR LEX(cursor)
#define YYMARKER LEX(marker)
#define YYCTXMARKER LEX(ctxmarker)
#define yyleng LEX(len)
#define yytext ((char*) LEX(text))
#undef YYDEBUG
#define YYDEBUG(a, b)
#define YYFILL(n)
#define NORMAL 0
#define PRE_RAW 1
#define RAW 2
#define INITIAL 3
ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
void phpdbg_init_lexer (phpdbg_param_t *stack, char *input) {
PHPDBG_G(parser_stack) = stack;
YYSETCONDITION(INITIAL);
LEX(text) = YYCURSOR = (unsigned char *) input;
LEX(len) = strlen(input);
}
static int unescape_string(char *s) {
switch (*s) {
case '\'':
case '\"': {
char start = *s;
size_t off = 1;
do {
if (s[off] == '\\') {
off++;
}
*s = s[off];
} while ((++s)[off] != start);
return off + 1;
}
}
return 0;
}
int phpdbg_lex (phpdbg_param_t* yylval) {
restart:
LEX(text) = YYCURSOR;
/*!re2c
re2c:yyfill:check = 0;
T_TRUE 'true'
T_YES 'yes'
T_ON 'on'
T_ENABLED 'enabled'
T_FALSE 'false'
T_NO 'no'
T_OFF 'off'
T_DISABLED 'disabled'
T_EVAL 'ev'
T_SHELL 'sh'
T_IF 'if'
T_RUN 'run'
T_RUN_SHORT "r"
WS [ \r\t]+
DIGITS [-]?[0-9\.]+
ID [^ \r\n\t:#\000]+
GENERIC_ID ([^ \r\n\t:#\000"']|":\\")+|["]([^\n\000"\\]|"\\\\"|"\\"["])+["]|[']([^\n\000'\\]|"\\\\"|"\\"['])+[']
ADDR [0][x][a-fA-F0-9]+
OPCODE (ZEND_|zend_)([A-Za-z])+
INPUT ("\\"[#"']|["]("\\\\"|"\\"["]|[^\n\000"])+["]|[']("\\"[']|"\\\\"|[^\n\000'])+[']|[^\n\000#"'])+
<!*> := yyleng = (size_t) YYCURSOR - (size_t) yytext;
<*>[\n\000] {
return 0;
}
<PRE_RAW, NORMAL>"-r"{WS}?{DIGITS} {
char *text = yytext + 2;
while (*++text < '0');
yylval->num = atoi(text);
return T_REQ_ID;
}
<NORMAL>{T_IF}{WS} {
YYSETCONDITION(RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_IF;
}
<NORMAL>"#"/{DIGITS} {
return T_POUND;
}
<*>"#" {
YYSETCONDITION(INITIAL);
return T_SEPARATOR;
}
<NORMAL>"::" {
return T_DCOLON;
}
<NORMAL>":"/[^\\] {
return T_COLON;
}
<NORMAL>{ID}"://" {
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = estrndup(yytext, yyleng);
yylval->len = yyleng;
return T_PROTO;
}
<NORMAL>({T_YES}|{T_ON}|{T_ENABLED}|{T_TRUE})/[ \r\t\n\000] {
phpdbg_init_param(yylval, NUMERIC_PARAM);
yylval->num = 1;
return T_TRUTHY;
}
<NORMAL>({T_NO}|{T_OFF}|{T_DISABLED}|{T_FALSE})/[ \r\t\n\000] {
phpdbg_init_param(yylval, NUMERIC_PARAM);
yylval->num = 0;
return T_FALSY;
}
<NORMAL>{DIGITS} {
phpdbg_init_param(yylval, NUMERIC_PARAM);
yylval->num = atoi(yytext);
return T_DIGITS;
}
<NORMAL>{ADDR} {
phpdbg_init_param(yylval, ADDR_PARAM);
yylval->addr = strtoul(yytext, 0, 16);
return T_ADDR;
}
<NORMAL>{OPCODE} {
phpdbg_init_param(yylval, OP_PARAM);
yylval->str = estrndup(yytext, yyleng);
yylval->len = yyleng;
return T_OPCODE;
}
<NORMAL>{GENERIC_ID} {
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = estrndup(yytext, yyleng - unescape_string(yytext));
yylval->len = yyleng;
return T_ID;
}
<RAW>{INPUT} {
phpdbg_init_param(yylval, STR_PARAM);
yylval->str = estrdup(yytext);
yylval->len = yyleng;
return T_INPUT;
}
<*>{WS} {
/* ignore whitespace */
goto restart;
}
<INITIAL>{T_EVAL}{WS} {
YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_EVAL;
}
<INITIAL>{T_SHELL}{WS} {
YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_SHELL;
}
<INITIAL>({T_RUN}|{T_RUN_SHORT}){WS} {
YYSETCONDITION(PRE_RAW);
phpdbg_init_param(yylval, EMPTY_PARAM);
return T_RUN;
}
<PRE_RAW>[^ ] {
YYSETCONDITION(RAW);
YYCURSOR = LEX(text);
goto restart;
}
<INITIAL>[^ ] {
YYSETCONDITION(NORMAL);
YYCURSOR = LEX(text);
goto restart;
}
*/
}