Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83

Свой компилятор: а правильно ли я разместил наборы токенов?

02.11.2017, 22:52. Показов 1463. Ответов 14

Студворк — интернет-сервис помощи студентам
Продолжаю тему пустого трепа и размышлений о том "как лучше и приятнее" сделать некоторые фичи компилятора на коленках.
На этот раз оглянулся назад к лексическому анализатору, замечу сразу, он работает сносно, мне нравится =)

Если конкретнее, то вопрос касается не самого анализатора, а набора токенов, которые он ищет.
Так как я работаю в ООП парадигме, с самого начала решено было инкапсулировать всё что связано с лексикой в класс Lexer.
Куда всё жёстче стало когда я закончил работу. Вышло так, что внутри Lexer'а у меня появился нехилый набор констант-токенов (в виде enum)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public:
    
    /*
     * Перечисление всех возможных типов токенов
     */
    enum TokenType {
        KEY_WORD,
        ONE_LIT_DELIM,
        TWO_LIT_DELIM,
        INTEGER,
        IDENTIFIER,
        LITERAL,
    };
    
    enum OneLitDelim {
        INPUT_END,
        LINE_DELIM,
        PLUS,
        MINUS,
        MULT,
        DIV,
        POW,
        ASSIGN,
        LPAREN,
        RPAREN,
        LBRACKET,
        RBRACKET,
        LBRACE,
        RBRACE,
        MORE,
        LESS,
        NOT,
        COMMA,
    };
    
    enum TwoLitDelim {
        PLUS_ASSIGN,
        MINUS_ASSIGN,
        DIV_ASSIGN,
        MULT_ASSIGN,
        INCR,
        DECR,
        EQUALS,
        MORE_OR_EQ,
        LESS_OR_EQ,
        NOT_EQ,
    };
    
    enum KeyWord {
        KEY_PROGRAM,
        KEY_VAR,
        KEY_IF,
        KEY_PRINT,
    };
Красота, НО вот крутость в том, что сейчас, когда я достал этот Lexer и использую его для синтаксического анализа, то мне крайне докучают постоянные
C++
1
2
3
4
5
6
7
//тут был код
Lexer::KEY_WORD
//тут тоже
Lexer::ONE_LIT_DELIM Lexer::PLUS Lexer::MINUS
//бла бла бла
Lexer:: Lexer:: Lexer::Lexer::Lexer::Lexer::Lexer::
//просто ужас
Короче, видимость - это жестоко. Уже пальцы болят нажимать на двоеточие. Возникло два варианта движения дальше:
1. Вынести эти константы куда нибудь ещё - пространство имён там, или ещё один класс, а в Lexer'е и синтаксическом анализаторе просто подключать это пространство с помощью using
2. Плевать на всё, ничего не менять, а просто использовать Lexer как неймспейс, юзать его (жестоко, но сработает же )
3. Не делать ничего, ибо хардкор он для крутых

Конечно, это не срочно, не принципиально, но я ведь думаю об этом, да и вопрос довольно интересный, в архитектурном плане, так что вот

P.S. Лексер у меня ещё с универских лаб, которые я потихоньку доделываю сейчас, тогда меня заставили использовать раздельные наборы для разных типов лексем, а при получении токена брать две константы вместо одной (типа парами - ONE_LIT_DELIM, PLUS - вот так). Причём на множественные вопросы "для чего" ответа не было. Ну надо, значит надо, сделал, а зачем, до сих пор не знаю, мб кто знает...
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.11.2017, 22:52
Ответы с готовыми решениями:

Как правильно предавать наборы контролов в представление из контроллера
В представлении нужно построить сложную таблицу. Таблица должна содержать столбцы контролов и текста. Как лучше всего передавать такой...

Свой компилятор C++
Приветствую всех. Меня интересует, можно ли взять какой нибудь компилятор C++, и добавить туда свои библиотеки и так далее? Сделав новый...

Eclipse + свой компилятор. Как?
Доброе утро! Наконец у меня что-то начало продвигаться в безнадежном деле... Установил в VirtualBox Debian. Под Debian поставил Eclipse...

