Other notes

Andrew Dalke dalke at dalkescientific.com
Thu Jan 6 14:24:52 EST 2005


Me
>>>> (BTW, it needs to be 1 .. 12 not 1..12 because 1. will be interpreted
>>>> as the floating point value "1.0".)<

Steve Holden:
> Indeed, but if ".." is defined as an acceptable token then there's 
> nothing to stop a strict LL(1) parser from disambiguating the cases in 
> question. "Token" is not the same thing as "character".

Python's tokenizer is greedy and doesn't take part in the
lookahead.  When it sees 1..12 the longest match is for "1."
which is a float.  What remains is ".2".  That also gets tokenized
as a float.  <float> <float> is not allowed in Python so the
parser raises an compile time SyntaxError exception

>>> 1..12
  File "<stdin>", line 1
    1..12
        ^
SyntaxError: invalid syntax
>>> 

Consider the alternative of "1..a".  Again "1." is tokenized
as a float.  What remains is ".a".  The longest match is "."
with "a" remaining.  Then the next token is "a".  The token
stream looks like
  <float 1.0><dot><name "a">
which gets converted to the same thing as
  getattr(1.0, "a")

That is legal syntax but floats don't have the "a" property
so Python raises an AttributeError at run-time.

>>> 1..a 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'float' object has no attribute 'a'
>>> 

Here's a property that does exist

>>> 1..__abs__
<method-wrapper object at 0x547d0>
>>> 


Because of the greedy lexing it isn't possible to do
"1.__abs__" to get the __abs__ method of an integer.
That's because the token stream is

 <float 1.0><name "__abs__">

which is a syntax error.

>>> 1.__abs__
  File "<stdin>", line 1
    1.__abs__
            ^
SyntaxError: invalid syntax
>>> 

One way to avoid that is to use "1 .__abs__".  See the
space after the "1"?  The tokenizer for this case creates

  <integer 1><dot><name "__abs__">


which create code equivalent to getattr(1, "__abs__") and
is valid syntax

>>> 1 .__abs__
<method-wrapper object at 0x54ab0>
>>> 

Another option is to use parentheses:  (1).__abs__

I prefer this latter option because the () is easier to
see than a space.  But I prefer using getattr even more.

				Andrew
				dalke at dalkescientific.com




More information about the Python-list mailing list