/*! \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 . */ #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 Attributes; typedef PIPair Define; typedef PIPair Typedef; typedef PIMap 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 parents; PIVector functions; PIVector members; PIVector 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 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 defines, custom_defines; //! \~english List of macro definitions with expansion. //! \~russian Список определений макросов с подстановкой. PIVector macros; //! \~english List of enumerated types. //! \~russian Список типов перечислений. PIVector enums; //! \~english List of type definitions. //! \~russian Список определений типов. PIVector typedefs; //! \~english List of parsed entities (classes, structs, etc.). //! \~russian Список разобранных сущностей (классов, структур и т.д.). PIVector 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 proc_files; PIString cur_file, main_file; PIStringList includes; Entity root_; Visibility cur_def_vis; PIString cur_namespace; PIMap tmp_temp; PIMap tmp_meta; }; /*! \} */ #endif // PICODEPARSER_H