#include <string.h>
%}
+%s RAW
+
%option outfile="phpdbg_lexer.c" header-file="phpdbg_lexer.h"
%option warn nodefault
C_NO "no"
C_OFF "off"
C_DISABLED "disabled"
+C_EVAL "eval"
+C_SHELL "shell"
DIGITS [0-9]+
ID [a-zA-Z][a-zA-Z0-9_]+
OPLINE 0x[a-fA-F0-9]+
LITERAL \"(\\.|[^\\"])*\"
WS [ \r\n\t]+
+INPUT [^\n]+
%%
-
-{WS} { }
-{C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} {
- yylval->type = NUMERIC_PARAM;
- yylval->num = 1;
- return C_TRUTHY;
-}
-{C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} {
- yylval->type = NUMERIC_PARAM;
- yylval->num = 0;
- return C_FALSY;
-}
-{DIGITS} {
- yylval->type = NUMERIC_PARAM;
- yylval->num = atoi(yytext);
- return T_DIGITS;
-}
-{METHOD} {
- yylval->type = METHOD_PARAM;
- yylval->method.class = "class";
- yylval->method.name = "func";
- return T_METHOD;
-}
-{FILE} {
- yylval->type = FILE_PARAM;
- yylval->file.name = strndup(yytext, yyleng);
- yylval->file.line = 0;
- return T_FILE;
-}
-{OPLINE} {
- yylval->type = ADDR_PARAM;
- yylval->addr = strtoul(yytext, NULL, 10);
- return T_OPLINE;
-}
-{LITERAL} {
- yylval->type = STR_PARAM;
- yylval->str = strndup(yytext, yyleng);
- yylval->len = yyleng;
- return T_LITERAL;
+{WS} { }
+<INITIAL>
+{
+ {C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} {
+ yylval->type = NUMERIC_PARAM;
+ yylval->num = 1;
+ return C_TRUTHY;
+ }
+ {C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} {
+ yylval->type = NUMERIC_PARAM;
+ yylval->num = 0;
+ return C_FALSY;
+ }
+ {C_EVAL} {
+ BEGIN(RAW);
+ return C_EVAL;
+ }
+ {C_SHELL} {
+ BEGIN(RAW);
+ return C_SHELL;
+ }
+ {DIGITS} {
+ yylval->type = NUMERIC_PARAM;
+ yylval->num = atoi(yytext);
+ return T_DIGITS;
+ }
+ {METHOD} {
+ yylval->type = METHOD_PARAM;
+ yylval->method.class = "class";
+ yylval->method.name = "func";
+ return T_METHOD;
+ }
+ {FILE} {
+ yylval->type = FILE_PARAM;
+ yylval->file.name = strndup(yytext, yyleng);
+ yylval->file.line = 0;
+ return T_FILE;
+ }
+ {OPLINE} {
+ yylval->type = ADDR_PARAM;
+ yylval->addr = strtoul(yytext, NULL, 10);
+ return T_OPLINE;
+ }
+ {LITERAL} {
+ yylval->type = STR_PARAM;
+ yylval->str = strndup(yytext, yyleng);
+ yylval->len = yyleng;
+ return T_LITERAL;
+ }
+ {ID} {
+ yylval->type = STR_PARAM;
+ yylval->str = strndup(yytext, yyleng);
+ yylval->len = yyleng;
+ return T_ID;
+ }
}
-[a-zA-Z]+ {
+<RAW>{INPUT} {
yylval->type = STR_PARAM;
yylval->str = strndup(yytext, yyleng);
yylval->len = yyleng;
-
- return C_CMD;
+ BEGIN(INITIAL);
+ return T_INPUT;
}
. {
/** command detection here **/
typedef void* yyscan_t;
#endif
}
-
+%expect 1
%output "phpdbg_parser.c"
%defines "phpdbg_parser.h"
%parse-param { phpdbg_param_t **expression }
%parse-param { yyscan_t scanner }
-%token C_CMD "command (possibly automatically detected)"
-
%token C_TRUTHY "truthy (true, on, yes or enabled)"
%token C_FALSY "falsy (false, off, no or disabled)"
%token C_STRING "string (some input, perhaps)"
+%token C_EVAL "eval"
+%token C_SHELL "shell"
%token T_DIGITS "digits (numbers)"
%token T_LITERAL "literal (T_LITERAL)"
%token T_OPLINE "opline (T_OPLINE)"
%token T_FILE "file (T_FILE)"
%token T_ID "identifier (T_ID)"
-
+%token T_INPUT "input (input string or data)"
%%
input
;
command
- : C_CMD { fprintf(stderr, "got cmd: %s\n", $1.str); }
- | C_CMD C_CMD { fprintf(stderr, "got sub: %s -> %s\n", $1.str, $2.str); }
+ : T_ID { fprintf(stderr, "got cmd: %s\n", $1.str); }
+ | T_ID T_ID { fprintf(stderr, "got sub: %s -> %s\n", $1.str, $2.str); }
+ /* exceptional cases below */
+ | C_EVAL T_INPUT { fprintf(stderr, "got eval: %s\n", $2.str); }
+ | C_SHELL T_INPUT { fprintf(stderr, "got shell: %s\n", $2.str); }
;
parameter
| T_OPLINE { $$ = $1; }
| T_ID { $$ = $1; }
| T_LITERAL { $$ = $1; }
+ | C_TRUTHY { $$ = $1; }
+ | C_FALSY { $$ = $1; }
;
handler