Семантичні комунальні послуги [закрито]


105

Я намагаюся знайти кілька хороших прикладів семантичних утиліт diff / merge. Традиційна парадигма порівняння файлів вихідного коду працює, порівнюючи рядки та символи .. але чи існують там утиліти (для будь-якої мови), які насправді враховують структуру коду при порівнянні файлів?

Наприклад, існуючі програми diff повідомлять про "різницю, знайдену у символі 2 рядка 125. Файл x містить пустоту, де файл y містить bool". Спеціалізований інструмент повинен мати змогу повідомляти "Тип повернення методу doSomething () змінено з void на bool".

Я можу стверджувати, що цей тип семантичної інформації - це насправді те, що користувач шукає при порівнянні коду, і має бути метою інструментів прогмінгу нового покоління. Чи є приклади цього в доступних інструментах?


3
Схоже, було проведено деякі дослідження щодо відстані редагування дерева. Застосовуючи це до AST, схоже, це було б першим, що потрібно спробувати. (Якщо хтось хотів спробувати написати таку річ.)
Джей Комінек,

2
Я не впевнений, чи справді це було б корисно. різниця на зразок тієї, яку ви згадали, легше помітити, ніж прочитати, особливо якщо у вас є інструмент, що виділяє відмінності в рядку. можливість розпізнати, якщо якийсь код щойно переміщений незмінним, було б простіше і корисніше, imho!
UncleZeiv

2
@UncleZeiv Я сподіваюся, що ця функція, природно, випливатиме з характеру інструменту. Крім того, можна було б виявити, що немає змін, якби хтось пройшов і змінив фігурні фігури дужок або відступ, наприклад, або змінив файл так, щоб статичні методи були згруповані тощо.
jasonmray

8
Мені це потрібно зараз у Visual Studio. Змусити розробників в команді використовувати одну і ту ж структуру форматування для полегшення різниці - це відстале мислення. Код повинен бути відформатований під деякий стандарт при реєстрації, і кожного разу, коли розробник відкриє файл, його слід відформатувати за власним смаком. Я шокований, що таке мислення не має більшого поширення на даний момент.
Ленґдон

3
ІМХО, це тонка тема для ТА. Якщо ви згодні з цим, проголосуйте за "повторне відкриття"
Іра Бакстер

Відповіді:


37

Ми розробили інструмент, який здатний точно впоратися з цим сценарієм. Перевірте http://www.semanticmerge.com

Він об'єднує (і відрізняється) на основі структури коду і не використовує текстові алгоритми, що в основному дозволяє розглядати такі випадки, залучаючи сильний рефактор. Він також може відображати як відмінності, так і конфлікти злиття, як ви бачите нижче:

введіть тут опис зображення

І замість того, щоб плутати з переміщенням текстових блоків, оскільки він аналізує спочатку, він може відображати конфлікти на основі методу (фактично за кожним елементом). Випадок, як попередній, навіть не може вирішити конфлікти вручну.

введіть тут опис зображення

Це мовний інструмент злиття, і було чудово нарешті відповісти на це питання :-)


Чи можливо інтегрувати його у SVN?
Ревізований

1
Однак версії Linux та Mac давні.
Майкл Піефель

29

Затемнення давно відчувало цю особливість. Це називається "Порівняйте структуру", і це дуже приємно. Ось зразковий скріншот для Java з подальшим ще одним для XML-файлу:

(Зверніть увагу на значки мінус і плюс для методів у верхній частині.)

Порівняння структури Java Eclipse Порівняння XML структури Eclipse


3
Чи дозволяє Структура Порівняння дозволяє об'єднувати зміни, як інші редактори злиття керування джерелами? Т.е. Скопіюйте цей метод з цієї версії в іншу.
Джонатан Паркер

1
Так, коли ви вибираєте зміну чи різницю (у верхній чи нижній панелях), кнопки панелі інструментів (показані на знімках екрана) дають можливість скопіювати зміни зліва направо або навпаки.
Хосам Алі

1
На жаль, скріншоти більше не видно у вашій (найвищої та прийнятій!) Відповіді. Чи можете ви надіслати їх ще раз?
блека

@blubb Дякуємо за повідомлення. Я виправив помилку із зображенням Java Comparer. Я спробую незабаром додати скріншот для XML Structure Comparer.
Хосам Алі

1
І чи це працює для інших мов, крім Java?
einpoklum

14

Щоб добре зробити «смислові порівняння», вам потрібно порівняти синтаксичні дерева мов та врахувати значення символів. Дійсно хороша семантична різниця зрозуміла б мовну семантику і зрозуміла, коли один блок коду був еквівалентний за функцією іншому. Досягнення цього далеко вимагає доказів теореми, і, хоча це було б надзвичайно мило, наразі не є практичним для реального інструменту.

Працездатним наближенням цього є просто порівняння синтаксичних дерев та повідомлення про зміни в частині вставлених, видалених, переміщених чи змінених структур. Дещо наблизившись до "семантичного порівняння", можна було повідомити, коли ідентифікатор послідовно змінюється через блок коду.

Дивіться наш http://www.semanticdesigns.com/Products/SmartDifferencer/index.html для механізму порівняння на основі синтаксису, який працює на багатьох мовах, і це робить вищенаведене наближення.

EDIT січня 2010 року: доступні версії для C ++, C #, Java, PHP та COBOL. На веб-сайті представлені конкретні приклади більшості з них.

EDIT травня 2010 року: додано Python та JavaScript.

EDIT Жовтень 2010: EGL додано.

EDIT Листопад 2010: Додано VB6, VBScript, VB.net


2
Привіт Іра, ти опублікував статтю про свій алгоритм різниці? У мене виникають проблеми з пошуком літератури для редагування дерев на відстані. Спасибі, Теренсе.
Теренс Парр

Якщо бути більш конкретним, шукайте diff3 не просто diff2
Теренс Парр

2
@Terence: Не існує жодної публікації нашого алгоритму різниці. Це обчислення Левенштейна на мінімальній відстані, використовуючи дерева суфіксів для ідентифікації рівних підкреслень, з деякими характеристиками для перейменування. IIRC, Ян виступив з доповіддю про це в практиці та досвіді програмного забезпечення. Наші та Ян - це diff2, не diff3.
Іра Бакстер

@IraBaxter Посилання на даний момент розірвано, і, здається, сайт не працює при відкритті з google посилання.
Разван Флавій Панда

Сайт резервний, посилання має бути в порядку.
Іра Бакстер

12

Те, що ви робите, - це "різниця дерев". Виявляється, зробити це набагато складніше, ніж простий текстовий розріз, орієнтований на лінійку, що насправді є лише порівнянням двох плоских послідовностей.

" Дрібнозернистий підхід до структурного порівняння XML " завершується, зокрема, наступним:

Наше теоретичне дослідження, а також наша експериментальна оцінка показали, що запропонований метод дає покращені результати структурної схожості стосовно існуючих альтернатив, маючи однакову складність у часі (O (N ^ 2))

(наголос мій)

Дійсно, якщо ви шукаєте більше прикладів розрізнення дерев, пропоную зосередитись на XML, оскільки це сприяє практичним розробкам у цій галузі.


Дякуємо за посилання. Я можу придумати декілька різних підходів до впровадження інструментів різної різниці, і ви вірні - більшість можна абстрагуватись до "дерева різниць". Складніші ситуації, можливо, навіть повинні бути абстраговані в "графіку різниці".
jasonmray

Так. Rational Modeler IBM (побудований на затемненні) намагається це зробити з моделями UML (графічно показуючи відмінності між двома моделями). Я не можу коментувати корисність результатів, оскільки я не дуже її використовую.
бендін

Я погоджуюся, що XML - це гарне місце для початку, оскільки ви можете просто створити схеми для представлення інших структур (наприклад, java-коду), а також використовувати дерево-diff на основі XML для реалізації коду diff.
jasonmray

"зробити це" => зробити щось схоже на "графік розл."
бендін

1
Див. Semdesigns.com/Products/SmartDifferencer/index.html для механізму порівняння на основі синтаксичного дерева, який працює з багатьма мовами.
Іра Бакстер


2

Вирішення цього питання може здійснюватися на основі кожної мови. Тобто, якщо це не розроблено з архітектурою плагінів, яка відкладає багато розбору коду на дерево і семантичного порівняння з мовним плагіном, тоді буде дуже важко підтримувати кілька мов. Якими мовами ви цікавитесь, щоб мати такий інструмент. Особисто мені хотілося б одного для C #.

Для C # є доповнення для складання Ref до рефлектора, але це робить лише відмінності на IL, а не на C #.

Ви можете завантажити розширення diff тут [zip] або перейти до проекту на сайті codeplex тут .


1
Дивіться semdesigns.com/Products/SmartDifferencer/index.html для механізму порівняння на основі синтаксичного дерева, який працює з багатьма мовами, використовуючи саме стиль мовного модуля. Ще не випущено, але версія C # дуже близька.
Іра Бакстер

Січень 2010: Випущено C # Smart Differencer.
Іра Бакстер

2

Компанія під назвою Zynamics пропонує інструмент семантичного розбору на двійковому рівні. Він використовує мову мета-збірки під назвою REIL для виконання графіко-теоретичного аналізу двох версій двійкового файла та створює кольорово-графічний графік для ілюстрації відмінностей між ними. Я не впевнений у ціні, але сумніваюся, що вона безкоштовна.


Посилання на семантичну різницю
emallove

2

http://prettydiff.com/

Pretty Diff мінімізує кожен вхід, щоб видалити коментарі та зайвий пробіл, а потім прикрасить код перед алгоритмом diff. Я не можу думати про те, щоб стати більш кодовою семантикою, ніж ця. І, його письмовий JavaScript, так що він працює безпосередньо в браузері.


5
Тоді у вас обмежена фантазія! А як щодо заміни позицій двох методів у файлі, залишаючи їх незмінними? Що з рефактори?
Робін Грін

(Ви не можете змінювати обмін деклараціями даних на Java таким чином, і все ще маєте еквівалентність через ініціалізатори; я вважаю, що у C # є подібні проблеми). Якщо ви використовуєте чисто смислові відмінності, то ви намагаєтеся вирішити еквівалентність машини Тьюрінга. Існує велика кількість можливостей для кращого порівняння чистого тексту та гіршого, ніж Тьюрінга неможливого.
Іра Бакстер

@IraBaxter Інструмент концептуально, очевидно, показуватиме лише еквівалентні речі, які насправді є рівнозначними. Якщо правильно зашифровано, він не матиме типу проблеми, який ви згадуєте.
Разван Флавій Панда

"Правильно закодований" означає доведення еквівалентності алгоритму, якщо ви хочете остаточний інструмент. Докази еквівалентності алгоритму загалом є твердими по Тюрінгу, тому такий інструмент на практиці не збирається. Ви можете отримати інструмент, який обробляє деякі еквіваленти, окрім лише змін синтаксису. На сьогоднішній день я не бачив, щоб хтось намагався створити такий інструмент.
Іра Бакстер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.