14
21 / 19 / 7
Регистрация: 14.03.2014
Сообщений: 249
02.11.2017, 23:02
DrankUser, Ну а стандарт вам не подсказчик ?
ISO 14882:2003 2.4
preprocessing-token:
header-name
identifier
pp-number
character-literal
string-literal
preprocessing-op-or-punc
each non-white-space character that cannot be one of the above
ISO 14882:2003 2.6
token:
identifier
keyword
literal
operator
punctuator

Там же и фазы трансляции расписаны чтоб голова не пухла от обилия задач.
0
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83
02.11.2017, 23:26  [ТС]
Pechkin80, я туплю что-то
Что за стандарт? Си++?

Окей, но набор токенов я уже завершил, а если надо будет ещё добавить, то дело нескольких секунд

Сам по себе вопрос темы немного в другом, или я не вкуриваю смысла вами сказанного...
0
21 / 19 / 7
Регистрация: 14.03.2014
Сообщений: 249
02.11.2017, 23:39
DrankUser, Вы компилятор по си++ пишите ? для языка программирования c++ существует международный стандарт. Он имеет разные версии, в зависимости от года выпуска стандарта: c++98(ISO 14882:1998), c++03(ISO 14882:2003), c++11(ISO 14882:2011), c++14(ISO 14882:2014), c++17(пока не опубликован). Я рекомендую использовать версию 2003 года так как она не такая огромная.

Добавлено через 4 минуты
Стандарт это нормативный документ, где формально изложено само описание языка. Другие источники, включая книжку Страуструпа это неофициально всё. Стандарт даёт хорошее преставление о структуре грамматики языка и о многом другом.
0
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83
02.11.2017, 23:41  [ТС]
Pechkin80, странно, но я нигде не писал о c++, я просто пишу что-то своё, ограниченное лишь моей фантазией, и небольшим ТЗ из универа, которое я постоянно нарушаю, насколько это возможно, ибо так хочу
0
21 / 19 / 7
Регистрация: 14.03.2014
Сообщений: 249
02.11.2017, 23:43
DrankUser, Ну даже если итак, то чтение первых трёх глав даст хорошую пищу как двигаться дальше.
0
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83
02.11.2017, 23:46  [ТС]
Pechkin80, о чём вообще идёт речь?

Вопрос мой о размещении набора констант в структуре проекта, причём тут вообще с++, его стандарты и движение дальше.
Конечно, за заметку спасибо, я подумаю над этим, но в данной теме это немного оффтоп
0
Неэпический
 Аватар для Croessmah
18148 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,031
Записей в блоге: 1
02.11.2017, 23:49
Возможно, Вам будет полезно:
1
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
03.11.2017, 09:28
Цитата Сообщение от DrankUser Посмотреть сообщение
Так как я работаю в ООП парадигме
В ООП парадигме может быть правильнее было бы некоторые подмножества лексем определить как реализации абстрактного класса (интерфейса) лексемы.
0
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83
03.11.2017, 10:05  [ТС]
woldemas, ну наконец-то хоть что-то по теме

Да, как вариант можно этот набор выложить в отдельный класс...
Так, сейчас я кстати ещё немного подумал о таблицах неконстантных токенов, можно сделать отдельный класс для них, и на его объект ссылаться во всех анализах, это как вариант
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
03.11.2017, 10:27
Цитата Сообщение от DrankUser Посмотреть сообщение
Да, как вариант можно этот набор выложить в отдельный класс...
Я имел в виду скорее такую конструкцию:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Lexem {
public:    
    const std::string & getValue() const;
    // Для обеспечение диспетчиризации по типу
    // без использования switch конструкций можно
    // попробовать использовать паттерн Visitor
    virtual void Accept(SyntaxAnalyzer &analyzer) = 0;
};
 
class NumericConstant : public Lexem {    
    //...    
    virtual void Accept(SyntaxAnalyzer &analyzer) {
        analyzer.ProcessNumericConstant(*this);
    }
};
 
class Variable : public Lexem {       
    //...
};
 
class Keyword : public Lexem {    
    //...
};
 
class BinaryOperator : public Lexem {    
    //...
};
 
