Semantic Diff Utilities [zamknięte]


105

Próbuję znaleźć dobre przykłady semantycznych narzędzi do porównywania / scalania. Tradycyjny paradygmat porównywania plików z kodem źródłowym polega na porównywaniu wierszy i znaków… ale czy istnieją narzędzia (dla dowolnego języka), które uwzględniają strukturę kodu podczas porównywania plików?

Na przykład, istniejące programy porównujące będą raportować „różnicę znalezioną w znaku 2 wiersza 125. Plik x zawiera void, gdzie plik y zawiera bool”. Specjalistyczne narzędzie powinno być w stanie zgłosić „Zwracany typ metody doSomething () zmieniony z void na bool”.

Twierdziłbym, że tego typu informacje semantyczne są w rzeczywistości tym, czego szuka użytkownik podczas porównywania kodu, i powinny być celem narzędzi programistycznych nowej generacji. Czy są jakieś przykłady tego w dostępnych narzędziach?


3
Wygląda na to, że przeprowadzono pewne badania dotyczące odległości edycji drzewa. Zastosowanie tego do AST wydaje się być pierwszą rzeczą, którą należy spróbować. (Gdyby ktoś chciał spróbować napisać coś takiego.)
Jay Kominek

2
Nie jestem pewien, czy to naprawdę by się przydało. różnica taka jak ta, o której wspomniałeś, jest łatwiejsza do zauważenia niż odczytania, zwłaszcza jeśli masz narzędzie podkreślające różnice w linii. możliwość rozpoznania, czy jakiś kod został właśnie przeniesiony w niezmienionej postaci, byłaby łatwiejsza i bardziej użyteczna, imho!
UncleZeiv

2
@UncleZeiv Mam nadzieję, że ta funkcja naturalnie wynikałaby z natury narzędzia. Ponadto byłby w stanie wykryć, że nie ma zmian, gdyby ktoś przeszedł i zmienił na przykład nawiasy klamrowe lub style wcięć lub przestawił plik, aby zgrupować metody statyczne itp.
jasonmray

8
Potrzebuję tego teraz w programie Visual Studio. Zmuszanie programistów w zespole do używania tej samej struktury formatowania w celu ułatwienia różnic jest myśleniem wstecz. Kod powinien być sformatowany zgodnie z jakimś standardem podczas wpisywania, a za każdym razem, gdy programista otwiera plik, powinien być sformatowany według własnych upodobań. Jestem zszokowany, że ten rodzaj myślenia nie jest obecnie bardziej rozpowszechniony.
Langdon

3
IMHO to dobry temat dla SO. Jeśli się na to zgodzisz, głosuj na „ponowne otwarcie”
Ira Baxter

Odpowiedzi:


37

Opracowaliśmy narzędzie, które jest w stanie precyzyjnie poradzić sobie z takim scenariuszem. Sprawdź http://www.semanticmerge.com

Scala (i różnicuje) na podstawie struktury kodu i nie używa algorytmów tekstowych, co w zasadzie pozwala radzić sobie z przypadkami podobnymi do poniższych, obejmujących silną refaktoryzację. Jest również w stanie renderować zarówno różnice, jak i konflikty scalania, jak widać poniżej:

wprowadź opis obrazu tutaj

I zamiast mylić się z przenoszonymi blokami tekstu, ponieważ najpierw analizuje, jest w stanie wyświetlić konflikty na podstawie metody (w rzeczywistości dla każdego elementu). Sprawa taka jak poprzednia nie będzie miała nawet ręcznych konfliktów do rozwiązania.

wprowadź opis obrazu tutaj

Jest to narzędzie do scalania uwzględniające język i wspaniale było móc wreszcie odpowiedzieć na to pytanie SO :-)


Czy można go zintegrować z SVN?
Revious

1
Jednak wersje dla Linuksa i Maca są starożytne.
Michael Piefel

29

Eclipse ma tę funkcję od dawna. Nazywa się „Porównanie struktur” i jest bardzo przyjemne. Oto przykładowy zrzut ekranu dla języka Java, a następnie drugi dla pliku XML:

(Zwróć uwagę na ikony minus i plus na metodach w górnym panelu).

Narzędzie porównywania struktur Java firmy Eclipse Narzędzie do porównywania struktur XML firmy Eclipse


