mirror of
https://github.com/php/php-src.git
synced 2026-03-25 16:52:18 +01:00
With Bison 3.0 some directives are deprecated:
- %name-prefix "x" should be %define api.prefix {x}
- %error-verbose should be %define parse.error verbose
Bison 3.3 also started emiting more warnings and since PHP souce parsers
are not POSIX compliant this patch fixes this as pointed out via
495a46aa1d.
201 lines
4.3 KiB
Plaintext
201 lines
4.3 KiB
Plaintext
%{
|
|
|
|
/*
|
|
* phpdbg_parser.y
|
|
* (from php-src root)
|
|
*/
|
|
|
|
#include "phpdbg.h"
|
|
#include "phpdbg_cmd.h"
|
|
#include "phpdbg_utils.h"
|
|
#include "phpdbg_cmd.h"
|
|
#include "phpdbg_prompt.h"
|
|
|
|
#define YYSTYPE phpdbg_param_t
|
|
|
|
#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
|
|
|
|
%}
|
|
|
|
%pure-parser
|
|
%define parse.error verbose
|
|
|
|
%code requires {
|
|
#include "phpdbg.h"
|
|
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
|
#define YY_TYPEDEF_YY_SCANNER_T
|
|
typedef void* yyscan_t;
|
|
#endif
|
|
}
|
|
|
|
%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("command", "type=\"parseerror\" msg=\"%s\"", "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();
|
|
}
|