mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
parse.y: enclose keyword token names by quotes
* parse.y (rb_yytnamerr): strip enclosing double-quotes, same as the default yytnamerr except for that single-quotes matching back-quotes do not stop stripping. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66903 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5e7d03531e
commit
59a6215af6
2 changed files with 128 additions and 50 deletions
176
parse.y
176
parse.y
|
@ -609,6 +609,12 @@ rb_strterm_mark(VALUE obj)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define yytnamerr(yyres, yystr) (YYSIZE_T)rb_yytnamerr(yyres, yystr)
|
||||||
|
size_t rb_yytnamerr(char *yyres, const char *yystr);
|
||||||
|
#ifdef RIPPER
|
||||||
|
#define yystpcpy Not used
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TOKEN2ID(tok) ( \
|
#define TOKEN2ID(tok) ( \
|
||||||
tTOKEN_LOCAL_BEGIN<(tok)&&(tok)<tTOKEN_LOCAL_END ? TOKEN2LOCALID(tok) : \
|
tTOKEN_LOCAL_BEGIN<(tok)&&(tok)<tTOKEN_LOCAL_END ? TOKEN2LOCALID(tok) : \
|
||||||
tTOKEN_INSTANCE_BEGIN<(tok)&&(tok)<tTOKEN_INSTANCE_END ? TOKEN2INSTANCEID(tok) : \
|
tTOKEN_INSTANCE_BEGIN<(tok)&&(tok)<tTOKEN_INSTANCE_END ? TOKEN2INSTANCEID(tok) : \
|
||||||
|
@ -776,55 +782,55 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <id>
|
%token <id>
|
||||||
keyword_class "class"
|
keyword_class "`class'"
|
||||||
keyword_module "module"
|
keyword_module "`module'"
|
||||||
keyword_def "def"
|
keyword_def "`def'"
|
||||||
keyword_undef "undef"
|
keyword_undef "`undef'"
|
||||||
keyword_begin "begin"
|
keyword_begin "`begin'"
|
||||||
keyword_rescue "rescue"
|
keyword_rescue "`rescue'"
|
||||||
keyword_ensure "ensure"
|
keyword_ensure "`ensure'"
|
||||||
keyword_end "end"
|
keyword_end "`end'"
|
||||||
keyword_if "if"
|
keyword_if "`if'"
|
||||||
keyword_unless "unless"
|
keyword_unless "`unless'"
|
||||||
keyword_then "then"
|
keyword_then "`then'"
|
||||||
keyword_elsif "elsif"
|
keyword_elsif "`elsif'"
|
||||||
keyword_else "else"
|
keyword_else "`else'"
|
||||||
keyword_case "case"
|
keyword_case "`case'"
|
||||||
keyword_when "when"
|
keyword_when "`when'"
|
||||||
keyword_while "while"
|
keyword_while "`while'"
|
||||||
keyword_until "until"
|
keyword_until "`until'"
|
||||||
keyword_for "for"
|
keyword_for "`for'"
|
||||||
keyword_break "break"
|
keyword_break "`break'"
|
||||||
keyword_next "next"
|
keyword_next "`next'"
|
||||||
keyword_redo "redo"
|
keyword_redo "`redo'"
|
||||||
keyword_retry "retry"
|
keyword_retry "`retry'"
|
||||||
keyword_in "in"
|
keyword_in "`in'"
|
||||||
keyword_do "do"
|
keyword_do "`do'"
|
||||||
keyword_do_cond "do (for condition)"
|
keyword_do_cond "`do' for condition"
|
||||||
keyword_do_block "do (for block)"
|
keyword_do_block "`do' for block"
|
||||||
keyword_do_LAMBDA "do (for lambda)"
|
keyword_do_LAMBDA "`do' for lambda"
|
||||||
keyword_return "return"
|
keyword_return "`return'"
|
||||||
keyword_yield "yield"
|
keyword_yield "`yield'"
|
||||||
keyword_super "super"
|
keyword_super "`super'"
|
||||||
keyword_self "self"
|
keyword_self "`self'"
|
||||||
keyword_nil "nil"
|
keyword_nil "`nil'"
|
||||||
keyword_true "true"
|
keyword_true "`true'"
|
||||||
keyword_false "false"
|
keyword_false "`false'"
|
||||||
keyword_and "and"
|
keyword_and "`and'"
|
||||||
keyword_or "or"
|
keyword_or "`or'"
|
||||||
keyword_not "not"
|
keyword_not "`not'"
|
||||||
modifier_if "if (modifier)"
|
modifier_if "`if' modifier"
|
||||||
modifier_unless "unless (modifier)"
|
modifier_unless "`unless' modifier"
|
||||||
modifier_while "while (modifier)"
|
modifier_while "`while' modifier"
|
||||||
modifier_until "until (modifier)"
|
modifier_until "`until' modifier"
|
||||||
modifier_rescue "rescue (modifier)"
|
modifier_rescue "`rescue' modifier"
|
||||||
keyword_alias "alias"
|
keyword_alias "`alias'"
|
||||||
keyword_defined "defined?"
|
keyword_defined "`defined?'"
|
||||||
keyword_BEGIN "BEGIN"
|
keyword_BEGIN "`BEGIN'"
|
||||||
keyword_END "END"
|
keyword_END "`END'"
|
||||||
keyword__LINE__ "__LINE__"
|
keyword__LINE__ "`__LINE__'"
|
||||||
keyword__FILE__ "__FILE__"
|
keyword__FILE__ "`__FILE__'"
|
||||||
keyword__ENCODING__ "__ENCODING__"
|
keyword__ENCODING__ "`__ENCODING__'"
|
||||||
|
|
||||||
%token <id> tIDENTIFIER "local variable or method"
|
%token <id> tIDENTIFIER "local variable or method"
|
||||||
%token <id> tFID "method"
|
%token <id> tFID "method"
|
||||||
|
@ -11177,6 +11183,78 @@ parser_compile_error(struct parser_params *p, const char *fmt, ...)
|
||||||
p->enc, fmt, ap);
|
p->enc, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
count_char(const char *str, int c)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
while (str[n] == c) ++n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* strip enclosing double-quotes, same as the default yytnamerr except
|
||||||
|
* for that single-quotes matching back-quotes do not stop stripping.
|
||||||
|
*
|
||||||
|
* "\"`class' keyword\"" => "`class' keyword"
|
||||||
|
*/
|
||||||
|
RUBY_FUNC_EXPORTED size_t
|
||||||
|
rb_yytnamerr(char *yyres, const char *yystr)
|
||||||
|
{
|
||||||
|
if (*yystr == '"') {
|
||||||
|
size_t yyn = 0, bquote = 0;
|
||||||
|
const char *yyp = yystr;
|
||||||
|
|
||||||
|
while (*++yyp) {
|
||||||
|
switch (*yyp) {
|
||||||
|
case '`':
|
||||||
|
if (!bquote) {
|
||||||
|
bquote = count_char(yyp+1, '`') + 1;
|
||||||
|
if (yyres) memcpy(&yyres[yyn], yyp, bquote);
|
||||||
|
yyn += bquote;
|
||||||
|
yyp += bquote - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto default_char;
|
||||||
|
|
||||||
|
case '\'':
|
||||||
|
if (bquote && count_char(yyp+1, '\'') + 1 == bquote) {
|
||||||
|
if (yyres) memcpy(yyres + yyn, yyp, bquote);
|
||||||
|
yyn += bquote;
|
||||||
|
yyp += bquote - 1;
|
||||||
|
bquote = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto do_not_strip_quotes;
|
||||||
|
|
||||||
|
case ',':
|
||||||
|
goto do_not_strip_quotes;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
if (*++yyp != '\\')
|
||||||
|
goto do_not_strip_quotes;
|
||||||
|
/* Fall through. */
|
||||||
|
default_char:
|
||||||
|
default:
|
||||||
|
if (yyres)
|
||||||
|
yyres[yyn] = *yyp;
|
||||||
|
yyn++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
case '\0':
|
||||||
|
if (yyres)
|
||||||
|
yyres[yyn] = '\0';
|
||||||
|
return yyn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do_not_strip_quotes: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yyres) return strlen(yystr);
|
||||||
|
|
||||||
|
return (YYSIZE_T)(yystpcpy(yyres, yystr) - yyres);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RIPPER
|
#ifdef RIPPER
|
||||||
|
|
|
@ -995,7 +995,7 @@ eom
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_parenthesised_statement_argument
|
def test_parenthesised_statement_argument
|
||||||
assert_syntax_error("foo(bar rescue nil)", /unexpected rescue \(modifier\)/)
|
assert_syntax_error("foo(bar rescue nil)", /unexpected `rescue' modifier/)
|
||||||
assert_valid_syntax("foo (bar rescue nil)")
|
assert_valid_syntax("foo (bar rescue nil)")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue