1 คะแนน โดย GN⁺ 2024-10-07 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ที่มาของ '\n'

  • เมื่อรันคำสั่ง just foo, justfile จะเขียนไบต์ 0x0A ลงในไฟล์ชื่อ bar
  • just เขียนด้วย Rust และตัวแยกวิเคราะห์ของ just จะแปลงโทเค็นสตริงของ just ที่มีลำดับ escape ให้เป็นสตริง UTF-8 ผ่านฟังก์ชัน cook_string

การประมวลผลของ Rust

  • rustc ประมวลผลรหัส escape ในฟังก์ชัน scan_escape
  • rustc เขียนด้วย Rust และคอมไพล์ตัวเอง ดังนั้นการทำความเข้าใจความหมายของ '\n' จึงถูกมอบหมายให้ rustc
  • rustc เวอร์ชันแรก ๆ เขียนด้วย OCaml และ rustc เวอร์ชัน OCaml จะจัดการ character escape ใน lexer

การประมวลผลของ OCaml

  • คอมไพเลอร์ OCaml ประเมิน \n เป็น \010 แล้วแทรกผลลัพธ์นั้นลงไป
  • 0x0A คือ 10 ดังนั้นเมื่อคอมไพเลอร์ OCaml ประมวลผล \n ก็จะได้ค่าไบต์ 0x0A

บทสรุป

  • เมื่อมี character escape \n ใน justfile ไบนารี just จะเขียนสตริงสุดท้ายโดยมีไบต์ 0x0A รวมอยู่ด้วย
  • ไบต์ 0x0A นี้ถูกแทรกโดย rustc และจุดเริ่มต้นก็คือคอมไพเลอร์ OCaml ที่แทรกไบต์ 0x0A ลงในไบนารี rustc เป็นครั้งแรก

สรุปโดย GN⁺

  • บทความนี้อธิบายว่า character escape \n ถูกแปลงเป็นไบต์ 0x0A ได้อย่างไร
  • ติดตามที่มาของไบต์ 0x0A ผ่านภูมิหลังทางประวัติศาสตร์ของคอมไพเลอร์ Rust และ OCaml
  • ให้มุมมองที่น่าสนใจเกี่ยวกับวิธีที่คอมไพเลอร์ของภาษาโปรแกรมจัดการ character escape
  • เป็นบทความที่ช่วยให้เข้าใจการทำงานของคอมไพเลอร์ Rust และ OCaml ได้ดียิ่งขึ้น

1 ความคิดเห็น

 
GN⁺ 2024-10-07
ความคิดเห็นจาก Hacker News
  • ผู้ใช้คนหนึ่งกล่าวว่าเขาอ่านไอเดียนี้ครั้งแรกจากวันที่ 42 ของบทความ "How I wrote a self-hosting C compiler in 40 days"

    • บทความนี้อธิบายว่าคอมไพเลอร์ตีความ "\\n" ในสตริงลิเทอรัลอย่างไร
    • อธิบายว่า "\\n" ไม่ได้มีข้อมูลรหัสอักขระ ASCII จริงอยู่ภายใน แต่ถูกส่งต่อมาเมื่อคอมไพเลอร์นำคอมไพเลอร์ไปคอมไพล์อีกที
    • ระบุว่าอักขระขึ้นบรรทัดใหม่ของคอมไพเลอร์นี้มีที่มาจาก GCC
  • มีการกล่าวว่าบนระบบ EBCDIC ควรคำนึงด้วยว่าคอมไพเลอร์ C ยุคแรกเกิดขึ้นบนระบบที่ไม่ใช่ ASCII

    • EBCDIC มีอักขระ NextLine และ LineFeed แบบชัดเจน
    • อธิบายว่าโค้ดง่าย ๆ ที่ทำงานได้บน ASCII อาจล้มเหลวบน EBCDIC
    • ใน EBCDIC ตัวพิมพ์เล็กมาก่อนตัวพิมพ์ใหญ่ และตัวอักษรมาก่อนตัวเลข ซึ่งเป็นลำดับตรงข้ามกับ ASCII
  • การรับประกันเพียงอย่างเดียวในมาตรฐาน C เกี่ยวกับการเข้ารหัสอักขระคือ ตัวเลข '0'-'9' ต้องถูกแมปแบบต่อเนื่องในลำดับเพิ่มขึ้น

    • ในทางทฤษฎี โปรแกรม C ง่าย ๆ ควรคอมไพล์จากซอร์สเดียวกันบนระบบ ASCII หรือ EBCDIC แล้วให้ผลลัพธ์เหมือนกัน
  • ผู้ใช้คนหนึ่งกล่าวถึงปาฐกถา Turing Award ของ Ken Thompson เรื่อง "Reflections on Trusting Trust" และคาดว่าบทความนี้น่าจะได้รับแรงบันดาลใจจากปาฐกถานั้น

  • มีคนสงสัยว่าคอมไพเลอร์ clang มีคุณสมบัติเดียวกันหรือไม่ โดยอธิบายว่าสิ่งนี้ถูกเขียนกำหนดไว้เป็นค่า 10 อย่างชัดเจนใน lib/Lex/LiteralSupport.cpp

  • ผู้ใช้คนหนึ่งสงสัยว่าทำไมต้องสืบค้นเพื่อทำความเข้าใจว่าเหตุใด "\\n" จึงถูกเข้ารหัสเป็น 10 โดยมองว่านี่เป็นสิ่งที่คาดหมายอยู่แล้ว

  • มีการบอกว่าบทความนี้อ่านแล้วเหมือนจุดตัดระหว่าง literate programming กับบทกวี และพยายามอธิบายกระบวนการที่ไบต์ 0x0A ถูกสร้างขึ้นผ่านวัฏจักรหลายร้อยรอบของการสร้างโค้ด

  • ผู้ใช้คนหนึ่งบอกว่าเพราะภาษา C จึงเคยคิดว่า "\\0???" เป็น octal escape และเข้าใจ "\\012" ว่าเป็น "\\x0a" หรือ "0x0a" ส่วน "\\010" คือ "0x08"

    • คาดเดาว่า OCaml อาจมี decimal escape แทนที่จะเป็น octal escape
  • มีการตั้งคำถามที่น่าสนใจว่า หาก ASCII หรือสตริงไม่มี escape code แล้วโค้ดของเราจะหน้าตาเป็นอย่างไร

  • มีการกล่าวถึงกฎข้อหนึ่งของการเขียนโปรแกรมว่า เมื่อมีอยู่สองวิธี และโอกาสที่วิธีหนึ่งจะถูกอีกวิธีหนึ่งจะผิดเป็น 50/50 คุณมักจะเลือกวิธีที่ผิดในตอนแรก