diff options
| author | Felix Jones <[email protected]> | 2017-02-16 13:33:46 +0000 |
|---|---|---|
| committer | Felix Jones <[email protected]> | 2017-02-16 13:33:46 +0000 |
| commit | d83aad8d570e4bbffa3bd3ce64e210f78afa425f (patch) | |
| tree | 5389a87c135b1bdf3e23a1ba02e02400b7cf80fc /mrbgems/mruby-compiler/core/parse.y | |
| parent | 70aa6dc38d75dd6b1e2c76f290bc576e36e36ea3 (diff) | |
| parent | b165708c8deba00685f9a27926c554aaa7f3b0fb (diff) | |
| download | mruby-d83aad8d570e4bbffa3bd3ce64e210f78afa425f.tar.gz mruby-d83aad8d570e4bbffa3bd3ce64e210f78afa425f.zip | |
Merge branch 'master' into android.rake-ndk-clang
Diffstat (limited to 'mrbgems/mruby-compiler/core/parse.y')
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 282 |
1 files changed, 168 insertions, 114 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 426c262fb..f8e4eb72f 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -41,6 +41,7 @@ static void yyerror(parser_state *p, const char *s); static void yywarn(parser_state *p, const char *s); static void yywarning(parser_state *p, const char *s); static void backref_error(parser_state *p, node *n); +static void void_expr_error(parser_state *p, node *n); static void tokadd(parser_state *p, int32_t c); #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) @@ -870,6 +871,7 @@ call_with_block(parser_state *p, node *a, node *b) break; case NODE_CALL: case NODE_FCALL: + case NODE_SCALL: n = a->cdr->cdr->cdr; if (!n->car) n->car = cons(0, b); else { @@ -1097,7 +1099,7 @@ heredoc_end(parser_state *p) %type <nd> literal numeric cpath symbol %type <nd> top_compstmt top_stmts top_stmt %type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call -%type <nd> expr_value arg_value arg_rhs primary_value +%type <nd> expr_value arg_rhs primary_value %type <nd> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure %type <nd> args call_args opt_call_args %type <nd> paren_args opt_paren_args variable @@ -1322,7 +1324,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym { $$ = new_asgn(p, $1, new_array(p, $3)); } - | mlhs '=' arg_value + | mlhs '=' arg { $$ = new_masgn(p, $1, $3); } @@ -1401,7 +1403,10 @@ expr : command_call expr_value : expr { if (!$1) $$ = new_nil(p); - else $$ = $1; + else { + void_expr_error(p, $1); + $$ = $1; + } } ; @@ -1907,20 +1912,13 @@ arg : lhs '=' arg_rhs } ; -arg_value : arg - { - $$ = $1; - if (!$$) $$ = new_nil(p); - } - ; - aref_args : none | args trailer { $$ = $1; NODE_LINENO($$, $1); } - | args ',' assocs trailer + | args comma assocs trailer { $$ = push($1, new_hash(p, $3)); } @@ -1931,9 +1929,14 @@ aref_args : none } ; -arg_rhs : arg %prec tOP_ASGN +arg_rhs : arg %prec tOP_ASGN + { + void_expr_error(p, $1); + $$ = $1; + } | arg modifier_rescue arg { + void_expr_error(p, $1); $$ = new_mod_rescue(p, $1, $3); } ; @@ -1955,7 +1958,7 @@ opt_call_args : none $$ = cons($1,0); NODE_LINENO($$, $1); } - | args ',' assocs ',' + | args comma assocs ',' { $$ = cons(push($1, new_hash(p, $3)), 0); NODE_LINENO($$, $1); @@ -1982,7 +1985,7 @@ call_args : command $$ = cons(list1(new_hash(p, $1)), $2); NODE_LINENO($$, $1); } - | args ',' assocs opt_block_arg + | args comma assocs opt_block_arg { $$ = cons(push($1, new_hash(p, $3)), $4); NODE_LINENO($$, $1); @@ -2005,13 +2008,13 @@ command_args : { } ; -block_arg : tAMPER arg_value +block_arg : tAMPER arg { $$ = new_block_arg(p, $2); } ; -opt_block_arg : ',' block_arg +opt_block_arg : comma block_arg { $$ = $2; } @@ -2021,44 +2024,47 @@ opt_block_arg : ',' block_arg } ; -args : arg_value +comma : ',' + | ',' heredoc_bodies + ; + +args : arg { + void_expr_error(p, $1); $$ = cons($1, 0); NODE_LINENO($$, $1); } - | tSTAR arg_value + | tSTAR arg { + void_expr_error(p, $2); $$ = cons(new_splat(p, $2), 0); NODE_LINENO($$, $2); } - | args ',' arg_value + | args comma arg { + void_expr_error(p, $3); $$ = push($1, $3); } - | args ',' tSTAR arg_value + | args comma tSTAR arg { + void_expr_error(p, $4); $$ = push($1, new_splat(p, $4)); } - | args ',' heredoc_bodies arg_value - { - $$ = push($1, $4); - } - | args ',' heredoc_bodies tSTAR arg_value - { - $$ = push($1, new_splat(p, $5)); - } ; -mrhs : args ',' arg_value +mrhs : args comma arg { + void_expr_error(p, $3); $$ = push($1, $3); } - | args ',' tSTAR arg_value + | args comma tSTAR arg { + void_expr_error(p, $4); $$ = push($1, new_splat(p, $4)); } - | tSTAR arg_value + | tSTAR arg { + void_expr_error(p, $2); $$ = list1(new_splat(p, $2)); } ; @@ -2097,7 +2103,7 @@ primary : literal } | tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen { - $$ = 0; + $$ = new_nil(p); } | tLPAREN compstmt ')' { @@ -2125,17 +2131,9 @@ primary : literal { $$ = new_return(p, 0); } - | keyword_yield '(' call_args rparen + | keyword_yield opt_paren_args { - $$ = new_yield(p, $3); - } - | keyword_yield '(' rparen - { - $$ = new_yield(p, 0); - } - | keyword_yield - { - $$ = new_yield(p, 0); + $$ = new_yield(p, $2); } | keyword_not '(' expr rparen { @@ -2450,7 +2448,7 @@ block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg } | f_arg ',' { - $$ = new_args(p, $1, 0, 1, 0, 0); + $$ = new_args(p, $1, 0, 0, 0, 0); } | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg { @@ -2688,7 +2686,7 @@ opt_rescue : keyword_rescue exc_list exc_var then | none ; -exc_list : arg_value +exc_list : arg { $$ = list1($1); } @@ -2783,10 +2781,6 @@ regexp : tREGEXP_BEG tREGEXP heredoc : tHEREDOC_BEG ; -opt_heredoc_bodies : /* none */ - | heredoc_bodies - ; - heredoc_bodies : heredoc_body | heredoc_bodies heredoc_body ; @@ -3115,7 +3109,7 @@ f_opt_asgn : tIDENTIFIER '=' } ; -f_opt : f_opt_asgn arg_value +f_opt : f_opt_asgn arg { $$ = cons(nsym($1), $2); } @@ -3233,23 +3227,23 @@ assocs : assoc } ; -assoc : arg_value tASSOC arg_value +assoc : arg tASSOC arg { $$ = cons($1, $3); } - | tLABEL arg_value + | tLABEL arg { $$ = cons(new_sym(p, $1), $2); } - | tLABEL_END arg_value + | tLABEL_END arg { $$ = cons(new_sym(p, new_strsym(p, $1)), $2); } - | tSTRING_BEG tLABEL_END arg_value + | tSTRING_BEG tLABEL_END arg { $$ = cons(new_sym(p, new_strsym(p, $2)), $3); } - | tSTRING_BEG string_rep tLABEL_END arg_value + | tSTRING_BEG string_rep tLABEL_END arg { $$ = cons(new_dsym(p, push($2, $3)), $4); } @@ -3308,11 +3302,12 @@ rbracket : opt_nl ']' trailer : /* none */ | nl - | ',' + | comma ; term : ';' {yyerrok;} | nl + | heredoc_body ; nl : '\n' @@ -3320,10 +3315,10 @@ nl : '\n' p->lineno++; p->column = 0; } - opt_heredoc_bodies + ; terms : term - | terms ';' {yyerrok;} + | terms term ; none : /* none */ @@ -3430,6 +3425,26 @@ backref_error(parser_state *p, node *n) } } +static void +void_expr_error(parser_state *p, node *n) +{ + int c; + + if (n == NULL) return; + c = (int)(intptr_t)n->car; + switch (c) { + case NODE_BREAK: + case NODE_RETURN: + case NODE_NEXT: + case NODE_REDO: + case NODE_RETRY: + yyerror(p, "void value expression"); + break; + default: + break; + } +} + static void pushback(parser_state *p, int c); static mrb_bool peeks(parser_state *p, const char *s); static mrb_bool skips(parser_state *p, const char *s); @@ -3730,6 +3745,44 @@ scan_hex(const int *start, int len, int *retlen) return retval; } +static int32_t +read_escape_unicode(parser_state *p, int limit) +{ + int32_t c; + int buf[9]; + int i; + + /* Look for opening brace */ + i = 0; + buf[0] = nextc(p); + if (buf[0] < 0) goto eof; + if (ISXDIGIT(buf[0])) { + /* \uxxxx form */ + for (i=1; i<limit; i++) { + buf[i] = nextc(p); + if (buf[i] < 0) goto eof; + if (!ISXDIGIT(buf[i])) { + pushback(p, buf[i]); + break; + } + } + } + else { + pushback(p, buf[0]); + } + c = scan_hex(buf, i, &i); + if (i == 0) { + eof: + yyerror(p, "Invalid escape character syntax"); + return -1; + } + if (c < 0 || c > 0x10FFFF || (c & 0xFFFFF800) == 0xD800) { + yyerror(p, "Invalid Unicode code point"); + return -1; + } + return c; +} + /* Return negative to indicate Unicode code point */ static int32_t read_escape(parser_state *p) @@ -3802,53 +3855,17 @@ read_escape(parser_state *p) return c; case 'u': /* Unicode */ - { - int buf[9]; - int i; - - /* Look for opening brace */ - i = 0; - buf[0] = nextc(p); - if (buf[0] < 0) goto eof; - if (buf[0] == '{') { + if (peek(p, '{')) { /* \u{xxxxxxxx} form */ - for (i=0; i<9; i++) { - buf[i] = nextc(p); - if (buf[i] < 0) goto eof; - if (buf[i] == '}') { - break; - } - else if (!ISXDIGIT(buf[i])) { - yyerror(p, "Invalid escape character syntax"); - pushback(p, buf[i]); - return 0; - } - } - } - else if (ISXDIGIT(buf[0])) { - /* \uxxxx form */ - for (i=1; i<4; i++) { - buf[i] = nextc(p); - if (buf[i] < 0) goto eof; - if (!ISXDIGIT(buf[i])) { - pushback(p, buf[i]); - break; - } - } + nextc(p); + c = read_escape_unicode(p, 8); + if (c < 0) return 0; + if (nextc(p) != '}') goto eof; } else { - pushback(p, buf[0]); + c = read_escape_unicode(p, 4); + if (c < 0) return 0; } - c = scan_hex(buf, i, &i); - if (i == 0) { - yyerror(p, "Invalid escape character syntax"); - return 0; - } - if (c < 0 || c > 0x10FFFF || (c & 0xFFFFF800) == 0xD800) { - yyerror(p, "Invalid Unicode code point"); - return 0; - } - } return -c; case 'b':/* backspace */ @@ -3906,7 +3923,10 @@ parse_string(parser_state *p) int beg = (intptr_t)p->lex_strterm->cdr->cdr->car; int end = (intptr_t)p->lex_strterm->cdr->cdr->cdr; parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; + int cmd_state = p->cmd_start; + if (beg == 0) beg = -3; /* should never happen */ + if (end == 0) end = -3; newtok(p); while ((c = nextc(p)) != end || nest_level != 0) { if (hinf && (c == '\n' || c < 0)) { @@ -3928,7 +3948,12 @@ parse_string(parser_state *p) } } if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) { - return tHEREDOC_END; + if (c < 0) { + p->parsing_heredoc = NULL; + } + else { + return tHEREDOC_END; + } } } if (c < 0) { @@ -3969,6 +3994,20 @@ parse_string(parser_state *p) tokadd(p, '\\'); tokadd(p, c); } + else if (c == 'u' && peek(p, '{')) { + /* \u{xxxx xxxx xxxx} form */ + nextc(p); + while (1) { + do c = nextc(p); while (ISSPACE(c)); + if (c == '}') break; + pushback(p, c); + c = read_escape_unicode(p, 8); + if (c < 0) break; + tokadd(p, -c); + } + if (hinf) + hinf->line_head = FALSE; + } else { pushback(p, c); tokadd(p, read_escape(p)); @@ -4093,10 +4132,12 @@ parse_string(parser_state *p) return tREGEXP; } yylval.nd = new_str(p, tok(p), toklen(p)); - if (IS_LABEL_SUFFIX(0)) { - p->lstate = EXPR_BEG; - nextc(p); - return tLABEL_END; + if (IS_LABEL_POSSIBLE()) { + if (IS_LABEL_SUFFIX(0)) { + p->lstate = EXPR_BEG; + nextc(p); + return tLABEL_END; + } } return tSTRING; @@ -4871,7 +4912,7 @@ parser_yylex(parser_state *p) char *endp; errno = 0; - d = strtod(tok(p), &endp); + d = mrb_float_read(tok(p), &endp); if (d == 0 && endp == tok(p)) { yywarning_s(p, "corrupted float value %s", tok(p)); } @@ -5477,7 +5518,10 @@ mrb_parser_parse(parser_state *p, mrbc_context *c) p->lex_strterm = NULL; parser_init_cxt(p, c); - yyparse(p); + if (yyparse(p) != 0 || p->nerr > 0) { + p->tree = 0; + return; + } if (!p->tree) { p->tree = new_nil(p); } @@ -5657,8 +5701,8 @@ mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c) return mrb_parse_nstring(mrb, s, strlen(s), c); } -static mrb_value -load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) +MRB_API mrb_value +mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c) { struct RClass *target = mrb->object_class; struct RProc *proc; @@ -5717,7 +5761,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) MRB_API mrb_value mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c) { - return load_exec(mrb, mrb_parse_file(mrb, f, c), c); + return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c); } MRB_API mrb_value @@ -5730,7 +5774,7 @@ mrb_load_file(mrb_state *mrb, FILE *f) MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c) { - return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); + return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); } MRB_API mrb_value @@ -6024,7 +6068,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_FCALL: case NODE_CALL: - printf("NODE_CALL:\n"); + case NODE_SCALL: + switch (nodetype) { + case NODE_FCALL: + printf("NODE_FCALL:\n"); break; + case NODE_CALL: + printf("NODE_CALL(.):\n"); break; + case NODE_SCALL: + printf("NODE_SCALL(&.):\n"); break; + default: + break; + } mrb_parser_dump(mrb, tree->car, offset+1); dump_prefix(tree, offset+1); printf("method='%s' (%d)\n", @@ -6504,8 +6558,8 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_HEREDOC: - printf("NODE_HEREDOC:\n"); - mrb_parser_dump(mrb, ((parser_heredoc_info*)tree)->doc, offset+1); + printf("NODE_HEREDOC (<<%s):\n", ((parser_heredoc_info*)tree)->term); + dump_recur(mrb, ((parser_heredoc_info*)tree)->doc, offset+1); break; default: |