// Анализатор может быть таким
// и по сути представляет собой конечный автомат
// вызовы методов Process осуществляются в нужной
// последовательности вырабатваемой лексером
class SyntaxAnalyzer {
public:
    virtual void ProcessNumericConstant(NumericConstant &nc) = 0;
    virtual void ProcessOperator(BinaryOperator &op) = 0;
    //...
};


Я когда-то писал что-то подобное, но там был не язык программирования, а язык описания данных, с довольно сложной грамматикой и синтаксическими конструкциями.
0
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83
03.11.2017, 10:41  [ТС]
woldemas, аа, я вижу
На самом деле когда я только взялся за лексер, у меня тоже были такие мысли, но на деле оказалось что создавать классы для токенов мне не надо, так как то что я показал вверху - это просто числовые константы, а класс для хранения одной константы звучит как-то бесполезно.

Вместо этого я сделал структуру Token, которая хранит в себе целочисленную пару тип-id для поиска нужной лексемы среди вышеуказанных енамов. Причём раньше у меня был всего один enum для всех констант, а потому даже надобность в паре отсутствовала, но увы, сейчас, по велению преподавательского состава, у меня несколько енамов.

А проблема сейчас лишь только в неудобстве размещения этих енамов, так как классов, работающих с ними много.

Сейчас я уже подумываю просто обернуть весь компилятор в неймспейс и сделать эти константы глобальными в этой области

Добавлено через 2 минуты
woldemas, хотя сейчас я перечитал ваш код, пораскинул мозгами, и понял, что это выглядит круто

Прикрутить к своему проекту я уже не смогу, так как это куча работы по рефакторингу, времени нет

Но вот в будущем может быть попробую поработать над такой структурой
0
21 / 19 / 7
Регистрация: 14.03.2014
Сообщений: 249
03.11.2017, 10:52
enum лучше вообще не использовать. Граматику лучше задавать текстовым файлом в виде формул бекуса нуара. Тогда после парсинга можно получить структуру что во что вложено.
0
0 / 2 / 3
Регистрация: 29.01.2017
Сообщений: 83
03.11.2017, 13:18  [ТС]
Pechkin80, отлично, прямо сейчас я брошу всё что сделал, и вместо того чтоб добиться хоть какого-то результата начну опять полгода рыться в книжках и читать про парсинг грамматик

Понимаете, я не то что бы считаю себя выше этого, нет, напротив, я думал об этом, но всё же более целесообразным считаю доделать хотя бы этот маленький проект. Плюс, вопрос тут вообще не в том, что лучше - enum, просто массив, или же структура ООП. Вопрос в том, как это всё обернуть для более удобного и рационального задания области видимости
0
21 / 19 / 7
Регистрация: 14.03.2014
Сообщений: 249
03.11.2017, 14:17
DrankUser, Всё уже украдено до вас. Никакие полгода не нужно. Если лень делать парсер формул б.с., то берёте готовую библиотеку xml парсинга (в кьюте например или libxml) приспосабливаете формат под свои нужды, за пару часов это делается. Я вам как раз и подсказываю как время сэкономить. Задавать все правила в коде постоянно это вы утоните в нём))) Для правил разрешения имён тоже лучше чтото скриптовое иметь.

Добавлено через 1 минуту
И я вам настоятельно рекомендую почитать стандарт. Как в нём реализовано то что вы хотите сделать, тоже разрешение имён.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.11.2017, 14:17
Помогаю со студенческими работами здесь

Свой компилятор: обработка ошибок
В рамках развития и стремления к высшему делаю свой компилятор. Пишу на плюсах. Пока готов только лексический анализатор, работаю над...

Написал свой синтаксический анализатор+компилятор выражений
Не знаю, можно ли так поступать на этом форуме. Хочу показать вам свои наработки. Я писал программу для построения графиков, мне нужно...

Нужен компилятор с возможностью установить свой значок и изменить информацию
Нужен компилятор с возможностью установить свой значок и изменить информацию(описание, версию и название файла, показываемое в свойствах) ...

разместил в слоях div
Посмотрел код сайта и решил поднять контент в верх, по причине удаленности контента от начала кода. Поднял на слоях <div> ...

Компилятор не хочит выполнять свою работу правильно
Вот код: // test1.cpp : Defines the entry point for the console application. // #include <stdafx.h> #include <iostream> ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru