Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency of ${hash{key}} #915

Closed
p5pRT opened this issue Dec 4, 1999 · 4 comments
Closed

Inconsistency of ${hash{key}} #915

p5pRT opened this issue Dec 4, 1999 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 4, 1999

Migrated from rt.perl.org#1851 (status was 'resolved')

Searchable as RT1851$

@p5pRT
Copy link
Author

p5pRT commented Dec 4, 1999

From mjtg@cus.cam.ac.uk

perldata says​:

  Within search patterns (which also undergo double-quotish
  substitution) there is a bad ambiguity​: Is /$foo[bar]/ to
  be interpreted as /${foo}[bar]/ (where [bar] is a character
  class for the regular expression) or as /${foo[bar]}/ (where <<<<<<
  [bar] is the subscript to array @​foo)? If @​foo doesn't
  otherwise exist, then it's obviously a character class. If
  @​foo exists, Perl takes a good guess about [bar], and is
  almost always right. If it does guess wrong, or if you're
  just plain paranoid, you can force the correct
  interpretation with curly brackets as above.

which I interpret as meaning it should work for substitutions in
search patterns at least. And experiment shows that it works in most
other cases. So this prints 213312 as expected​:

  @​a = (2,3,4);
  $h{${a[0]}} = 13;
  ${h{$a[1]}} = 12;
  print %h;

But if you try to nest them, there is a syntax error (and parsing stops
immediately rather than continuing to the end of the script)​:

  @​a = (2,3,4);
  ${h{${a[0]}}} = 13;
  This line isn't parsed.

gives

  syntax error at - line 2, near "}}"
  Execution of - aborted due to compilation errors.

Mike Guy

% perl -V
Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration​:
  Platform​:
  osname=sunos, osvers=4.1.3, archname=sun4-sunos
  uname=''
  hint=previous, useposix=true, d_sigaction=define
  usethreads=undef useperlio=undef d_sfio=undef
  Compiler​:
  cc='gcc', optimize='-O', gccversion=2.7.2.3
  cppflags='-I/usr/local/include -DREG_INFTY=22790'
  ccflags ='-I/usr/local/include -DREG_INFTY=22790'
  stdchar='unsigned char', d_stdstdio=define, usevfork=true
  intsize=4, longsize=4, ptrsize=4, doublesize=8
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
  alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries​:
  ld='ld', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/ucblib
  libs=-ldbm -ldl -lm -lc -lposix
  libc=/lib/libc.so.1.8, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
  cccdlflags='-fpic', lddlflags='-assert nodefinitions -L/usr/local/lib'

Characteristics of this binary (from libperl)​:
  Locally applied patches​:
  pos.list
  IO.file.return
  int.delimiter
  bigfloat
  Built under sunos
  Compiled at Jul 7 1999 16​:09​:54
  @​INC​:
  /home/mjtg/perl5.005_03/lib
  /home/mjtg/perl5.005_03/lib
  /home/mjtg/perl5.005_03/lib
  .

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 1999

From @TimToady

I'm working on this one, in case anyone else was thinking about it.
Basically, lex_fakebrack needs to go away.

Larry

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 1999

From [Unknown Contact. See original ticket]

Larry Wall writes​:

I'm working on this one, in case anyone else was thinking about it.
Basically, lex_fakebrack needs to go away.

Thanks. There are not so many *totally* incomprehensible places in
toke.c, and lex_fakebrack is one of them. Probably one could not
grok it because it was coded wrong on the first place... ;-)

Ilya

@p5pRT
Copy link
Author

p5pRT commented Dec 7, 1999

From @TimToady

M.J.T. Guy writes​:
: @​a = (2,3,4);
: ${h{${a[0]}}} = 13;
: This line isn't parsed.
:
: gives
:
: syntax error at - line 2, near "}}"
: Execution of - aborted due to compilation errors.

Here's the patch. Be sure to make regen_headers. We might be able to
do something similar with lex_formbrack, but I chickened out. Bock, bock.

Larry

Inline Patch
diff -ru perl5.005_62/intrpvar.h perl5.005_62pat/intrpvar.h
--- perl5.005_62/intrpvar.h	Tue Oct  5 16:29:09 1999
+++ perl5.005_62pat/intrpvar.h	Tue Dec  7 10:14:18 1999
@@ -252,7 +252,6 @@
 PERLVAR(Ilex_expect,	expectation)	/* expect after determined token */
 PERLVAR(Ilex_brackets,	I32)		/* bracket count */
 PERLVAR(Ilex_formbrack,	I32)		/* bracket count at outer format level */
-PERLVAR(Ilex_fakebrack,	I32)		/* outer bracket is mere delimiter */
 PERLVAR(Ilex_casemods,	I32)		/* casemod count */
 PERLVAR(Ilex_dojoin,	I32)		/* doing an array interpolation */
 PERLVAR(Ilex_starts,	I32)		/* how many interps done on level */
diff -ru perl5.005_62/toke.c perl5.005_62pat/toke.c
--- perl5.005_62/toke.c	Mon Oct 11 22:22:11 1999
+++ perl5.005_62pat/toke.c	Tue Dec  7 11:11:12 1999
@@ -31,6 +31,9 @@
 static void restore_expect(pTHXo_ void *e);
 static void restore_lex_expect(pTHXo_ void *e);
 
+#define XFAKEBRACK 128
+#define XENUMMASK 127
+
 #define UTF (PL_hints & HINT_UTF8)
 /*
  * Note: we try to be careful never to call the isXXX_utf8() functions
@@ -360,7 +363,6 @@
 
     SAVEI32(PL_lex_dojoin);
     SAVEI32(PL_lex_brackets);
-    SAVEI32(PL_lex_fakebrack);
     SAVEI32(PL_lex_casemods);
     SAVEI32(PL_lex_starts);
     SAVEI32(PL_lex_state);
@@ -387,7 +389,6 @@
     PL_lex_defer = 0;
     PL_expect = XSTATE;
     PL_lex_brackets = 0;
-    PL_lex_fakebrack = 0;
     New(899, PL_lex_brackstack, 120, char);
     New(899, PL_lex_casestack, 12, char);
     SAVEFREEPV(PL_lex_brackstack);
@@ -963,7 +964,6 @@
     PL_lex_state = PL_sublex_info.super_state;
     SAVEI32(PL_lex_dojoin);
     SAVEI32(PL_lex_brackets);
-    SAVEI32(PL_lex_fakebrack);
     SAVEI32(PL_lex_casemods);
     SAVEI32(PL_lex_starts);
     SAVEI32(PL_lex_state);
@@ -988,7 +988,6 @@
 
     PL_lex_dojoin = FALSE;
     PL_lex_brackets = 0;
-    PL_lex_fakebrack = 0;
     New(899, PL_lex_brackstack, 120, char);
     New(899, PL_lex_casestack, 12, char);
     SAVEFREEPV(PL_lex_brackstack);
@@ -1036,7 +1035,6 @@
 	SAVEFREESV(PL_linestr);
 	PL_lex_dojoin = FALSE;
 	PL_lex_brackets = 0;
-	PL_lex_fakebrack = 0;
 	PL_lex_casemods = 0;
 	*PL_lex_casestack = '\0';
 	PL_lex_starts = 0;
@@ -2988,7 +2986,8 @@
 	    PL_lex_formbrack = 0;
 	if (PL_lex_state == LEX_INTERPNORMAL) {
 	    if (PL_lex_brackets == 0) {
-		if (PL_lex_fakebrack) {
+		if (PL_expect & XFAKEBRACK) {
+		    PL_expect &= XENUMMASK;
 		    PL_lex_state = LEX_INTERPEND;
 		    PL_bufptr = s;
 		    return yylex();	/* ignore fake brackets */
@@ -2999,9 +2998,9 @@
 		    PL_lex_state = LEX_INTERPEND;
 	    }
 	}
-	if (PL_lex_brackets < PL_lex_fakebrack) {
+	if (PL_expect & XFAKEBRACK) {
+	    PL_expect &= XENUMMASK;
 	    PL_bufptr = s;
-	    PL_lex_fakebrack = 0;
 	    return yylex();		/* ignore fake brackets */
 	}
 	force_next('}');
@@ -5609,8 +5608,6 @@
     char *bracket = 0;
     char funny = *s++;
 
-    if (PL_lex_brackets == 0)
-	PL_lex_fakebrack = 0;
     if (isSPACE(*s))
 	s = skipspace(s);
     d = dest;
@@ -5715,9 +5712,8 @@
 			"Ambiguous use of %c{%s%s} resolved to %c%s%s",
 			funny, dest, brack, funny, dest, brack);
 		}
-		PL_lex_fakebrack = PL_lex_brackets+1;
 		bracket++;
-		PL_lex_brackstack[PL_lex_brackets++] = XOPERATOR;
+		PL_lex_brackstack[PL_lex_brackets++] = XOPERATOR | XFAKEBRACK;
 		return s;
 	    }
 	} 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant