X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/f0a2b745ce6c03aec6412d79ce0b782f20eddce4..60666776a83addda0a7fcb957c6b5007b8e030f3:/toke.c diff --git a/toke.c b/toke.c index 75fb327..961866b 100644 --- a/toke.c +++ b/toke.c @@ -39,15 +39,13 @@ Individual members of C have their own documentation. #include "EXTERN.h" #define PERL_IN_TOKE_C #include "perl.h" +#include "dquote_static.c" #define new_constant(a,b,c,d,e,f,g) \ S_new_constant(aTHX_ a,b,STR_WITH_LEN(c),d,e,f, g) #define pl_yylval (PL_parser->yylval) -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#define YYINITDEPTH 200 - /* XXX temporary backwards compatibility */ #define PL_lex_brackets (PL_parser->lex_brackets) #define PL_lex_brackstack (PL_parser->lex_brackstack) @@ -675,13 +673,9 @@ Perl_lex_start(pTHX_ SV *line, PerlIO *rsfp, bool new_filter) parser->old_parser = oparser = PL_parser; PL_parser = parser; - Newx(parser->stack, YYINITDEPTH, yy_stack_frame); - parser->ps = parser->stack; - parser->stack_size = YYINITDEPTH; - - parser->stack->state = 0; - parser->yyerrstatus = 0; - parser->yychar = YYEMPTY; /* Cause a token to be read. */ + parser->stack = NULL; + parser->ps = NULL; + parser->stack_size = 0; /* on scope exit, free this parser and restore any outer one */ SAVEPARSER(parser); @@ -750,7 +744,6 @@ Perl_parser_free(pTHX_ const yy_parser *parser) PerlIO_close(parser->rsfp); SvREFCNT_dec(parser->rsfp_filters); - Safefree(parser->stack); Safefree(parser->lex_brackstack); Safefree(parser->lex_casestack); PL_parser = parser->old_parser; @@ -1929,6 +1922,17 @@ S_force_next(pTHX_ I32 type) #endif } +void +Perl_yyunlex(pTHX) +{ + if (PL_parser->yychar != YYEMPTY) { + start_force(-1); + NEXTVAL_NEXTTOKE = PL_parser->yylval; + force_next(PL_parser->yychar); + PL_parser->yychar = YYEMPTY; + } +} + STATIC SV * S_newSV_maybe_utf8(pTHX_ const char *const start, STRLEN len) { @@ -2868,7 +2872,7 @@ S_scan_const(pTHX_ char *start) goto default_action; } - /* eg. \132 indicates the octal constant 0x132 */ + /* eg. \132 indicates the octal constant 0132 */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { @@ -2883,10 +2887,11 @@ S_scan_const(pTHX_ char *start) case 'o': { STRLEN len; + const char* error; - char* error = grok_bslash_o(s, &uv, &len, 1); + bool valid = grok_bslash_o(s, &uv, &len, &error, 1); s += len; - if (error) { + if (! valid) { yyerror(error); continue; } @@ -3952,7 +3957,7 @@ Perl_madlex(pTHX) PL_thismad = 0; /* just do what yylex would do on pending identifier; leave PL_thiswhite alone */ - if (PL_pending_ident) + if (PL_lex_state != LEX_KNOWNEXT && PL_pending_ident) return S_pending_ident(aTHX); /* previous token ate up our whitespace? */ @@ -4211,7 +4216,7 @@ Perl_yylex(pTHX) SvREFCNT_dec(tmp); } ); /* check if there's an identifier for us to look at */ - if (PL_pending_ident) + if (PL_lex_state != LEX_KNOWNEXT && PL_pending_ident) return REPORT(S_pending_ident(aTHX)); /* no identifier pending identification */ @@ -6130,7 +6135,7 @@ Perl_yylex(pTHX) int result; char *saved_bufptr = PL_bufptr; PL_bufptr = s; - result = CALL_FPTR(PL_keyword_plugin)(aTHX_ PL_tokenbuf, len, &o); + result = PL_keyword_plugin(aTHX_ PL_tokenbuf, len, &o); s = PL_bufptr; if (result == KEYWORD_PLUGIN_DECLINE) { /* not a plugged-in keyword */ @@ -6204,8 +6209,9 @@ Perl_yylex(pTHX) gvp = 0; if (hgv && tmp != KEY_x && tmp != KEY_CORE) /* never ambiguous */ Perl_ck_warner(aTHX_ packWARN(WARN_AMBIGUOUS), - "Ambiguous call resolved as CORE::%s(), %s", - GvENAME(hgv), "qualify as such or use &"); + "Ambiguous call resolved as CORE::%s(), " + "qualify as such or use &", + GvENAME(hgv)); } } @@ -6288,16 +6294,15 @@ Perl_yylex(pTHX) /* if we saw a global override before, get the right name */ + sv = S_newSV_maybe_utf8(aTHX_ PL_tokenbuf, + len ? len : strlen(PL_tokenbuf)); if (gvp) { + SV * const tmp_sv = sv; sv = newSVpvs("CORE::GLOBAL::"); - sv_catpv(sv,PL_tokenbuf); - } - else { - /* If len is 0, newSVpv does strlen(), which is correct. - If len is non-zero, then it will be the true length, - and so the scalar will be created correctly. */ - sv = newSVpv(PL_tokenbuf,len); + sv_catsv(sv, tmp_sv); + SvREFCNT_dec(tmp_sv); } + #ifdef PERL_MAD if (PL_madskills && !PL_thistoken) { char *start = SvPVX(PL_linestr) + PL_realtokenstart; @@ -6307,17 +6312,11 @@ Perl_yylex(pTHX) #endif /* Presume this is going to be a bareword of some sort. */ - CLINE; pl_yylval.opval = (OP*)newSVOP(OP_CONST, 0, sv); pl_yylval.opval->op_private = OPpCONST_BARE; - /* UTF-8 package name? */ - if (UTF && !IN_BYTES && - is_utf8_string((U8*)SvPVX_const(sv), SvCUR(sv))) - SvUTF8_on(sv); /* And if "Foo::", then that's what it certainly is. */ - if (len) goto safe_bareword; @@ -6493,10 +6492,27 @@ Perl_yylex(pTHX) const char *proto = SvPV_const(MUTABLE_SV(cv), protolen); if (!protolen) TERM(FUNC0SUB); - if ((*proto == '$' || *proto == '_') && proto[1] == '\0') - OPERATOR(UNIOPSUB); while (*proto == ';') proto++; + if ( + ( + ( + *proto == '$' || *proto == '_' + || *proto == '*' + ) + && proto[1] == '\0' + ) + || ( + *proto == '\\' && proto[1] && proto[2] == '\0' + ) + ) + OPERATOR(UNIOPSUB); + if (*proto == '\\' && proto[1] == '[') { + const char *p = proto + 2; + while(*p && *p != ']') + ++p; + if(*p == ']' && !p[1]) OPERATOR(UNIOPSUB); + } if (*proto == '&' && *s == '{') { if (PL_curstash) sv_setpvs(PL_subname, "__ANON__"); @@ -7304,14 +7320,13 @@ Perl_yylex(pTHX) case KEY_quotemeta: UNI(OP_QUOTEMETA); - case KEY_qw: + case KEY_qw: { + OP *words = NULL; s = scan_str(s,!!PL_madskills,FALSE); if (!s) missingterm(NULL); PL_expect = XOPERATOR; - force_next(')'); if (SvCUR(PL_lex_stuff)) { - OP *words = NULL; int warned = 0; d = SvPV_force(PL_lex_stuff, len); while (len) { @@ -7343,18 +7358,17 @@ Perl_yylex(pTHX) newSVOP(OP_CONST, 0, tokeq(sv))); } } - if (words) { - start_force(PL_curforce); - NEXTVAL_NEXTTOKE.opval = words; - force_next(THING); - } } + if (!words) + words = newNULLLIST(); if (PL_lex_stuff) { SvREFCNT_dec(PL_lex_stuff); PL_lex_stuff = NULL; } - PL_expect = XTERM; - TOKEN('('); + PL_expect = XOPERATOR; + pl_yylval.opval = sawparens(words); + TOKEN(QWLIST); + } case KEY_qq: s = scan_str(s,!!PL_madskills,FALSE); @@ -13928,6 +13942,66 @@ Perl_keyword_plugin_standard(pTHX_ } /* +=for apidoc Amx|OP *|parse_fullstmt|U32 flags + +Parse a single complete Perl statement. This may be a normal imperative +statement, including optional label, or a declaration that has +compile-time effect. It is up to the caller to ensure that the dynamic +parser state (L et al) is correctly set to reflect the source +of the code to be parsed and the lexical context for the statement. + +The op tree representing the statement is returned. This may be a +null pointer if the statement is null, for example if it was actually +a subroutine definition (which has compile-time side effects). If not +null, it will be the result of a L call, normally including +a C or equivalent op. + +If an error occurs in parsing or compilation, in most cases a valid op +tree (most likely null) is returned anyway. The error is reflected in +the parser state, normally resulting in a single exception at the top +level of parsing which covers all the compilation errors that occurred. +Some compilation errors, however, will throw an exception immediately. + +The I parameter is reserved for future use, and must always +be zero. + +=cut +*/ + +OP * +Perl_parse_fullstmt(pTHX_ U32 flags) +{ + OP *fullstmtop; + if (flags) + Perl_croak(aTHX_ "Parsing code internal error (%s)", "parse_fullstmt"); + ENTER; + SAVEVPTR(PL_eval_root); + PL_eval_root = NULL; + if(yyparse(GRAMFULLSTMT) && !PL_parser->error_count) + qerror(Perl_mess(aTHX_ "Parse error")); + fullstmtop = PL_eval_root; + LEAVE; + return fullstmtop; +} + +void +Perl_munge_qwlist_to_paren_list(pTHX_ OP *qwlist) +{ + PERL_ARGS_ASSERT_MUNGE_QWLIST_TO_PAREN_LIST; + deprecate("qw(...) as parentheses"); + force_next(')'); + if (qwlist->op_type == OP_STUB) { + op_free(qwlist); + } + else { + start_force(PL_curforce); + NEXTVAL_NEXTTOKE.opval = qwlist; + force_next(THING); + } + force_next('('); +} + +/* * Local variables: * c-indentation-style: bsd * c-basic-offset: 4