Tại sao chúng ta không lưu trữ cây cú pháp thay vì mã nguồn?


111

Chúng tôi có rất nhiều ngôn ngữ lập trình. Mọi ngôn ngữ đều được phân tích cú pháp và kiểm tra cú pháp trước khi được dịch thành mã để cây cú pháp trừu tượng (AST) được xây dựng.

Chúng ta có cây cú pháp trừu tượng này, tại sao chúng ta không lưu trữ cây cú pháp này thay vì mã nguồn (hoặc bên cạnh mã nguồn)?

Bằng cách sử dụng AST thay vì mã nguồn. Mỗi lập trình viên trong một nhóm có thể tuần tự cây này sang bất kỳ ngôn ngữ nào họ muốn (với ngữ pháp tự do ngữ cảnh phù hợp) và phân tích lại AST khi chúng kết thúc. Vì vậy, điều này sẽ loại bỏ cuộc tranh luận về các câu hỏi về phong cách mã hóa (nơi đặt {và}, nơi đặt khoảng trắng, thụt lề, v.v.)

Những ưu và nhược điểm của phương pháp này là gì?


37
Lisp thường được viết dưới dạng cây cú pháp trừu tượng. Nó không bắt được nhiều ngôn ngữ giống Algol hơn.
David Thornley

2
Tôi không thể tin rằng David là người duy nhất đề cập rằng các chương trình LISP là một cây cú pháp trừu tượng.
WuHoUnited

3
Ngoài những điểm khác: AST thậm chí không phải là điều cuối cùng. Nó cũng không mất nhiều thời gian để tạo AST ra khỏi mã. Khi tôi chạy StyleCop trên dự án VS2010 nhỏ của mình, nó chạy hàng chục quy tắc dựa trên AST khác nhau trên hàng ngàn dòng mã rất nhanh (đôi khi là một hoặc hai giây). Nó cũng khá dễ dàng để mở rộng StyleCop và viết quy tắc tùy chỉnh. Tôi nghi ngờ rằng việc phân tích mã nguồn thành AST là một vấn đề dễ hiểu và là một vấn đề tương đối dễ dàng. Nó đang đến với ngôn ngữ tốt ngay từ đầu, và tối ưu hóa, và tất cả các thư viện khó, không phân tích cú pháp.
Công việc

1
Đã phân tích mã, không dễ để tạo mã cho ngôn ngữ khác. (Làm thế nào bạn sẽ dịch sự hợp nhất ngầm của Prolog thành C?). Chủ yếu những gì bạn có là một AST cho chương trình ban đầu.
Ira Baxter

3
Vấn đề phân tích cú pháp được hiểu rõ về mặt kỹ thuật, nhưng nó không phải là một nhiệm vụ dễ dàng để phân tích C hoặc C ++ vì chúng là những ngôn ngữ khó chịu lộn xộn. Nhiều trình biên dịch trình phân tích cú pháp C hoặc C ++ sang AST: Clang, GCC, ... Chúng không nhằm mục đích lưu trữ chương trình và GCC rất muốn trở thành trình biên dịch, không phải là một công cụ phân tích chương trình. Bộ công cụ tái cấu trúc phần mềm DMS của chúng tôi phân tích nhiều phương ngữ của C và C ++, tạo ra AST, bảng biểu tượng và các loại tạo tác phân tích dòng chảy khác nhau. Pro lớn của phương pháp này là khả năng xây dựng các công cụ thay đổi tự động. semanticdesigns.com/
Products / DMS / DMSToolkit.html

Câu trả lời:


72

Khoảng trắng và bình luận

Nói chung, AST không bao gồm khoảng trắng, dấu kết thúc dòng và nhận xét.

Định dạng có ý nghĩa

Bạn đã đúng rằng trong hầu hết các trường hợp, đây là một số dương (loại bỏ định dạng các cuộc chiến thánh), có nhiều trường hợp định dạng của mã gốc truyền tải một số ý nghĩa, chẳng hạn như trong các chuỗi ký tự chuỗi nhiều dòng và "các đoạn mã" (tách các khối của báo cáo với một dòng trống).

Mã không thể được biên dịch

Mặc dù nhiều trình phân tích cú pháp rất linh hoạt khi thiếu cú ​​pháp, mã có lỗi thường dẫn đến một cây cú pháp rất kỳ lạ, điều này rất ổn và cho đến khi người dùng tải lại tệp. Bạn đã bao giờ mắc lỗi trong IDE của mình và sau đó đột nhiên toàn bộ tệp có "squigglies"? Hãy tưởng tượng làm thế nào mà sẽ được tải lại trong ngôn ngữ khác.

