วิธีการสร้างภาษาโปรแกรม JVM?


93

ฉันได้สร้างคอมไพเลอร์ในภาษา C (โดยใช้ Lex & Bison) สำหรับภาษาการเขียนโปรแกรมแบบไดนามิกที่รองรับลูปการประกาศฟังก์ชันภายในฟังก์ชันการเรียกซ้ำ ฯลฯ ฉันยังสร้างเครื่องเสมือนที่รันโค้ดกลางที่สร้างโดยคอมไพเลอร์

ฉันกำลังคิดเกี่ยวกับการรวบรวมเป็น Java bytecode แทนที่จะเป็นรหัสกลางของฉันเอง

ผมเห็นว่าคำถามเกี่ยวกับการสร้างภาษา JVM ได้รับแล้วถามแต่ผมไม่หาคำตอบให้ข้อมูลมาก

นี่คือคำถามของฉัน:

  1. ฉันเดาว่าจะสร้างภาษาสำหรับ JVM สิ่งที่ต้องทำคือการอ่านหนังสือข้อกำหนดของ JVMคุณสามารถแนะนำหนังสืออะไรได้อีกบ้าง (ยกเว้น Dragon Book แน่นอน) ส่วนใหญ่ฉันกังวลเกี่ยวกับหนังสือหรือแบบฝึกหัดเกี่ยวกับวิธีสร้างภาษา JVM ไม่ใช่คอมไพเลอร์โดยทั่วไป
  2. มีไลบรารี Java มากมายสำหรับอ่านเขียนและเปลี่ยน.classไฟล์เช่นjclasslib , bcel , gnu bytecodeฯลฯ คุณจะแนะนำตัวไหน นอกจากนี้คุณทราบถึงไลบรารี C ที่ทำงานเดียวกันหรือไม่?
  3. ฉันกำลังคิดที่จะดูภาษาอื่นที่กำหนดเป้าหมายไปที่ JVM เช่น Clojure, Jython หรือ JRuby แต่ภาษาทั้งหมดเหล่านี้มีระดับสูงและซับซ้อนมาก (เพื่อสร้างคอมไพเลอร์สำหรับพวกเขา) ฉันกำลังมองหาภาษาการเขียนโปรแกรมที่ง่ายกว่า (ฉันไม่สนใจว่ามันไม่รู้จักหรือไม่ได้ใช้) ที่กำหนดเป้าหมาย JVM และคอมไพเลอร์เป็นโอเพ่นซอร์ส ความคิดใด ๆ ?

คำตอบ:


63

ฉันอยากจะแนะนำ ASM ด้วย แต่ลองดูที่Jasminฉันใช้มัน (หรือต้องใช้) สำหรับโครงการของมหาวิทยาลัยและมันก็ใช้ได้ดีทีเดียว ฉันเขียนชุดค่าผสม lexer-parser-analyzer-optimizer-generator สำหรับภาษาโปรแกรมโดยใช้ Java และ Jasmin ดังนั้นมันจึงสร้าง JVM Code ฉันได้อัปโหลดรหัสที่นี่ ; ส่วนที่น่าสนใจที่ควรจะเป็นรหัสที่มาของตัวเอง ในโฟลเดอร์bytecode/InsanelyFastByteCodeCreator.javaคุณจะพบโค้ดส่วนหนึ่งที่แปลง AST Tree เป็นรูปแบบอินพุตของแอสเซมเบลอร์ Jasmin มันค่อนข้างตรงไปตรงมา

ภาษาต้นทาง (ซึ่งถูกแปลงเป็น AST โดย lexer-parser-analyzer) เป็นชุดย่อยของ Java ที่เรียกว่า MiniJava มันไม่มีคุณสมบัติที่ "ซับซ้อน" บางอย่างเช่นการสืบทอดตัวสร้างวิธีการคงที่ฟิลด์ส่วนตัวและวิธีการ คุณลักษณะเหล่านี้ไม่มีความยากในการใช้งาน แต่มีงานอื่นในการเขียนแบ็กเอนด์ x86 (เพื่อสร้างแอสเซมเบลอร์เครื่อง) และสิ่งเหล่านี้มักจะเกิดขึ้นได้ยากหากคุณไม่มี JVM ที่จัดการบางสิ่งเหล่านั้น

