mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-06 00:31:10 +01:00
feat(CppParser): C++11 attributes support
This commit is contained in:
parent
ad07839db9
commit
568b0fca8e
@ -32,8 +32,8 @@ class CppParser_API Attributes
|
|||||||
/// name and values are strings.
|
/// name and values are strings.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<std::string, std::string> AttrMap;
|
using AttrMap = std::map<std::string, std::string>;
|
||||||
typedef AttrMap::const_iterator Iterator;
|
using Iterator = AttrMap::const_iterator;
|
||||||
|
|
||||||
Attributes();
|
Attributes();
|
||||||
/// Creates the Attributes object.
|
/// Creates the Attributes object.
|
||||||
|
@ -46,6 +46,8 @@ public:
|
|||||||
{
|
{
|
||||||
OP_OPENBRACKET = 1, // [
|
OP_OPENBRACKET = 1, // [
|
||||||
OP_CLOSBRACKET, // ]
|
OP_CLOSBRACKET, // ]
|
||||||
|
OP_DBL_OPENBRACKET, // [[
|
||||||
|
OP_DBL_CLOSBRACKET, // ]]
|
||||||
OP_OPENPARENT, // (
|
OP_OPENPARENT, // (
|
||||||
OP_CLOSPARENT, // )
|
OP_CLOSPARENT, // )
|
||||||
OP_OPENBRACE, // {
|
OP_OPENBRACE, // {
|
||||||
@ -101,7 +103,7 @@ public:
|
|||||||
int asInteger() const;
|
int asInteger() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, int> OpMap;
|
using OpMap = std::map<std::string, int>;
|
||||||
|
|
||||||
OpMap _opMap;
|
OpMap _opMap;
|
||||||
};
|
};
|
||||||
@ -112,7 +114,7 @@ class CppParser_API IdentifierToken: public CppToken
|
|||||||
public:
|
public:
|
||||||
enum Keywords
|
enum Keywords
|
||||||
{
|
{
|
||||||
KW_ALIGNAS = 1,
|
KW_ALIGNAS = 100, // Note: start with 100 to avoid overlapping definitions with operators
|
||||||
KW_ALIGNOF,
|
KW_ALIGNOF,
|
||||||
KW_AND,
|
KW_AND,
|
||||||
KW_AND_EQ,
|
KW_AND_EQ,
|
||||||
@ -206,7 +208,7 @@ public:
|
|||||||
int asInteger() const;
|
int asInteger() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, int> KWMap;
|
using KWMap = std::map<std::string, int>;
|
||||||
|
|
||||||
KWMap _kwMap;
|
KWMap _kwMap;
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ namespace CppParser {
|
|||||||
|
|
||||||
class CppParser_API Decl: public Symbol
|
class CppParser_API Decl: public Symbol
|
||||||
/// This class represents a simple declaration in a C++ source file.
|
/// 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:
|
public:
|
||||||
Decl(const std::string& decl, NameSpace* pNameSpace);
|
Decl(const std::string& decl, NameSpace* pNameSpace);
|
||||||
|
@ -37,8 +37,8 @@ class CppParser_API Enum: public Symbol
|
|||||||
/// a collection of EnumValues.
|
/// a collection of EnumValues.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<EnumValue*> Values;
|
using Values = std::vector<EnumValue*>;
|
||||||
typedef Values::const_iterator Iterator;
|
using Iterator = Values::const_iterator;
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
@ -49,8 +49,8 @@ public:
|
|||||||
FN_DELETE = 1024 /// The function has been deleted.
|
FN_DELETE = 1024 /// The function has been deleted.
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Parameter*> Parameters;
|
using Parameters = std::vector<Parameter*>;
|
||||||
typedef Parameters::const_iterator Iterator;
|
using Iterator = Parameters::const_iterator;
|
||||||
|
|
||||||
Function(const std::string& decl, NameSpace* pNameSpace);
|
Function(const std::string& decl, NameSpace* pNameSpace);
|
||||||
/// Creates the Function.
|
/// Creates the Function.
|
||||||
|
@ -33,10 +33,10 @@ class CppParser_API NameSpace: public Symbol
|
|||||||
/// This class represents a namespace.
|
/// This class represents a namespace.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::multimap<std::string, Symbol*> SymbolTable;
|
using SymbolTable = std::multimap<std::string, Symbol*>;
|
||||||
typedef SymbolTable::const_iterator Iterator;
|
using Iterator = SymbolTable::const_iterator;
|
||||||
typedef std::map<std::string, std::string> AliasMap;
|
using AliasMap = std::map<std::string, std::string>;
|
||||||
typedef std::vector<std::string> NameSpaceVec;
|
using NameSpaceVec = std::vector<std::string>;
|
||||||
|
|
||||||
NameSpace();
|
NameSpace();
|
||||||
/// Creates the NameSpace.
|
/// Creates the NameSpace.
|
||||||
|
@ -73,7 +73,7 @@ protected:
|
|||||||
const Poco::Token* parseExtern(const Poco::Token* pNext);
|
const Poco::Token* parseExtern(const Poco::Token* pNext);
|
||||||
const Poco::Token* parseTypeDef(const Poco::Token* pNext);
|
const Poco::Token* parseTypeDef(const Poco::Token* pNext);
|
||||||
const Poco::Token* parseUsing(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* parseParameters(const Poco::Token* pNext, Function* pFunc);
|
||||||
const Poco::Token* parseBlock(const Poco::Token* pNext);
|
const Poco::Token* parseBlock(const Poco::Token* pNext);
|
||||||
const Poco::Token* parseEnum(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* parseClassMembers(const Poco::Token* pNext, Struct* pClass);
|
||||||
const Poco::Token* parseAccess(const Poco::Token* pNext);
|
const Poco::Token* parseAccess(const Poco::Token* pNext);
|
||||||
const Poco::Token* parseIdentifier(const Poco::Token* pNext, std::string& id);
|
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 addSymbol(Symbol* pSymbol, int lineNumber, bool addGST = true);
|
||||||
void pushNameSpace(NameSpace* pNameSpace, int lineNumber, bool addGST = true);
|
void pushNameSpace(NameSpace* pNameSpace, int lineNumber, bool addGST = true);
|
||||||
@ -102,7 +103,7 @@ protected:
|
|||||||
const Poco::Token* nextToken();
|
const Poco::Token* nextToken();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::vector<NameSpace*> NSStack;
|
using NSStack = std::vector<NameSpace*>;
|
||||||
|
|
||||||
NameSpace::SymbolTable& _gst;
|
NameSpace::SymbolTable& _gst;
|
||||||
Poco::CountingInputStream _istr;
|
Poco::CountingInputStream _istr;
|
||||||
|
@ -51,13 +51,13 @@ public:
|
|||||||
Struct* pClass;
|
Struct* pClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Base> BaseClasses;
|
using BaseClasses = std::vector<Base>;
|
||||||
typedef BaseClasses::const_iterator BaseIterator;
|
using BaseIterator = BaseClasses::const_iterator;
|
||||||
typedef std::vector<Struct*> StructVec;
|
using StructVec = std::vector<Struct*>;
|
||||||
typedef StructVec::const_iterator DerivedIterator;
|
using DerivedIterator = StructVec::const_iterator;
|
||||||
typedef std::vector<Function*> Functions;
|
using Functions = std::vector<Function*>;
|
||||||
typedef std::set<Function*> FunctionSet;
|
using FunctionSet = std::set<Function*>;
|
||||||
typedef std::set<Struct*> StructSet;
|
using StructSet = std::set<Struct*>;
|
||||||
|
|
||||||
Struct(const std::string& decl, bool isClass, NameSpace* pNameSpace);
|
Struct(const std::string& decl, bool isClass, NameSpace* pNameSpace);
|
||||||
/// Creates the Struct.
|
/// Creates the Struct.
|
||||||
|
@ -85,6 +85,13 @@ public:
|
|||||||
Access getAccess() const;
|
Access getAccess() const;
|
||||||
/// Returns the symbol's access.
|
/// 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);
|
void setDocumentation(const std::string& text);
|
||||||
/// Sets the symbol's documentation.
|
/// Sets the symbol's documentation.
|
||||||
|
|
||||||
@ -169,6 +176,7 @@ private:
|
|||||||
std::string _package;
|
std::string _package;
|
||||||
std::string _library;
|
std::string _library;
|
||||||
Attributes _attrs;
|
Attributes _attrs;
|
||||||
|
std::string _attributeList;
|
||||||
|
|
||||||
static int _nextId;
|
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
|
inline const std::string& Symbol::getDocumentation() const
|
||||||
{
|
{
|
||||||
return _documentation;
|
return _documentation;
|
||||||
|
@ -49,9 +49,11 @@ void CppToken::syntaxError(const std::string& expected, const std::string& actua
|
|||||||
|
|
||||||
OperatorToken::OperatorToken()
|
OperatorToken::OperatorToken()
|
||||||
{
|
{
|
||||||
int i = 1;
|
int i = OP_OPENBRACKET;
|
||||||
_opMap["["] = i++;
|
_opMap["["] = i++;
|
||||||
_opMap["]"] = i++;
|
_opMap["]"] = i++;
|
||||||
|
_opMap["[["] = i++;
|
||||||
|
_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 ';':
|
case ';':
|
||||||
case '?':
|
case '?':
|
||||||
case '~':
|
case '~':
|
||||||
case ',':
|
case ',':
|
||||||
break;
|
break;
|
||||||
|
case '[':
|
||||||
|
if (next == '[')
|
||||||
|
{
|
||||||
|
_value += (char) istr.get();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
if (next == ']')
|
||||||
|
{
|
||||||
|
_value += (char) istr.get();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
if (next == '.')
|
if (next == '.')
|
||||||
{
|
{
|
||||||
@ -231,7 +243,7 @@ int OperatorToken::asInteger() const
|
|||||||
|
|
||||||
IdentifierToken::IdentifierToken()
|
IdentifierToken::IdentifierToken()
|
||||||
{
|
{
|
||||||
int i = 1;
|
int i = KW_ALIGNAS;
|
||||||
_kwMap["alignas"] = i++;
|
_kwMap["alignas"] = i++;
|
||||||
_kwMap["alignof"] = i++;
|
_kwMap["alignof"] = i++;
|
||||||
_kwMap["and"] = i++;
|
_kwMap["and"] = i++;
|
||||||
|
@ -39,6 +39,7 @@ using Poco::NumberFormatter;
|
|||||||
using Poco::SyntaxException;
|
using Poco::SyntaxException;
|
||||||
using Poco::icompare;
|
using Poco::icompare;
|
||||||
using Poco::trimInPlace;
|
using Poco::trimInPlace;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@ -117,6 +118,8 @@ inline void Parser::append(std::string& decl, const std::string& token)
|
|||||||
token != "," &&
|
token != "," &&
|
||||||
token != "[" &&
|
token != "[" &&
|
||||||
token != "]" &&
|
token != "]" &&
|
||||||
|
token != "[[" &&
|
||||||
|
token != "]]" &&
|
||||||
last != '~' &&
|
last != '~' &&
|
||||||
last != ':' &&
|
last != ':' &&
|
||||||
last != '(' &&
|
last != '(' &&
|
||||||
@ -380,7 +383,7 @@ const Token* Parser::parseClassMembers(const Token* pNext, Struct* /*pClass*/)
|
|||||||
poco_assert (isOperator(pNext, OperatorToken::OP_OPENBRACE));
|
poco_assert (isOperator(pNext, OperatorToken::OP_OPENBRACE));
|
||||||
|
|
||||||
pNext = next();
|
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())
|
switch (pNext->asInteger())
|
||||||
{
|
{
|
||||||
@ -575,6 +578,11 @@ const Token* Parser::parseVarFunc(const Token* pNext)
|
|||||||
const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
||||||
{
|
{
|
||||||
_pCurrentSymbol = 0;
|
_pCurrentSymbol = 0;
|
||||||
|
std::string attrs;
|
||||||
|
if (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET))
|
||||||
|
{
|
||||||
|
pNext = parseAttributes(pNext, attrs);
|
||||||
|
}
|
||||||
if (isKeyword(pNext, IdentifierToken::KW_EXTERN))
|
if (isKeyword(pNext, IdentifierToken::KW_EXTERN))
|
||||||
{
|
{
|
||||||
pNext = parseExtern(pNext);
|
pNext = parseExtern(pNext);
|
||||||
@ -596,6 +604,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
|||||||
if (!currentNameSpace()->lookup(name))
|
if (!currentNameSpace()->lookup(name))
|
||||||
{
|
{
|
||||||
Variable* pVar = new Variable(decl, currentNameSpace());
|
Variable* pVar = new Variable(decl, currentNameSpace());
|
||||||
|
pVar->setAttributeList(attrs);
|
||||||
addSymbol(pVar, static_cast<int>(_istr.getCurrentLineNumber()));
|
addSymbol(pVar, static_cast<int>(_istr.getCurrentLineNumber()));
|
||||||
}
|
}
|
||||||
pNext = next();
|
pNext = next();
|
||||||
@ -611,7 +620,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
|||||||
pNext = next();
|
pNext = next();
|
||||||
expectOperator(pNext, OperatorToken::OP_OPENPARENT, "(");
|
expectOperator(pNext, OperatorToken::OP_OPENPARENT, "(");
|
||||||
}
|
}
|
||||||
pNext = parseFunc(pNext, decl);
|
pNext = parseFunc(pNext, attrs, decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_pCurrentSymbol = 0;
|
_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));
|
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)
|
if (name.find(':') == std::string::npos)
|
||||||
{
|
{
|
||||||
pFunc = new Function(decl, currentNameSpace());
|
pFunc = new Function(decl, currentNameSpace());
|
||||||
|
pFunc->setAttributeList(attrs);
|
||||||
addSymbol(pFunc, line);
|
addSymbol(pFunc, line);
|
||||||
}
|
}
|
||||||
pNext = parseParameters(pNext, pFunc);
|
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)
|
void Parser::addSymbol(Symbol* pSymbol, int lineNumber, bool addGST)
|
||||||
{
|
{
|
||||||
pSymbol->setLineNumber(lineNumber);
|
pSymbol->setLineNumber(lineNumber);
|
||||||
|
@ -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)
|
void Symbol::setDocumentation(const std::string& text)
|
||||||
{
|
{
|
||||||
_documentation = text;
|
_documentation = text;
|
||||||
|
Loading…
Reference in New Issue
Block a user