2008-09-19 25 views
11

Có những công cụ gì để tôi xây dựng một DSL ngoài thực, trung thực và tốt. Và không, tôi không nói về việc lạm dụng Ruby, Boo, XML hoặc một ngôn ngữ hoặc cú pháp hiện có khác, tôi có nghĩa là một DSL bên ngoài REAL - ngôn ngữ của riêng tôi cho mục đích của riêng tôi.Xây dựng các DSL bên ngoài hiệu quả

Tôi biết rằng có một vài bàn làm việc ngôn ngữ đang được phát triển và tôi đã nghe nói về những thứ như "Irony" cho .NET. Và, tất nhiên, có ANTLR, Lex/Yaac, v.v. nhưng tôi sợ những thứ đó quá phức tạp với những gì tôi đang cố gắng làm.

Vui lòng nói về công cụ trình tạo DSL mà bạn có thể đã sử dụng hoặc nghe nói và hiển thị của bạn về cách thức trợ giúp và những nhược điểm của nó.

+0

LƯU Ý: Tôi không nhất thiết phải tìm kiếm tính hoàn chỉnh của Turing tại đây. Chủ yếu chỉ là cú pháp biểu thức để cấu hình mọi thứ trong mô hình của tôi. – chadmyers

Trả lời

9

Tôi đã viết DSL ở Boo, Irony.NET và một bộ công cụ có tên là Grammatica. Bạn nói rằng một trình tạo phân tích cú pháp quá phức tạp, nhưng bạn có thể quá vội vàng trong bản án của bạn, thực tế chúng khá đơn giản khi bạn sử dụng một đường cong học tập nhỏ và mở ra một thế giới rộng lớn về khả năng dễ dàng ghi đè nỗ lực. Tôi đã tìm thấy ký hiệu cần thiết để viết các ngữ pháp cho hầu hết các trình tạo trình phân tích cú pháp hơi giống với việc diễn đạt các biểu thức chính quy - bạn phải bẻ cong tâm trí một chút để cho chúng vào, nhưng phần thưởng rất quan trọng.

Ý kiến ​​của tôi là: Nếu ngôn ngữ mục tiêu của bạn đủ đơn giản để nó có thể được xử lý bởi một nhà thiết kế trực quan, thì viết một ngữ pháp cho nó bằng trình tạo trình phân tích cú pháp sẽ khá dễ dàng.

Nếu DSL mục tiêu của bạn đủ phức tạp, bạn sẽ cần phải đổ mồ hôi viết một ngữ pháp, sau đó công cụ trực quan bị mờ sẽ không cắt mù tạt và bạn sẽ phải học cách viết một ngữ pháp dù sao.

Tôi đồng ý về lâu dài về nội bộ so với DSL bên ngoài. Tôi đã viết một DSL nội bộ trong Boo và đã phải sửa đổi cú pháp DSL của tôi để làm cho nó hoạt động, và nó luôn luôn cảm thấy giống như một hack. Cùng một ngữ pháp sử dụng Irony.NET hoặc ANTLR sẽ dễ dàng thực hiện với sự linh hoạt hơn.

Tôi có một số blog post thảo luận một số tùy chọn. Bài viết tập trung vào việc viết một DSL để đánh giá biểu thức thời gian chạy, nhưng các công cụ đều giống nhau.

Trải nghiệm của tôi với Irony.NET là tất cả đều tích cực và có một số ngôn ngữ tham chiếu được triển khai bằng cách sử dụng nó, đây là một nơi tốt để bắt đầu. Nếu ngôn ngữ của bạn là đơn giản, nó là hoàn toàn không phức tạp để có được và chạy. Ngoài ra còn có một thư viện trên CodeProject được gọi là TinyParser - thư viện này thực sự thú vị, vì nó tạo ra trình phân tích cú pháp là mã nguồn thuần túy, có nghĩa là sản phẩm cuối cùng của bạn hoàn toàn không có tham chiếu của bên thứ ba. Tuy nhiên, tôi đã không sử dụng nó.

4

Bạn thực sự nên xem Ragel. Đó là một khuôn khổ để nhúng các máy trạng thái trong mã nguồn thông thường của bạn. Ragel hỗ trợ C, C++, Objective-C, D, Java và Ruby.

Tính năng tuyệt vời của Ragel để viết các tệp phân tích cú pháp tệp và giao thức cũng như bước qua các công cụ DSL bên ngoài. Chủ yếu bởi vì nó cho phép bạn thực hiện bất kỳ loại mã nào về quá trình chuyển đổi trạng thái và như vậy.

Một vài dự án đáng chú ý sử dụng Ragel là, Mongrel, một máy chủ web tuyệt vời. Và Hpricot, một trình phân tích cú pháp html dựa trên ruby, được lấy cảm hứng từ jQuery.

Một tính năng tuyệt vời khác của Ragel là làm thế nào nó có thể tạo ra các biểu đồ dựa trên graphviz hình dung các máy trạng thái của bạn. Dưới đây là ví dụ được lấy từ Zed Shaw'sarticle on ragel state charts.

ragel state chart http://www.zedshaw.com/tips/HelloMachine_small.png

+0

Tuyệt vời. Tôi chắc chắn sẽ kiểm tra điều này! – chadmyers

8

Nếu bạn đang xem xét bằng văn bản DSL độc lập, sau đó bạn đang xem xét xây dựng trình biên dịch - không có cách nào xung quanh nó. Xây dựng trình biên dịch kiến ​​thức lập trình cần thiết và nó thực sự không khó như thường nghĩ. Steve Yegge của Righ Programmer Food tóm tắt giá trị của việc biết làm thế nào để xây dựng trình biên dịch khá độc đáo.

Có rất nhiều cách để bắt đầu. Tôi khuyên bạn nên kiểm tra 2 bài báo được đề cập trong bài viết: Want to write a compiler? Just read these Two papers. Người đầu tiên, Let's build a compiler, rất dễ tiếp cận. Nó sử dụng Turbo Pascal như một ngôn ngữ thực hiện, nhưng bạn có thể dễ dàng thực hiện nó bằng bất kỳ ngôn ngữ nào khác - mã nguồn rất rõ ràng. Pascal là một ngôn ngữ đơn giản.

Khi bạn có cảm giác tốt về cách mọi thứ hoạt động và thuật ngữ có liên quan, tôi khuyên bạn nên nghiên cứu một số thứ như ANTLR. ANTLR có một IDE đẹp, ANTLRWorks, đi kèm với một thông dịch viên và một trình gỡ lỗi. Nó cũng tạo ra hình ảnh thực sự tốt về ngữ pháp của bạn khi đang bay. Tôi thấy nó vô giá trong việc học.

ANTLR có một số hướng dẫn hay, mặc dù ban đầu chúng có thể hơi bị áp đảo. This one là tốt đẹp, mặc dù nó chống lại ANTLR 2.0, vì vậy bạn có thể gặp phải sự không tương thích với một phiên bản mới hơn (hiện tại phiên bản mới nhất là 3.1).

Cuối cùng, có một cách tiếp cận khác đối với DSL: Phương pháp tiếp cận Lisp. Với cú pháp ít cú pháp của Lisp (mã của bạn về cơ bản là các cây cú pháp trừu tượng), bạn có thể định dạng các ngôn ngữ vô tận ra khỏi nó, miễn là bạn đã quen với các dấu ngoặc đơn :).