ในกรณีที่คุณสงสัยเกี่ยวกับชื่อคลาสแปลก ๆ : งานของโครงการมหาวิทยาลัยคือการแปลง AST ให้เป็นSSA Graph (แทนรหัสอินพุต) ปรับกราฟให้เหมาะสมแล้วเปลี่ยนเป็น Java bytecode นั่นเป็นเรื่องของ¾ของการทำงานของโครงการและInsanlyFastByteCodeCreatorเป็นเพียงการสรุปสั้น ๆ เพื่อทดสอบทุกอย่าง

ดูหนังสือ "Java Virtual Machine" จาก Jon Meyer และ Troy Downing หนังสือเล่มนี้อ้างอิง Jasmin Assembler อย่างหนัก มันมีประโยชน์มากสำหรับการทำความเข้าใจภายใน JVM


ขอบคุณสำหรับคำตอบฉันจะดูที่ Jasmin และฉันก็ดีใจเช่นกันถ้าคุณสามารถอัปโหลดแหล่งที่มาเพื่อที่ฉันจะได้ดู เกี่ยวกับหนังสือที่คุณแนะนำดูเหมือนว่าน่าสนใจ แต่มันพิมพ์ไม่ออกและค่อนข้างเก่า :(

หนังสือเป็นมือสองราคาถูกมากแม้ว่า ฉันพบสำเนาในราคาไม่กี่ดอลลาร์
namin

ดูการแก้ไขของฉันด้านบนหากคุณมีข้อสงสัยเรายินดีที่จะช่วยเหลือ
theomega

ลิงก์ไปยัง "ซอร์สโค้ดเอง" เสีย แม้ว่าฉันเดาว่าน่าจะเกิดขึ้นหลังจาก 8 ปี
Llew Vallis

@LlewVallis ถ้าผมตีความข้อมูลทั้งหมดขวารหัสน่าจะเป็นที่นี่: github.com/replimoc/compiler
U880D

15

ภาคเรียนที่แล้วฉันได้เข้าเรียนในหลักสูตร "Compiler Construction" โครงการของเราคือสิ่งที่คุณต้องการทำ

ภาษาที่ผมเคยใช้ในการเขียนภาษาของฉันเป็นScala มันทำงานบน JVM แต่รองรับคุณสมบัติขั้นสูงมากมายที่ Java ไม่มี (ยังเข้ากันได้กับ java JVM แท้)

เพื่อการส่งออก Java bytecode ฉันใช้ห้องสมุด Scala CAFEBABE จัดทำเอกสารไว้อย่างดีและคุณไม่จำเป็นต้องลงลึกในชั้นเรียน java เพื่อทำความเข้าใจว่าต้องทำอย่างไร

นอกจากหนังสือเล่มนี้ฉันคิดว่าคุณสามารถค้นหาข่าวสารมากมายได้โดยไปที่ห้องทดลองที่เราทำระหว่างหลักสูตร


เสียงนี้เหมือนหลักสูตรที่ดี คุณช่วยแบ่งปันบันทึกหรือรหัสของคุณได้ไหม
Pedro

1
ไม่มีปัญหาฉันจะตรวจสอบว่าข้อมูลสำรองของฉันอยู่ที่ไหนและโพสต์ลิงก์ที่นี่เพื่อให้คุณสามารถดาวน์โหลดได้โดยเร็ว
Kami

1
เรียบร้อยฉันกำลังมองหาหลักสูตรคอมไพเลอร์ภาคปฏิบัติซึ่งกำหนดเป้าหมายไปที่ JVM พร้อมเนื้อหาทั้งหมดทางออนไลน์สำหรับการศึกษาด้วยตนเอง
namin

5

ASMสามารถเป็นทางออกสำหรับการสร้าง bytecode การเริ่มต้นการตรวจสอบหัวข้อที่เกี่ยวกับการสร้างองค์ประกอบจากคู่มือ


4

ฉันคิดว่าจะดูภาษาอื่นที่กำหนดเป้าหมายไปที่ JVM เช่น Clojure, Jython หรือ JRuby แต่ภาษาทั้งหมดเหล่านี้มีระดับสูงและซับซ้อนมาก (เพื่อสร้างคอมไพเลอร์สำหรับพวกเขา)

คำแนะนำ:คุณสามารถมีลักษณะที่Lua โปรแกรมภาษาที่มีการใช้งาน JVM มันเหมือนLuaJ

ตัวแปล Lua ที่มีน้ำหนักเบารวดเร็วเป็นศูนย์กลางที่ เขียนขึ้นสำหรับ J2ME และ J2SE พร้อมไลบรารีสำหรับพื้นฐานสตริงตารางแพ็กเกจคณิตศาสตร์ io ระบบปฏิบัติการดีบักและโครูทีนคอมไพเลอร์การโยง luajava และเอ็นจินการเขียนสคริปต์ที่เสียบได้ JSR-233 การผูก

(เพื่อไม่ให้สับสนกับ LuaJava ที่ใช้ libs ดั้งเดิมกับวิธี JNI)


ขอบคุณ. ฉันจะดู

4

เมื่อสุดสัปดาห์ที่แล้วฉันถามตัวเองด้วยคำถามเดียวกันกับการเปลี่ยนภาษาของเล่นของฉันไปยัง JVM

ฉันใช้เวลาเพียงไม่กี่ชั่วโมงในการค้นหาข้อมูลดังนั้นโปรดใช้การอ้างอิงนี้ด้วยเกลือเม็ดหนึ่ง

  • รูปแบบภาษาการดำเนินงาน ฉันเกลียด antlr แต่หนังสือเล่มนี้ดูดีมาก หากคุณไม่ชอบ antlr ก็มีวิธีที่ดีมากเกี่ยวกับการแยกวิเคราะห์ "เทคนิคการแยกวิเคราะห์คำแนะนำที่ใช้ได้จริง"

    เรียนรู้การสร้างโปรแกรมอ่านไฟล์คอนฟิกูเรชันตัวอ่านข้อมูลตัวสร้างโค้ดที่เป็นแบบโมเดลตัวแปลต้นทางไปยังซอร์สตัววิเคราะห์ซอร์สและตัวแปล คุณไม่จำเป็นต้องมีพื้นฐานด้านวิทยาการคอมพิวเตอร์ Terence Parr ผู้สร้าง ANTLR อธิบายการใช้ภาษาโดยแยกย่อยออกเป็นรูปแบบการออกแบบที่พบบ่อยที่สุด แบบตามแบบแผนคุณจะได้เรียนรู้ทักษะสำคัญที่คุณต้องใช้ในการใช้ภาษาคอมพิวเตอร์ของคุณเอง

    บทที่ 10 ครอบคลุมใน 30 หน้า (ถึง IMO แบบเร็ว) หัวข้อนี้ แต่มีบทอื่นที่คุณอาจสนใจ

    • 10 การสร้างตัวแปล Bytecode
      • 10.1 การเขียนโปรแกรมตัวตีความ Bytecode .
      • 10.2 การกำหนดไวยากรณ์ภาษาแอสเซมบลี
      • 10.3 สถาปัตยกรรมเครื่อง Bytecode . . . .
      • 10.4 จะไปที่ไหนจากที่นี่ . . . . . . . . .
      • หน้า 26. Bytecode Assembler . . . . . . . . . .
      • หน้า 27 ตัวแปล Bytecode แบบเรียงซ้อน . .
      • หน้า 28. ตัวแปล Bytecode แบบลงทะเบียน
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • การนำ Lua 5.0 ไปใช้งานนี่เป็นเอกสารที่ยอดเยี่ยมเกี่ยวกับเครื่อง bytecode ที่ลงทะเบียน อ่านมันเพื่อประโยชน์ของมัน

    • เสียงกระเพื่อมเป็นชิ้นเล็ก ๆ หนังสือเล่มนี้สอนวิธีเขียน 2 schme compailers ที่รวบรวมถึง C บทเรียนมากมายสามารถเรียนรู้ได้จากหนังสือเล่มนี้ ฉันเป็นเจ้าของหนังสือเล่มนี้และมันดีมากสำหรับทุกคนที่น่าสนใจคือเสียงกระเพื่อม แต่อาจจะไม่ใช่ถ้วยชาของคุณ

      นี่คือเรื่องราวที่ครอบคลุมของความหมายและการใช้ภาษาตระกูล Lisp ทั้งหมด ได้แก่ Lisp, Scheme และภาษาถิ่นที่เกี่ยวข้อง อธิบายถึงล่าม 11 คนและคอมไพเลอร์ 2 ตัว ...

    http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473

ตรวจสอบ Dalvik7 VM ซึ่งเป็น VM แบบลงทะเบียน DVM ทำงานบน bytecodes ที่แปลงจากไฟล์ Java Class ที่คอมไพล์โดยคอมไพเลอร์ Java

มีรายชื่อส่งเมลเกี่ยวกับหัวข้อคือ jvm-languages

คุณวางแผนที่จะอัปโหลดรหัสไปที่ใดก็ได้หรือไม่? ฉันต้องการที่จะดู


Are you planning to upload the code to anyplace?ฉันไม่ภูมิใจกับรหัสนั้น :( ... ฉันอาจจะเขียนใหม่ทั้งหมดอย่างไรก็ตามถ้าฉันทำฉันจะแจ้งให้คุณทราบขอบคุณมากสำหรับคำแนะนำของคุณ

2

ฉันอยากจะแนะนำให้คุณเรียนรู้ก่อนว่าแอสเซมบลี JVM ทำงานอย่างไรหากคุณยังไม่รู้

คำแนะนำหลายคนมีรูปแบบ?nameที่?เป็นiถ้าคำสั่งที่ทำงานบนกับชนิดจำนวนเต็มและaถ้ามันทำงานร่วมกับชนิดการอ้างอิง

โดยทั่วไป JVM เป็นเครื่องสแต็กที่ไม่มีการลงทะเบียนดังนั้นคำสั่งทั้งหมดจึงทำงานกับข้อมูลโดยตรงบนสแต็ก คุณสามารถผลักดัน / ป๊อปอัพข้อมูล?push/?popและย้ายข้อมูลระหว่างตัวแปรท้องถิ่น (สแต็คสถานอ้างอิงโดยชดเชย) ?store/?loadและด้านบนของสแต็คโดยใช้ คำแนะนำที่สำคัญอื่น ๆ ได้แก่invoke???และif_???และ

สำหรับหลักสูตรคอมไพเลอร์ของมหาวิทยาลัยเราใช้Jasminในการประกอบโปรแกรม ฉันไม่รู้ว่านี่เป็นวิธีที่ดีที่สุดหรือเปล่า แต่อย่างน้อยมันก็เป็นจุดเริ่มต้นที่ง่าย

นี่คือข้อมูลอ้างอิงคำสั่งสำหรับ JVM เวอร์ชันเก่าซึ่งอาจมีคำสั่งน้อยกว่าคำสั่งใหม่


0

ก่อนอื่นฉันจะปิดแก้ไขคอมไพเลอร์ของฉันเพื่อส่งออก Java จริงแทนรหัส Java byte (ซึ่งหมายถึงการสร้างตัวแปลมากกว่าคอมไพเลอร์) และรวบรวมเอาต์พุต Java ด้วยสภาพแวดล้อม Java ที่สะดวก (ซึ่งอาจสร้างรหัสวัตถุที่ดีกว่า กว่าคอมไพเลอร์ของฉันเอง)

คุณสามารถใช้เทคนิคเดียวกันนี้ (เช่นคอมไพล์เป็น C #) เพื่อสร้างโค้ด CLI byte หรือคอมไพล์ไปยัง Pascal เพื่อสร้าง P-code เป็นต้น

ไม่ชัดเจนว่าทำไมคุณถึงพิจารณารหัส Java แทนที่จะใช้ VM ของคุณเอง แต่ถ้าเป็นเพื่อประสิทธิภาพแน่นอนคุณควรพิจารณารวบรวมรหัสเครื่องจริงด้วย


การคอมไพล์สำหรับ JVM จะช่วยให้โค้ดของตัวเองทำงานได้กว้างกว่าถ้าคอมไพล์เป็นโค้ดเนทีฟ นอกจากนี้การคอมไพล์เป็น bytecode จะทำให้โค้ดสามารถทำบางสิ่งที่เป็นไปไม่ได้ในภาษา Java เอง
supercat

0

แน่นอนครั้งหนึ่งสามารถใช้ Java เพื่อเขียนภาษาใหม่ได้ ด้วย Java สะท้อน API คุณสามารถบรรลุได้ ถ้าความเร็วไม่สำคัญมากเกินไปฉันจะให้การตั้งค่า Java แทน ASM การเขียนโปรแกรมเป็นเรื่องง่ายและผิดพลาดน้อยลงใน Java (IMHO) ลองดูที่ภาษา RPN 7 มันเขียนด้วยภาษาจาวาทั้งหมด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.