Phát triển ngôn ngữ năng động


11

Tôi đã tạo ra một số trình biên dịch viết tay cho các ngôn ngữ rất đơn giản nhưng bây giờ tôi muốn thử phát triển một ngôn ngữ động, tương tự như Python hoặc Ruby đơn giản hóa. Tuy nhiên, thật dễ dàng để tôi quấn đầu xung quanh cách trình biên dịch làm việc. Trình biên dịch nguyên thủy chỉ cần dịch. Nhưng tôi không thể làm điều này nếu ngôn ngữ năng động. Tôi phải viết một trình thông dịch hoặc VM theo dõi thông tin trong thời gian chạy và giúp tôi làm việc nhiều hơn.

Nói tóm lại, có bất kỳ tài nguyên nào tôi nên kiểm tra xem xét tôi có biết trình biên dịch hoạt động như thế nào nhưng muốn chuyển sang tạo trình thông dịch không? Có một vài máy ảo cho các ngôn ngữ động, nhưng tôi không có vấn đề gì với việc tự lăn. Đây là tất cả chỉ cho kinh nghiệm cá nhân của tôi.

Tôi đang tìm kiếm thông tin về cách chuyển từ trình biên dịch sang trình thông dịch. Nếu tôi đã tạo một trình biên dịch cho ngôn ngữ X nhưng bây giờ phải viết trình thông dịch, thì cần phải làm gì và có tài nguyên nào đi qua quy trình không?

Tôi không muốn các tài nguyên rộng hoặc trừu tượng đi qua cách trình biên dịch hoặc máy ảo hoạt động. Tôi có rất nhiều sách giáo khoa về chủ đề này. Tất cả các tài nguyên tôi tìm thấy trực tuyến đều cho rằng bạn có 0 kinh nghiệm và do đó bắt đầu với việc phân tích từ vựng hoặc cú pháp hoặc chúng cực kỳ trừu tượng. Tôi có một trình biên dịch làm việc, nhưng bây giờ tôi muốn biến nó thành một trình thông dịch và thêm các tính năng động cho ngôn ngữ.

Tôi không thể tìm thấy tài nguyên trong quá trình này, nó có thể quá giới hạn về phạm vi hoặc tài nguyên ở "phần cuối" của trình thông dịch mà không quá lý thuyết, đó là lý do tại sao tôi đăng ở đây.


1
Có hàng tấn tài nguyên như thế này. Lưu ý rằng dòng giữa trình biên dịch và trình thông dịch bị mờ hơn bạn nghĩ; trình biên dịch C # 4.0 hỗ trợ lập trình động, cũng như một số trình biên dịch khác.
Robert Harvey

@RobertHarvey Vâng, những gì tôi đang hỏi là các tài nguyên để tạo thời gian chạy / trình thông dịch / máy ảo của riêng tôi. Trình thông dịch .Net quá phức tạp đối với tôi.
Austin Henley


1
Và kiểm tra câu hỏi SO này , có một vài ý kiến ​​với các tham chiếu đến các câu hỏi khác khá thú vị ...
yannis

Câu trả lời:


4

Đầu tiên tìm hiểu về việc thực hiện phiên dịch. Tôi đề nghị PLAI (Ngôn ngữ lập trình: Ứng dụng và Phiên dịch) . Nó đi vào phần thịt của sự diễn giải một cách nhanh chóng mà không cần quá dài theo cú pháp.

Đối với ngôn ngữ của bạn, bạn sẽ có thể sử dụng lại phần đầu của trình biên dịch (phần lớn trình phân tích cú pháp) và thư viện thời gian chạy (GC, cấu trúc dữ liệu, hoạt động nguyên thủy, v.v.).

Tất nhiên, bạn cũng có thể triển khai một ngôn ngữ động với trình biên dịch tạo mã xử lý (một số) cấu trúc dữ liệu giống như bạn sẽ sử dụng trong trình thông dịch. Ví dụ: trong một trình thông dịch, bạn có thể triển khai các biến toàn cục dưới dạng bảng băm được lập chỉ mục chuỗi. Trong trình biên dịch, bạn sẽ biên dịch các tham chiếu biến toàn cục thành mã thực hiện tra cứu bằng cùng một bảng. Ngược lại, bạn có thể biên dịch các biến từ vựng thành một biểu diễn hiệu quả hơn (đối số "gốc" và tham chiếu cấu trúc đóng).


5

Nếu bạn muốn tìm hiểu những điều cơ bản trong việc triển khai một trình thông dịch cho một ngôn ngữ động, tôi không thể tưởng tượng một nơi tốt hơn để bắt đầu hơn nguồn gốc của ngôn ngữ lập trình được diễn giải, năng động đầu tiên: Lisp.

