feat(CppParser): C++11 attributes support

This commit is contained in:
Günter Obiltschnig 2024-02-05 21:05:12 +01:00
parent ad07839db9
commit 568b0fca8e
12 changed files with 94 additions and 30 deletions

View File

@ -32,8 +32,8 @@ class CppParser_API Attributes
/// name and values are strings.
{
public:
typedef std::map<std::string, std::string> AttrMap;
typedef AttrMap::const_iterator Iterator;
using AttrMap = std::map<std::string, std::string>;
using Iterator = AttrMap::const_iterator;
Attributes();
/// Creates the Attributes object.

View File

@ -46,6 +46,8 @@ public:
{
OP_OPENBRACKET = 1, // [
OP_CLOSBRACKET, // ]
OP_DBL_OPENBRACKET, // [[
OP_DBL_CLOSBRACKET, // ]]
OP_OPENPARENT, // (
OP_CLOSPARENT, // )
OP_OPENBRACE, // {
@ -101,7 +103,7 @@ public:
int asInteger() const;
private:
typedef std::map<std::string, int> OpMap;
using OpMap = std::map<std::string, int>;
OpMap _opMap;
};
@ -112,7 +114,7 @@ class CppParser_API IdentifierToken: public CppToken
public:
enum Keywords
{
KW_ALIGNAS = 1,
KW_ALIGNAS = 100, // Note: start with 100 to avoid overlapping definitions with operators
KW_ALIGNOF,
KW_AND,
KW_AND_EQ,
@ -206,7 +208,7 @@ public:
int asInteger() const;
private:
typedef std::map<std::string, int> KWMap;
using KWMap = std::map<std::string, int>;
KWMap _kwMap;
};

View File

@ -28,7 +28,7 @@ namespace CppParser {
class CppParser_API Decl: public Symbol
/// This class represents a simple declaration in a C++ source file.
/// It is a base class for Function, TypeDef or Variable.
/// It is a base class for Function, TypeDef, Using or Variable.
{
public:
Decl(const std::string& decl, NameSpace* pNameSpace);

View File

@ -37,8 +37,8 @@ class CppParser_API Enum: public Symbol
/// a collection of EnumValues.
{
public:
typedef std::vector<EnumValue*> Values;
typedef Values::const_iterator Iterator;
using Values = std::vector<EnumValue*>;
using Iterator = Values::const_iterator;
enum Flags
{

View File

@ -49,8 +49,8 @@ public:
FN_DELETE = 1024 /// The function has been deleted.
};
typedef std::vector<Parameter*> Parameters;
typedef Parameters::const_iterator Iterator;
using Parameters = std::vector<Parameter*>;
using Iterator = Parameters::const_iterator;
Function(const std::string& decl, NameSpace* pNameSpace);
/// Creates the Function.

View File

@ -33,10 +33,10 @@ class CppParser_API NameSpace: public Symbol
/// This class represents a namespace.
{
public:
typedef std::multimap<std::string, Symbol*> SymbolTable;
typedef SymbolTable::const_iterator Iterator;
typedef std::map<std::string, std::string> AliasMap;
typedef std::vector<std::string> NameSpaceVec;
using SymbolTable = std::multimap<std::string, Symbol*>;
using Iterator = SymbolTable::const_iterator;
using AliasMap = std::map<std::string, std::string>;
using NameSpaceVec = std::vector<std::string>;
NameSpace();
/// Creates the NameSpace.

View File

@ -73,7 +73,7 @@ protected:
const Poco::Token* parseExtern(const Poco::Token* pNext);
const Poco::Token* parseTypeDef(const Poco::Token* pNext);
const Poco::Token* parseUsing(const Poco::Token* pNext);
const Poco::Token* parseFunc(const Poco::Token* pNext, std::string& decl);
const Poco::Token* parseFunc(const Poco::Token* pNext, const std::string& attrs, std::string& decl);
const Poco::Token* parseParameters(const Poco::Token* pNext, Function* pFunc);
const Poco::Token* parseBlock(const Poco::Token* pNext);
const Poco::Token* parseEnum(const Poco::Token* pNext);
@ -82,6 +82,7 @@ protected:
const Poco::Token* parseClassMembers(const Poco::Token* pNext, Struct* pClass);
const Poco::Token* parseAccess(const Poco::Token* pNext);
const Poco::Token* parseIdentifier(const Poco::Token* pNext, std::string& id);
const Poco::Token* parseAttributes(const Poco::Token* pNext, std::string& attrs);
void addSymbol(Symbol* pSymbol, int lineNumber, bool addGST = true);
void pushNameSpace(NameSpace* pNameSpace, int lineNumber, bool addGST = true);
@ -102,7 +103,7 @@ protected:
const Poco::Token* nextToken();
private:
typedef std::vector<NameSpace*> NSStack;
using NSStack = std::vector<NameSpace*>;
NameSpace::SymbolTable& _gst;
Poco::CountingInputStream _istr;

View File

@ -51,13 +51,13 @@ public:
Struct* pClass;
};
typedef std::vector<Base> BaseClasses;
typedef BaseClasses::const_iterator BaseIterator;
typedef std::vector<Struct*> StructVec;
typedef StructVec::const_iterator DerivedIterator;
typedef std::vector<Function*> Functions;
typedef std::set<Function*> FunctionSet;
typedef std::set<Struct*> StructSet;
using BaseClasses = std::vector<Base>;
using BaseIterator = BaseClasses::const_iterator;
using StructVec = std::vector<Struct*>;
using DerivedIterator = StructVec::const_iterator;
using Functions = std::vector<Function*>;
using FunctionSet = std::set<Function*>;
using StructSet = std::set<Struct*>;
Struct(const std::string& decl, bool isClass, NameSpace* pNameSpace);
/// Creates the Struct.

View File

@ -85,6 +85,13 @@ public:
Access getAccess() const;
/// Returns the symbol's access.
void setAttributeList(const std::string& attrs);
/// Sets the C++11 attribute list, e.g. "[[noreturn]]".
const std::string& getAttributeList() const;
/// Returns the C++11 attribute list, or an empty string
/// if the symbol does not have one.
void setDocumentation(const std::string& text);
/// Sets the symbol's documentation.
@ -169,6 +176,7 @@ private:
std::string _package;
std::string _library;
Attributes _attrs;
std::string _attributeList;
static int _nextId;
};
@ -189,6 +197,12 @@ inline const std::string& Symbol::name() const
}
inline const std::string& Symbol::getAttributeList() const
{
return _attributeList;
}
inline const std::string& Symbol::getDocumentation() const
{
return _documentation;

View File

@ -49,9 +49,11 @@ void CppToken::syntaxError(const std::string& expected, const std::string& actua
OperatorToken::OperatorToken()
{
int i = 1;
int i = OP_OPENBRACKET;
_opMap["["] = i++;
_opMap["]"] = i++;
_opMap["[["] = i++;
_opMap["]]"] = i++;
_opMap["("] = i++;
_opMap[")"] = i++;
_opMap["{"] = i++;
@ -159,13 +161,23 @@ void OperatorToken::finish(std::istream& istr)
case ')':
case '{':
case '}':
case '[':
case ']':
case ';':
case '?':
case '~':
case ',':
break;
case '[':
if (next == '[')
{
_value += (char) istr.get();
}
break;
case ']':
if (next == ']')
{
_value += (char) istr.get();
}
break;
case '.':
if (next == '.')
{
@ -231,7 +243,7 @@ int OperatorToken::asInteger() const
IdentifierToken::IdentifierToken()
{
int i = 1;
int i = KW_ALIGNAS;
_kwMap["alignas"] = i++;
_kwMap["alignof"] = i++;
_kwMap["and"] = i++;

View File

@ -39,6 +39,7 @@ using Poco::NumberFormatter;
using Poco::SyntaxException;
using Poco::icompare;
using Poco::trimInPlace;
using namespace std::string_literals;
namespace Poco {
@ -117,6 +118,8 @@ inline void Parser::append(std::string& decl, const std::string& token)
token != "," &&
token != "[" &&
token != "]" &&
token != "[[" &&
token != "]]" &&
last != '~' &&
last != ':' &&
last != '(' &&
@ -380,7 +383,7 @@ const Token* Parser::parseClassMembers(const Token* pNext, Struct* /*pClass*/)
poco_assert (isOperator(pNext, OperatorToken::OP_OPENBRACE));
pNext = next();
while (pNext->is(Token::IDENTIFIER_TOKEN) || pNext->is(Token::KEYWORD_TOKEN) || isOperator(pNext, OperatorToken::OP_COMPL) || isOperator(pNext, OperatorToken::OP_DBL_COLON))
while (pNext->is(Token::IDENTIFIER_TOKEN) || pNext->is(Token::KEYWORD_TOKEN) || isOperator(pNext, OperatorToken::OP_COMPL) || isOperator(pNext, OperatorToken::OP_DBL_COLON) || isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET))
{
switch (pNext->asInteger())
{
@ -575,6 +578,11 @@ const Token* Parser::parseVarFunc(const Token* pNext)
const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
{
_pCurrentSymbol = 0;
std::string attrs;
if (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET))
{
pNext = parseAttributes(pNext, attrs);
}
if (isKeyword(pNext, IdentifierToken::KW_EXTERN))
{
pNext = parseExtern(pNext);
@ -596,6 +604,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
if (!currentNameSpace()->lookup(name))
{
Variable* pVar = new Variable(decl, currentNameSpace());
pVar->setAttributeList(attrs);
addSymbol(pVar, static_cast<int>(_istr.getCurrentLineNumber()));
}
pNext = next();
@ -611,7 +620,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
pNext = next();
expectOperator(pNext, OperatorToken::OP_OPENPARENT, "(");
}
pNext = parseFunc(pNext, decl);
pNext = parseFunc(pNext, attrs, decl);
}
}
_pCurrentSymbol = 0;
@ -641,7 +650,7 @@ const Token* Parser::parseExtern(const Token* pNext)
}
const Token* Parser::parseFunc(const Token* pNext, std::string& decl)
const Token* Parser::parseFunc(const Token* pNext, const std::string& attrs, std::string& decl)
{
poco_assert (isOperator(pNext, OperatorToken::OP_OPENPARENT));
@ -651,6 +660,7 @@ const Token* Parser::parseFunc(const Token* pNext, std::string& decl)
if (name.find(':') == std::string::npos)
{
pFunc = new Function(decl, currentNameSpace());
pFunc->setAttributeList(attrs);
addSymbol(pFunc, line);
}
pNext = parseParameters(pNext, pFunc);
@ -909,6 +919,25 @@ const Token* Parser::parseIdentifier(const Token* pNext, std::string& id)
}
const Poco::Token* Parser::parseAttributes(const Poco::Token* pNext, std::string& attrs)
{
poco_assert (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET));
append(attrs, pNext);
pNext = next();
while (pNext && !isOperator(pNext, OperatorToken::OP_DBL_CLOSBRACKET))
{
append(attrs, pNext);
pNext = next();
}
if (pNext)
{
append(attrs, pNext);
pNext = next();
}
return pNext;
}
void Parser::addSymbol(Symbol* pSymbol, int lineNumber, bool addGST)
{
pSymbol->setLineNumber(lineNumber);

View File

@ -59,6 +59,12 @@ void Symbol::setAccess(Access access)
}
void Symbol::setAttributeList(const std::string& attrs)
{
_attributeList = attrs;
}
void Symbol::setDocumentation(const std::string& text)
{
_documentation = text;