Có thể người dùng không cam kết mã không thể mã hóa, nhưng họ chắc chắn có nhu cầu lưu cục bộ.

Không có hai ngôn ngữ là kết hợp hoàn hảo

Như những người khác đã chỉ ra, hầu như không có hai ngôn ngữ có tính năng tương đương hoàn hảo. Gần nhất tôi có thể nghĩ là VB và C #, hoặc JavaScript và CoffeeScript, nhưng ngay cả VB cũng có các tính năng như Văn học XML không có tương đương trong C # và chuyển đổi JavaScript sang CoffeeScript có thể dẫn đến rất nhiều chữ JavaScript.

Kinh nghiệm cá nhân:

Trong một ứng dụng phần mềm tôi viết, chúng tôi thực sự cần phải làm điều này, vì người dùng dự kiến ​​sẽ nhập các biểu thức "tiếng Anh đơn giản" được chuyển đổi sang JS trong nền. Chúng tôi đã xem xét chỉ lưu trữ phiên bản JS, nhưng hầu như không có cách nào có thể chấp nhận được để tải và tải một cách đáng tin cậy, vì vậy cuối cùng chúng tôi luôn lưu trữ cả văn bản người dùng và phiên bản JS, cũng như một cờ cho biết nếu "tiếng Anh đơn giản "Phiên bản được phân tích cú pháp hoàn hảo hay không.


9
Có các trình phân tích cú pháp để nắm bắt các bình luận và bố cục trong AST. Bộ công cụ chuyển đổi phần mềm DMS của chúng tôi thực hiện điều này tốt. Nó có một thời gian khó khăn với mã bất hợp pháp; nó có một trình phân tích cú pháp ngôn ngữ chính xác.
Ira Baxter

2
Thực sự có một công cụ chuyển đổi Javascript thành CoffeeScript , vì vậy tôi nghĩ rằng JavaScript và CoffeScript có thể dịch lẫn nhau mà không cần bằng chữ Javascript.
Peter Olson

Công cụ thú vị, Peter, tôi đã không nhận thức được nó.
Kevin McCormick

+1 cho định dạng có ý nghĩa và trải nghiệm cá nhân thú vị. - Khoảng trắng không quan trọng đối với câu hỏi và ý kiến ​​có thể được lưu giữ. Các mã có lỗi sẽ dễ dàng được sửa chữa hơn và tất nhiên phần "một ngôn ngữ để thống trị tất cả" của câu hỏi là không thể truy cập được.
cregox

43

Tại sao chúng ta không lưu trữ cây cú pháp này thay vì mã nguồn? Mỗi lập trình viên trong một nhóm có thể tuần tự cây này sang bất kỳ ngôn ngữ nào, họ muốn và phân tích lại cho AST khi họ hoàn thành.

Thật vậy, đó là một ý tưởng hợp lý. Microsoft đã có một dự án nghiên cứu vào những năm 1990 để làm gần như chính xác điều đó .

Một số kịch bản đến với tâm trí.

Thứ nhất là khá tầm thường; như bạn nói, bạn có thể khiến AST được hiển thị thành các chế độ xem khác nhau tùy thuộc vào sở thích của các lập trình viên khác nhau cho những thứ như khoảng cách, v.v. Nhưng lưu trữ AST là quá mức cần thiết cho kịch bản đó; chỉ cần viết cho mình một máy in đẹp Khi bạn tải một tập tin vào trình soạn thảo của mình, hãy chạy máy in đẹp để đưa nó vào định dạng ưa thích của bạn và quay lại định dạng ban đầu khi bạn lưu nó.

Thứ hai là thú vị hơn. Nếu bạn có thể lưu trữ cây cú pháp trừu tượng thì mã thay đổi mã sẽ không trở thành văn bản mà là cú pháp. Tái cấu trúc nơi mã được di chuyển xung quanh trở nên dễ hiểu hơn nhiều. Mặt trái của khóa học là việc viết các thuật toán khác biệt cây không chính xác tầm thường và thường phải được thực hiện trên cơ sở mỗi ngôn ngữ. Text diff hoạt động cho hầu hết mọi ngôn ngữ.