Trong bài viết gốc năm 1960 , John McCarthy đã định nghĩa 5 chức năng nguyên thủy cần thiết cho một Lisp. Tất nhiên, McCarthy chỉ dự định bài báo của mình về Lisp như một bài tập học thuật; đó là một sinh viên tốt nghiệp đã bắt chước evallắp ráp và tạo ra trình thông dịch Lisp đầu tiên. Paul Graham xác định bảy nguyên thủy : quote, nguyên tử, eq, khuyết điểm, xe hơi, cdr và cond.

Vấn đề là, bạn thực sự có thể thực hiện Lisp bằng bất kỳ ngôn ngữ nào; một khi bạn thực hiện eval, thật dễ dàng để thiết lập REPL và bạn có một trình thông dịch tương tác . Mọi người đã chán hoặc đủ tò mò để triển khai Lisps bằng C, Java, Ruby, Python và nhiều ngôn ngữ khác. Và không phải lúc nào cũng có mục đích; Điều quan trọng cần nhớ là Quy tắc thứ mười của Greensasta :

Bất kỳ chương trình C hoặc Fortran nào đủ phức tạp đều chứa một chương trình ad hoc, được chỉ định không chính thức, có lỗi, triển khai chậm một nửa Common Lisp.

Tôi không nói rằng mục tiêu cuối cùng của bạn phải là triển khai Lisp; nhưng đồng âm có lợi ích của nó khi học cách thực hiện một ngôn ngữ năng động; tại sao phải giải quyết các vấn đề cú pháp khi bạn có thể học một ngôn ngữ trong đó cú pháp thành ngữ giống hệt AST của ngôn ngữ sử dụng từ vựng / trình phân tích cú pháp?

Nhưng dù sao ... chỉ là một gợi ý. Nhưng đó là lý do chính đáng mà hầu hết các ngôn ngữ lập trình tuyệt vời kể từ C có ít nhất một chút bản chất Lisp.


1
Tôi ước tôi có thể chấp nhận hai câu trả lời. Cảm ơn, tôi nghĩ rằng tôi thực sự sẽ thực hiện một trình thông dịch Lisp. Thật dễ dàng để phân tích cú pháp, có rất nhiều tài liệu và mã hiện có, và sẽ cho tôi một nền tảng để làm việc. Thật không may, tôi đã tham gia một lớp học đại học sử dụng Scheme và nó khiến tôi phải nhổ tóc;)
Austin Henley

1
Bây giờ tôi đang cố gắng biên dịch ngôn ngữ của mình thành phương ngữ Lisp của riêng tôi!
Austin Henley


0

Tôi đã đặt (~ 600 dòng C #) này vào miền công cộng, hỗ trợ trích dẫn / danh sách / áp dụng / eval / test / etc và cho phép dễ dàng tùy chỉnh cú pháp giống Lisp và / hoặc các nội dung ngữ nghĩa dễ dàng:

https://repl.it/CdjV/3

Ví dụ:

        var factorial = (Lambda)language.
            Evaluate
            (@"
                ( => ( n ) (
                        ? ( != n 0 )
                        ( * n ( this ( - n 1 ) ) )
                        1
                    )
                )
            ");

        var sw = new System.Diagnostics.Stopwatch();
        var n = 12;
        var r = 0;
        int k;
        sw.Start();
        for (k = 0; k < 10000; k++)
        {
            r = (int)factorial.Invoke(null, n);
        }
        sw.Stop();
        Console.WriteLine("{0}! = {1}", n, r);
        Console.WriteLine();
        Console.WriteLine("in {0} ms (for {1} times)", sw.ElapsedMilliseconds, k.ToString("0,0"));

'HTH,


0

Giả sử bạn biết một chút về Đề án (ví dụ đã đọc SICP ) hoặc Lisp, tôi khuyên bạn nên sử dụng cuốn sách Lisp In Small Pieces của Queinnec . Nó giải thích một số biến thể của trình thông dịch và trình biên dịch giống như Lisp (bao gồm mã byte hoặc C).

Ngoài ra, hãy đọc Ngôn ngữ lập trình của Scott , Sách Rồng mới nhất , cẩm nang GC , Các loại ngôn ngữ & lập trình của Pierce .

Tôi đang tìm kiếm thông tin về cách chuyển từ trình biên dịch sang trình thông dịch.

Sau đó, đánh giá một phần (& dự đoán Futamura) và phong cách tiếp tục có thể có liên quan.

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.