Шукаєте чіткого визначення того, що таке «токенізатор», «парсер» та «лексери» та як вони пов’язані між собою та використовуються?


151

Я шукаю чіткого визначення того, що таке "токенізатор", "аналізатор" і "лексер" і як вони пов'язані один з одним (наприклад, чи використовує аналізатор токенізатор чи навпаки)? Мені потрібно створити програму буде проходити через вихідні файли c / h для витягування декларації даних та визначень.

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

Я переглядав Вікіпедію на такі теми та програми, як Lex та Yacc, але ніколи не пройшов клас компілятора (EE major), мені важко повністю зрозуміти, що відбувається.

Відповіді:


166

Токенізатор розбиває потік тексту на лексеми, зазвичай, шукаючи пробіли (вкладки, пробіли, нові рядки).

Лексер - це в основному лексема, але він зазвичай прикріплює додатковий контекст до лексем - цей маркер є числом, цей маркер є рядковим літералом, цей інший маркер є оператором рівності.

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

Останнє, що я перевірив, найкращою книгою на цю тему була "Укладачі: принципи, методи та засоби", зазвичай відома як "Книга Дракона".


8
Без сумніву, "Книга Драконів" - це хороша книга, але вона вимагає від читача гарного підґрунтя в CS. Деяка книга з більш практичним зверненням - «Написання укладачів та перекладачів» Рональда Мака, «Сучасна реалізація компілятора», Ендрю Апель; "Конструкція компілятора", Niklaus Wirth; "Компіляція з C # та Java" та "Компілятори та генератори компіляторів: вступ із C ++" Пат Террі; і, звичайно, "остаточний довідник ANTLR" Терренса Парра.
Андре Артус

5
Просто для впевненості, я не збиваю вашої рекомендації. "Книга Драконів" була моєю першою книгою про компіляторну техніку, але це було важко в порівнянні, скажімо, з книгою Вірта, що є книгою, яку можна пограбувати за кілька годин. Тоді у мене було небагато варіантів, оскільки це була єдина книга, яку я міг взяти на руки (це був 1991 рік, перед Amazon і WWW). У мене було це і колекція текстових файлів, виготовлена ​​Джеком У. Креншо, під назвою "ПОБУДИМО БУДІТЬ КОМПЛІКЕР" (спасибі Джеку!). Це все ще книга для більш повного розуміння принципів, але більшості програмістів просто потрібен прагматичний вступ.
Андре Артус

10
Я не погодився б, що аналізатор / за визначенням / створює абстрактне синтаксичне дерево. Парсери можуть виробляти всілякі різні виходи. Наприклад, звичайно, що аналізатор виробляє послідовність викликів до якогось інтерфейсу будівельника - див. Шаблон будівельника в книзі шаблонів «Банда чотирьох». Ключовим моментом є те, що аналізатор аналізує послідовність лексем, щоб визначити, чи відповідає послідовність деякій (як правило, вільній від контексту) граматиці і може дати деякий вихід на основі граматичної структури послідовності.
Теодор Норвелл

2
"Зробимо компілятор" тут: compilers.iecc.com/crenshaw . Я знайшов посилання звідси: prog21.dadgum.com/30.html
Роджер Ліпскомб

1
@Pithkos: якщо це єдині обмеження, все, що ви сказали, це функція, яка приймає вхід в одному безіменному (математичному) домені і виробляє та виводить в інший безіменний домен, наприклад, F (X) -> Y Досить багато це означає ви можете назвати це лише функцією. Якщо ви наполягаєте на тому, що домен X є <StreamOfCharacter, Grammar>, а домен Y - дерево, властивістю, що він відображає форму граматики, то F (X, G) -> T було б щось, що я б назвав a аналізатор. Ми часто маємо F відносно G, оскільки G не змінюється часто, тому F [G] (X) -> T - це те, що ти зазвичай бачиш як аналізатор.
Іра Бакстер

18

Приклад:

int x = 1;

Лексери або маркери розділять це на лексеми 'int', 'x', '=', '1', ';'.

Аналізатор візьме ці лексеми і використає їх для розуміння певним чином:

  • у нас є заява
  • це визначення цілого числа
  • ціле число називається "x"
  • 'x' має бути ініціалізовано зі значенням 1

9
Лексер зазначає, що "int", "=" та ";" є лексемами без подальшого значення, що "x" - це ім'я ідентифікатора чи щось таке, значення "x", а "1" - ціле число або число, значення "1". Токенізатор не обов'язково робити це.
Девід Торнлі

5

Я б сказав, що лексери та токенізатори - це одне і те ж, і вони розбивають текст на його складові частини ("лексеми"). Потім аналізатор інтерпретує лексеми за допомогою граматики.

Я б не надто зациклювався на точному термінологічному використанні, хоча люди часто використовують «розбір», щоб описати будь-яку дію інтерпретації грудочки тексту.


1
З PEG-аналізаторами різниця між токенізатором і аналізатором ще менш зрозуміла.
Андре Артус

0

( додавання до поданих відповідей )

  • Tokenizer також видалить будь-які коментарі та поверне лише лексеми до Lexer.
  • Лексер також визначить сфери дії для цих жетонів (змінні / функції)
  • Parser тоді створить структуру коду / програми

1
Привіт @downvoter, чи можете ви детальніше пояснити, чому ви насправді робили ставку?
Корай Тугай

1
Я не переслідувач, але я думаю, що голосування може бути тому, що ваша відповідь не здається правильною. Токенізатор може видаляти шум (як правило, пробіл, але, можливо, також коментарі), але він часто не подає лексеру. Лексер на основі DFA буде токенізувати та ідентифікувати, що таке лексеми (наприклад, число, рядок, ідентифікатор, але також пробіл чи коментар), але він не може їх обширити, оскільки для цього знадобиться дерево синтаксису, яке згодом будується аналізатор
Lucero

1) Я не розумію вашого розрізнення між "лексером" та "токенізатором". Я створив парсери для 50+ мов, і ніколи не було двох окремих механізмів, які розбивають вихідний текст на атоми, тому для мене це просто синоніми. 2) Якщо ви збираєте, видалення коментарів та пробілів має сенс у лексемі. Якщо ви створюєте інструменти трансформації від джерела до джерела, ви не можете втрачати коментарі, оскільки вони повинні з’являтися знову в перетвореному тексті. Тому ВИНАГИ видаляти коментарі неправильно; ми можемо сперечатися про те, як вдається зберегти пробіл. ...
Іра Бакстер

1
... [Інструменти, які я будую (див. Мою біографію), охоплюють обох з належною вірністю для відтворення їх у перетвореному коді; ми йдемо далі, і фіксуємо формат атомів, включаючи дивні речі, такі як лапки, що використовуються на символьних рядках, і радіо / провідний нульовий підрахунок чисел, все на службі уникнути відхилення користувачем трансформованого результату. Отже, те, що ви пропустили, - це не тільки те, що лексери не обов'язково знімають інформацію, але насправді їм може знадобитися захоплення інформації вище та поза нераціональним символом] ....
Іра Бакстер

... 3) Лексери визначають лише "сфери" в безнадійно незграбних аналізаторах, які важко обробляють синтаксичні неоднозначності. C і C ++ парсери є канонічним прикладом; дивіться мою дискусію на сайті stackoverflow.com/a/1004737/120163 ). Не треба робити це (потворно). Тож я вважаю вашу відповідь просто помилковою.
Іра Бакстер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.