Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 13
1

Все виды(способы) объявления переменных, функций, классов, типов и т.п. на С++

28.03.2015, 18:16. Показов 2939. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пишу обфускатор кода, написанного на С++ и появилась необходимость знания всевозможных способов объявления чего-либо на С++. Так как планирую с входным файлом следующее:
1)Прочесать весь файл посимвольно
2)Выделять имена (переменных, функций, и т.п.) и заносить в список имен
3)Сгенерировать список рандомных строк.
4)Заменить во входном файле каждое слово из списка имен, на слова из списка рандомных строк.

Так вот, самое сложное во втором пункте, т.е. в распознании факта объявления. Есть ли какая-то общая черта всех способов объявления? И по какому признаку можно понять, что в строке произошло объявление?

Пока я для себя выделил такие вот случаи(примеры):

C++
1
2
3
4
5
6
7
8
9
//Для наглядности
1) int a;
2) int a, b;
3) int a[100], b[CONSTName];
4) STACK <int> IntStack
5) int MyFunc();
6) int MyFunc(int a, int b);
7) class MyClass{..}
8) struct MyStruct{..}
Что я еще пропустил? (Подозреваю, что много)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.03.2015, 18:16
Ответы с готовыми решениями:

Какие есть способы объявления аргументов функций?
Например было какое то объявление procedure myproc(var f:File), вместо myproc(f:File). Чем они...

Как пропукать только объявления функций двух типов без аргументов из потока ввода?
Необходимо создать сценарий, который из всех принимаемых со стандартного потока строк с помощью...

Проблема с получением типов переменных двух классов друг у друга
Вообщем столкнулся с такой ситуацией: Есть 2 класса, которые имеют в своём теле определение...

Реализация отношения классов типа двунаправленная ассоциация, UML, порядок объявления классов, неполный класс
Доброго времени суток! Осваивая UML, решил реализовать отношение двунаправленной ассоциации по...

15
Модератор
Эксперт С++
13507 / 10757 / 6412
Регистрация: 18.12.2011
Сообщений: 28,712
28.03.2015, 18:32 2
C++
1
2
3
4
5
6
7
8
int & a;
int * a;
const int a;
static int a;
long int a;
unsigned int a;
union MyStruct{..}
enum num{...}
1
236 / 196 / 21
Регистрация: 04.06.2014
Сообщений: 1,309
28.03.2015, 18:45 3
И зачем всё это глобально объявлять?
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
28.03.2015, 18:53 4
Цитата Сообщение от ShinaZin Посмотреть сообщение
Что я еще пропустил? (Подозреваю, что много)
слишком многое.

вообще попытка проконтролировать типо-образования - плохой путь.
потому что их очень много. и есть множество рецептов таких образований.

намного проще идентифицировать имена без учета типа-образования:

на языке с++ любые символы в исходном коде,
которые не являются ключевыми словами языка - это какие то объявления.

а ключевых слов языка не так уж и много.


например:

C++
1
struct MyStruct{..} trololo; //<--- MyStruct - имя, trololo - имя
Здесь нужно
1. маскировать: 'MyStruct' и 'trololo'
2. выпиливать полностью весь комментарий

комментариев бывает три вида:

C++
1
// ololo
C++
1
/* ololo */
C++
1
2
3
#if 0
ololo
#endif
пропасти комментарии связанные с препроцессором - это жесть.
потому что там можно по всякому изголяццо:

C++
1
2
3
4
5
6
7
8
// хэдэр
#if SURPRIZE
 
// сюрприз определяется в  спп файле, который этот хэдэр инклюдит
// поэтому, в некоторых случаях блок будет исключен из компиляции
// а в некоторых может быть включен
 
#endif
1
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 13
28.03.2015, 19:19  [ТС] 5
Суть не в глобальности, мне не важно, в каком контексте и блоке произошло объявление, мне необходимо понять, как выдрать имя объявляемого, из факта объявления, нужная какая-то общая маска. А выявить ее не так уж и легко как я понял и считать количество слов бессмысленно. Наверное придется затачивать свой "выдиратель имен" под вид "(модификаторы и т.д.) тип (разделитель пробел или табуляция) (*, &, ' ')имя1 ( = значение, имяN = значение"). Но при таком подходе программе нужно как-то понять, что очередное слово это тип данных (в том числе библиотечные типы, и пользовательские). Вопрос - как?

