0

Python 2.7 を使用しています。

これが起こったことです:

>>> 2+++2
4

Python インタープリターがこの式をどのように解釈するかはわかりません。

私が思いつく唯一の理由は、最初の「+」の後に続く「+」は単項演算子と見なされ、最初の「+」は二項演算子と見なされるということですが、実際にどのようなメカニズムが起こっているのかはわかりません確かに。

Python プログラミング言語の文法の詳細に関して誰かに質問に答えてもらいたいです。また、他のあいまいな表現についても報告してもらいたいと思います。以下にリストされている他の式をいくつか思いつきました(結果とともに):

>>> 2------------2
4
>>> 2+-2+-2+-2+-2+-2-------------------------2
-10
4

3 に答える 3

7

あなたが正しい; ご想像のとおり、 Python はこれを と解釈して2 + (++2)います。これは、次のように 2+2 および 2+++2 のコンパイル済みバイトコードを見るとわかります。

>>> dis.dis(lambda: 2+2)
  1           0 LOAD_CONST               2 (4)
              3 RETURN_VALUE        
>>> dis.dis(lambda: 2+++2)
  1           0 LOAD_CONST               1 (2)
              3 LOAD_CONST               1 (2)
              6 UNARY_POSITIVE      
              7 UNARY_POSITIVE      
              8 BINARY_ADD          
              9 RETURN_VALUE    

Python が 2+++2 をこのように解析する理由を知りたいと思うかもしれません。まず、コードはトークンに分割されます。

>>> from cStringIO import StringIO
>>> import tokenize
>>> tokenize.generate_tokens(StringIO("2+++2").readline)
  9 <generator object generate_tokens at 0x0000000007BC7480>
>>> list(tokenize.generate_tokens(StringIO("2+++2").readline))
  10 
[(2, '2', (1, 0), (1, 1), '2+++2'),
 (51, '+', (1, 1), (1, 2), '2+++2'),
 (51, '+', (1, 2), (1, 3), '2+++2'),
 (51, '+', (1, 3), (1, 4), '2+++2'),
 (2, '2', (1, 4), (1, 5), '2+++2'),
 (0, '', (2, 0), (2, 0), '')]

トークンのリストを構文ツリーに関連付けるのはパーサーです。

>>> st = ast.parse("2+++2")
>>> st
  36 <_ast.Module at 0x7d2acc0>
>>> ast.dump(st)
  37 'Module(body=[Expr(value=BinOp(left=Num(n=2), op=Add(), right=UnaryOp(op=UAdd(), operand=UnaryOp(op=UAdd(), operand=Num(n=2)))))])'

これは、標準の明確化規則に従います。

于 2013-03-20T11:15:48.313 に答える
2

Python が単項および2 項算術演算を定義する方法を見てみましょう。特に単項式:

u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr

の部分を見ることができます。これは、数字の後に続く数字が有効な単項式である"+" u_exprことを意味します (一種の再帰的なものですね?)。+

一方、あなたはこれらの2つを手に入れました:

m_expr ::=  u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr
        | m_expr "%" u_expr
a_expr ::=  m_expr | a_expr "+" m_expr | a_expr "-" m_expr

つまり、バイナリ式がある場合、最初のアトムを読み取り、次に符号を読み取り、次のバイナリ/単項式を読み取ります。次のようなコードを読み取ります。

2+-2+-2+-2+-2+---2+-2

基本的に次のように:

2 + (-2) + (-2) + (-2) + (-2) + (-(-(-2))) + (-2)
于 2013-03-20T11:23:24.393 に答える
1

文法的には完全に明白です:

arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power

したがって、任意の要素の前に単項演算子の 1 つを付けることができるため、これは、算術式が二項演算子を消費するまで拡張されます。C の ++ 演算子も Haskell の新しい演算子を定義する機能もないため、あいまいではありません。

于 2013-03-20T11:28:36.223 に答える