summaryrefslogtreecommitdiffstats
path: root/tools/slang-cpp-extractor/parser.h
blob: cf0147e8b4367c46c4a3908df4f43c15c6a6d68c (plain)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef CPP_EXTRACT_PARSER_H
#define CPP_EXTRACT_PARSER_H

#include "diagnostics.h"
#include "node.h"
#include "identifier-lookup.h"
#include "node-tree.h"

#include "../../source/compiler-core/slang-lexer.h"

namespace CppExtract {
using namespace Slang;

class Parser
{
public:

    typedef uint32_t NodeTypeBitType;

    SlangResult expect(TokenType type, Token* outToken = nullptr);

    bool advanceIfMarker(Token* outToken = nullptr);
    bool advanceIfToken(TokenType type, Token* outToken = nullptr);
    bool advanceIfStyle(IdentifierStyle style, Token* outToken = nullptr);

    SlangResult pushAnonymousNamespace();
    SlangResult pushScope(ScopeNode* node);
    SlangResult consumeToClosingBrace(const Token* openBraceToken = nullptr);
    SlangResult popScope();

        /// Parse the contents of the source file
    SlangResult parse(SourceOrigin* sourceOrigin, const Options* options);

    void setKindEnabled(Node::Kind kind, bool isEnabled = true);
    bool isTypeEnabled(Node::Kind kind) { return (m_nodeTypeEnabled & (NodeTypeBitType(1) << int(kind))) != 0; }

    void setKindsEnabled(const Node::Kind* kinds, Index kindsCount, bool isEnabled = true);

    Parser(NodeTree* nodeTree, DiagnosticSink* sink);

protected:
    static Node::Kind _toNodeKind(IdentifierStyle style);

    bool _isMarker(const UnownedStringSlice& name);

    SlangResult _maybeConsumeScope();

    SlangResult _parsePreDeclare();
    SlangResult _parseTypeSet();

    SlangResult _maybeParseNode(Node::Kind kind);
    SlangResult _maybeParseContained(Node** outNode);

    SlangResult _parseTypeDef();
    SlangResult _parseEnum();
    SlangResult _parseMarker();
    SlangResult _parseSpecialMacro();

    SlangResult _maybeParseType(List<Token>& outToks, Token& outName);
    SlangResult _maybeParseType(UnownedStringSlice& outType, Token& outName);
    SlangResult _maybeParseType(Index& ioTemplateDepth, TokenReader::ParsingCursor& outCursor);

    SlangResult _parseExpression(List<Token>& outExprTokens);
    
    SlangResult _maybeParseTemplateArgs(Index& ioTemplateDepth);
    SlangResult _maybeParseTemplateArg(Index& ioTemplateDepth);

        /// Parse balanced - if a sink is set will report to that sink
    SlangResult _parseBalanced(DiagnosticSink* sink);

    bool _isCtor();

        /// Concatenate all tokens from start to the current position
    UnownedStringSlice _concatTokens(TokenReader::ParsingCursor start);
    UnownedStringSlice _concatTokens(const Token* toks, Index toksCount);

    UnownedStringSlice _concatType(TokenReader::ParsingCursor start, TokenReader::ParsingCursor nameCursor);

    void _getTypeTokens(TokenReader::ParsingCursor start, TokenReader::ParsingCursor nameCursor, List<Token>& outToks);

        /// Consume what looks like a template definition
    SlangResult _consumeTemplate();
    SlangResult _maybeConsume(IdentifierStyle style);

    SlangResult _consumeToSync();
        /// Consumes balanced parens. Will return an error if not matched. Assumes starts on opening (
    SlangResult _consumeBalancedParens();

    NodeTypeBitType m_nodeTypeEnabled;

    TokenList m_tokenList;
    TokenReader m_reader;

    List<ScopeNode*> m_scopeStack;

    ScopeNode* m_currentScope;          ///< The current scope being processed
    SourceOrigin* m_sourceOrigin;       ///< The source origin that all tokens are in

    DiagnosticSink* m_sink;             ///< Diagnostic sink 

    NodeTree* m_nodeTree;    ///< Shared state between parses. Nodes will be added to this

    const Options* m_options;
};

} // CppExtract

#endif