Thứ ba giống như những gì Simonyi đã hình dung cho Lập trình có chủ ý: rằng các khái niệm cơ bản phổ biến cho các ngôn ngữ lập trình là những gì được tuần tự hóa, và sau đó bạn có các quan điểm khác nhau về các khái niệm được biểu hiện bằng các ngôn ngữ khác nhau. Mặc dù là một ý tưởng hay, nhưng thực tế xấu là các ngôn ngữ đủ khác nhau về chi tiết của chúng mà cách tiếp cận mẫu số chung thấp nhất không thực sự hiệu quả.

Vì vậy, trong ngắn hạn, đó là một ý tưởng đáng yêu nhưng nó là một lượng lớn công việc làm thêm cho một lợi ích tương đối nhỏ. Đó là lý do tại sao hầu như không ai làm điều đó.


3
Trên thực tế, bạn có thể thực hiện khác biệt cây theo cách độc lập với ngôn ngữ. Bạn cần trình phân tích cú pháp ngôn ngữ cụ thể để xây dựng cây. Xem dòng công cụ khác biệt thông minh của chúng tôi, so sánh AST cho nhiều ngôn ngữ. Tất cả đều sử dụng cùng một công cụ tìm khác nhau. semanticdesigns.com/Sản phẩm
SmartDifferencer

1
Tôi hy vọng sẽ thấy đội ngũ theo phong cách của tôi-in-in-tải-phong cách-in-lưu-in-lưu trong Visual Studio một ngày nào đó ... đã hy vọng trong nhiều năm ... chưa có may mắn ...
Roman Starkov

19

Bạn có thể lập luận rằng đây chính xác là mã byte trong .NET. Chương trình phản xạ của Redgate thực hiện dịch mã byte trở lại thành một loạt các ngôn ngữ lập trình .NET.

Tuy nhiên, có vấn đề. Cú pháp là ngôn ngữ cụ thể theo nhiều ngôn ngữ mà bạn có thể đại diện cho một ngôn ngữ không có đại diện trong các ngôn ngữ khác. Điều này xảy ra trong .NET với C ++ là ngôn ngữ .NET duy nhất có quyền truy cập vào tất cả 7 cấp độ truy cập.

Bên ngoài môi trường .NET, nó trở nên phức tạp hơn nhiều. Mỗi ngôn ngữ sau đó bắt đầu có bộ thư viện liên kết riêng. Không thể phản ánh một cú pháp chung trong cả C và Java, phản ánh cùng một cách thực hiện các hướng dẫn khi chúng giải quyết các vấn đề mô phỏng theo những cách rất khác nhau.


5
Bạn đã bao giờ thử dịch ngược MSIL do F # sản xuất chưa?
SK-logic

12

Tôi giống như một số ý tưởng của bạn, nhưng bạn đánh giá quá cao việc dịch ngôn ngữ sang ngôn ngữ dễ dàng như thế nào. Nếu nó dễ dàng như vậy, bạn thậm chí sẽ không cần lưu trữ AST, vì bạn luôn có thể phân tích ngôn ngữ X sang AST sau đó chuyển từ AST sang ngôn ngữ Y.

Tuy nhiên, tôi muốn các thông số kỹ thuật của trình biên dịch nghĩ thêm một chút về việc phơi bày một số AST thông qua một số loại API. Những thứ như lập trình hướng, tái cấu trúc và phân tích chương trình tĩnh có thể được thực hiện thông qua API như vậy, mà không cần người thực hiện các khả năng đó phải làm lại rất nhiều công việc đã được các nhà biên dịch thực hiện.

Thật kỳ lạ khi cấu trúc dữ liệu của lập trình viên thường đại diện cho một chương trình giống như một bó các tệp chứa các chuỗi.


5
Bạn đã theo dõi sự phát triển của dự án " Roslyn " của Microsoft để mở trình biên dịch VBc và C # dưới dạng API chưa? Có một bản phát hành xem trước có sẵn.
Carson63000

11

Tôi nghĩ rằng những điểm nổi bật nhất là:

  • Không có lợi ích. Bạn nói rằng nó có nghĩa là mọi người đều có thể sử dụng ngôn ngữ thú cưng của họ. Nhưng điều đó không đúng - sử dụng biểu diễn cây cú pháp sẽ chỉ tạo ra sự khác biệt về cú pháp, chứ không phải về ngữ nghĩa. Nó hoạt động ở một mức độ nào đó đối với các ngôn ngữ rất giống nhau - như VB và C #, hoặc Java và Scala. Nhưng thậm chí không có hoàn toàn.

  • Đó là vấn đề. Bạn đã đạt được tự do ngôn ngữ, nhưng bạn đã mất tự do công cụ. Bạn không còn có thể đọc và chỉnh sửa mã trong trình soạn thảo văn bản hoặc thậm chí bất kỳ IDE nào - bạn phụ thuộc vào một công cụ cụ thể nói đại diện AST của bạn cho cả đọc và chỉnh sửa mã. Không có gì đạt được ở đây.

    Để minh họa điểm cuối cùng này, hãy xem RealBasic, đây là một triển khai độc quyền của phương ngữ BASIC mạnh mẽ. Trong một thời gian, nó gần như là ngôn ngữ có thể cất cánh, nhưng nó hoàn toàn phụ thuộc vào nhà cung cấp, đến mức bạn chỉ có thể xem mã trong IDE của họ vì nó được lưu ở định dạng phi văn bản độc quyền. Sai lầm lớn .


4
Lợi ích tiềm năng là nó có thể kết thúc các cuộc tranh luận bất tận như "tab so với dấu cách", "unix so với cửa sổ giằng / thụt lề", "tiền tố m_ trước các thành viên hay không", bởi vì chúng có thể được chuyển thành các tùy chọn IDE đơn giản.
nikie

1
@nikie Đúng nhưng bạn đã có thể thực hiện việc này bằng các công cụ định dạng lại - như astylehoặc UnniversalIndent. Không cần định dạng nhị phân phức tạp.
Konrad Rudolph

2
Lợi ích thực sự sẽ là tiềm năng để có các công cụ diff / patch giúp bạn hiểu rõ hơn về những gì thực sự thay đổi. Nhưng điều đó dường như ngụ ý cần một toàn bộ công cụ mới để kiểm soát phiên bản, đây là một hạn chế nghiêm trọng.
Peter Taylor

1
Nếu bạn nghĩ rằng "Không có lợi ích gì", thì bạn đã không thấy Bàn làm việc Miền của Phần mềm có chủ ý.
Craig Stuntz

1
Tóm lại, logic tương tự có thể được chiếu vào các biểu diễn khác nhau, không phải tất cả các văn bản dựa trên, làm cho các quy tắc có thể truy cập được đối với những người không lập trình. Ví dụ, các chuyên gia tên miền như chuyên gia tính toán có thể viết các bộ phận truyền động của ứng dụng bảo hiểm. Giống như DSL ngoại trừ không giới hạn trong đại diện đó. Điều này rất liên quan đến câu hỏi, mặc dù. Có một bản demo tốt .
Craig Stuntz

6

Tôi nghĩ, nếu bạn lưu trữ cả văn bản và AST, thì bạn chưa thực sự thêm bất cứ thứ gì hữu ích, vì văn bản đã có sẵn trong một ngôn ngữ và AST có thể nhanh chóng được xây dựng lại từ văn bản.

Mặt khác, nếu bạn chỉ lưu trữ AST, bạn sẽ mất những thứ như nhận xét không thể khôi phục được.


6
và nếu bạn làm cho phần bình luận của cây cú pháp (với các nút bình luận có thể là con của bất cứ thứ gì)?
ratchet freak

Công cụ của chúng tôi làm chính xác điều đó. Xem ý kiến ​​khác của tôi trong chủ đề này.
Ira Baxter

4

Tôi tin rằng ý tưởng này rất thú vị trên lý thuyết nhưng không thực tế lắm vì các ngôn ngữ lập trình khác nhau hỗ trợ các cấu trúc khác nhau, một số ngôn ngữ không có tương đương trong các ngôn ngữ khác.

Ví dụ: X ++ có câu lệnh 'while select' không thể được viết bằng C # mà không có nhiều mã bổ sung (các lớp bổ sung, logic bổ sung, v.v.). http://msdn.microsoft.com/en-us/l Library / aa558063.aspx

Điều tôi đang nói ở đây là nhiều ngôn ngữ có đường cú pháp dịch theo các khối mã lớn của cùng một ngôn ngữ hoặc thậm chí các yếu tố hoàn toàn không tồn tại ở các ngôn ngữ khác. Dưới đây là một ví dụ tại sao phương pháp AST sẽ không hoạt động:

