123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- %require "3.0"
- /*
- * phpdbg_parser.y
- * (from php-src root)
- */
- %code requires {
- #include "phpdbg.h"
- #ifndef YY_TYPEDEF_YY_SCANNER_T
- #define YY_TYPEDEF_YY_SCANNER_T
- typedef void* yyscan_t;
- #endif
- }
- %code {
- #include "phpdbg_cmd.h"
- #include "phpdbg_utils.h"
- #include "phpdbg_cmd.h"
- #include "phpdbg_prompt.h"
- #include "phpdbg_parser.h"
- #include "phpdbg_lexer.h"
- #undef yyerror
- static int yyerror(const char *msg);
- ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
- #ifdef _MSC_VER
- #define YYMALLOC malloc
- #define YYFREE free
- #endif
- }
- %define api.prefix {phpdbg_}
- %define api.pure full
- %define api.value.type {phpdbg_param_t}
- %define parse.error verbose
- %token END 0 "end of command"
- %token T_EVAL "eval"
- %token T_RUN "run"
- %token T_SHELL "shell"
- %token T_IF "if (condition)"
- %token T_TRUTHY "truthy (true, on, yes or enabled)"
- %token T_FALSY "falsy (false, off, no or disabled)"
- %token T_STRING "string (some input, perhaps)"
- %token T_COLON ": (colon)"
- %token T_DCOLON ":: (double colon)"
- %token T_POUND "# (pound sign followed by digits)"
- %token T_SEPARATOR "# (pound sign)"
- %token T_PROTO "protocol (file://)"
- %token T_DIGITS "digits (numbers)"
- %token T_LITERAL "literal (string)"
- %token T_ADDR "address"
- %token T_OPCODE "opcode"
- %token T_ID "identifier (command or function name)"
- %token T_INPUT "input (input string or data)"
- %token T_UNEXPECTED "input"
- %token T_REQ_ID "request id (-r %d)"
- %% /* Rules */
- input
- : command { $$ = $1; }
- | input T_SEPARATOR command { phpdbg_stack_separate($1.top); $$ = $3; }
- | %empty
- ;
- command
- : parameters { $$.top = PHPDBG_G(parser_stack)->top; }
- | full_expression { phpdbg_stack_push(PHPDBG_G(parser_stack), &$1); $$.top = PHPDBG_G(parser_stack)->top; }
- ;
- parameters
- : parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$1); $$.top = PHPDBG_G(parser_stack)->top; }
- | parameters parameter { phpdbg_stack_push(PHPDBG_G(parser_stack), &$2); $$.top = PHPDBG_G(parser_stack)->top; }
- | parameters T_REQ_ID { $$ = $1; PHPDBG_G(req_id) = $2.num; }
- ;
- parameter
- : T_ID T_COLON T_DIGITS {
- $$.type = FILE_PARAM;
- $$.file.name = $2.str;
- $$.file.line = $3.num;
- }
- | T_ID T_COLON T_POUND T_DIGITS {
- $$.type = NUMERIC_FILE_PARAM;
- $$.file.name = $1.str;
- $$.file.line = $4.num;
- }
- | T_PROTO T_ID T_COLON T_DIGITS {
- $$.type = FILE_PARAM;
- $$.file.name = malloc($1.len + $2.len + 1);
- if ($$.file.name) {
- memcpy(&$$.file.name[0], $1.str, $1.len);
- memcpy(&$$.file.name[$1.len], $2.str, $2.len);
- $$.file.name[$1.len + $2.len] = '\0';
- }
- $$.file.line = $4.num;
- }
- | T_PROTO T_ID T_COLON T_POUND T_DIGITS {
- $$.type = NUMERIC_FILE_PARAM;
- $$.file.name = malloc($1.len + $2.len + 1);
- if ($$.file.name) {
- memcpy(&$$.file.name[0], $1.str, $1.len);
- memcpy(&$$.file.name[$1.len], $2.str, $2.len);
- $$.file.name[$1.len + $2.len] = '\0';
- }
- $$.file.line = $5.num;
- }
- | T_ID T_DCOLON T_ID {
- $$.type = METHOD_PARAM;
- $$.method.class = $1.str;
- $$.method.name = $3.str;
- }
- | T_ID T_DCOLON T_ID T_POUND T_DIGITS {
- $$.type = NUMERIC_METHOD_PARAM;
- $$.method.class = $1.str;
- $$.method.name = $3.str;
- $$.num = $5.num;
- }
- | T_ID T_POUND T_DIGITS {
- $$.type = NUMERIC_FUNCTION_PARAM;
- $$.str = $1.str;
- $$.len = $1.len;
- $$.num = $3.num;
- }
- | T_IF T_INPUT {
- $$.type = COND_PARAM;
- $$.str = $2.str;
- $$.len = $2.len;
- }
- | T_OPCODE { $$ = $1; }
- | T_ADDR { $$ = $1; }
- | T_LITERAL { $$ = $1; }
- | T_TRUTHY { $$ = $1; }
- | T_FALSY { $$ = $1; }
- | T_DIGITS { $$ = $1; }
- | T_ID { $$ = $1; }
- ;
- req_id
- : T_REQ_ID { PHPDBG_G(req_id) = $1.num; }
- | %empty
- ;
- full_expression
- : T_EVAL req_id T_INPUT {
- $$.type = EVAL_PARAM;
- $$.str = $3.str;
- $$.len = $3.len;
- }
- | T_SHELL req_id T_INPUT {
- $$.type = SHELL_PARAM;
- $$.str = $3.str;
- $$.len = $3.len;
- }
- | T_RUN req_id {
- $$.type = RUN_PARAM;
- $$.len = 0;
- }
- | T_RUN req_id T_INPUT {
- $$.type = RUN_PARAM;
- $$.str = $3.str;
- $$.len = $3.len;
- }
- ;
- %%
- static int yyerror(const char *msg) {
- phpdbg_error("Parse Error: %s", msg);
- {
- const phpdbg_param_t *top = PHPDBG_G(parser_stack);
- while (top) {
- phpdbg_param_debug(top, "--> ");
- top = top->next;
- }
- }
- return 0;
- }
- int phpdbg_do_parse(phpdbg_param_t *stack, char *input) {
- if (!*input) {
- return 0;
- }
- if (PHPDBG_G(cur_command)) {
- free(PHPDBG_G(cur_command));
- }
- PHPDBG_G(cur_command) = strdup(input);
- phpdbg_init_lexer(stack, input);
- return yyparse();
- }
|