-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
HeaderParser.h
88 lines (75 loc) · 2.55 KB
/
HeaderParser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#pragma once
#include <string>
#include <vector>
#include "TypeSet.h"
// Parses structures from a C++ header file.
class HeaderParser {
public:
enum class Error {
OK = 0,
TYPE_REDEFINITION,
UNSUPPORTED_TYPE,
UNEXPECTED_EOF,
STRUCT_NAME_EXPECTED,
ENUM_NAME_EXPECTED,
INVALID_STRUCTURE_SYNTAX,
INVALID_ENUM_SYNTAX,
INVALID_TYPENAME_SYNTAX,
INVALID_ARRAY_SYNTAX,
INVALID_NAMESPACE_SYNTAX,
NOT_IMPLEMENTED
};
HeaderParser(TypeSet *outputTypeSet, const char *headerStart, size_t headerLength);
Error parse();
private:
TypeSet *typeSet;
const char *cur, *end;
std::vector<std::string> curNamespace;
std::vector<std::string> usingNamespaces;
bool parseStructNamesOnly = false; // prepass in case input files are in the wrong order
enum SkipWhitespaceMode {
SINGLE_LINE,
MULTI_LINE
};
enum BraceTypes {
ANY_BRACES_EXCEPT_ANGLED,
ANY_BRACES_INCLUDING_ANGLED
};
Type * findType(const std::string &name);
template <typename... T>
ContainerTemplate<T...> * findContainerTemplate(const std::string &name);
void parseSection();
void parseNamespace();
const Type * parseStruct();
const Type * parseEnum();
const Type * parseType();
int parseArrayLength();
std::string readNamespacedIdentifier();
std::string readIdentifier();
void skipWhitespaceAndComments(SkipWhitespaceMode mode);
void skipWhitespace(SkipWhitespaceMode mode);
void skipComment();
void skipStringLiteral();
void skipExpression();
void skipBlock(BraceTypes braceTypes);
void skipSection();
void skipTemplateArgument();
void skipDirective();
bool matchSymbol(char s);
bool matchKeyword(const char *keyword);
static bool isNonSymbol(char c);
};
HeaderParser::Error parseHeader(TypeSet &outputTypeSet, const std::string &headerString);
template <typename... T>
ContainerTemplate<T...> * HeaderParser::findContainerTemplate(const std::string &name) {
if (name.empty())
return nullptr;
if (name.size() >= 2 && name[0] == ':' && name[1] == ':')
return typeSet->findContainerTemplate<T...>(name.substr(2));
if (ContainerTemplate<T...> *containerTemplate = typeSet->findContainerTemplate<T...>(name))
return containerTemplate;
for (const std::string &ns : usingNamespaces)
if (ContainerTemplate<T...> *containerTemplate = typeSet->findContainerTemplate<T...>(ns+"::"+name))
return containerTemplate;
return nullptr;
}