Ngôn ngữ X có từ khóa K được dịch, trong AST theo 4 câu: S1, S2, S3 và S4. AST hiện được dịch theo ngôn ngữ Y và lập trình viên thay đổi S2. Bây giờ điều gì xảy ra với bản dịch trở lại X? Mã được dịch là 4 câu thay vì một từ khóa ...

Đối số cuối cùng chống lại cách tiếp cận AST là các chức năng nền tảng: điều gì xảy ra khi một chức năng được nhúng trong nền tảng? Giống như Môi trường của .NET.GetEn Môi trường Biến đổi. Làm thế nào để bạn dịch nó?


4

Có một hệ thống được xây dựng xung quanh ý tưởng này: JetBrains MPS . Một trình soạn thảo hơi kỳ quặc, hoặc chỉ khác nhau, nhưng nói chung nó không phải là một vấn đề lớn như vậy. Vấn đề lớn nhất là, tốt, rằng nó không phải là một văn bản nữa, vì vậy bạn không thể sử dụng bất kỳ công cụ dựa trên văn bản bình thường - biên tập viên khác, grep, sed, hợp nhất và các công cụ diff vv


2
... nhưng bạn có được rất nhiều tính năng soạn thảo. Hãy xem xét mở rộng câu trả lời này một chút, đây là một công nghệ rất thú vị, đáng để đi sâu hơn một chút vào chi tiết về những lợi thế của việc không lưu trữ mã nguồn dưới dạng văn bản. Ví dụ như tôi đã trả lời câu hỏi này trên các tab so với dấu cách .
Steven Jeuris

AST có thể được lưu ở định dạng có thể đọc được của con người và không ở dạng nhị phân. Bây giờ bạn có thể sử dụng các công cụ linux để thay thế mọi phương thức trong mã lấy làm đối tượng tuần tự hóa tham số không? nó sẽ rất khó để viết, nhưng AST làm điều đó rất dễ dàng.
IAd CHƯƠNG 11/11/11

1
Mọi người liên tục mắc lỗi này. AST làm cho nó dễ dàng hơn nếu bạn chỉ có văn bản thô. Nhưng đối với bất cứ điều gì thú vị, bạn cần một loạt thông tin bổ sung: kiểm soát và luồng dữ liệu, bảng biểu tượng, phân tích phạm vi, ... ASTs chỉ là một phần nhỏ của những gì thực sự cần thiết.
Ira Baxter

@Ira Baxter, tất nhiên là dễ dàng hơn với AST. Nhưng khó hơn nhiều để tích hợp vào cơ sở hạ tầng hiện có .
SK-logic

4

Thực tế, có một số sản phẩm, thường được gọi là "bàn làm việc ngôn ngữ" lưu trữ AST và hiện tại, trong các trình soạn thảo của họ, một "phép chiếu" của AST trở lại thành một ngôn ngữ cụ thể. Như @ sk-logic đã nói, MPS của JetBrains là một trong những hệ thống như vậy. Một cái khác là Bàn làm việc có chủ ý của Phần mềm.

Tiềm năng cho các bàn làm việc ngôn ngữ có vẻ rất cao, đặc biệt là trong lĩnh vực ngôn ngữ dành riêng cho tên miền, vì bạn có thể tạo một phép chiếu cụ thể theo miền. Ví dụ, cố ý trình bày một DSL liên quan đến điện dự án dưới dạng sơ đồ mạch - dễ dàng và chính xác hơn cho một chuyên gia miền để thảo luận và phê bình so với mạch được mô tả bằng ngôn ngữ lập trình dựa trên văn bản.

Trong thực tế, các bàn làm việc ngôn ngữ đã bị chậm để bắt kịp bởi vì ngoài công việc DSL, các nhà phát triển có thể thích làm việc trong một ngôn ngữ lập trình chung, quen thuộc. Khi so sánh trực tiếp với một trình soạn thảo văn bản hoặc IDE lập trình, các bàn làm việc ngôn ngữ có hàng tấn chi phí và lợi thế của chúng gần như không rõ ràng. Không có bàn làm việc ngôn ngữ nào tôi từng thấy đã tự khởi động đến mức có thể dễ dàng mở rộng IDE của mình - nghĩa là, nếu bàn làm việc ngôn ngữ tuyệt vời cho năng suất, tại sao công cụ bàn làm việc ngôn ngữ lại trở nên tốt hơn -và tốt hơn với tốc độ nhanh hơn và nhanh hơn?