Добавлено через 16 минут
Цитата Сообщение от hoggy Посмотреть сообщение
вообще попытка проконтролировать типо-образования - плохой путь.
потому что их очень много. и есть множество рецептов таких образований.
намного проще идентифицировать имена без учета типа-образования:
на языке с++ любые символы в исходном коде,
которые не являются ключевыми словами языка - это какие то объявления.
а ключевых слов языка не так уж и много.
В самом начале я тоже об этом думал, но тут возникла другая проблема. Как исключить из рассмотрения библиотечные функции, типы и т.д.? всякие cin, cout, string, Stack, system, strcpy, ifstream, pow... Лезть в хэдеры и проверять там? Там свои проблемы вылезут..
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
28.03.2015, 19:37 6
Цитата Сообщение от ShinaZin Посмотреть сообщение
В самом начале я тоже об этом думал, но тут возникла другая проблема. Как исключить из рассмотрения библиотечные функции, типы и т.д.?
а зачем их исключать?
0
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 13
28.03.2015, 19:55  [ТС] 7
cin, cout, string, Stack, system, strcpy, ifstream, pow
Ведь все это обфускатор не должен заменять, ибо код станет нерабочим.
Даже если и заменять, то заменять полноценно рабочими аналогами с рандомным именем, но копировать каждую библиотечную функцию это бред.
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
28.03.2015, 20:06 8
Цитата Сообщение от ShinaZin Посмотреть сообщение
Есть ли какая-то общая черта всех способов объявления? И по какому признаку можно понять, что в строке произошло объявление?
конечно есть. и этих черт не мало этим чертям чертам посвящены главы 7(declarations) и 8(declarators) стандарта
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
28.03.2015, 20:07 9
Цитата Сообщение от ShinaZin Посмотреть сообщение
Ведь все это обфускатор не должен заменять, ибо код станет нерабочим.
наверное, все таки он должен суметь заменить так, что бы все работало.

так то существует 100500 разных способов, как заморочить голову вашему обусфактору,
в том плане, что ему будет очень сложно отличить:
что здесь стандартное, а что пользовательское.

вопрос: "а как в принципе определить, что тут стандартное, а что местное" - это отдельный инженерный ребус.
---------------------------------------------------------------------------------

например...
обусфактор может составить список всех имен, которые найдет в исходнике.
а потом запутать их при помощи препроцессора.

в самом исходнике мы увидим дибильные имена.
если сильно присмотреться: в самом начале подключается волшебный инклюд,
который содержит всю магию.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
28.03.2015, 20:19 10
Цитата Сообщение от hoggy Посмотреть сообщение
если сильно присмотреться: в самом начале подключается волшебный инклюд,
который содержит всю магию.
тогда будет достаточно пропустить код через препроцессор и получим всё на блюдичке.
0
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 13
28.03.2015, 20:26  [ТС] 11
Цитата Сообщение от retmas Посмотреть сообщение
главы 7(declarations) и 8(declarators) стандарта
Цитата Сообщение от hoggy Посмотреть сообщение
вопрос: "а как в принципе определить, что тут стандартное, а что местное" - это отдельный инженерный ребус.
Но, теперь я уже не знаю, с какой стороны лучше подойти. Делать мб огромный файл с зарезервированными словами, которые нельзя заменять(или такой список уже есть где-то), или все же пытаться поймать все объявления и вырезать оттуда имена(что более логично, но очень тяжело). Куда копать?
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
28.03.2015, 20:39 12
Цитата Сообщение от ShinaZin Посмотреть сообщение
Делать мб огромный файл с зарезервированными словами, которые нельзя заменять
даже не могу представить такой список для проектов использующих boost/MFC/VCL/прочее.
уж лучше и надежнее парсить объявления, которые подчинены строгому и главное конечному числу правил
0
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 13
28.03.2015, 21:01  [ТС] 13
всем спасибо за мнения и советы. Буду думать над парсингом. Возможно тут меня спасут регулярные выражения, но пока я не знаю, есть ли такие библиотеки/или что то, для работы с такими выражениями на с++.

Не по теме:

Может в конце вовсе обращусь к баш скриптам с его утилитами.

