1 ポイント 投稿者 GN⁺ 2024-10-07 | 1件のコメント | WhatsAppで共有

'\n' の由来

  • just foo コマンドを実行すると、justfile0x0A バイトを bar というファイルに書き込む
  • just は Rust で書かれており、just パーサーは cook_string という関数を通じて、エスケープシーケンスを含む just の文字列トークンを UTF-8 文字列に変換する

Rust での処理

  • rustcscan_escape という関数でエスケープコードを処理する
  • rustc は Rust で書かれた自己ホスト型コンパイラであり、'\n' の意味を理解するために rustc 自身に委ねている
  • 初期バージョンの rustc は OCaml で書かれており、OCaml 版の rustc は lexer で文字エスケープを処理していた

OCaml での処理

  • OCaml コンパイラは \n\010 として評価し、その結果を埋め込む
  • 0x0A は 10 なので、OCaml コンパイラが \n を処理するときに 0x0A のバイト値が得られる

結論

  • justfile\n の文字エスケープがあると、just バイナリは 0x0A バイトを含めて最終的な文字列に書き込む
  • この 0x0A バイトは rustc によって埋め込まれたものであり、その起点は OCaml コンパイラが最初に rustc バイナリへ 0x0A バイトを埋め込んだことにある

GN⁺ の要約

  • この記事は、\n の文字エスケープがどのように 0x0A バイトへ変換されるのかを説明している
  • Rust と OCaml コンパイラの歴史的背景を通じて、0x0A バイトの出所をたどっている
  • プログラミング言語のコンパイラが文字エスケープをどのように処理するかについて、興味深い洞察を提供している
  • Rust と OCaml のコンパイラ動作を理解する助けになる記事である

1件のコメント

 
GN⁺ 2024-10-07
Hacker Newsの意見
  • あるユーザーは、自分がこのアイデアを最初に読んだのは "How I wrote a self-hosting C compiler in 40 days" という記事の42日目だったと述べている

    • この記事では、コンパイラが文字列リテラル内の "\n" をどのように解釈するかを説明している
    • "\n" 自体は実際の ASCII 文字コード情報を含んでおらず、コンパイラがコンパイラをコンパイルするときに受け渡されると説明している
    • このコンパイラの改行文字は GCC に由来すると言及している
  • EBCDIC システムでは、初期の C コンパイラが ASCII ではないシステム上で登場したことを考慮すべきだと述べている

    • EBCDIC には明示的な NextLine 文字と LineFeed 文字があった
    • ASCII では動作する単純なコードでも、EBCDIC では失敗する可能性があると説明している
    • EBCDIC では小文字が大文字より前に来て、文字が数字より前に来るなど、ASCII と正反対の並び順を持つ
  • C 標準における文字エンコーディングについての唯一の保証は、数字の '0' から '9' が連続した昇順で割り当てられていることだとしている

    • 理論上は、単純な C プログラムであれば、ASCII でも EBCDIC でも同じソースをコンパイルして同じ出力を生成できるはずだと述べている
  • あるユーザーは Ken Thompson のチューリング賞講演 "Reflections on Trusting Trust" に触れ、この文章はその講演に着想を得たものではないかと推測している

  • clang コンパイラにも同じ性質があるのか気にしており、これは lib/Lex/LiteralSupport.cpp で明示的に 10 としてコードされていると説明している

  • あるユーザーは、なぜ "\n" が 10 にエンコードされている理由を理解するために調べる必要があったのか不思議だとし、それは予想どおりだと考えている

  • この記事は文芸的プログラミングと詩の交差点のように読めると述べ、コード生成の何百ものサイクルを通じて 0x0A バイトが生成される過程を説明しようとしているという

  • あるユーザーは、C 言語のせいで "\0???" を 8 進エスケープだと思っており、"\012" は "\x0a" または "0x0a"、"\010" は "0x08" だと認識していたと説明している

    • OCaml には 8 進エスケープではなく 10 進エスケープがあるのかもしれないと推測している
  • ASCII や文字列にエスケープコードがなかったら、私たちのコードはどう見えていたのかという興味深い問いを投げかけている

  • プログラミングのひとつの法則として、2 つの方法があり、どちらかが正しくどちらかが間違っている確率が五分五分なら、最初は間違っているほうを選びがちだと述べている