2014-10-08 40 views
1
>>> 1 .__hash__() 
1 
>>> 1.__hash__() 
    File "<stdin>", line 1 
    1.__hash__() 
      ^
SyntaxError: invalid syntax 

在此之前已經介紹過,第二個示例不起作用,因爲int文本實際上被解析爲float。int文字的屬性訪問

我的問題是,爲什麼不是 python解析爲一個int的屬性訪問,當解釋爲一個float是一個語法錯誤?關於lexical analysis的文檔部分似乎暗示只有在其他解釋不明確時才需要空白,但也許我錯誤地閱讀了本節。

在預感上,似乎詞法分析器是貪婪的(儘可能採用最大的標誌),但我沒有這個說法的來源。

回答

2

仔細閱讀,它說

需要空白兩個記號之間僅當它們級聯本來被解釋爲不同的令牌(例如,ab是一個符號,而是一個b爲兩個符號)。

1.__hash__()標記化如下:

import io, tokenize 
for token in tokenize.tokenize(io.BytesIO(b"1.__hash__()").read): 
    print(token.string) 

#>>> utf-8 
#>>> 1. 
#>>> __hash__ 
#>>> (
#>>>) 
#>>> 

Python的詞法分析器會選擇令牌which comprises the longest possible string that forms a legal token, when read from left to right;解析後沒有兩個令牌應該可以合併成一個有效的令牌。邏輯非常類似於in your other question

混淆似乎並沒有認識到令牌化步驟是一個完全不同的步驟。如果語法允許分裂令牌只是爲了讓解析器快樂那麼可以肯定你所期望的

_ or1. 

來標記爲

_ 
or 
1. 

但目前還沒有這樣的規則,所以它作爲標記化

_ 
or1 
. 
3

詞法分析器非常簡單,不會回溯。語言分析器通常分爲一個階段階段和一個分析階段,或者一個詞法分析器和一個分析器。詞法分析器將字符流分解爲標記,然後解析器根據標記確定程序結構。詞法分析器看到四個標記:1.,__hash__,(,):float,identifier,open-paren,close-paren。解析器無法理解這些標記,但這並不意味着詞法分析器會嘗試以不同的方式區分這些字符。

3

這只是一個定義問題;語法是語言完成這項工作的語言。

Attribute references定義在比floating point literals更廣泛的層次上。因此,從語法層面來說,解析器必須將1.識別爲浮點文字而不是屬性引用。

當然,解析器本身可能會在達到_時回溯,並試圖找出它是而不是而不是一個浮點數字,而是一個屬性引用。但是,由於CPython的解析器是LL(1) parser回溯不是一個選項。因此,語法必須經過很多改變才能讓解析器識別這一點(儘管如果LL(1)解析器甚至有可能,我現在還不確定)。我們也可以將Python的解析器改爲別的東西,也許可以做一些回溯,但這樣做不僅是一項非常困難的任務(它也需要改變語法),但會增加解析過程的複雜性(並且這可能會降低速度)。

所以也許這將是可能的,但它將需要語言規範的重大變化。而這僅僅是個問題。它也會破壞利用這種早期浮動識別的現有代碼,例如, 1.if True else 0