Tạo ngôn ngữ lập trình JVM


91

Tôi đã tạo một trình biên dịch trong C (sử dụng lex & bison) cho ngôn ngữ lập trình kiểu động hỗ trợ các vòng lặp, khai báo hàm bên trong hàm, gọi đệ quy, v.v. Tôi cũng đã tạo một máy ảo chạy mã trung gian do trình biên dịch tạo ra.

Bây giờ tôi đang nghĩ thay vì biên dịch sang mã trung gian của riêng mình, hãy biên dịch nó thành mã byte java.

Tôi thấy rằng câu hỏi về cách tạo một ngôn ngữ JVM đã được hỏi nhưng tôi không tìm thấy câu trả lời cho lắm.

Vì vậy, đây là những câu hỏi của tôi:

  1. Tôi đoán để tạo ngôn ngữ cho JVM, điều bắt buộc là phải đọc sách đặc tả JVM , bạn có thể đề xuất những cuốn sách nào khác (tất nhiên là ngoại trừ Dragon Book)? Tôi chủ yếu quan tâm đến sách hoặc hướng dẫn về cách tạo ngôn ngữ JVM, chứ không phải trình biên dịch nói chung.
  2. Có rất nhiều thư viện Java để đọc, ghi và thay đổi các tệp .class như jclasslib , bcel , gnu bytecode , v.v. Bạn sẽ đề xuất cái nào? Ngoài ra, bạn có biết các thư viện C làm công việc tương tự không?
  3. Tôi đang nghĩ về việc xem xét có thể một ngôn ngữ khác nhắm mục tiêu JVM như Clojure, Jython hoặc JRuby. Nhưng tất cả các ngôn ngữ này đều có trình độ rất cao và phức tạp (để tạo một trình biên dịch cho chúng). Tôi đang tìm kiếm một ngôn ngữ lập trình đơn giản hơn (tôi không bận tâm nếu nó không biết hoặc không được sử dụng) nhắm mục tiêu JVM và trình biên dịch của nó là mã nguồn mở. Bất kỳ ý tưởng?

Câu trả lời:


61

Tôi cũng muốn giới thiệu ASM, nhưng hãy xem Jasmin , tôi đã sử dụng nó (hoặc: phải sử dụng nó) cho một dự án đại học và nó hoạt động khá tốt, tôi đã viết tổ hợp lexer / parse / analyzer / Optimizer / máy phát điện cho một ngôn ngữ lập trình sử dụng java và jasmin, do đó tạo ra Mã JVM. Tôi đã tải lên mã ở đây , phần thú vị phải là mã nguồn của chính nó . Trong thư mục "bytecode / InsanelyFastByteCodeCreator.java", bạn tìm thấy một đoạn mã biến một Cây AST thành định dạng đầu vào của trình hợp dịch jasmin. Là khá thẳng về phía trước.

Ngôn ngữ nguồn (đã được chuyển thành AST bởi Lexer + Parser + Analyzer) là một tập con của Java được gọi là MiniJava. Nó thiếu một số tính năng "phức tạp" như Kế thừa, Trình tạo, phương thức tĩnh, trường / phương thức riêng. Không có tính năng nào trong số đó là khó thực hiện, nhưng có một nhiệm vụ khác là viết một chương trình phụ trợ X86 (vì vậy để tạo trình lắp ráp máy) và những thứ đó có xu hướng trở nên khó khăn nếu bạn không có JVM xử lý một số thứ.

Trong trường hợp bạn thắc mắc về tên Class lạ: Nhiệm vụ của dự án đại học là biến AST thành aa SSA Graph (vì vậy một đồ thị đại diện cho mã đầu vào), sau đó tối ưu hóa đồ thị và sau đó biến đồ thị thành mã byte java. Đó là khoảng 3/4 công việc của dự án và InsanlyFastByteCodeCreator chỉ là một bước ngắn để kiểm tra mọi thứ.

Hãy xem cuốn sách "Máy ảo Java" của Jon Meyer và Troy Downing. Cuốn sách này đề cập nhiều đến Jasmin-Assembler, nó khá hữu ích để hiểu nội bộ của JVM.