một "bàn làm việc ngôn ngữ" không nhất thiết phải dựa trên việc lưu trữ AST thô. Chúng cũng có thể được định hướng theo cú pháp văn bản đơn giản, xem ví dụ meta-alternative.net/pfront.pdf (và cái này thực sự mở rộng trình soạn thảo Visual Studio và Emacs với bất kỳ eDSL nào được triển khai trên đầu trang).
SK-logic

Đó là một bài báo thú vị; nó nhắc nhở tôi (trong tham vọng, hoàn toàn không thực hiện) về một công cụ có tên SugarJ đã được trình bày tại SPLASH / OOPSLA vài tuần trước: uni-marburg.de/fb12/ps/research/sugarj
Larry OBrien

Thật thú vị, tôi cũng sẽ thử nó.
SK-logic

3

Bạn đã đọc được suy nghĩ của tôi.

Khi tôi tham gia một khóa học trình biên dịch, một vài năm trước, tôi phát hiện ra rằng nếu bạn lấy AST và tuần tự hóa nó, với ký hiệu tiền tố thay vì ký hiệu infix thông thường và sử dụng dấu ngoặc đơn để phân định toàn bộ câu lệnh, bạn sẽ nhận được Lisp. Trong khi tôi đã học về Scheme (một phương ngữ của Lisp) trong các nghiên cứu đại học của tôi, tôi chưa bao giờ thực sự đạt được sự đánh giá cao về nó. Tôi chắc chắn đã đạt được sự đánh giá cao đối với Lisp và phương ngữ của nó, là kết quả của khóa học đó.

Vấn đề với những gì bạn đề xuất:

  1. thật khó / chậm để soạn AST trong môi trường đồ họa. Rốt cuộc, hầu hết chúng ta có thể gõ nhanh hơn chúng ta có thể di chuyển một con chuột. Chưa hết, một câu hỏi mới nổi là "làm thế nào để bạn viết mã chương trình với máy tính bảng?" Gõ trên máy tính bảng chậm / cồng kềnh, so với bàn phím / máy tính xách tay có bàn phím phần cứng. Nếu bạn có thể tạo AST bằng cách kéo và thả các thành phần từ bảng màu lên khung vẽ trên màn hình lớn, lập trình thiết bị màn hình cảm ứng trên máy tính bảng có thể trở thành một điều thực sự.

  2. vài / không có công cụ hiện có của chúng tôi hỗ trợ này. Chúng tôi có nhiều thập kỷ phát triển trong việc tạo ra các IDE ngày càng phức tạp và các biên tập viên ngày càng thông minh. Chúng tôi có tất cả các công cụ này để định dạng lại văn bản, so sánh văn bản, tìm kiếm văn bản. Đâu là các công cụ có thể thực hiện tương đương với tìm kiếm biểu thức chính quy trên cây? Hay một khác biệt của hai cây? Tất cả những điều này được thực hiện dễ dàng với văn bản. Nhưng họ chỉ có thể so sánh các từ. Thay đổi tên biến, sao cho các từ khác nhau nhưng ý nghĩa ngữ nghĩa là như nhau và các công cụ tìm khác biệt đó gặp rắc rối. Các công cụ như vậy, được phát triển để hoạt động trên AST thay vì văn bản, sẽ cho phép bạn tiến gần hơn đến việc so sánh ý nghĩa ngữ nghĩa. Đó sẽ là một điều tốt.

  3. trong khi việc biến mã nguồn chương trình thành AST tương đối dễ hiểu (chúng ta có trình biên dịch và trình thông dịch, phải không?), biến AST thành mã chương trình không được hiểu rõ lắm. Nhân hai số nguyên tố để có được một số tổng hợp lớn, tương đối đơn giản nhưng việc tìm ra một số tổng hợp lớn trở lại các số nguyên tố khó khăn hơn nhiều; đó là nơi chúng ta đang phân tích cú pháp so với dịch ngược AST. Đó là nơi mà sự khác biệt giữa các ngôn ngữ trở thành một vấn đề. Ngay cả trong một ngôn ngữ cụ thể, có nhiều cách để dịch ngược AST. Lặp lại thông qua một bộ sưu tập các đối tượng và nhận được một số loại kết quả, ví dụ. Sử dụng một vòng lặp for, lặp qua một mảng? Đó sẽ là nhỏ gọn và nhanh chóng, nhưng có những hạn chế. Sử dụng một Iterator của một số loại, hoạt động trên một bộ sưu tập? Bộ sưu tập đó có thể có kích thước thay đổi, giúp tăng thêm tính linh hoạt với chi phí (có thể) về tốc độ. Bản đồ / Giảm? Phức tạp hơn, nhưng ngầm hiểu song song. Và đó chỉ là dành cho Java, tùy thuộc vào sở thích của bạn.

