{"id":16156339,"url":"https://github.com/ilyabizyaev/pascal-parser","last_synced_at":"2025-04-07T01:17:11.517Z","repository":{"id":163656785,"uuid":"229158489","full_name":"IlyaBizyaev/pascal-parser","owner":"IlyaBizyaev","description":"Pascal array declaration parser for the Translation Methods course at ITMO","archived":false,"fork":false,"pushed_at":"2019-12-20T19:11:03.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-13T06:43:04.930Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IlyaBizyaev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-20T00:05:40.000Z","updated_at":"2019-12-20T19:11:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"6278c295-97f3-4695-8a5f-3faccde7d91f","html_url":"https://github.com/IlyaBizyaev/pascal-parser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaBizyaev%2Fpascal-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaBizyaev%2Fpascal-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaBizyaev%2Fpascal-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaBizyaev%2Fpascal-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IlyaBizyaev","download_url":"https://codeload.github.com/IlyaBizyaev/pascal-parser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247574092,"owners_count":20960497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T01:44:40.172Z","updated_at":"2025-04-07T01:17:11.495Z","avatar_url":"https://github.com/IlyaBizyaev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Лабораторная работа №2. Ручное построение нисходящих синтаксических анализаторов.\n## Вариант 9. Описание массивов в Паскале\n\n*Илья Бизяев, курс «Методы трансляции», ИТМО, 2019*\n\n### Формулировка задания\nМассив в Pascal. Заголовок начинается ключевым словом `var`, далее идёт имя массива,\nдвоеточие, ключевое слово `array`, далее описание диапазона индексов, затем `of` и\nимя типа. Диапазон индексов представляет собой две границы, между которыми две точки.  \nИспользуйте один терминал для всех имен переменных и имен типов. Используйте один\nтерминал для ключевого слов `var` и `array` (не несколько `v`, `a`, `r`).  \nПример: `var x: array [1..10] of integer`;\n\n### Грамматика\nПостроим грамматику для указанного класса выражений:\n\n| Нетерминал              | Описание                                                     |\n| ----------------------- | ------------------------------------------------------------ |\n| `S -\u003e V X : A [D] O T;` | Массив в Pascal состоит из V — ключевого слова `var`, X — имени массива, далее `:` и A - `array`, D — списка диапазонов значений индексов, заключённого в квадратные скобки, O — `of`, T — типа элементов в массиве, `;`. |\n| `D -\u003e D,D or R`         | Массив может быть n-мерным, поэтому каждый список диапазонов может состоять из двух, разделённых запятой, или же являться одним диапазоном R. |\n| `R -\u003e N..N or T`        | Диапазон индексов состоит из двух чисел N, разделённых двумя точками, либо одного названия типа (идентификатора). |\n| `X -\u003e X,X or id`        | Объявление массивов может состоять из одного или нескольких имён, имя каждого — идентификатор. |\n| `T -\u003e id`               | По условию для имён массивов и имен типов используется один терминал — идентификатор. |\n| `N -\u003e number`           | У чисел свой идентификатор, чтобы отличать их от имён.       |\n\n\nДля построения нисходящего парсера без возврата требуется [LL(1)-грамматика](https://neerc.ifmo.ru/wiki/index.php?title=LL(k)-грамматики,_множества_FIRST_и_FOLLOW), а выбранная\nграмматика в силу наличия левой рекурсии и правого ветвления таковой не является. Устраним [левую рекурсию](https://neerc.ifmo.ru/wiki/index.php?title=Устранение_левой_рекурсии) и [правое ветвление](https://neerc.ifmo.ru/wiki/index.php?title=LL(k)-грамматики,_множества_FIRST_и_FOLLOW#.D0.90.D0.BB.D0.B3.D0.BE.D1.80.D0.B8.D1.82.D0.BC_.D1.83.D1.81.D1.82.D1.80.D0.B0.D0.BD.D0.B5.D0.BD.D0.B8.D1.8F_.D0.BF.D1.80.D0.B0.D0.B2.D0.BE.D0.B3.D0.BE_.D0.B2.D0.B5.D1.82.D0.B2.D0.BB.D0.B5.D0.BD.D0.B5.D0.BD.D0.B8.D1.8F) в правилах для D и X, используя соответствующие алгоритмы.  \nПолучится грамматика:\n\n| Нетерминал               | Описание                                     |\n| ------------------------ | -------------------------------------------- |\n| `S  -\u003e V X : A [D] O T;` | Описание массива в Pascal                    |\n| `D  -\u003e RD''`             | Список диапазонов индексов                   |\n| `R  -\u003e N..N or T`        | Один диапазон                                |\n| `D''-\u003e D'`               | Продолжение списка диапазонов                |\n| `D''-\u003e ε`                | Конец списка диапазонов                      |\n| `D' -\u003e ,DP`              | Описание нового диапазона индексов           |\n| `P  -\u003e D'`               | Продолжение нового диапазона                 |\n| `P  -\u003e ε `               | Конец списка                                 |\n| `X  -\u003e idX''`            | Список имён массивов                         |\n| `X''-\u003e X'`               | Продолжение списка имён массивов             |\n| `X''-\u003e ε`                | Конец списка имён массивов                   |\n| `X' -\u003e ,XY`              | Описание нового имени элемента в списке имён |\n| `Y  -\u003e X'`               | Новый элемент списка имён                    |\n| `Y  -\u003e ε`                | Конец списка имён                            |\n| `T  -\u003e id`               | Тип элементов массива                        |\n| `N  -\u003e number`           | Числовая граница индексов массива            |\n\n\n### Лексический анализатор\nЛексический анализатор получает на вход строку и выдаёт последовательность терминалов\n(токенов). Пробелы и переводы строк игнорируются.\n\n| Терминал  | Токен         |\n|-----------|---------------|\n| `\u003cid\u003e`    | Id            |\n| `\u003cnumber\u003e`| Number        |\n| `var`     | Var           |\n| `:`       | Colon         |\n| `array`   | Array         |\n| `[`       | OpenSBracket  |\n| `..`      | DoubleDot     |\n| `,`       | Comma         |\n| `]`       | CloseSBracket |\n| `of`      | Of            |\n| `;`       | Semicolon     |\n| `ε`       | Epsilon       |\n| `$`       | Eof           |\n\n\n\n### Синтаксический анализатор\nДля написания парсера нам требуется построить множества [FIRST и FOLLOW](https://neerc.ifmo.ru/wiki/index.php?title=LL(k)-грамматики,_множества_FIRST_и_FOLLOW#defLLK) для нетерминалов нашей грамматики:\n\n|      | FIRST     | FOLLOW      |\n|------|-----------|-------------|\n| `S`  | `var`     | `$`         |\n| `D`  | `n`       | `]`,`,`     |\n| `D'` | `,`       | `]`,`,`     |\n| `D''`| `ε`,`,`   | `]`,`,`     |\n| `R`  | `n`       | `,`,`]`     |\n| `P`  | `ε`,`,`   | `]`,`,`     |\n| `X`  | `\u003cid\u003e`    | `:`,`,`     |\n| `X'` | `,`       | `:`,`,`     |\n| `X''`| `ε`,`,`   | `:`,`,`     |\n| `Y`  | `ε`,`,`   |  `:`,`,`    |\n| `T`  | `\u003cid\u003e`    | `;`         |\n| `N`  | `\u003cnumber\u003e`| `.`,`,`,`]` |\n\n\n### Визуализация дерева разбора\nПостроенные деревья разбора можно представлять графически, например, сохраняя их в формате\n[Dot (Graphviz)](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) и конвертируя в векторные файлы SVG.\n![Пример дерева](example.svg)\n\n### Набор тестов\nТесты для лексического и синтаксического анализаторов написаны с использованием встроенных\nсредств тестирования языка Rust; краткое описание тестов обозначено в названиях тестовых\nфункций.\n\n### Сборка и использование программы\n**Структура программы**\n\n* [main.rs](src/main.rs) — точка входа программы. Принимает на стандартный ввод выражение для разбора,\nвыводит в стандартный вывод дерево разбора в формате [Dot (Graphviz)](https://en.wikipedia.org/wiki/DOT_(graph_description_language)).\n* [lexer.rs](src/parser/lexer.rs) — лексический анализатор.\n* [parser.rs](src/parser.rs) — синтаксический анализатор.\n* [lexer/tests.rs](src/parser/lexer/tests.rs), [parser/tests.rs](src/parser/tests.rs) — тесты.\n\n**Зависимости**  \nРешение использует только стандартную библиотеку Rust и протестировано с `rustc 1.39.0`.\n\n**Команды**\n\n* Пример запуска решения:  \n`echo \"var x: array [1..10] of integer;\" | cargo run | dot -Tsvg \u003e test.svg`\n* Запуск тестов:  \n`cargo test`\n* Сборка без запуска:  \n`cargo build [--release]`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filyabizyaev%2Fpascal-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filyabizyaev%2Fpascal-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filyabizyaev%2Fpascal-parser/lists"}