Це команда pretzel, яку можна запустити в безкоштовному хостинг-провайдері OnWorks за допомогою однієї з наших безкоштовних онлайн-робочих станцій, таких як Ubuntu Online, Fedora Online, онлайн-емулятор Windows або онлайн-емулятор MAC OS
ПРОГРАМА:
ІМ'Я
pretzel - універсальний генератор prettyprinter
СИНТАКСИС
крендель [-qtgdh] [-o вихідний файл] префікс файлу
крендель [-qtgdh] [-o вихідний файл] файл1 файл2
ОПИС
Pretzel — це програма, яка створює модуль prettyprinter з формального опису
спосіб, у який певна мова має бути красиво надрукована. А красивий принтер є функцією або
програма, яка змінює вихідний код для покращення його читабельності. Створено Prettyprinters
by pretzel вивести вихідний код LaTeX, який можна використовувати у ваших власних документах. NB що
крендель виробляє Модулі, а не програми!
Ви повинні надати два вхідних файли pretzel, які вказують спосіб заданого вихідного коду
має бути красиво надруковано. Ці два файли називаються відформатовано знак файл (суфікс .ft)
і відформатовано граматика файл (суфікс .fg).
З цих вхідних даних pretzel генерує дві речі: дійсний flex(1) файл, який формує
prettyprinting сканер і дійсний бізон(1) вхідний файл, який можна використовувати для створення
prettyprinting аналізатор (це фактично prettyprinter). Є сценарій оболонки
крендель-це що полегшує використання кренделя (див крендель-це(1)). Ця довідкова сторінка лише призначена
як коротка довідка про використання кренделів. Перегляньте основну документацію pretzel, якщо ви
є новими для всього цього.
Викликаючи кренделек
Виклик pretzel може мати дві форми: або викликати його, вказавши лише загальний префікс
два файли введення або вкажіть обидва файли окремо в командному рядку. Якщо ви вкажете
обидва файли, відформатований файл маркера буде першим.
прикладів
Скажімо, викликаються ваші вхідні файли foo.ft та foo.fg. Тоді можна сказати
кренделек Foo
правильно викликати крендель. Якщо ваші файли називаються foo.ft та bar.fg тоді ви мали б
сказати
кренделек foo.ft bar.fg
виконати роботу.
ВАРІАНТИ
Крендель розпізнає такі варіанти:
-q Біжи тихо.
-t Обробляти лише відформатований файл маркера.
-g Обробити лише відформатований файл граматики (параметри -t та -g є взаємними
ексклюзив).
-d Друк інформації про налагодження на екрані.
-h Роздрукувати повідомлення про повне використання.
-o ім'я
Скористайтесь ім'я як префікс згенерованих вихідних файлів.
THE ВХІД ФАЙЛИ
У цьому розділі коротко описано формат вхідних файлів і формат команда примітиви
що крендель підтримує.
Команда відформатовано знак файл
Відформатований файл маркерів містить список визначень маркерів із відповідними їм
«гарнодрукована» форма. Красиво друкована форма токена буде називатися an атрибут або
переклад.
Загальна структура відформатованого файлу маркера така
декларацій
%%
знак Визначення
Як правило, в декларацій частина порожня. Можна поставити загальний опис файлу
тут (як коментар C), а також перевизначення типового інтерфейсу.
Команда знак Визначення розділ відформатованого файлу маркерів містить серію маркерів
визначення форми:
модель знак атрибут
Команда модель має бути дійсним регулярним виразом (з точки зору flex(1)) і має бути
без відступу. The знак вказує символічне ім'я маркера для шаблону і починається
на першому непробілному символі після шаблону. Назва токена має бути законною
ім'я для ідентифікатора в нотації Pascal і повинен be всі in верхній справа (Підкреслення є
дозволено, але не на початку слова.)
Команда атрибут оскільки цей маркер, тобто його гарна друкована форма, складається з усього тексту
між двома дужками для завивки { та }. Атрибути можуть бути простими рядками
(у подвійних лапках), команди форматування (див. нижче), ваш власний код C++ (включений у
кутові кронштейни [ та ], див. нижче) або поєднання обох, об’єднаних разом
необов'язковий + знак. Визначення атрибутів можуть охоплювати кілька рядків і початок { не потрібно
стояти на одному рядку з визначенням лексеми; однак наступні рядки мають мати відступ
з принаймні одним порожнім або однією вкладкою.
Якщо ви визначаєте рядки як частину визначення атрибута, ви повинні вказати їх у C
типу моди, тобто ви можете вставляти нові рядки та табуляції за допомогою \n та \t. Але якщо ти хочеш
вставте зворотну косу риску в рядок, не забудьте поставити дві зворотні косі риски \\ в
вхідний файл. Це особливо важливо, якщо ви використовуєте TeX як верстальщик.
Якщо визначення атрибута пропущено, pretzel створює для цього атрибут
шаблон за замовчуванням. Атрибут за замовчуванням складається з рядка, що містить текст
зіставляється за відповідним зразком.
Сам користувач також може звернутися до відповідного тексту за допомогою послідовності **. Таким чином
"foo" BAR
"foo" BAR { ** }
"foo" BAR { "foo" }
всі мають однакове значення.
Можна використовувати a | знак як назва лексеми; це означає, що поточний регулярний вираз має
те саме ім'я маркера (а також той самий атрибут), що й маркер, указаний нижче
рядок (порожні рядки ігноруються). Визначення атрибута за a | є незаконним. Проте
ви можете вказати регулярні вирази без назви токена або атрибута для надання a
правило за замовчуванням або з’їдати пробіли.
Оголошення та визначення токенів мають бути розділені рядком, який містить лише
два символи %%.
прикладів
Наведені нижче приклади є законними визначеннями токенів:
[0-9] ЦИФРОВИЙ
"{" ВІДЧИНЕНО { "\\{" відступ змусити }
[az][a-z0-9]* ID { "{\\це " ** "}" }
"функція" |
"процедура" PROC_INTRO { велика_сила + ** }
[\t\ \n] |
.
Команда відформатовано граматика файл
У відформатованому файлі граматики користувач кодує загальну граматику prettyprinting для
мова програмування. Це робиться шляхом визначення контекстно-вільної граматики мови
і шляхом додавання інформації про створення нових атрибутів у кожне правило. Його заг
контур виглядає так:
знак декларацій
%%
граматика Правила
Команда знак декларацій розділ може бути порожнім, а роздільник між двома частинами
файл %% має відображатися без відступу в одному рядку.
Команда граматика Правила Розділ містить збірку правил контекстно-вільної граматики
який може супроводжуватися визначенням атрибута. Правило уточнюється шляхом формулювання
результуюча лексема, двокрапка, а потім ряд лексем, які будуть скорочені за цим правилом.
Правило закінчується крапкою з комою. Наприклад, визначення блоку в Pascal може виглядати так
це:
блок : ПОЧАТИ stmt_list END ;
Після списку маркерів у правій частині двокрапки може бути визначення атрибута;
це визначення визначає, як переклад виробленого символу отримується з
жетони в правій частині правила.
Визначення атрибута взято в квадратні дужки { та } і може знову складатися
рядків (у подвійних лапках), команд форматування або коду C (в кутових дужках [
та ], див. нижче), об’єднаних необов’язковим +. Але тут також можна звернутися до
атрибути токенів у правій частині правила. Це робиться трохи незручно
позначення з числом, якому передує a $ знак долара. Цифри стосуються
порядок появи символів у правій частині правила. Так $1 відноситься до
перший знак правила, $2 до другого і так далі.
Знову ж таки, визначення атрибутів можуть охоплювати кілька рядків і рядків
вказаний способом C.
Визначення атрибута можна опустити. Якщо це так, крендель за замовчуванням сформує
атрибут створеного символу з простого об’єднання атрибутів на
права сторона правила. Звичайно, у вас також можуть бути порожні праві частини правила (до
виробляти речі з нічого) або просто об’єднувати два або більше правил, що призводить до
той самий символ з a |.
Для кожного термінального маркера, який з’являється в правилах граматики, має бути спеціальний рядок
записано в розділі оголошень файлу. Ці визначення мають вигляд
%токен ім'я токена
Про це дуже важливо не забувати.
прикладів
Наприклад, тут знову можливе визначення блоку в Pascal, тепер із an
приклад визначення атрибута:
блок : ПОЧАТИ stmt_list END { $1 $2 змусити $3 } ;
Атрибут a блок тому складатиметься з атрибутів ПОЧАТИ та
stmt_list лексеми, об'єднані разом з a змусити командування та переклад в END
лексема.
Ці два рядки означають те саме:
stmt : блок SEMI ;
stmt : блок SEMI { $1 $2 } ;
Це теж правові норми:
stmt_list : { змусити }
| stmt_list stmt SEMI { $1 $2 $3 змусити };
Коментарі та код
Існує дуже простий спосіб вставити коментарі у відформатований маркер і відформатувати
файли граматики. Це робиться на кшталт C++ шляхом додавання перед коментарем подвійного символу
слеш //. Усі символи між цим знаком і кінцем рядка ігноруються
кренделі.
В обох файлах ви можете розмістити додатковий код C/C++ до та після визначень/граматики
розділи. Якщо ви хочете вставити код у кінець файлу, вам потрібно поставити другий %%
в окремому рядку та помістіть код за ним. Код C/C++ перед визначеннями/правилами
розділ повинен бути пов'язаний з a %{, %} пара. Вставка додаткового коду цікава для
люди, які хочуть отримати до нього доступ із визначення атрибута.
код в атрибут Визначення
Починаючи з версії 2.0, крендель дозволяє вставляти код C++ у визначення атрибутів.
Ось як pretzel очікує від вас написання коду у ваших вхідних файлах pretzel:
Фрагменти коду взяті в кутові дужки. Будь-які кутові дужки, які з’являються
у коді C необхідно екранувати зворотною скісною рискою. Перед і можуть бути блоки коду
за визначенням атрибута, які викликаються початок код та закінченнякод. Тільки один
дозволений початковий або кінцевий блок коду. Обидва абсолютно необов’язкові, але якщо ви хочете
вкажіть або або, вам потрібне визначення атрибута. Початковий код виконується перед
будується атрибут нового токена, завершальний код виконується після створення атрибута
і перед поверненням до функції виклику (у сканері).
Частини коду в визначеннях атрибутів повинні повертати вказівник на an атрибут об'єкт класу
(див. файл attr/attr.nw у розподілі кренделів для деталей). У межах форматованого
файл маркера, відповідний текст буде видимим для вас у формі a char * yytext змінна. Файл
символічні назви токенів доступні за тією самою назвою, яку їм дає pretzel.
Початковий код, код у визначеннях атрибутів і кінцевий код абсолютно необов’язкові. Але
у будь-якому місці, де вони дозволені, може бути розміщений лише один біт коду в дужках. Ось
приклад із відформатованого файлу граматики:
id : ID { [пошук($1) ? create("{\\bf ") :
create("{\\it ")] $1 "}" };
У цьому прикладі показано, як форматувати ідентифікатор залежно від того, чи є він у пошуку
стіл чи ні. Ідентифікатори можна встановити в таблицю, наприклад, так:
typedef : TYPEDEF_LIKE INT_LIKE ID
[ встановити ($3); ]
{ $1 $2 "{\\bf " $3 "}" };
Більше прикладів можна знайти в Pretzelbook. Загальні підпрограми для екранування ідентифікаторів
створювати та керувати таблицями пошуку для перетворення в і з Атрибут* або для виведення налагодження
інформацію можна знайти у файлах, що належать C prettyprinter у каталозі
мови / cee розподілу кренделів.
Команда комплект of формат Команди
Ось список команд форматування, які підтримує крендель, і їх значення:
нулю пуста команда.
відступ робить відступ наступного рядка трохи більше.
відступ
повертає останній відступ (зменшує відступ).
змусити примусово розрив рядка.
break_space
позначає можливий пробіл для розриву рядка.
варіант 1...варіант 9
позначає необов'язковий розрив рядка з рядком продовження з невеликим відступом
відносно нормального вихідного положення.
резервна копія позначає невеликий пропуск.
велика_сила
примусово розрив рядка та вставляє трохи додаткового пробілу.
без_відступу
змушує поточний рядок виводитися вліво.
відмінити стирає будь-які break_space, вибирати, змусити or велика_сила команду, що негайно
передує або йде за ним, а також скасовує будь-який резервна копія наступна за ним команда.
Щоб отримати повну довідкову інформацію про те, як писати крендель, перегляньте Pretzelbook
який входить до розподілу кренделів.
сформований команда попередня обробка
Команди форматування попередньо обробляються відповідно до наступних двох правил:
1. Послідовність послідовних
break_space, змусити, і / або велика_сила команди замінено однією командою (the
максимум із заданих).
2. відмінити команда скасовує будь-які break_space, вибирати, змусити or велика_сила наказує це
безпосередньо передувати або слідувати за ним, а також скасовувати будь-які резервна копія наступна команда
його.
THE ВИХІД ФАЙЛИ
Якщо pretzel працює без помилок, ви отримаєте визначення класу prettyprinter C++
у вигляді двох файлів. Перший файл дійсний бізон(1) файл, з якого фактично
можна отримати клас парсера prettyprinting. Другий файл (генерується з відформатованого
файл маркерів) можна обробити за допомогою flex(1) генератор сканера для формування красивого друку
клас сканера, який використовується аналізатором.
Команда бізон файл
Згенерований файл bison містить визначення для класу аналізатора prettyprinting, який
є підкласом наступного абстрактного базового класу (міститься у файлі Pparse.h в
крендель включає каталог):
#включати
#include"attr.h"
#include"output.h"
клас Pparse {
громадськості:
Pparse() {};
~Pparse() {};
віртуальний Int prettyprint(istream*, ostream*) = 0;
віртуальний Int prettyprint(istream*, Вихід*) = 0;
};
prettyprinter, створений pretzel, буде підкласом такої форми:
#включати Pparse.h // включати абстрактний база клас
клас PPARSE_NAME : громадськість Pparse {
громадськості:
PPARSE_NAME(); ~PPARSE_NAME();
Int prettyprint(istream*, ostream*);
Int prettyprint(istream*, Вихід*);
анулювати debug_on(); анулювати debug_off();
};
Ім'я класу можна змінити шляхом перевизначення макросу препроцесора PPARSE_NAME
у відформатованому файлі граматики. Справжня функція prettyprinting красивий відбиток Що
читає текст із вхідного потоку (тобто C++ istream об’єкт) і виводить результати в an
вихідний потік (тобто C++ ostream об'єкт, див ios(3C++)). Друга перевантажена версія
of красивий відбиток приймає Вихід об'єкт (див. файл вихід/вихід.nw і крендельбук
у дистрибутиві pretzel для деталей) і використовує це для виведення коду prettyprinted.
Команда відлагоджувати функції можна використовувати для перетворення виводу налагодження на cerr включення і виключення.
Команда flex файл
Клас парсера prettyprinting покладається на службу сканера prettyprinting, який може
виготовляти за допомогою другого файлу для кренделів. Він містить повне визначення сканера
підклас цього абстрактного базового класу (див. файл Pscan.h у каталозі pretzel include):
#включати #include"attr.h"
клас Pscan {
громадськості:
Pscan (istream*) {}; ~Pscan() {};
віртуальний Int сканування (атрибут**) = 0;
};
Сканер має бути ініціалізований за допомогою C++ istream покажчик, з якого він отримує вхідні дані.
Дзвінок до актуального сканування функція повертає ціле число (код маркера просто
відскановано або 0 у кінці файлу), а також атрибут виклику за посиланням, що містить вміст
токен (див. файл attr/attr.nw від розподілу кренделів).
Створений клас сканера prettyprinting є підкласом і виглядає так:
#включати Pscan.h // включати абстрактний база клас
клас PSCAN_NAME : громадськість Pscan {
громадськості:
PSCAN_NAME(istream*);
~PSCAN_NAME();
Int сканування (Атрибут**);
Ім’я сканера можна змінити у відформатованому файлі маркера шляхом перевизначення
PSCAN_NAME макрос у розділі оголошень. Клас сканера очікує знайти маркер
визначень, спільних для сканера та аналізатора у файлі під назвою ptokdefs.h і буде намагатися
щоб включити цей файл. Ви повинні надати цей файл самостійно або скористатися -d варіант
Bison, щоб створити такий, який відповідає відформатованій граматиці (див бізон(1)). Ви можете змінити
ім'я файлу, який сканер очікує шляхом перевизначення PTOKDEFS_NAME макрос в
розділ декларацій відформатованого файлу маркерів. Заголовні файли коментарів до анотації
базові класи та підкласи за замовчуванням знаходяться в каталозі включення кренделя.
Використовуйте pretzel онлайн за допомогою сервісів onworks.net