Theo thời gian, nỗ lực phát triển sẽ được mở rộng và chúng tôi sẽ phát triển bằng cách sử dụng màn hình cảm ứng và AST. Đánh máy sẽ trở nên ít cần thiết hơn. Tôi thấy đó là một sự tiến bộ hợp lý từ nơi chúng ta đang ở, nhìn vào cách chúng ta sử dụng máy tính, ngày nay, Điều đó sẽ giải quyết # 1.

Chúng tôi đã làm việc với cây. Lisp chỉ đơn thuần là các AST được tuần tự hóa. XML (và HTML, bởi phần mở rộng) chỉ là một cây được tuần tự hóa. Để thực hiện tìm kiếm, chúng tôi đã có một vài nguyên mẫu: XPath và CSS (tương ứng cho XML và HTML). Khi các công cụ đồ họa được tạo cho phép chúng tôi tạo các bộ chọn và sửa đổi kiểu CSS, chúng tôi sẽ giải quyết được phần 2. Khi các bộ chọn đó có thể được mở rộng để hỗ trợ các biểu thức chính quy, chúng tôi sẽ tiến gần hơn. Vẫn đang tìm kiếm một công cụ khác biệt đồ họa tốt để so sánh hai tài liệu XML hoặc HTML. Khi mọi người phát triển các công cụ đó, # 2 sẽ có thể được giải quyết. Mọi người đã làm việc trên những thứ đó; họ chỉ không có ở đó, chưa.

Cách duy nhất tôi có thể thấy để có thể dịch ngược các AST đó thành văn bản ngôn ngữ lập trình sẽ là thứ gì đó tìm kiếm mục tiêu. Nếu tôi sửa đổi mã hiện có, mục tiêu có thể đạt được bằng thuật toán làm cho mã được sửa đổi của tôi giống với mã bắt đầu nhất (khác biệt văn bản tối thiểu). Nếu tôi viết mã từ đầu, mục tiêu có thể là mã nhỏ nhất, chặt nhất (có thể là vòng lặp for). Hoặc nó có thể là mã song song hiệu quả nhất có thể (có thể là bản đồ / thu nhỏ hoặc thứ gì đó liên quan đến CSP). Vì vậy, cùng một AST có thể dẫn đến mã khác nhau đáng kể, ngay cả trong cùng một ngôn ngữ, dựa trên cách đặt mục tiêu. Phát triển một hệ thống như vậy sẽ giải quyết # 3. Nó sẽ phức tạp về mặt tính toán, có nghĩa là chúng ta có thể cần một số kiểu sắp xếp máy khách-máy chủ,


1

Nếu ý định của bạn là loại bỏ cuộc tranh luận về các kiểu định dạng, thì có lẽ điều bạn muốn là một trình soạn thảo đọc trong tệp nguồn, định dạng nó theo sở thích cá nhân của bạn để hiển thị và chỉnh sửa, nhưng khi lưu nó, hãy định dạng lại theo kiểu đã chọn sử dụng.

Thật dễ dàng nếu bạn sử dụng một trình soạn thảo như Emacs . Thay đổi kiểu định dạng của toàn bộ tệp là một công việc ba lệnh.

Bạn cũng có thể xây dựng các hook để tự động chuyển đổi tệp theo kiểu của riêng bạn khi tải và chuyển đổi nó thành kiểu nhóm khi lưu.


1
Sau đó, bạn sẽ vẫn cần một khác biệt ngữ nghĩa và hợp nhất (nghĩa là, một lần nữa, cấp AST).
SK-logic

Không, trình chỉnh sửa sẽ điều chỉnh lại kiểu nhóm để lưu trữ nguồn - vì vậy bạn sẽ so sánh một loại nguồn với cùng loại.
Gustav Bertram

một điểm tốt, một đại diện chuẩn hóa duy nhất giải quyết tất cả các vấn đề
SK-logic

1
Không, nó chỉ giải quyết các vấn đề về việc kết hợp hai tệp để nhận dạng. Nếu bạn muốn thấy sự khác biệt giữa các tập tin, lý tưởng nhất là bạn cần một cái gì đó hiểu cấu trúc. Tôi yêu emacs của tôi, nhưng nó không hiểu cấu trúc.
Ira Baxter

