mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
parse.y: lex_state trace by yydebug
* parse.y (trace_lex_state): trace lex_state changes if yydebug is set, and send the messages to rb_stdout. * parse.y (rb_parser_printf): store YYPRINTF messages per lines so that lex_state traces do not mix. * tool/ytab.sed: add parser argument to yy_stack_print too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53095 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ada76728f6
commit
0f076affb6
5 changed files with 83 additions and 31 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
||||||
|
Sun Dec 13 23:46:10 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* parse.y (trace_lex_state): trace lex_state changes if yydebug is
|
||||||
|
set, and send the messages to rb_stdout.
|
||||||
|
|
||||||
|
* parse.y (rb_parser_printf): store YYPRINTF messages per lines
|
||||||
|
so that lex_state traces do not mix.
|
||||||
|
|
||||||
|
* tool/ytab.sed: add parser argument to yy_stack_print too.
|
||||||
|
|
||||||
|
Sun Dec 13 23:45:19 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* parse.y (trace_lex_state): trace lex_state changes if yydebug is
|
||||||
|
set, and send the messages to rb_stdout.
|
||||||
|
|
||||||
|
* parse.y (rb_parser_printf): store YYPRINTF messages per lines
|
||||||
|
so that lex_state traces do not mix.
|
||||||
|
|
||||||
|
* tool/ytab.sed: add parser argument to yy_stack_print too.
|
||||||
|
|
||||||
Sun Dec 13 20:41:16 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun Dec 13 20:41:16 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* parse.y (build_lex_state_name, trace_lex_state): lex_state is
|
* parse.y (build_lex_state_name, trace_lex_state): lex_state is
|
||||||
|
|
1
node.h
1
node.h
|
@ -506,6 +506,7 @@ void *rb_parser_malloc(struct parser_params *, size_t);
|
||||||
void *rb_parser_realloc(struct parser_params *, void *, size_t);
|
void *rb_parser_realloc(struct parser_params *, void *, size_t);
|
||||||
void *rb_parser_calloc(struct parser_params *, size_t, size_t);
|
void *rb_parser_calloc(struct parser_params *, size_t, size_t);
|
||||||
void rb_parser_free(struct parser_params *, void *);
|
void rb_parser_free(struct parser_params *, void *);
|
||||||
|
void rb_parser_printf(struct parser_params *parser, const char *fmt, ...);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
|
|
65
parse.y
65
parse.y
|
@ -44,6 +44,12 @@
|
||||||
#define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
|
#define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
|
||||||
#define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
|
#define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
|
||||||
#define YYFREE(ptr) rb_parser_free(parser, (ptr))
|
#define YYFREE(ptr) rb_parser_free(parser, (ptr))
|
||||||
|
#ifdef HAVE_VA_ARGS_MACRO
|
||||||
|
# define YYFPRINTF(f, fmt, ...) rb_parser_printf(parser, fmt, ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# define YYFPRINTF rb_parser_printf
|
||||||
|
# define stderr parser
|
||||||
|
#endif
|
||||||
#undef malloc
|
#undef malloc
|
||||||
#undef realloc
|
#undef realloc
|
||||||
#undef calloc
|
#undef calloc
|
||||||
|
@ -95,11 +101,9 @@ enum lex_state_e {
|
||||||
|
|
||||||
# define SET_LEX_STATE(ls) \
|
# define SET_LEX_STATE(ls) \
|
||||||
(lex_state = trace_lex_state(lex_state, (ls), __LINE__))
|
(lex_state = trace_lex_state(lex_state, (ls), __LINE__))
|
||||||
#if PARSER_DEBUG
|
|
||||||
static enum lex_state_e trace_lex_state(enum lex_state_e from, enum lex_state_e to, int line);
|
static enum lex_state_e trace_lex_state(enum lex_state_e from, enum lex_state_e to, int line);
|
||||||
#else
|
# define trace_lex_state(from, to, line) \
|
||||||
# define trace_lex_state(from, to, line) (to)
|
(yydebug ? trace_lex_state(from, to, line) : (to))
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef VALUE stack_type;
|
typedef VALUE stack_type;
|
||||||
|
|
||||||
|
@ -274,6 +278,8 @@ struct parser_params {
|
||||||
token_info *token_info;
|
token_info *token_info;
|
||||||
VALUE compile_option;
|
VALUE compile_option;
|
||||||
|
|
||||||
|
VALUE debug_buffer;
|
||||||
|
|
||||||
ID cur_arg;
|
ID cur_arg;
|
||||||
|
|
||||||
int last_cr_line;
|
int last_cr_line;
|
||||||
|
@ -9179,54 +9185,47 @@ id_is_var_gen(struct parser_params *parser, ID id)
|
||||||
}
|
}
|
||||||
#endif /* !RIPPER */
|
#endif /* !RIPPER */
|
||||||
|
|
||||||
#if PARSER_DEBUG
|
|
||||||
static const char lex_state_names[][13] = {
|
static const char lex_state_names[][13] = {
|
||||||
"EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
|
"EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
|
||||||
"EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
|
"EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
|
||||||
"EXPR_LABEL", "EXPR_LABELED",
|
"EXPR_LABEL", "EXPR_LABELED",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *
|
static VALUE
|
||||||
build_lex_state_name(enum lex_state_e state, char *buf, size_t size)
|
append_lex_state_name(enum lex_state_e state, VALUE buf)
|
||||||
{
|
{
|
||||||
int i, sep = 0;
|
int i, sep = 0;
|
||||||
char *p = buf;
|
|
||||||
unsigned int mask = 1;
|
unsigned int mask = 1;
|
||||||
size_t n;
|
|
||||||
static const char none[] = "EXPR_NONE";
|
static const char none[] = "EXPR_NONE";
|
||||||
|
|
||||||
for (i = 0; i < EXPR_MAX_STATE; ++i, mask <<= 1) {
|
for (i = 0; i < EXPR_MAX_STATE; ++i, mask <<= 1) {
|
||||||
if ((unsigned)state & mask) {
|
if ((unsigned)state & mask) {
|
||||||
if (sep) {
|
if (sep) {
|
||||||
if (size < 2) break;
|
rb_str_cat(buf, "|", 1);
|
||||||
--size;
|
|
||||||
*p++ = '|';
|
|
||||||
}
|
}
|
||||||
sep = 1;
|
sep = 1;
|
||||||
n = strlcpy(p, lex_state_names[i], size);
|
rb_str_cat_cstr(buf, lex_state_names[i]);
|
||||||
if (n >= size) break;
|
|
||||||
size -= n;
|
|
||||||
p += n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p == buf && size >= sizeof(none)) {
|
if (!sep) {
|
||||||
n = strlcpy(buf, none, size);
|
rb_str_cat(buf, none, sizeof(none)-1);
|
||||||
p += n;
|
|
||||||
}
|
}
|
||||||
*p = '\0';
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef trace_lex_state
|
||||||
static enum lex_state_e
|
static enum lex_state_e
|
||||||
trace_lex_state(enum lex_state_e from, enum lex_state_e to, int line)
|
trace_lex_state(enum lex_state_e from, enum lex_state_e to, int line)
|
||||||
{
|
{
|
||||||
char buf1[sizeof(lex_state_names)], buf2[sizeof(lex_state_names)];
|
VALUE mesg;
|
||||||
build_lex_state_name(from, buf1, sizeof(buf1));
|
mesg = rb_str_new_cstr("lex_state: ");
|
||||||
build_lex_state_name(to, buf2, sizeof(buf2));
|
append_lex_state_name(from, mesg);
|
||||||
printf("lex_state: %s -> %s at L%d\n", buf1, buf2, line);
|
rb_str_cat_cstr(mesg, " -> ");
|
||||||
|
append_lex_state_name(to, mesg);
|
||||||
|
rb_str_catf(mesg, " at line %d\n", line);
|
||||||
|
rb_io_write(rb_stdout, mesg);
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RIPPER
|
#ifdef RIPPER
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -10776,6 +10775,7 @@ parser_initialize(struct parser_params *parser)
|
||||||
parser->result = Qnil;
|
parser->result = Qnil;
|
||||||
parser->parsing_thread = Qnil;
|
parser->parsing_thread = Qnil;
|
||||||
#endif
|
#endif
|
||||||
|
parser->debug_buffer = Qnil;
|
||||||
parser->enc = rb_utf8_encoding();
|
parser->enc = rb_utf8_encoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11034,6 +11034,21 @@ rb_parser_free(struct parser_params *parser, void *ptr)
|
||||||
xfree(ptr);
|
xfree(ptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_parser_printf(struct parser_params *parser, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
VALUE mesg = parser->debug_buffer;
|
||||||
|
|
||||||
|
if (NIL_P(mesg)) parser->debug_buffer = mesg = rb_str_new(0, 0);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
rb_str_vcatf(mesg, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (RSTRING_END(mesg)[-1] == '\n') {
|
||||||
|
rb_io_write(rb_stdout, mesg);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RIPPER
|
#ifdef RIPPER
|
||||||
|
|
|
@ -191,13 +191,13 @@ class TestRubyOptions < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_yydebug
|
def test_yydebug
|
||||||
assert_in_out_err(["-ye", ""]) do |r, e|
|
assert_in_out_err(["-ye", ""]) do |r, e|
|
||||||
assert_equal([], r)
|
assert_not_equal([], r)
|
||||||
assert_not_equal([], e)
|
assert_equal([], e)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_in_out_err(%w(--yydebug -e) + [""]) do |r, e|
|
assert_in_out_err(%w(--yydebug -e) + [""]) do |r, e|
|
||||||
assert_equal([], r)
|
assert_not_equal([], r)
|
||||||
assert_not_equal([], e)
|
assert_equal([], e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ a\
|
||||||
/^yydestruct.*yymsg/,/#endif/{
|
/^yydestruct.*yymsg/,/#endif/{
|
||||||
/^yydestruct/{
|
/^yydestruct/{
|
||||||
/parser/!{
|
/parser/!{
|
||||||
h
|
H
|
||||||
s/^/ruby_parser_&/
|
s/^/ruby_parser_&/
|
||||||
s/)$/, parser)/
|
s/)$/, parser)/
|
||||||
/\*/s/parser)$/struct parser_params *&/
|
/\*/s/parser)$/struct parser_params *&/
|
||||||
|
@ -22,7 +22,7 @@ a\
|
||||||
}
|
}
|
||||||
/^#endif/{
|
/^#endif/{
|
||||||
x
|
x
|
||||||
/^./{
|
/yydestruct/{
|
||||||
i\
|
i\
|
||||||
struct parser_params *parser;
|
struct parser_params *parser;
|
||||||
a\
|
a\
|
||||||
|
@ -31,6 +31,22 @@ a\
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/^yy_stack_print/{
|
||||||
|
/parser/!{
|
||||||
|
H
|
||||||
|
s/)$/, parser)/
|
||||||
|
/\*/s/parser)$/struct parser_params *&/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/yy_stack_print.*;/{
|
||||||
|
x
|
||||||
|
/yy_stack_print/{
|
||||||
|
x
|
||||||
|
s/\(yy_stack_print *\)(\(.*\));/\1(\2, parser);/
|
||||||
|
x
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
s/^\([ ]*\)\(yyerror[ ]*([ ]*parser,\)/\1parser_\2/
|
s/^\([ ]*\)\(yyerror[ ]*([ ]*parser,\)/\1parser_\2/
|
||||||
s!^ *extern char \*getenv();!/* & */!
|
s!^ *extern char \*getenv();!/* & */!
|
||||||
s/^\(#.*\)".*\.tab\.c"/\1"parse.c"/
|
s/^\(#.*\)".*\.tab\.c"/\1"parse.c"/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue