Оригинал статьи доступен на cs.rit.edu.

Це сайт Джей, LALR(1) генератор синтаксичних аналізаторів: Berkeley yacc © перенаправлені на C# і Java:

  • Використання
  • Вхідний формат
  • Дженеріки
  • Файли основи
  • Управління класом
  • Завантаження

Використання

jay читає граматичну специфікацію з файлу і генерує для неї парсер LALR (1). Синтаксичний аналізатор складається з набору таблиць синтаксичного аналізу та підпрограми драйвера на наборі, який рахується від стандартного вводу. Відповідні набори існують для Java і C#. Таблиці і драйвер записуються в стандартний висновок.

jay [-ctv] [-b file-prefix] grammar skeleton|<skeleton

java -jar jay.jar [-ctv] [-b file-prefix] grammar skeleton|<skeleton

Доступні наступні параметри:

— b file-prefix змінює префікс, що додається до імен вторинних вихідних файлів, на рядок, що позначається file_prefix. Префікс за замовчуванням є символ y.

— c організовує директиви #line препроцесора C, які будуть включені в вивід. Це корисно тільки для C#.

— t організовує налагоджувальну інформацію для включення у вихідні дані. Фактична інформація контролюється файлами набору; оскільки вона поширюється, вона залежить від додаткових пакунків середовища виконання. Для C# це частина завантаження вихідного коду, для Java — jay.yydebug.

— v змушує опис згенерованого парсера для людського сприйняття записуватись у файл file_prefix.output.

Якщо задана одна з змінних оточення TMPDIR, TMP або TEMP, то в якості імені директорії, в якій створюються тимчасові файли, буде використовуватися рядок змінної середовища.

Вхідний формат

Формат введення і алгоритм LALR (1) не були змінені з yacc. Вам слід звернутися до обширної літератури по yacc, щоб отримати докладні відомості про написання і налагодження граматики, виправлення помилок, стратегій дій і т. д.

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

Директива %union була видалена. jay використовує Object (або System.Object з C#) для стека значень. Отже, ім’я в позначенні тегу <name> відноситься до класу або інтерфейсу.

Це має значення для привидів, які генерує jay: ні C#, ні Java не дозволяють присвоюватись наведеним змінним. Таким чином, позначення $ $ відноситься до об’єкта без приведення, оскільки $ $ зазвичай присвоюється. Якщо $$ використовується для інших цілей, він зазвичай повинен буде використовувати явний тип $<name>$, який перетворюється на приведення до name.

Аналогічно, позначення $n присвоюється рідко. Тому, jay створює роль, якщо нотація $<>N використовується для запобігання закидання.

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

jay поняття не має про наслідування. Це може призвести до появи необґрунтованих попереджувальних повідомлень зі скаргами на сумнівні призначення. Було визнано, що ці повідомлення в цілому корисні, навіть якщо деякі з них є помилковими.

Генерики

Таблиці та скелетні файли jay не використовують параметризовані типи. jay.yydebug кодується без параметризованих типів, однак вихідники містять код з дженериками в рядках, які на даний момент закоментовані.

Позначення <tag> може містити вкладені кутові дужки і всередині них символи [] blank ? , на додаток до звичайних буквено-цифрових . $ _ . Однак посилання на стек значень $ n наводяться з використанням відповідного тега, і приведення до параметризованого типу викличе неперевірене попередження в Java.

Клас парсера може бути позначений як @SuppressWarnings («неперевірений»); однак, в той час як це може бути варіантом для Java 5, і це ймовірно, нерозумно.

Файли набору

Двійкове або вихідне завантаження включає два скелетних файли для Java і один для C#. Файл набору управляє форматом створюваних таблиць і включає в себе фактичний алгоритм парсера, який інтерпретує таблиці. Алгоритми однакові у всіх розподілених файлах, але skeleton.tables ініціалізують різні таблиці, читаючи файл ресурсу під час виконання; це уникає межі, яку система Java накладає на розмір сегмента коду для класу.

Щоб створити файл ресурсів, створіть синтаксичний аналізатор за допомогою skeleton.tables. З вихідного коду парсера витягніть рядки, що починаються з / / yy, і видаліть саме цей префікс. Отриманий файл повинен знаходитися в тому ж каталозі, що й файл класу аналізатора, і повинен використовувати ім’я класу аналізатора і суфікс .tables.

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

t позначає рядок, який має відношення до трасування. Зазвичай він копіюється з / / t; якщо встановлено параметр -t, рядок копіюється без провідного t.

Нарешті, рядок з початковим пробілом містить команду, яка приводить до висновку деякої табличної інформації і яка може використовувати іншу частину рядка в якості параметра.

actions видають код з дій як тіло switch.

epilog видає текст, що слідує за другим %%.

local виділяє текст В % { % } після першого %%.

prolog видає текст в межах % { % } до першого%%.

tokens prefix створює кожне значення маркера в якості ініціалізованого ідентифікатора, а решту рядка-в якості префікса.

version comment створює коментар / / з рештою рядка.

yyCheck prefix   виділіть тіло відповідної таблиці з залишком рядка в якості префікса для кожного вихідного рядка.

yyDgoto prefix

yyGindex prefix

yyLen prefix

yyLhs prefix

yyRindex prefix

yySindex prefix

yyTable prefix

yyFinal prefix видає значення як ініціалізатор із залишком рядка в якості префікса.

yyNames prefix видає таблицю у вигляді списку слів, а залишок рядка – у вигляді префікса для кожного вихідної рядка.

yyNames-strings видають таблицю як список рядкових ініціалізаторів.

yyRule prefix видає таблицю у вигляді списку рядків, а залишок рядка — у вигляді префікса для кожної вихідної лінії.

yyRule-strings видають таблицю як список рядкових ініціалізаторів.

Кожна таблиця передує коментарю з інформацією про вимірювання.

Управління класами

Дизайн файлу скелета повинен враховувати дві проблеми: як вбудувати парсер в клас і як взаємодіяти зі сканером.

Розподілені файли набору очікують, що користувач надасть prolog у % { % }, що містить заголовок класу, і epilog після другого%%, який закриває цей клас. jay не знає ім’я класу аналізатора.

Інтерфейс до сканера yyInput генерується як член кожного класу парсера; це може бути або не бути хорошим вибором. Існує три методи: advance немає аргументів, і повинне повертатися логічне значення, яке вказує, що сканер успішно вибрав наступний вхідний символ; token не має аргументів і повинен повертати поточний вхідний символ як цілочисельне значення, на яке очікує парсер; value не має аргументів і повертає значення об’єкта для розміщення на статусі/значення стека для вводу символу. Трасування очікує, що маркер і значення будуть постійними функціями між кожним викликом для просування.

Явні значення токенів генеруються як константи в класі парсера. Одиночні символи представляють себе; однак для тих, які Jay сприймає в ASCII, а не в наборі символів Unicode. Можливо, було б краще визначити константи в інтерфейсі сканера, але очікується, що сканер реалізований як внутрішній клас аналізатора. pj підтримує це уявлення, навіть якщо сканер явно створений з використанням JLex.

Завантажити

Версія:

1.1.1, червень 2006 року.

Автор:

Аксель Т. Шрейнер.