mysql-server/sql/debug_lo_parser.yy
2025-03-05 14:31:37 +07:00

381 lines
7.4 KiB
Text

%{
/* Copyright (c) 2018, 2024, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <string>
#include "sql/debug_lo_misc.h"
#include "sql/debug_lo_parser.h"
#include "sql/debug_lo_scanner.h"
#include "sql/debug_lock_order.h"
#include "mysql/components/services/log_builtins.h"
#include "mysqld_error.h"
class LO_graph;
void process_arc(LO_parser_param *p,
char *from,
char *state,
char *to,
bool recursive,
char *operation,
int flags,
char *constraint,
char *comment);
void process_bind(LO_parser_param *p,
char *from,
char *to,
int flags);
void process_node(LO_parser_param *p,
char *node,
char *operation,
int flags);
void LOCK_ORDER_error(YYLTYPE *yyloc, LO_parser_param *p, const char* msg);
#define YYLEX_PARAM param->m_scanner
%}
%pure-parser
%locations
%lex-param { yyscan_t YYLEX_PARAM }
%parse-param { struct LO_parser_param *param }
%union
{
char *m_str;
int m_flags;
}
%start graph
%expect 0
%token ARC_SYM
%token BIND_SYM
%token COMMENT_SYM
%token CONSTRAINT_SYM
%token DEBUG_SYM
%token FLAGS_SYM
%token FROM_SYM
%token IGNORED_SYM
%token LOOP_SYM
%token NODE_SYM
%token OP_SYM
%token RECURSIVE_SYM
%token STATE_SYM
%token <m_str> STR_SYM
%token TO_SYM
%token TRACE_SYM
%token UNFAIR_SYM
%type <m_flags> opt_arc_flags;
%type <m_flags> arc_flags;
%type <m_flags> arc_flag;
%type <m_flags> opt_bind_flags;
%type <m_flags> bind_flags;
%type <m_flags> bind_flag;
%type <m_flags> node_flag;
%type <m_str> opt_comment;
%type <m_str> opt_constraint;
%type <m_str> opt_state;
%%
graph:
list_of_declarations_opt
;
list_of_declarations_opt:
/* empty */
| list_of_declarations
;
list_of_declarations:
declaration
| list_of_declarations declaration
;
opt_arc_flags:
/* empty */
{
$$ = 0;
}
| FLAGS_SYM arc_flags
{
$$ = $2;
}
;
arc_flags:
arc_flags arc_flag
{
$$ = $1 | $2;
}
| arc_flag
{
$$ = $1;
}
;
arc_flag:
TRACE_SYM
{
$$ = LO_FLAG_TRACE;
}
| DEBUG_SYM
{
$$ = LO_FLAG_DEBUG;
}
| LOOP_SYM
{
$$ = LO_FLAG_LOOP;
}
| IGNORED_SYM
{
$$ = LO_FLAG_IGNORED;
}
;
opt_bind_flags:
/* empty */
{
$$ = 0;
}
| FLAGS_SYM bind_flags
{
$$ = $2;
}
;
bind_flags:
bind_flags bind_flag
{
$$ = $1 | $2;
}
| bind_flag
{
$$ = $1;
}
;
bind_flag:
UNFAIR_SYM
{
$$ = LO_FLAG_UNFAIR;
}
;
node_flag:
IGNORED_SYM
{
$$ = LO_FLAG_IGNORED;
}
;
opt_state:
/* empty */
{
$$ = nullptr;
}
| STATE_SYM STR_SYM
{
$$ = $2;
}
;
opt_constraint:
/* empty */
{
$$ = nullptr;
}
| CONSTRAINT_SYM STR_SYM
{
$$ = $2;
}
;
opt_comment:
/* empty */
{
$$ = nullptr;
}
| COMMENT_SYM STR_SYM
{
$$ = $2;
}
;
declaration:
arc_declaration
| bind_declaration
| node_declaration
;
/*
Note: can not use the [from] and $from syntax,
because this requires a recent bison.
*/
arc_declaration:
ARC_SYM
FROM_SYM
STR_SYM /* [from] = 3 */
opt_state /* [state] = 4 */
TO_SYM
STR_SYM /* [to] = 6 */
opt_arc_flags /* [flags] = 7 */
opt_constraint /* [constraint] = 8 */
opt_comment /* [comment] = 9 */
{
process_arc(param, $3, $4, $6, false, nullptr, $7, $8, $9);
}
| ARC_SYM
FROM_SYM
STR_SYM /* [from] = 3 */
opt_state /* [state] = 4 */
TO_SYM
STR_SYM /* [to] = 6 */
OP_SYM
STR_SYM /* [op] = 8 */
opt_arc_flags /* [flags] = 9 */
opt_constraint /* [constraint] = 10 */
opt_comment /* [comment] = 11 */
{
process_arc(param, $3, $4, $6, false, $8, $9, $10, $11);
}
| ARC_SYM
FROM_SYM
STR_SYM /* [from] = 3 */
opt_state /* [state] = 4 */
TO_SYM
STR_SYM /* [to] = 6 */
RECURSIVE_SYM
OP_SYM
STR_SYM /* [op] = 9 */
opt_arc_flags /* [flags] = 10 */
opt_constraint /* [constraint] = 11 */
opt_comment /* [comment] == 12 */
{
process_arc(param, $3, $4, $6, true, $9, $10, $11, $12);
}
;
bind_declaration:
BIND_SYM
STR_SYM /* [from] = 2 */
TO_SYM
STR_SYM /* [to] = 4 */
opt_bind_flags /* [flags] = 5 */
{
process_bind(param, $2, $4, $5);
}
;
node_declaration:
NODE_SYM
STR_SYM /* [node] = 2 */
node_flag /* [flag] = 3 */
{
process_node(param, $2, nullptr, $3);
}
| NODE_SYM
STR_SYM /* [node] = 2 */
OP_SYM
STR_SYM /* [op] = 4 */
node_flag /* [flag] = 5 */
{
process_node(param, $2, $4, $5);
}
;
%%
void process_arc(LO_parser_param *p,
char *from,
char *state,
char *to,
bool recursive,
char *operation,
int flags,
char *constraint,
char *comment)
{
LO_authorised_arc arc;
arc.m_from_name = from;
arc.m_from_state = state;
arc.m_to_name = to;
arc.m_op_recursive = recursive;
arc.m_to_operation = operation;
arc.m_flags = flags;
arc.m_constraint = constraint;
arc.m_comment = comment;
LO_add_authorised_arc(p->m_graph, &arc);
}
void process_bind(LO_parser_param *p,
char *from,
char *to,
int flags)
{
LO_authorised_arc arc;
arc.m_from_name = from;
arc.m_from_state = nullptr;
arc.m_to_name = to;
arc.m_op_recursive = false;
arc.m_to_operation = nullptr;
arc.m_flags = LO_FLAG_BIND | flags;
arc.m_constraint = nullptr;
arc.m_comment = nullptr;
LO_add_authorised_arc(p->m_graph, &arc);
}
void process_node(LO_parser_param *p,
char *node,
char *operation,
int flags)
{
LO_node_properties prop;
prop.m_name = node;
prop.m_operation = operation;
prop.m_flags = flags;
LO_add_node_properties(p->m_graph, &prop);
}
void LOCK_ORDER_error(YYLTYPE * yylloc_param, LO_parser_param * p, const char* msg)
{
/* message format = "Lock order dependencies file <%s> (%d:%d) - (%d:%d) : %s" */
LogErr(ERROR_LEVEL, ER_LOCK_ORDER_DEPENDENCIES_SYNTAX,
p->m_filename,
yylloc_param->first_line,
yylloc_param->first_column,
yylloc_param->last_line,
yylloc_param->last_column,
msg);
}