友人が私にこのページを見せてくれ、フォーラム ユーザーの 1 人の署名に奇妙なコードがあることに気付きました。
コードは次のようなワンライナーです。
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
スクロールが削除されました:
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True to False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True))) ): 停止: On Local Error GoTo 0
驚くべきことに、有効なプロシージャ レベルのスコープにそのまま貼り付けるだけで (そして、もう一度触れないでください!)、そのコードはコンパイルされます (実行しようとはしませんでしたが、それは無関係です)。
いくつかの観察:
- 命令の区切り記号/コロンが新しい行に置き換えられると、コンパイルされなくなります
On Local Error
に簡略化できますOn Error
- ネストされた変換は一見特に興味深いものではありませんが、その一連の変換と比較を単純なものに置き換えると
Debug.Assert True
、コードが一貫してコンパイルされるようになるため、コンパイラが混乱していることがわかります。 - コードが貼り付けられると、コンパイルされます。VBEが行を検証した後に何らかの方法で(単に削除しても
Local
)変更された場合、コンパイルが停止し、行が削除されて再貼り付けされない限り、VBAにそれを理解させるものは何もないようです。 - 最新のラバーダックの文法/パーサーは、実際の VBA 仕様に基づいて厳密にモデル化されており、問題なく解析および解決されます(これには正直驚きました)。
- 行がコンパイルされないことがわかっている場合、カット/再貼り付けしてもコンパイルされません... しかし、VBE の外部から再度貼り付けると、突然コンパイルされます。
問題は、このコードが VB 言語仕様に対してどのようにコンパイルされるのかということです。VB[6|A|E] 実装のバグですか? 言い換えれば、なぜ/どのように機能するのですか?
命令区切り文字 ( ) と inline-if 構文に関係があると思います。ステートメントがない場合、ブロックではなく 1 行になります。:
End If
しかし、では、その特定のコードがシュレディンガーのコードである理由は何でしょうか? それを同時に合法と違法にするのは何ですか?
正式な文法定義 (ANTLR) を使用して生成されたパーサーによってコードが正しく解析される場合、それは正当な構造である必要がありますか? それでは、単にその行に戻って ENTER を押すだけで、合法でなくなるのはなぜですか?