2

私はPythonのドキュメント2.76を読んでいます

これは、3 種類のブール演算の字句構文です

or_test  ::=  and_test | or_test "or" and_test
and_test ::=  not_test | and_test "and" not_test
not_test ::=  comparison | "not" not_test

これは比較のための字句構文です:

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
                 | "is" ["not"] | ["not"] "in"

or_expr の字句構文:

and_expr ::=  shift_expr | and_expr "&" shift_expr
xor_expr ::=  and_expr | xor_expr "^" and_expr
or_expr  ::=  xor_expr | or_expr "|" xor_expr

ドキュメントの表記については、次のとおりです。

垂直バー (|) は、選択肢を区切るために使用されます。これは、この表記法で最も拘束力の低い演算子です。

ここで質問が来ます:

  1. not_test ::= comparison | "not" not_testのように解析されます

    not_test ::= comparison | ("not" not_test)?

  2. 1.が true の場合、有効なcomparisonも有効ですnot_test1 < 2not_testnot

  3. さらに、validand_testは単一の validnot_testである可能性があるため、 1 < 2validand_testも同様です。についても同様or_testです。

  4. では、有効な とは何comparisonですか? 1 < 2明らかにパターンに適合します。そして、これらのビットごとの比較 expr も有効ですcomparison。共通しているのは、少なくとも 1 つの演算子 ('>'、'<'、またはビット単位のもの) の存在が必要であることです。(わからない。)

  5. ここで奇妙な部分になります。x and yたとえば、考えてみましょう。によると

and_test ::= not_test | and_test "and" not_test

and_test ::= not_test | (and_test "and" not_test) # このように解析されたと思いますか?

が true でx and yある場合and_test( がnot_test存在するため、 になることはありませんand)、は valid であるx必要があり、and_testこれはただ 1 つの valid である可能性がありますnot_test。そして、あまりにもy有効でなければなりませnot_testん。

Anot_testは、1 つまたは が前に付いたcomparison別のいずれかです。したがって、 aは基本的に 0 個以上の s の後に 1 が続きます。ここで重要なのは、 の字句構文です。not_testnotnot_testnotcomparisoncomparison

によると4.、 acomparisonには少なくとも 1 つの演算子が必要です。ただし、これは次の例と競合します。

x = 3、y = 4 を割り当てます。3 and 4有効なようですand_test

しかし、どうすれば有効なの3かわかりません。どこで私は間違えましたか?4comparison

4

4 に答える 4

2

正式な文法は、単に言語の部分を定義するだけでなく、優先順位を指定します。そのため、式部分の文法ノードの多くには、ノードの実際の名前に適合しない左側の代替が含まれています。これらの選択肢は、次に高い優先順位を持つ文法ノードを指定します (したがって、ツリーを展開するときは、優先順位の低い操作に続いて優先順位の高い操作を展開します)。

これは、算術演算子で最も明確です。

power ::=  primary ["**" u_expr]
u_expr ::=  power | "-" u_expr | "+" u_expr | "~" u_expr
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
shift_expr ::=  a_expr | shift_expr ( "<<" | ">>" ) a_expr

結合が unary よりも (少なくとも左側で) 強いため、その代替の 1 つとしてu_exprhasを観察してください。単項演算は乗算演算よりも厳密にバインドされるため、a に展開できます。また、乗算演算は加算演算よりも厳密にバインドされるため、a に展開できます。これらのステートメントは、そのステートメントが実際には加算演算であると見なすべきであることを暗示しようとしているわけではありません(ただし、文法的な意味では、1 項加算のと見なすことができます)。powerpowerm_expru_expra_exprm_exprx * y


これが意味することは、基本的に、式を解析するノードに到達するまで、ノードの LHS に沿ってトレースできるということです。

たとえば、式は文法に従って3 + 4有効です(ただし、一般的な言語の意味での「比較」ではありません)。comparisonチェーンに合わせて展開できるからです

comparison > or_expr > xor_expr > and_expr > shift_expr > a_expr > a_expr + m_expr

さらに

a_expr > m_expr > u_expr > power > primary > atom > literal > integer > decimalinteger > etc...

各段階で、基本的に優先順位チェーンを 1 ランク上げます。これにより、操作の順序を決定するための非常に明確な方法が得られます。

于 2014-02-27T05:29:54.233 に答える
1

あなたの質問文を解析しましょう:):

ですか?1 < 2_not_test

not_test: 'not' not_test | comparison

# `comparison: expr (comp_op expr)*`
not_test: expr comp_op expr

# `comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'`
not_test: expr < expr

# `expr: xor_expr ('|' xor_expr)*`
not_test: xor_expr < xor_expr

# `xor_expr: and_expr ('^' and_expr)*`
not_test: and_expr < and_expr

# `and_expr: shift_expr ('&' shift_expr)*`
not_test: shift_expr < shift_expr

# shift_expr: arith_expr (('<<'|'>>') arith_expr)*
not_test: arith_expr < arith_expr

# arith_expr: term (('+'|'-') term)*
not_test: term < term

# term: factor (('*'|'/'|'%'|'//') factor)*
not_test: factor < factor

# factor: ('+'|'-'|'~') factor | power
not_test: power < power

# power: atom trailer* ['**' factor]
not_test: atom < atom

#atom: ('(' [yield_expr|testlist_comp] ')' |
#       '[' [listmaker] ']' |
#       '{' [dictorsetmaker] '}' |
#       '`' testlist1 '`' |
#       NAME | NUMBER | STRING+)
not_test: NUMBER < NUMBER
not_test: 1 < 2
于 2014-02-27T06:25:32.650 に答える
0
  1. 順序が重要であるため、括弧はグループ化に使用されるため、いいえ。

  2. NA、1 は true ではないため

したがって、ここであなたの論理が崩壊し始めると思います。ここで重要なのは、これらが論理のステートメントであるということです。「引数が False の場合は True を返し、それ以外の場合は False を返す」だけではありません。

したがって、最初の値がnot_test(or_testおよびを介してand_test) に与えられ、次に 2 番目の値が に与えられ、not_testそれらが比較されてブール値が返されます。

于 2014-02-27T05:29:45.690 に答える