Files
pip/libs/main/code/picodeparser.h

290 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \file picodeparser.h
* \addtogroup Code
* \{
* \~
* \brief
* \~english C++ code parser
* \~russian Разбор C++ кода
* \details
* \~english Parser for analyzing C++ source files. Extracts information about classes, structures, enums, macros, functions, and members.
* \~russian Парсер для анализа C++ исходных файлов. Извлекает информацию о классах, структурах, перечислениях, макросах, функциях и членах.
*/
/*
PIP - Platform Independent Primitives
C++ code parser
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICODEPARSER_H
#define PICODEPARSER_H
#include "pievaluator.h"
#include "pifile.h"
inline bool _isCChar(const PIChar & c) {
return (c.isAlpha() || (c.toAscii() == '_'));
}
inline bool _isCChar(const PIString & c) {
if (c.isEmpty()) return false;
return _isCChar(c[0]);
}
class PIP_EXPORT PICodeParser {
public:
//! \~english Default constructor.
//! \~russian Конструктор по умолчанию.
PICodeParser();
enum Visibility {
Global,
Public,
Protected,
Private
};
enum Attribute {
NoAttributes = 0x0,
Const = 0x01,
Static = 0x02,
Mutable = 0x04,
Volatile = 0x08,
Inline = 0x10,
Virtual = 0x20,
Extern = 0x40
};
typedef PIFlags<Attribute> Attributes;
typedef PIPair<PIString, PIString> Define;
typedef PIPair<PIString, PIString> Typedef;
typedef PIMap<PIString, PIString> MetaMap;
//! \~english Represents a preprocessor macro.
//! \~russian Представляет препроцессорный макрос.
struct PIP_EXPORT Macro {
Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) {
name = n;
value = v;
args = a;
}
//! \~english Expand macro with given arguments.
//! \~russian Раскрыть макрос с заданными аргументами.
//! \param args_ Arguments string
//! \param ok Output flag indicating success
//! \return Expanded macro value
PIString expand(PIString args_, bool * ok = 0) const;
PIString name;
PIString value;
PIStringList args;
};
//! \~english Represents a class/struct member variable or function.
//! \~russian Представляет переменную-член или функцию класса/структуры.
struct PIP_EXPORT Member {
Member() {
visibility = Global;
size = 0;
bits = -1;
is_type_ptr = false;
attributes = NoAttributes;
}
//! \~english Check if member is a bitfield.
//! \~russian Проверить, является ли член битовым полем.
bool isBitfield() const { return bits > 0; }
MetaMap meta;
PIString type;
PIString name;
PIStringList arguments_full;
PIStringList arguments_type;
PIStringList dims;
Visibility visibility;
Attributes attributes;
bool is_type_ptr;
int size;
int bits;
};
//! \~english Represents a parsed entity (class, struct, namespace, etc.).
//! \~russian Представляет разобранную сущность (класс, структуру, пространство имен и т.д.).
struct PIP_EXPORT Entity {
Entity() {
visibility = Global;
is_anonymous = false;
size = 0;
parent_scope = 0;
}
MetaMap meta;
PIString type;
PIString name;
PIString file;
Visibility visibility;
int size;
bool is_anonymous;
Entity * parent_scope;
PIVector<Entity *> parents;
PIVector<Member> functions;
PIVector<Member> members;
PIVector<Typedef> typedefs;
};
//! \~english Represents an enumerator value.
//! \~russian Представляет значение перечисления.
struct PIP_EXPORT EnumeratorInfo {
EnumeratorInfo(const PIString & n = PIString(), int v = 0, const MetaMap & m = MetaMap()) {
name = n;
value = v;
meta = m;
}
MetaMap meta;
PIString name;
int value;
};
//! \~english Represents a parsed enum type.
//! \~russian Представляет разобранный тип перечисления.
struct PIP_EXPORT Enum {
Enum(const PIString & n = PIString()) { name = n; }
MetaMap meta;
PIString name;
PIVector<EnumeratorInfo> members;
};
//! \~english Parse C++ source file.
//! \~russian Разбор C++ исходного файла.
//! \param file Path to source file
//! \param follow_includes Whether to follow include directives
void parseFile(const PIString & file, bool follow_includes = true);
//! \~english Parse multiple C++ source files.
//! \~russian Разбор нескольких C++ исходных файлов.
//! \param files List of file paths
//! \param follow_includes Whether to follow include directives
void parseFiles(const PIStringList & files, bool follow_includes = true);
//! \~english Parse C++ source from string content.
//! \~russian Разбор C++ исходного кода из строки.
//! \param fc Source code content
void parseFileContent(PIString fc);
//! \~english Add directory to search for include files.
//! \~russian Добавить директорию для поиска включаемых файлов.
//! \param dir Directory path
void includeDirectory(const PIString & dir) { includes << dir; }
//! \~english Add custom macro definition.
//! \~russian Добавить пользовательское определение макроса.
//! \param def_name Macro name
//! \param def_value Macro value
void addDefine(const PIString & def_name, const PIString & def_value) { custom_defines << Define(def_name, def_value); }
//! \~english Check if name refers to an enum type.
//! \~russian Проверить, является ли имя типом перечисления.
//! \param name Name to check
//! \return true if name is an enum
bool isEnum(const PIString & name);
//! \~english Find entity by name.
//! \~russian Найти сущность по имени.
//! \param en Entity name
//! \return Pointer to entity or nullptr
Entity * findEntityByName(const PIString & en);
//! \~english Get list of parsed files.
//! \~russian Получить список разобранных файлов.
//! \return List of file paths
PIStringList parsedFiles() const { return PIStringList(proc_files.toVector()); }
//! \~english Get main file path.
//! \~russian Получить путь к главному файлу.
//! \return Main file path
PIString mainFile() const { return main_file; }
//! \~english Get global scope entity.
//! \~russian Получить сущность глобальной области видимости.
//! \return Pointer to global entity
const PICodeParser::Entity * global() const { return &root_; }
//! \~english Get maximum iterations for macros substitution.
//! \~russian Получить максимальное количество итераций для подстановки макросов.
//! \return Maximum iterations count
int macrosSubstitutionMaxIterations() const { return macros_iter; }
//! \~english Set maximum iterations for macros substitution.
//! \~russian Установить максимальное количество итераций для подстановки макросов.
//! \param value Maximum iterations count
void setMacrosSubstitutionMaxIterations(int value) { macros_iter = value; }
//! \~english List of defined macros.
//! \~russian Список определенных макросов.
PIVector<Define> defines, custom_defines;
//! \~english List of macro definitions with expansion.
//! \~russian Список определений макросов с подстановкой.
PIVector<Macro> macros;
//! \~english List of enumerated types.
//! \~russian Список типов перечислений.
PIVector<Enum> enums;
//! \~english List of type definitions.
//! \~russian Список определений типов.
PIVector<Typedef> typedefs;
//! \~english List of parsed entities (classes, structs, etc.).
//! \~russian Список разобранных сущностей (классов, структур и т.д.).
PIVector<Entity *> entities;
private:
void clear();
bool parseFileInternal(const PIString & file, bool follow_includes);
bool parseFileContent(PIString & fc, bool main);
bool parseDirective(PIString d);
Entity * parseClassDeclaration(const PIString & fc);
Entity * parseClass(Entity * parent, PIString & fc, bool is_namespace);
MetaMap parseMeta(PIString & fc);
bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta);
Typedef parseTypedef(PIString fc);
bool parseMember(Entity * parent, PIString & fc);
int extractMemberBits(PIString & fc);
void restoreTmpTemp(Member * e);
void restoreTmpMeta(Member * e);
MetaMap maybeMeta(PIString & fc);
bool macroCondition(const PIString & mif, PIString mifcond);
bool isDefineExists(const PIString & dn);
double defineValue(const PIString & dn);
void replaceMeta(PIString & dn);
PIString procMacros(PIString fc);
double procMacrosCond(PIString fc);
bool isDeclaration(const PIString & fc, int start, int * end);
bool isMainFile(const PIString & fc);
void normalizeEntityNamespace(PIString & n);
int macros_iter, anon_num;
bool with_includes;
PIEvaluator evaluator;
PISet<PIString> proc_files;
PIString cur_file, main_file;
PIStringList includes;
Entity root_;
Visibility cur_def_vis;
PIString cur_namespace;
PIMap<PIString, PIString> tmp_temp;
PIMap<PIString, MetaMap> tmp_meta;
};
/*! \}
*/
#endif // PICODEPARSER_H