php-インデントされたリストをブールツリーに解析します
次のようなテキストがあります
foo
and foo2
and bar
or something
and somethingElse
or somethingElse2
or somethingElse3
and baz
or godknows
or godknows2
これは次のように解釈する必要があります:
(
foo
&& foo2
&& (bar || (something && (somethingElse || somethingElse2 || somethingElse 3)))
&& (baz || godknows || godknows2)
)
現在、私は1行ずつ読んでいます。現在の行も属しているという表現を理解するために、インデントを測定して次の行の表現を解析する必要があることはわかっていますが、次の行も消費せずにそれを有効に行う方法を理解するのに苦労しています。
再帰的な解決策があるような問題のようですが、それは私を逃れています。
入力形式は固定されていません。比較的読みやすい式をブール値のツリーに変換できるようにしたいので、まだ読みやすいより適切な形式で答えられる場合は、実行してください:)
答え :
解決策:
このスタイルのインデントを使用するPythonは、インデントレベルのスタックを維持することによって解析を行います。新しい行を確認すると、現在の深さが増加したかどうかを確認することで、前の行からインデントされているかどうかを判断します。その場合、Pythonは、入力ストリームに挿入された「インデント」と呼ばれる非表示のシンボルがあったと偽ります。次に、新しい深さをスタックにプッシュします。
インデントが減少すると、Pythonはスタックを繰り返しポップし、インデントレベルがスタックの値と一致するまで、「DEDENT」と呼ばれる非表示の記号が入力ストリームに挿入されたように見せかけます。
ここでは、「INDENT」と「DEDENT」を(と)に置き換えることで、このアプローチを非常に簡単に適応させることができます。 (トークンが前の変数の前に挿入されたことを確認して、後でマイナーな変換を行う必要がありますが、これはそれほど難しくないと思います。
この変更により、これを非常に簡単に解析できるようになります。たとえば、スクリプト
A
and B
or C
and D
or E
に変換されます
A and (B or (C and D))) or E
これがお役に立てば幸いです!
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。