Tiện ích khác biệt ngữ nghĩa [đã đóng]


105

Tôi đang cố gắng tìm một số ví dụ điển hình về các tiện ích khác biệt / hợp nhất ngữ nghĩa. Mô hình truyền thống so sánh các tệp mã nguồn hoạt động bằng cách so sánh các dòng và ký tự .. nhưng có bất kỳ tiện ích nào hiện có (cho bất kỳ ngôn ngữ nào) thực sự xem xét cấu trúc của mã khi so sánh các tệp không?

Ví dụ, các chương trình khác biệt hiện có sẽ báo cáo "sự khác biệt được tìm thấy ở ký tự 2 của dòng 125. Tệp x chứa void, trong đó tệp y chứa bool". Một công cụ chuyên dụng sẽ có thể báo cáo "Kiểu trả về của phương thức doSomething () đã thay đổi từ void thành bool".

Tôi cho rằng loại thông tin ngữ nghĩa này thực sự là thứ mà người dùng đang tìm kiếm khi so sánh mã và nên là mục tiêu của các công cụ giao dịch thế hệ tiếp theo. Có bất kỳ ví dụ nào về điều này trong các công cụ có sẵn không?


3
Có vẻ như đã có một số nghiên cứu được thực hiện về khoảng cách chỉnh sửa cây. Áp dụng điều đó cho AST có vẻ như đây sẽ là điều đầu tiên bạn nên thử. (Nếu ai đó muốn thử viết loại điều này.)
Jay Kominek

2
Tôi không chắc liệu nó có thực sự hữu ích hay không. sự khác biệt như cái bạn đã đề cập dễ thấy hơn là đọc, đặc biệt nếu bạn có một công cụ đánh dấu sự khác biệt trong một dòng. khả năng nhận biết nếu một số mã vừa được di chuyển không thay đổi sẽ dễ dàng và hữu ích hơn, imho!
UncleZeiv 07/02/09

2
@UncleZeiv Tôi hy vọng tính năng đó sẽ tuân theo tự nhiên từ bản chất của công cụ. Bên cạnh đó, nó sẽ có thể phát hiện rằng không có thay đổi nếu có ai đã đi qua và thay đổi cú đúp xoăn hoặc phong cách thụt lề, ví dụ, hoặc sắp xếp lại các tập tin vì vậy phương pháp tĩnh được nhóm, vv ..
jasonmray

8
Tôi cần cái này trong Visual Studio ngay bây giờ. Việc buộc các nhà phát triển trong một nhóm sử dụng cùng một cấu trúc định dạng để tạo điều kiện cho sự khác biệt là suy nghĩ ngược. Mã phải được định dạng theo một số tiêu chuẩn khi đăng ký và bất kỳ khi nào nhà phát triển mở tệp, nó phải được định dạng theo ý thích của họ. Tôi bị sốc rằng kiểu suy nghĩ này không được lan truyền rộng rãi hơn vào thời điểm này.
Langdon

3
IMHO đây là một chủ đề tốt cho SO. Nếu bạn đồng ý điều này, hãy bỏ phiếu để "mở cửa lại"
Ira Baxter

Câu trả lời:


37

Chúng tôi đã phát triển một công cụ có thể giải quyết chính xác tình huống này. Kiểm tra http://www.semanticmerge.com

Nó hợp nhất (và khác biệt) dựa trên cấu trúc mã và không sử dụng các thuật toán dựa trên văn bản, về cơ bản cho phép bạn giải quyết các trường hợp như sau, liên quan đến cấu trúc lại mạnh mẽ. Nó cũng có thể hiển thị cả sự khác biệt và xung đột hợp nhất như bạn có thể thấy bên dưới:

nhập mô tả hình ảnh ở đây

Và thay vì bối rối với các khối văn bản được di chuyển, vì nó phân tích cú pháp trước, nó có thể hiển thị các xung đột trên cơ sở mỗi phương thức (trên thực tế là mỗi phần tử). Một trường hợp như trước thậm chí sẽ không có xung đột thủ công để giải quyết.

nhập mô tả hình ảnh ở đây

Nó là một công cụ hợp nhất nhận biết ngôn ngữ và thật tuyệt khi cuối cùng có thể trả lời câu hỏi SO này :-)


Có thể tích hợp nó với SVN không?
Dự kiến

1
Tuy nhiên, phiên bản Linux và Mac là phiên bản cổ.
Michael Piefel

29

Eclipse đã có tính năng này từ lâu. Nó được gọi là "So sánh cấu trúc", và nó rất hay. Đây là một ảnh chụp màn hình mẫu cho Java, tiếp theo là một ảnh chụp màn hình khác cho tệp XML:

(Lưu ý các biểu tượng dấu trừ và dấu cộng trên các phương thức trong ngăn phía trên.)

Trình so sánh cấu trúc Java của Eclipse Trình so sánh cấu trúc XML của Eclipse


3
So sánh cấu trúc có cho phép bạn hợp nhất các thay đổi giống như các trình chỉnh sửa hợp nhất kiểm soát nguồn khác không? Tức là Sao chép phương pháp này từ phiên bản này sang phiên bản khác.
Jonathan Parker

1
Có, khi bạn chọn một thay đổi hoặc khác biệt (ở ngăn trên hoặc ngăn dưới), các nút trên thanh công cụ (hiển thị trong ảnh chụp màn hình) cung cấp cho bạn tùy chọn để sao chép thay đổi từ trái sang phải hoặc ngược lại.
Hosam Aly

1
Rất tiếc, ảnh chụp màn hình không còn hiển thị trong câu trả lời (được ủng hộ cao nhất và được chấp nhận!) Của bạn. Bạn có thể gửi lại chúng không?
blubb

@blubb Cảm ơn đã thông báo cho tôi. Tôi đã sửa lỗi với hình ảnh Java Comparer. Tôi sẽ sớm thêm ảnh chụp màn hình cho Trình so sánh cấu trúc XML.
Hosam Aly

1
Và điều đó có hoạt động với các ngôn ngữ khác ngoài Java không?
einpoklum

14

Để làm tốt "so sánh ngữ nghĩa", bạn cần so sánh cây cú pháp của các ngôn ngữ và tính đến ý nghĩa của các ký hiệu. Một khác biệt ngữ nghĩa thực sự tốt sẽ hiểu ngữ nghĩa của ngôn ngữ và nhận ra khi nào một khối mã tương đương với chức năng khác. Đi xa đến mức này cần một câu châm ngôn về định lý, và mặc dù nó sẽ cực kỳ dễ thương, nhưng hiện tại không thực tế cho một công cụ thực sự.

Một phép gần đúng khả thi của điều này chỉ đơn giản là so sánh các cây cú pháp và báo cáo các thay đổi về cấu trúc được chèn, xóa, di chuyển hoặc thay đổi. Tiến gần hơn đến "so sánh ngữ nghĩa", người ta có thể báo cáo khi một số nhận dạng được thay đổi nhất quán trên một khối mã.

Hãy xem http://www.semanticdesigns.com/Products/SmartDifferencer/index.html của chúng tôi để biết công cụ so sánh dựa trên cây cú pháp hoạt động với nhiều ngôn ngữ, thực hiện ước lượng ở trên.

CHỈNH SỬA tháng 1 năm 2010: Các phiên bản có sẵn cho C ++, C #, Java, PHP và COBOL. Trang web hiển thị các ví dụ cụ thể cho hầu hết những điều này.

CHỈNH SỬA Tháng 5 năm 2010: Python và JavaScript được thêm vào.

CHỈNH SỬA Tháng 10 năm 2010: Đã thêm EGL.

EDIT tháng 11 năm 2010: VB6, VBScript, VB.net được thêm vào


2
Xin chào Ira, bạn đã xuất bản một bài báo về thuật toán khác biệt của mình chưa? Tôi đang gặp sự cố khi tìm tài liệu khác về khoảng cách chỉnh sửa cây. Cảm ơn, Terence.
Terence Parr,

Để cụ thể hơn, tìm kiếm diff3 diff2 không đơn giản
Terence Parr

2
@Terence: Không có công bố nào về thuật toán khác biệt của chúng tôi. Đây là một phép tính khoảng cách tối thiểu của Levenstein bằng cách sử dụng cây hậu tố để xác định các cây con bằng nhau, với một số huerstics để xử lý việc đổi tên. IIRC, Yang đã có một bài báo về vấn đề này trong Thực hành và Kinh nghiệm Phần mềm. Của chúng tôi và của Yang là khác nhau2, không khác biệt3.
Ira Baxter

@IraBaxter Liên kết hiện đã bị hỏng và trang web dường như không hoạt động khi mở từ liên kết google.
Răzvan Flavius ​​Panda

Trang web đã được sao lưu, liên kết sẽ ổn.
Ira Baxter,

12

Những gì bạn đang tìm hiểu là một "cây khác biệt". Nó chỉ ra rằng điều này khó làm tốt hơn nhiều so với một sự khác biệt văn bản hướng dòng đơn giản, mà thực sự chỉ là sự so sánh của hai chuỗi phẳng.

" Phương pháp tiếp cận so sánh cấu trúc XML chi tiết " kết luận một phần với:

Nghiên cứu lý thuyết cũng như đánh giá thực nghiệm của chúng tôi cho thấy rằng phương pháp đề xuất mang lại kết quả tương tự về cấu trúc được cải thiện so với các giải pháp thay thế hiện có, đồng thời có cùng độ phức tạp về thời gian (O (N ^ 2))

(nhấn mạnh của tôi)

Thật vậy, nếu bạn đang tìm kiếm thêm ví dụ về sự khác biệt cây, tôi khuyên bạn nên tập trung vào XML vì nó đang thúc đẩy những phát triển thực tế trong lĩnh vực đó.


Cảm ơn các liên kết. Tôi có thể nghĩ ra một vài cách tiếp cận khác nhau để triển khai các công cụ khác biệt sematic, và bạn đã đúng - hầu hết có thể được trừu tượng hóa thành "điểm khác biệt cây". Các tình huống phức tạp hơn thậm chí có thể cần được trừu tượng hóa thành một "đồ thị khác biệt".
jasonmray

Đúng vậy. Rational Modeler của IBM (được xây dựng trên nhật thực) cố gắng thực hiện điều này với các mô hình UML (hiển thị sự khác biệt giữa hai mô hình bằng đồ thị). Tôi không thể bình luận về tính hữu ích của kết quả vì tôi không sử dụng nó nhiều.
bentin

Tôi đồng ý rằng XML là một nơi tốt để bắt đầu, vì bạn có thể đơn giản đưa ra các lược đồ để đại diện cho các cấu trúc khác (chẳng hạn như mã java chẳng hạn) và sử dụng một khác biệt cây dựa trên XML để triển khai một khác biệt mã.
jasonmray

"do this" => làm điều gì đó tương tự như "đồ thị khác biệt".
uốn cong

1
Xem semdesigns.com/Products/SmartDifferencer/index.html để biết công cụ so sánh dựa trên cây cú pháp hoạt động với nhiều ngôn ngữ.
Ira Baxter


2

Giải pháp cho điều này sẽ dựa trên cơ sở ngôn ngữ. Tức là trừ khi nó được thiết kế với một kiến ​​trúc plugin xác định rất nhiều phân tích cú pháp mã thành một cây và so sánh ngữ nghĩa với một plugin ngôn ngữ cụ thể thì sẽ rất khó hỗ trợ nhiều ngôn ngữ. Bạn quan tâm đến (các) ngôn ngữ nào khi có một công cụ như vậy. Cá nhân tôi thích một cái cho C #.

Đối với C #, có một bổ trợ khác lắp ráp cho Reflector nhưng nó chỉ tạo ra sự khác biệt trên IL không phải C #.

Bạn có thể tải xuống bổ trợ khác tại đây [zip] hoặc truy cập dự án trên trang codeplex tại đây .


1
Xem semdesigns.com/Products/SmartDifferencer/index.html để biết công cụ so sánh dựa trên cây cú pháp hoạt động với nhiều ngôn ngữ, sử dụng chính xác kiểu plugin ngôn ngữ. Vẫn chưa được phát hành, nhưng một phiên bản C # đã rất gần.
Ira Baxter

Tháng 1 năm 2010: C # Smart Differencer được phát hành.
Ira Baxter

2

Một công ty tên là Zynamics cung cấp một công cụ khác biệt ngữ nghĩa cấp nhị phân. Nó sử dụng một ngôn ngữ meta-assembly gọi là REIL để thực hiện phân tích lý thuyết đồ thị của 2 phiên bản của một nhị phân và tạo ra một biểu đồ được mã hóa màu để minh họa sự khác biệt giữa chúng. Tôi không chắc chắn về giá cả, nhưng tôi nghi ngờ nó là miễn phí.


Liên kết đến khác biệt ngữ nghĩa cấp nhị phân: zynamics.com/bindiff.html
emallove

2

http://prettydiff.com/

Pretty Diff thu nhỏ từng đầu vào để loại bỏ các nhận xét và khoảng trắng không cần thiết, sau đó làm đẹp mã trước thuật toán khác biệt. Tôi không thể nghĩ về cách nào để trở nên mã nhiều ngữ nghĩa hơn thế này. Và, JavaScript được viết của nó để nó chạy trực tiếp trong trình duyệt.


5
Sau đó, bạn có một trí tưởng tượng hạn chế! Còn về việc hoán đổi vị trí của hai phương thức trong một tệp mà vẫn giữ nguyên chúng thì sao? Điều gì về tái cấu trúc?
Robin Green

(Bạn không thể hoán đổi các khai báo dữ liệu trong Java theo cách này, và vẫn có sự tương đương, do các trình khởi tạo; Tôi giả sử C # cũng có những rắc rối tương tự). Nếu bạn đi tìm sự khác biệt ngữ nghĩa thuần túy, thì bạn đang cố gắng giải quyết sự tương đương của máy Turing. Có rất nhiều phạm vi để thực hiện đối sánh văn bản thuần túy tốt hơn và tệ hơn là không thể Turing.
Ira Baxter

@IraBaxter Công cụ về mặt khái niệm rõ ràng sẽ chỉ hiển thị dưới dạng những thứ tương đương mà thực sự là tương đương. Nếu được mã hóa đúng cách, nó sẽ không có loại vấn đề mà bạn đang đề cập.
Răzvan Flavius ​​Panda

"Được mã hóa đúng cách" có nghĩa là chứng minh sự tương đương của thuật toán nếu bạn muốn có công cụ tối ưu. Các chứng minh tương đương thuật toán nói chung là khó Turing, vì vậy bạn sẽ không có được một công cụ như vậy trong thực tế. Những gì bạn có thể nhận được là một công cụ xử lý một số trường hợp tương đương khác ngoài những thay đổi về cú pháp. Cho đến nay, tôi chưa thấy ai cố gắng tạo ra một công cụ như vậy.
Ira Baxter,
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.