0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
28.03.2015, 21:25 14
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда будет достаточно пропустить код через препроцессор и получим всё на блюдичке.
верная мысль.
но препроцессором путать следы все равно нужно.
что бы стандартные имена не выпячивались.

просто это нужно использовать в комплексе с подменой имен пользовательских.

Цитата Сообщение от ShinaZin Посмотреть сообщение
Но, теперь я уже не знаю, с какой стороны лучше подойти. Делать мб огромный файл с зарезервированными словами, которые нельзя заменять(или такой список уже есть где-то), или все же пытаться поймать все объявления и вырезать оттуда имена(что более логично, но очень тяжело). Куда копать?
Вариант №1

сначала вам нужно произвести подмену имен путем анализа типо-образования.
причем, не обязательно пытаться сразу охватить все возможные случаи.
достаточно замаскировать наиболее распространенные варианты.

далее, полученный файл проходит обработку "маскировка препроцессором".

в результате получаем непонятную кашу.

даже если и глянуть выхлоп препроцессора, то мы увидим: где то появятся имена наподобие cout,
но основная масса кода все равно будет оставаться нечитабельной.

а дальше уже нужно смотреть по обстоятельствам:
если хочется замаскировать ещё больше - просто анализируем больше всяких типа-образований.

-----------------------------

Вариант №2

при запуске обусфактора, ему указывается каталог, где находится исходный код проекта.
обусфактор рекурсивно обходит весь каталог, и собирает список путей всех исходных файлов проекта.

далее, рассмотрим код:

C++
1
2
3
4
5
6
#include<iostream>
int main()
{
    int v = 10;
    std::cout << v;
}
обусфактор, зная пути к всем исходникам проекта однозначно может определить,
что iostream - это стандартный заголовочный файл.

он может рекурсивно пройтись по нему, собирая все имена.

и тогда он сможет абсолютно точно вам сказать:

cout - стандартное имя (было обнаружено внутри стандартных заголовков)
все остальное - местное.

что бы ускорить работу обусфактора, можно кэшировать информацию о стандартных именах.
и тогда повстречав cout в следующий раз (возможно в другом исходнике),
ему уже не нужно будет лазить по стандартным заголовкам.
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
28.03.2015, 21:26 15
Цитата Сообщение от ShinaZin Посмотреть сообщение
2)Выделять имена (переменных, функций, и т.п.) и заносить в список имен
Этого мало, так как можно написать имя и как string, и как std::string. И вообще говоря, в зависимости от контекста это могут быть разные вещи (в std один стринг, а у меня другой). Тут надо делать полноценный парсер C++.
0
0 / 0 / 0
Регистрация: 03.04.2014
Сообщений: 13
28.03.2015, 21:51  [ТС] 16
Цитата Сообщение от hoggy Посмотреть сообщение
Вариант №1
сначала вам нужно произвести подмену имен путем анализа типо-образования.
причем, не обязательно пытаться сразу охватить все возможные случаи.
достаточно замаскировать наиболее распространенные варианты.
Данный вариант мне больше приглянулся, буду делать его (ибо мне пока что только в учебных и самообразовательных целях), но правильнее вариант 2, так что, возможно, реализация будет чем-то средним между этими вариантами. Осталось подумать(придумать) как именно парсить и какие варианты объявлений распространены больше всего. Ну это я уж сам, наверное тему можно закрыть. Спасибо за то, что нашли время.
0
28.03.2015, 21:51
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.03.2015, 21:51
Помогаю со студенческими работами здесь

Способы объявления шаблона
Здравствуйте! Возникли непонятки в ходе изучения шаблонов. Взглянем на код: #include &lt;iostream&gt;...

"Автозаполнение" имен типов/функций/переменных
Собственно вопрос в названии. Чтобы понимать, что за &quot;автозаполнение&quot; : когда вписываешь экземпляр...

В предложенной программе подчеркните все операторы присваивания и восстановите описания типов переменных
привет. нужна помощь с задачкой на Паскале: В предложенной программе подчеркните все операторы...

Объявления классов
Класс может быть объявлен так: class MyClass { ... }; а может быть объявлен и так ...

Виды классов в css
Не могу понять кое что. Допустим в файле css можно прописать span.text {font-weight:normal;}, но...

Объявления переменных
Добрый вечер! Подскажите какая разница между объявления переменных в конструкторе (в.1) и в...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru