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

Parsing problem for "$a+++$b" #470

Closed
p5pRT opened this issue Sep 3, 1999 · 11 comments
Closed

Parsing problem for "$a+++$b" #470

p5pRT opened this issue Sep 3, 1999 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 3, 1999

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

Searchable as RT1311$

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From merriam@world.std.com

Pardon if this isn't a bug; I'm a new Perl programmer.

I run this in the perl debugger​:

$a = 1;$b = 2;
$a+++$b;
print $a
2
print $b
2

The problem is that the statement $a+++$b is
ambiguous between ($a++)+$b and $a+(++$b). This
is a parsing issue as opposed to a precedence issue.

The correct response is an error. It is pain to find
in generated perl code. :-(.

If you disagree, please explain it. No fair just
whisking it away.

Thank you,

Charles Merriam
Gleefully Unemployed
merriam@​world.std.com
408 773 8824


Site configuration information for perl 5.00503​:

Summary of my perl5 (5.0 patchlevel 5 subversion 03) configuration​:
  Platform​:
  osname=MSWin32, osvers=4.0, archname=MSWin32-x86-object
  uname=''
  hint=recommended, useposix=true, d_sigaction=undef
  usethreads=undef useperlio=undef d_sfio=undef
  Compiler​:
  cc='cl.exe', optimize='-O2 -MD -DNDEBUG -TP -GX', gccversion=
  cppflags='-DWIN32'
  ccflags ='-O2 -MD -DNDEBUG -TP -GX -DWIN32 -D_CONSOLE -DNO_STRICT
-DHAVE_DES_FCRYPT -DPERL_OBJECT'
  stdchar='char', d_stdstdio=define, usevfork=false
  intsize=4, longsize=4, ptrsize=4, doublesize=8
  d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
  alignbytes=8, usemymalloc=n, prototype=define
  Linker and Libraries​:
  ld='link', ldflags ='-nologo -nodefaultlib -release -machine​:x86'
  libpth="C​:\Perl\lib\core"
  libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib
odbc32.lib odbccp32.lib PerlCRT.lib
  libc=C​:\Perl\lib\CORE\PerlCRT.lib, so=dll, useshrplib=yes,
libperl=perlcore.lib
  Dynamic Linking​:
  dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release
-machine​:x86'

Locally applied patches​:
  ACTIVEPERL_LOCAL_PATCHES_ENTRY


@​INC for perl 5.00503​:
  C​:/Perl/lib
  C​:/Perl/site/lib
  .


Environment for perl 5.00503​:
  HOME (unset)
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=C​:\PERL\BIN;C​:\WINDOWS;C​:\WINDOWS;C​:\WINDOWS\COMMAND;C​:\VISUALCAFE\BIN;C​:\VISUALCAFE\JAVA\BIN

  PERL_BADLANG (unset)
  SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From @tamias

On Thu, Sep 02, 1999 at 11​:41​:21PM -0700, C M wrote​:

This is a bug report for perl from merriam@​world.std.com,
generated with the help of perlbug 1.26 running under perl 5.00503.

Pardon if this isn't a bug; I'm a new Perl programmer.

I run this in the perl debugger​:

$a = 1;$b = 2;
$a+++$b;
print $a
2
print $b
2

The problem is that the statement $a+++$b is
ambiguous between ($a++)+$b and $a+(++$b). This
is a parsing issue as opposed to a precedence issue.

The tokenizer/parser sees ++, so that's an auto-increment operator.
Then the tokenizer/parser sees +, so that's an addition operator.

The correct response is an error. It is pain to find
in generated perl code. :-(.

So don't generate Perl code like that. :) Easy enough to solve with
whitespace in the appropriate place(s).

Ambiguity is fun, it's what makes the Obfuscated Perl Contest interesting.

Ronald

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From @TimToady

C M writes​:
: The problem is that the statement $a+++$b is
: ambiguous between ($a++)+$b and $a+(++$b). This
: is a parsing issue as opposed to a precedence issue.
:
: The correct response is an error. It is pain to find
: in generated perl code. :-(.
:
: If you disagree, please explain it. No fair just
: whisking it away.

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

A corollary to that is that, if you write $a+++$b without whitespace
on purpose, you'd darn well better know how the lexer works. The use
of whitespace is not mandatory, but it is highly recommended. English
distinguishes "must" from "should" for a reason.

Larry

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From [Unknown Contact. See original ticket]

Larry Wall writes​:

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

Unfortunately, this rule is not applicable to Perl.

  perl -wle 'print 1..3'
  123

Given the above rule, one would expect "1.3".

Ilya

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From @gbarr

On Fri, Sep 03, 1999 at 06​:40​:00PM -0400, Ilya Zakharevich wrote​:

Larry Wall writes​:

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

Unfortunately, this rule is not applicable to Perl.

perl -wle 'print 1..3'
123

Given the above rule, one would expect "1.3".

You would ? please explain.

--
Since you're clearly mad as a mongoose, I'll bid you good-day.
  -- Edmund to Captain Rum : Black Adder II "Potato"

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From [Unknown Contact. See original ticket]

Graham Barr wrote​:

On Fri, Sep 03, 1999 at 06​:40​:00PM -0400, Ilya Zakharevich wrote​:

Larry Wall writes​:

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

Unfortunately, this rule is not applicable to Perl.

perl -wle 'print 1..3'
123

Given the above rule, one would expect "1.3".

You would ? please explain.

Yeah, I would expect "13" if anything.

1 token
1. token
1.. not a token
. token
.3 token

hmm, print ".3" to filehandle "1.". Ok, switch to 'print (1..3)' and
assume we find a valid parse. Then it's "13".

print (1. . 3) ==> "13"

Now, how about 1...3? (First, figure out what you think perl really will
do)
1....3 is unsurprising.
But 1.....3 is an error. Hmmm... parser not trying quite hard enough! I
can add spaces to fix it. Perhaps somebody should patch the lexer/parser
to handle this? Like, by automatically printing "Just another perl
hacker", perhaps? ;)

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From @tamias

On Fri, Sep 03, 1999 at 06​:40​:00PM -0400, Ilya Zakharevich wrote​:

Larry Wall writes​:

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

Unfortunately, this rule is not applicable to Perl.

perl -wle 'print 1..3'
123

Given the above rule, one would expect "1.3".

Hmm, Larry said "longest operator token", not "longest token".

1 .. 3

has a longer operator token than

1. . 3

Ronald

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 1999

From [Unknown Contact. See original ticket]

On Fri, Sep 03, 1999 at 07​:30​:51PM -0500, Graham Barr wrote​:

Unfortunately, this rule is not applicable to Perl.

perl -wle 'print 1..3'
123

Given the above rule, one would expect "1.3".

You would ? please explain.

Bad me, expecting 1. . 3 to be "1.3". Of course, it is "13".

Ilya

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 1999

From [Unknown Contact. See original ticket]

Ilya Zakharevich <ilya@​math.ohio-state.edu> writes​:

Larry Wall writes​:

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

Unfortunately, this rule is not applicable to Perl.

perl -wle 'print 1..3'
123

Given the above rule, one would expect "1.3".

Why? '..' is longer than '.' so I would expect 1 .. 3 i.e. 1 2 3

Ilya
--
Nick Ing-Simmons

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 1999

From [Unknown Contact. See original ticket]

Nick Ing-Simmons writes​:

Mere ambiguity is not sufficient for an error. The typical modern lexer
has the built-in presupposition that it should always find the longest
operator token that it can. If you meant a shorter operator,
you *must* insert whitespace. Other than that, whitespace is not
required. It's a simple rule that has served many languages well.

Unfortunately, this rule is not applicable to Perl.

perl -wle 'print 1..3'
123

Given the above rule, one would expect "1.3".
  ^^^^^ "13"

Why? '..' is longer than '.' so I would expect 1 .. 3 i.e. 1 2 3

Tokens are processed left to right, thus the greediness is as in
RExen. Say, 0.45 is not parsed as 0 . 45.

Ilya

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 1999

From @TimToady

Ilya Zakharevich writes​:
: Nick Ing-Simmons writes​:
: > >> Mere ambiguity is not sufficient for an error. The typical modern lexer
: > >> has the built-in presupposition that it should always find the longest
: > >> operator token that it can. If you meant a shorter operator,
: > >> you *must* insert whitespace. Other than that, whitespace is not
: > >> required. It's a simple rule that has served many languages well.
: > >
: > >Unfortunately, this rule is not applicable to Perl.
: > >
: > > perl -wle 'print 1..3'
: > > 123
: > >
: > >Given the above rule, one would expect "1.3".
: ^^^^^ "13"
:
: > Why? '..' is longer than '.' so I would expect 1 .. 3 i.e. 1 2 3
:
: Tokens are processed left to right, thus the greediness is as in
: RExen. Say, 0.45 is not parsed as 0 . 45.

Yes, Perl does an occasional lookahead when it figures the human
involved would do the same. You can think of it as the exception that
proves the rule. Well, okay, I don't know if you can, but I can. :-)

And I did say "operator token" on purpose...

Larry

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