Nếu bạn làm theo cách tiếp cận đó, bạn muốn sử dụng Lisp có thể nhúng. Trong Java, bạn có Clojure, một phương ngữ Lisp có khả năng tương tác hoàn hảo với JVM và các thư viện của nó. Tôi đã không sử dụng nó cá nhân, nhưng có vẻ tốt.Đối với Đề án, có GNU Guile, là licensed under LGPL. Đối với Common Lisp, có ECL, cũng theo LGPL. Cả hai đều sử dụng giao diện C cho khả năng tương tác, vì vậy bạn có thể nhúng chúng vào bất kỳ ngôn ngữ nào khác. ECL là duy nhất trong số Lisps trong đó mỗi hàm Lisp được thực hiện như một hàm C, vì vậy bạn có thể viết mã Lisp trong C nếu bạn muốn (nói, bên trong các phương thức mở rộng của riêng bạn - bạn có thể tạo các hàm C hoạt động trên các đối tượng Lisp, và sau đó gọi chúng từ Lisp). Tôi đã sử dụng ECL cho một dự án phụ của tôi trong một thời gian, và tôi thích nó. Người duy trì khá tích cực và đáp ứng.

+0

Bạn không giúp tôi ở đây. hahah Tôi đã sai lầm với ANTLR trước đây và tôi biết nó là khả năng, nhưng tôi đã hy vọng cho một cái gì đó không khá phức tạp/phức tạp. Tôi đoán tôi sẽ phải cho nó một cái nhìn khác. – chadmyers

1

Tôi đã sử dụng Irony với kết quả tốt. Phần lớn về sự trớ trêu là bạn có thể dễ dàng bao gồm nó trong bất kỳ thời gian chạy nào bạn sẽ sử dụng DSL cho. Tôi đang tạo ra một DSL bên ngoài mà tôi cư trú vào một mô hình ngữ nghĩa được viết bằng C# để trớ trêu là rất tốt. Sau đó, tôi sử dụng mô hình ngữ nghĩa để tạo mã bằng StringTemplate.

1

Nếu bạn dự định triển khai một DSL bên ngoài, Spoofax (http://strategoxt.org/Spoofax) là một Bàn làm việc ngôn ngữ tốt để thực hiện việc này. Nó là một trình soạn thảo văn bản Langauge dựa trên phân tích cú pháp, sử dụng một số công nghệ tiên tiến như SDF, Stratego. Bên cạnh việc triển khai DSL, bạn có thể nhận được một dịch vụ biên tập rất phong phú như, hoàn thành mã, xem phác thảo, intellisense vv. Nó đã được sử dụng để xây dựng một số ngôn ngữ, ví dụ: http://mobl-lang.org/. Kiểm tra điều này để có ý tưởng về hỗ trợ được cung cấp.

Dự án Spoofax đi kèm với một triển khai DSL mẫu tốt nhất của hộp và trình tạo mã java. Nó có thể hoạt động như một điểm khởi đầu để bắt đầu với các công cụ.

Làm theo các chi tiết hướng dẫn về cách sử dụng bàn làm việc langauge này: http://strategoxt.org/Spoofax/Tour.

Hy vọng điều đó sẽ hữu ích!

0

Đối với các DSL bên ngoài nghiêm trọng, bạn không thể tránh được sự cố phân tích cú pháp; ANTLR là ít nhất của những gì bạn cần. Những gì bạn muốn kiểm tra là các hệ thống chuyển đổi chương trình, có thể được sử dụng để ánh xạ cú pháp DSL tùy ý vào các ngôn ngữ đích như Java.

Xem http://en.wikipedia.org/wiki/Program_transformation

2

Xtext được xây dựng cho việc này.

Từ trang web:

Xtext là một khuôn khổ cho sự phát triển của ngôn ngữ lập trình và ngôn ngữ miền cụ thể.

Nó bao gồm tất cả các khía cạnh của cơ sở hạ tầng ngôn ngữ hoàn chỉnh, từ trình phân tích cú pháp, qua trình liên kết, trình biên dịch hoặc thông dịch để tích hợp hoàn toàn hàng đầu Tích hợp IDE Eclipse. Nó đi kèm với các giá trị mặc định tốt cho tất cả các khía cạnh này và đồng thời mọi khía cạnh đơn lẻ đều có thể được điều chỉnh theo yêu cầu của bạn theo số .

Các vấn đề liên quan