Cảm ơn câu trả lời của bạn, tôi sẽ xem qua Jasmin. Và tôi cũng rất vui nếu bạn có thể tải lên nguồn để tôi có thể xem qua. Về cuốn sách bạn đề xuất, nó có vẻ thú vị nhưng nó đã hết in và khá cũ :(.

Cuốn sách đã qua sử dụng rất rẻ. Tôi đã tìm thấy một bản sao với giá vài đô la.
namin

Hãy xem bản chỉnh sửa của tôi ở trên, nếu bạn có bất kỳ câu hỏi nào, tôi sẽ sẵn lòng trợ giúp.
theomega

Liên kết đến "chính mã nguồn" bị hỏng. Mặc dù tôi đoán điều đó sẽ được mong đợi sau 8 năm.
Llew Vallis

@LlewVallis, nếu tôi diễn giải tất cả thông tin đúng, thì mã có vẻ ở đây: github.com/replimoc/compiler .
U880D

14

Học kỳ trước, tôi đã tham dự một khóa học "Xây dựng trình biên dịch". Dự án của chúng tôi là chính xác những gì bạn muốn làm.

Ngôn ngữ tôi đã sử dụng để viết ngôn ngữ của mình là Scala . Nó chạy trên JVM nhưng hỗ trợ rất nhiều tính năng nâng cao mà Java không có (vẫn hoàn toàn tương thích với java JVM thuần túy).

Để xuất ra mã bytecode của java, tôi đã sử dụng thư viện Scala CAFEBABE . Được ghi chép đầy đủ và bạn không cần phải đi sâu vào bên trong các lớp java để hiểu những gì cần làm.

Bên cạnh cuốn sách, tôi nghĩ bạn có thể tìm thấy rất nhiều thông tin bằng cách đi qua các phòng thí nghiệm mà chúng tôi đã thực hiện trong suốt khóa học.


Đây là một khóa học tuyệt vời. Bạn có muốn chia sẻ ghi chú hoặc mã của mình không?
Pedro

1
Không sao, tôi sẽ kiểm tra xem các bản sao lưu của mình ở đâu và đăng liên kết ở đây để bạn có thể tải xuống càng sớm càng tốt.
Kami

1
Gọn gàng, tôi đã tìm kiếm một khóa học biên dịch thực hành nhắm mục tiêu JVM với tất cả các tài liệu trực tuyến để tự học.
namin

5

ASM có thể là một giải pháp để tạo bytecode. Để bắt đầu, hãy kiểm tra các chủ đề về cách tạo các phần tử từ sách hướng dẫn .


4

Tôi đang suy nghĩ để xem xét có thể một ngôn ngữ khác nhắm mục tiêu JVM như Clojure, Jython hoặc JRuby. Nhưng tất cả các ngôn ngữ này đều có trình độ rất cao và phức tạp (để tạo một trình biên dịch cho chúng).

Gợi ý: Bạn có thể xem qua Ngôn ngữ lập trình Lua , có các triển khai JVM của nó như LuaJ .

Trình thông dịch Lua nhẹ , nhanh, tập trung vào Java được viết cho J2ME và J2SE, với các thư viện cho các gói cơ bản, chuỗi, bảng, gói, toán học, io, hệ điều hành, gỡ lỗi và coroutine, trình biên dịch , liên kết luajava và công cụ viết mã có thể cắm JSR-233 ràng buộc.

(Đừng nhầm với LuaJava sử dụng lib gốc với cách tiếp cận JNI.)


Cảm ơn bạn. Tôi sẽ xem xét

3

Cuối tuần trước, tôi đã tự hỏi mình câu hỏi tương tự để chuyển ngôn ngữ đồ chơi của tôi sang JVM.

Tôi chỉ dành vài giờ để tìm kiếm thông tin, vì vậy hãy xem tài liệu tham khảo này với một chút muối.

  • Các mẫu triển khai ngôn ngữ . Tôi ghét antlr nhưng cuốn sách này trông rất hay. Nếu bạn không thích antlr cũng vậy, có một hướng dẫn rất hay về phân tích cú pháp "Kỹ thuật phân tích cú pháp. Hướng dẫn thực hành."

    Tìm hiểu cách xây dựng trình đọc tệp cấu hình, trình đọc dữ liệu, trình tạo mã theo hướng mô hình, trình dịch từ nguồn sang nguồn, trình phân tích nguồn và trình thông dịch. Bạn không cần có kiến ​​thức nền tảng về khoa học máy tính — Người tạo ra ANTLR, Terence Parr, làm sáng tỏ việc triển khai ngôn ngữ bằng cách chia nhỏ nó thành các mẫu thiết kế phổ biến nhất. Theo mẫu, bạn sẽ học các kỹ năng chính cần thiết để triển khai ngôn ngữ máy tính của riêng mình.

    Chương 10 bao gồm 30 trang (để IMO nhanh) chủ đề này. Nhưng có những chương khác mà có lẽ bạn sẽ quan tâm.

    • 10 Xây dựng phiên dịch Bytecode
      • 10.1 Lập trình phiên dịch Bytecode. .
      • 10.2 Định nghĩa cú pháp hợp ngữ
      • 10.3 Kiến trúc máy Bytecode. . . . .
      • 10.4 Đi đâu từ đây. . . . . . . . . .
      • Tr.26. Bytecode Assembler. . . . . . . . . . .
      • Tr.27. Trình thông dịch Bytecode dựa trên ngăn xếp. . .
      • Tr.28. Trình thông dịch Bytecode Dựa trên Đăng ký
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • Việc triển khai Lua 5.0 Đây là một bài báo hay về máy bytecode dựa trên thanh ghi. Hãy đọc nó ngay cả vì lợi ích của nó.

    • Lisp trong các mảnh nhỏ. Cuốn sách này dạy cách viết một trình biên dịch 2 schme biên dịch sang C. Vì vậy, nhiều bài học có thể được học từ cuốn sách này. Tôi sở hữu một bản sao của cuốn sách này và nó thực sự tốt cho bất kỳ ai thú vị là nói ngọng, nhưng có thể không phải là tách trà của bạn.

      Đây là tài khoản toàn diện về ngữ nghĩa và việc triển khai toàn bộ họ ngôn ngữ Lisp, cụ thể là Lisp, Scheme và các phương ngữ liên quan. Nó mô tả 11 trình thông dịch và 2 trình biên dịch ...

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

Kiểm tra máy ảo Dalvik7, máy ảo dựa trên đăng ký. DVM hoạt động trên các mã byte được chuyển đổi từ các tệp Lớp Java được biên dịch bởi trình biên dịch Java.

Có một danh sách gửi thư về chủ đề, jvm-language.

Bạn có định tải mã lên bất kỳ nơi nào không? Tôi muốn có một cái nhìn.


Are you planning to upload the code to anyplace?Tôi không tự hào về mã mà :( ... Tôi có lẽ sẽ viết lại toàn bộ điều Dù sao Nếu tôi làm, tôi sẽ cho bạn biết Cảm ơn bạn rất nhiều vì lời đề nghị của bạn...

2

Trước tiên, tôi khuyên bạn nên tìm hiểu cách lắp ráp JVM hoạt động, nếu bạn chưa biết về nó.

Nhiều hướng dẫn có dạng ?name, đó ?inếu lệnh hoạt động với kiểu số nguyên vàa nếu nó hoạt động với kiểu tham chiếu.

Về cơ bản, JVM là một máy ngăn xếp không có thanh ghi, vì vậy tất cả các lệnh đều hoạt động với dữ liệu trực tiếp trên ngăn xếp. Bạn có thể đẩy / bật dữ liệu với ?push/?popvà di chuyển dữ liệu giữa các biến cục bộ (vị trí ngăn xếp được tham chiếu bởi hiệu số) và đầu ngăn xếp bằng cách sử dụng ?store/?load. Một số hướng dẫn quan trọng khác là invoke???if_??? .

Đối với khóa học biên dịch của trường đại học của tôi, chúng tôi đã sử dụng Jasmin để lắp ráp các chương trình. Tôi không biết đây có phải là cách tốt nhất hay không, nhưng ít nhất nó là một nơi dễ dàng để bắt đầu.

Đây là tham chiếu hướng dẫn cho phiên bản cũ của JVM, có thể chứa ít hướng dẫn hơn phiên bản mới.


0

Đầu tiên, tôi sẽ lùi lại, sửa đổi trình biên dịch của mình để xuất ra Java thực thay vì mã byte Java (có nghĩa là tạo nhiều trình dịch hơn trình biên dịch) và biên dịch đầu ra Java với bất kỳ môi trường Java nào thuận tiện (có thể sẽ tạo ra mã đối tượng tốt hơn hơn trình biên dịch của riêng tôi).

Bạn có thể sử dụng kỹ thuật tương tự (ví dụ: biên dịch sang C #) để tạo mã byte CLI hoặc biên dịch sang Pascal để tạo mã P, v.v.

Không rõ tại sao bạn lại xem xét mã Java thay vì sử dụng máy ảo của riêng mình, nhưng nếu đó là vì hiệu suất thì tất nhiên bạn cũng nên xem xét biên dịch sang mã máy thực tế.


Biên dịch cho JVM sẽ cho phép mã của một người được chạy rộng rãi hơn là nếu một người biên dịch sang mã gốc. Hơn nữa, biên dịch sang bytecode sẽ giúp mã có thể thực hiện một số điều không thể thực hiện được trong chính ngôn ngữ Java.
supercat

0

Tất nhiên một lần có thể sử dụng Java để viết một ngôn ngữ mới. Với API phản chiếu Java, bạn có thể đạt được nhiều điều. Nếu tốc độ không quá quan trọng, tôi sẽ ưu tiên Java thay vì ASM. Lập trình dễ dàng hơn và ít lỗi hơn trong Java (IMHO) . Hãy xem ngôn ngữ RPN thứ 7 . Nó hoàn toàn được viết bằng Java.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.