Чому використання лексера / парсера для двійкових даних так неправильно?


13

Я часто працюю з лексером / парсерами , на відміну від комбінатора парсера і бачу людей, які ніколи не брали клас на розбір, запитують про розбір бінарних даних. Зазвичай дані не тільки двійкові, але й контекстно-залежні. Це в основному призводить до наявності лише одного типу токена, лексеми для байта.

Чи може хтось пояснити, чому розбір бінарних даних за допомогою лексера / аналізатора настільки неправильний з достатньою чіткістю для студента CS, який не взяв клас розбору, але з опорою на теорію?


Я здогадуюсь, що лексер, ймовірно, не може знайти лексеми, менші за байт / слово. Якщо вам це потрібно, Erlang має чудову підтримку для розбору бінарних файлів: user.it.uu.se/~pergu/papers/JFP_06.pdf
Дейв Кларк

3
Я не думаю, що ваше припущення є правдивим. Очевидно, що безконтекстні дані створюють проблеми (які часто можна обійти), але ви можете дати граматики для двійкових слів. Напевно, ви не зможете використовувати популярні генератори парсера, оскільки вони передбачають введення тексту. Але це вже інше питання.
Рафаель

@GuyCoder: Багато класичні приклади граматик використовувати бінарні алфавіти, наприклад , . S0S10S
Рафаель

1
28

5
@GuyCoder: Усі дані, що генеруються іншою програмою, можуть бути описані граматикою. Це, можливо, не є контекстним.
Рафаель

Відповіді:


10

В принципі, нічого поганого немає.

На практиці,

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

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

    Потім ви можете почати грати трюки, як, наприклад, записаний вручну лексер, здатний впоратися з цим зворотним зв'язком з аналізатора (lex / yacc обробка C використовує такі типи, наприклад, для обробки typedef). Але тоді ми приходимо до другого пункту.

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


"мови є регулярними" Якщо ", але також контекстно-чутливими", що означають, що двійкові дані є граматикою, я уточню у відповіді. Це стосується частини проблеми; люди схильні думати граматики або звичайні мови, як тільки ви згадуємо парсер.
Гай Кодер

7

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

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

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

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

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

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


2
Це хороша перспектива, але я відчуваю, що вона не відповідає на питання.
Рафаель

LANGSEC: Language-theoretic Securityпропонує цікаву перспективу. В одній із статей йдеться про "дивні машини": спеціальні аналізатори відомого формату, що утворюють засоби управління вхідними системами. Вони можуть насправді не працювати за призначенням. Через неправильні припущення, несправна машина буде виконувати непередбачувані переходи стану, даючи особливо продуманий вхід, виконуючи обчислення, які не повинні бути можливими. Це створює вектор атаки. Використання формальних граматик дало б достовірно правильні алгоритми.
Матей Морейра

0

a+b×(cd)+e(+ a (* b (- c d)) e)a b c d - * + e +. Звичайні математичні позначення мають більше надмірності, ніж Lisp (що вимагає більшої кількості дужок, але отримує змінні артури безкоштовно, тому потрібно менше символів для вираження виразів за допомогою великих артій) або RPL (який ніколи не потребує дужок). Така надмірність рідко корисна для комп'ютерів - і там, де вона є, що може виникнути помилки в даних, логіка виправлення помилок зазвичай тримається окремо від функціонального значення даних, наприклад, використовуючи коди виправлення помилок, які застосовуються до довільних послідовності байтів незалежно від того, що вони представляють.

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

Ще один фактор проти нетривіальних аналізаторів бінарних даних полягає в тому, що багато бінарних форматів розроблені так, щоб вони були проаналізовані кодом низького рівня, який любить працювати в постійній пам'яті з невеликими накладними витратами. Фіксовані розміри бажані, коли застосовні, щоб дозволити довільне повторення елемента. Такий формат, як TLV, який дозволяє ліворуч-правому аналізатору спершу виділити потрібний об'єм пам'яті для об'єкта, а потім прочитати представлення об'єкта. Розбір зліва направо є перевагою, оскільки дозволяє обробляти дані в міру надходження, без проміжного буфера.


Який сенс у перших двох абзацах? Навіть якщо у вас немає надмірності, вам потрібен аналізатор. Крім того, перший абзац невірний: є приклади, коли всі слова дозволені, але ви розбираєтесь, щоб отримати структуру (наприклад, передбачення вторинної структури РНК).
Рафаель

@Raphael Нетривіальний аналізатор зазвичай передбачає надмірність (так, як ви зазначаєте, є винятки). Я не вважав мовами, призначеними ні для людей, ні для комп'ютерів, це цікавий приклад. Перші два абзаци обговорюють типові відмінності між бінарними та читаними людьми форматами (типовий сенс, що якщо ви шукаєте винятки, ви їх знайдете).
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.