diff --git a/parse.y b/parse.y index e4e82516d2..383b5ef03b 100644 --- a/parse.y +++ b/parse.y @@ -6840,6 +6840,15 @@ parse_rational(struct parser_params *p, char *str, int len, int seen_point) return rb_rational_new(v, rb_int_positive_pow(10, fraclen)); } +static enum yytokentype +no_digits(struct parser_params *p) +{ + yyerror0("numeric literal without digits"); + if (peek(p, '_')) nextc(p); + /* dummy 0, for tUMINUS_NUM at numeric */ + return set_integer_literal(p, INT2FIX(0), 0); +} + static enum yytokentype parse_numeric(struct parser_params *p, int c) { @@ -6854,7 +6863,6 @@ parse_numeric(struct parser_params *p, int c) c = nextc(p); } if (c == '0') { -#define no_digits() do {yyerror0("numeric literal without digits"); return 0;} while (0) int start = toklen(p); c = nextc(p); if (c == 'x' || c == 'X') { @@ -6875,7 +6883,7 @@ parse_numeric(struct parser_params *p, int c) pushback(p, c); tokfix(p); if (toklen(p) == start) { - no_digits(); + return no_digits(p); } else if (nondigit) goto trailing_uc; suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); @@ -6899,7 +6907,7 @@ parse_numeric(struct parser_params *p, int c) pushback(p, c); tokfix(p); if (toklen(p) == start) { - no_digits(); + return no_digits(p); } else if (nondigit) goto trailing_uc; suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); @@ -6923,7 +6931,7 @@ parse_numeric(struct parser_params *p, int c) pushback(p, c); tokfix(p); if (toklen(p) == start) { - no_digits(); + return no_digits(p); } else if (nondigit) goto trailing_uc; suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); @@ -6937,7 +6945,7 @@ parse_numeric(struct parser_params *p, int c) /* prefixed octal */ c = nextc(p); if (c == -1 || c == '_' || !ISDIGIT(c)) { - no_digits(); + return no_digits(p); } } if (c >= '0' && c <= '7') { diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb index f626e05397..3b6aa0c096 100644 --- a/test/ruby/test_literal.rb +++ b/test/ruby/test_literal.rb @@ -516,11 +516,12 @@ class TestRubyLiteral < Test::Unit::TestCase } } bug2407 = '[ruby-dev:39798]' - head.each {|h| - if /^0/ =~ h - assert_syntax_error("#{h}_", /numeric literal without digits\Z/, "#{bug2407}: #{h.inspect}") + head.grep_v(/^0/) do |s| + head.grep(/^0/) do |h| + h = "#{s}#{h}_" + assert_syntax_error(h, /numeric literal without digits\Z/, "#{bug2407}: #{h.inspect}") end - } + end end def test_float