Emacs là tuyệt vời, nhưng tôi không bao giờ sử dụng nó để tìm khác biệt. Để khác biệt cây nguồn của tôi trước khi đăng ký, tôi luôn sử dụng meld . Nó thực sự hiểu SVN và git. Trên Windows, tôi có thể sử dụng WinMerge kết hợp với rùa.
Gustav Bertram

1

Thật khó để đọc và sửa đổi AST, thay vì mã nguồn.

Tuy nhiên, một số công cụ liên quan đến trình biên dịch không cho phép sử dụng AST. Mã byte Java và mã trung gian .NET hoạt động tương tự như AST.


1
Thật dễ dàng để sửa đổi AST bằng các công cụ cơ học, hơn là làm như vậy với văn bản. Bạn có thể làm điều này với các thay đổi theo hướng mẫu. Xem semanticdesigns.com/
Products / DMS / ProgramTransatures.html

2
Nói điều này với LISPers ngay bây giờ ...
hugomg

@Ira Baxter. Tôi biết, tôi thực sự làm việc trên một công cụ trực quan tùy chỉnh hoạt động trực tiếp với AST, tuy nhiên, đôi khi, các nhà phát triển phải làm việc với văn bản thay vì trực quan. Một số AST cũng được trình bày dưới dạng ngôn ngữ lập trình ngắn hơn trong văn bản.
umlcat

@umlcat, bạn có thể cho tôi biết thêm về công việc của bạn trên một công cụ trực quan cho AST không?
Daniel Albuschat

@Daniel Albuschat Tôi đang làm việc với một dự án ngôn ngữ lập trình thú cưng. Trình phân tích cú pháp rất khó thực hiện, vì vậy tôi bỏ qua nó và tạo một công cụ trong đó tôi hiển thị AST (biểu mẫu với điều khiển treeview) và thêm biểu thức trực tiếp. Và có thể làm ngược lại, tạo mã từ AST.
umlcat

0

đó là một ý tưởng hay; nhưng AST của mỗi ngôn ngữ khác với mọi ngôn ngữ khác.

ngoại lệ duy nhất tôi biết là dành cho VB.NET và C #, trong đó microsoft lập luận rằng chúng là "cùng một ngôn ngữ với các cú pháp khác nhau". Ngay cả các ngôn ngữ .NET khác (IronPython, F #, bất cứ điều gì) cũng khác nhau ở cấp AST.

Điều tương tự với các ngôn ngữ JVM, tất cả chúng đều nhắm đến cùng một mã byte, nhưng các cấu trúc ngôn ngữ khác nhau, làm cho nó trở thành các ngôn ngữ khác nhau và AST khác nhau.

Ngay cả các ngôn ngữ 'lớp mỏng', như CoffeScript và Xtend cũng chia sẻ rất nhiều lý thuyết về các ngôn ngữ cơ bản (JavaScript và Java, tương ứng); nhưng đưa ra các khái niệm cấp cao hơn (hoặc nên) được giữ lại ở cấp AST.

nếu Xtend có thể được xây dựng lại từ Java AST, tôi nghĩ rằng nó đã được định nghĩa là một trình giải mã Java-to-Xtend 'tạo ra sự trừu tượng hóa cấp cao hơn từ mã Java hiện tại, bạn có nghĩ vậy không?


1
Là một người thân thuộc với cả trình biên dịch C # và VB, tôi có thể nói với bạn rằng chúng chắc chắn giống nhau nhưng có đủ các chi tiết quan trọng khác nhau đến mức không thể coi chúng là "cùng một ngôn ngữ với các cú pháp khác nhau". Chúng tôi đã xem xét làm điều đó cho dự án Roslyn; xây dựng một trình biên dịch duy nhất có thể biên dịch cả hai ngôn ngữ với cơ sở bằng nhau - và sau nhiều cuộc tranh luận đã quyết định chọn hai trình biên dịch cho hai ngôn ngữ.
Eric Lippert

@EricLippert: thật đáng xấu hổ. không phải là tôi đã từng lên kế hoạch học một trong hai ngôn ngữ, nhưng nó có vẻ như là một ngoại lệ tốt. Tôi nghĩ htat để lại lisp-like-Dylan và algol-like-Dylan là 'ngôn ngữ giống nhau với ví dụ cú pháp khác nhau'.
Javier
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.