3
Czy porównywanie struktur umożliwia scalanie zmian, podobnie jak inne edytory scalające kontroli źródła? To znaczy skopiuj tę metodę z tej wersji do innej wersji.
Jonathan Parker

1
Tak, po wybraniu zmiany lub różnicy (w górnym lub dolnym okienku) przyciski paska narzędzi (pokazane na zrzutach ekranu) dają możliwość skopiowania zmiany od lewej do prawej lub odwrotnie.
Hosam Aly

1
Niestety zrzuty ekranu nie są już widoczne w Twojej (najwyżej ocenionej i zaakceptowanej!) Odpowiedzi. Czy mógłbyś przesłać je ponownie?
blubb

@blubb Dzięki za powiadomienie mnie. Poprawiłem błąd z obrazem Java Comparer. Wkrótce spróbuję dodać zrzut ekranu dla porównywarki struktur XML.
Hosam Aly

1
I czy to działa w językach innych niż Java?
einpoklum

14

Aby dobrze wykonać „porównania semantyczne”, należy porównać drzewa składniowe języków i wziąć pod uwagę znaczenie symboli. Naprawdę dobra różnica semantyczna rozumiałaby semantykę języka i zdawała sobie sprawę, kiedy jeden blok kodu byłby równoważny funkcji z innym. Posunięcie się tak daleko wymaga dowodzenia twierdzeniem i chociaż byłoby to niezwykle urocze, nie jest obecnie praktyczne dla prawdziwego narzędzia.

Użytecznym przybliżeniem tego jest po prostu porównanie drzew składni i raportowanie zmian pod względem wstawionych, usuniętych, przeniesionych lub zmienionych struktur. Zbliżając się nieco do „porównania semantycznego”, można by zgłosić, że identyfikator jest zmieniany konsekwentnie w całym bloku kodu.

Zobacz naszą http://www.semanticdesigns.com/Products/SmartDifferencer/index.html, aby zapoznać się z mechanizmem porównywania opartym na drzewie składni, który działa z wieloma językami i wykonuje powyższe przybliżenie.

EDYCJA, styczeń 2010: Dostępne wersje dla C ++, C #, Java, PHP i COBOL. Witryna zawiera konkretne przykłady większości z nich.

EDYCJA Maj 2010: Dodano Python i JavaScript.

EDYCJA Październik 2010: dodano EGL.

EDYCJA listopad 2010: dodano VB6, VBScript, VB.net


2
Cześć Ira, czy opublikowałeś artykuł o swoim algorytmie porównywania? Mam problem ze znalezieniem literatury na temat różnic odległości przy edycji drzewa. Dzięki, Terence.
Terence Parr

Mówiąc dokładniej, szukam diff3 nie plain diff2
Terence Parr

2
@Terence: Nie ma publikacji naszego algorytmu diff. Jest to obliczenie minimalnej odległości Levensteina przy użyciu drzew sufiksowych do identyfikacji równych poddrzew, z pewnymi parametrami huerstics do obsługi zmiany nazwy. IIRC, Yang miał artykuł na ten temat w Software Practice and Experience. Nasze i Yang to diff2, a nie diff3.
Ira Baxter

@IraBaxter Link jest obecnie uszkodzony, a witryna wydaje się nie działać podczas otwierania z linku Google.
Răzvan Flavius ​​Panda

Witryna została utworzona, łącze powinno być w porządku.
Ira Baxter

12

To, czego szukasz, to "różnica drzew". Okazuje się, że jest to o wiele trudniejsze do wykonania niż prosta tekstowa różnica zorientowana liniowo, która jest tak naprawdę tylko porównaniem dwóch płaskich sekwencji.

Podejście do szczegółowego porównania strukturalnego XML ” kończy się częściowo następująco:

Nasze badanie teoretyczne, a także ocena eksperymentalna wykazały, że proponowana metoda daje lepsze wyniki podobieństwa strukturalnego w odniesieniu do istniejących alternatyw, mając jednocześnie złożoność czasową (O (N ^ 2))

(podkreślenie moje)

Rzeczywiście, jeśli szukasz więcej przykładów różnicowania drzew, proponuję skupić się na XML, ponieważ jest to motorem praktycznych zmian w tej dziedzinie.


Dzięki za link. Przychodzi mi do głowy kilka różnych podejść do implementacji narzędzi do porównywania sematycznego, i masz rację - większość z nich można wyabstrahować w "różnicach drzewiastych". Bardziej złożone sytuacje mogą nawet wymagać wyodrębnienia w postaci „różnicy grafów”.
jasonmray

Tak. IBM Rational Modeler (zbudowany na eclipse) próbuje to zrobić z modelami UML (pokazując graficznie różnice między dwoma modelami). Nie mogę komentować przydatności wyników, ponieważ nie używam ich zbyt często.
bendin

Zgadzam się, że XML jest dobrym miejscem do rozpoczęcia, ponieważ można po prostu wymyślić schematy reprezentujące inne struktury (na przykład kod java) i użyć drzewa różnicowego opartego na XML, aby zaimplementować różnicę w kodzie.
jasonmray,

"do this" => zrób coś podobnego do "graph diff".
bendin

1
Zobacz semdesigns.com/Products/SmartDifferencer/index.html, aby zapoznać się z mechanizmem porównywania opartym na drzewie składni, który działa w wielu językach.
Ira Baxter


2

Rozwiązanie tego problemu byłoby zależne od języka. To znaczy, jeśli nie jest zaprojektowany z architekturą wtyczek, która odracza wiele przetwarzania kodu do drzewa i porównania semantycznego z wtyczką specyficzną dla języka, bardzo trudno będzie obsługiwać wiele języków. W jakich językach chciałbyś mieć takie narzędzie. Osobiście chciałbym jeden dla C #.

W przypadku języka C # istnieje dodatek diff zestawu do Reflector, ale robi to tylko różnicę w IL, a nie C #.

Możesz pobrać dodatek diff tutaj [zip] lub przejść do projektu w witrynie codeplex tutaj .


1
Odwiedź stronę semdesigns.com/Products/SmartDifferencer/index.html, aby zapoznać się z mechanizmem porównywania opartym na drzewie składni, który działa z wieloma językami, używając dokładnie tego stylu wtyczki językowej. Jeszcze nie wydana, ale wersja C # jest bardzo bliska.
Ira Baxter

Styczeń 2010: Wydanie C # Smart Differencer.
Ira Baxter

2

Firma o nazwie Zynamics oferuje narzędzie do porównywania semantycznego na poziomie binarnym. Używa meta-asemblera zwanego REIL, aby przeprowadzić analizę teoretyczną dwóch wersji pliku binarnego i tworzy kolorowy wykres ilustrujący różnice między nimi. Nie jestem pewien ceny, ale wątpię, że jest darmowa.


Link do różnicy semantycznej na poziomie binarnym: zynamics.com/bindiff.html
emallove

2

http://prettydiff.com/

Pretty Diff minimalizuje każde wejście, aby usunąć komentarze i niepotrzebne białe znaki, a następnie upiększa kod przed algorytmem porównywania. I tak nie mogę myśleć o tym, aby stać się bardziej semantycznym kodem niż to. I ma napisany JavaScript, więc działa bezpośrednio w przeglądarce.


5
Wtedy masz ograniczoną wyobraźnię! A co z zamianą pozycji dwóch metod w pliku, pozostawiając je niezmienione? A co z refaktoryzacjami?
Robin Green

(Nie możesz w ten sposób zamieniać deklaracji danych w Javie i nadal masz równoważność ze względu na inicjatory; zakładam, że C # ma podobne problemy). Jeśli wybierzesz czysty semantyczny diff, to próbujesz rozwiązać równoważność maszyny Turinga. Jest wiele możliwości uzyskania lepszego dopasowania niż zwykłe dopasowanie tekstu i gorzej niż Turinga niemożliwego.
Ira Baxter

@IraBaxter Koncepcyjnie narzędzie będzie oczywiście wyświetlać tylko jako równoważne rzeczy, które w rzeczywistości są równoważne. Jeśli jest prawidłowo zakodowany, nie będzie miał typu problemu, o którym wspominasz.
Răzvan Flavius ​​Panda

„Prawidłowo zakodowane” oznacza udowodnienie równoważności algorytmów, jeśli chcesz mieć najlepsze narzędzie. Dowody równoważności algorytmów są generalnie trudne według Turinga, więc nie zdobędziesz takiego narzędzia w praktyce. To, co możesz otrzymać, to narzędzie, które obsługuje niektóre równoważności inne niż tylko zmiany składni. Do tej pory nie widziałem nikogo, kto próbowałby zbudować takie narzędzie.
Ira Baxter
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.