1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #ifndef QSSG_GLSLPARSER_H |
5 | #define QSSG_GLSLPARSER_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtQuick3DGlslParser/private/glsllexer_p.h> |
19 | #include <QtQuick3DGlslParser/private/glslast_p.h> |
20 | #include <QtQuick3DGlslParser/private/glslengine_p.h> |
21 | #include <QtQuick3DGlslParser/private/glslparsertable_p.h> |
22 | #include <vector> |
23 | #include <stack> |
24 | |
25 | QT_BEGIN_NAMESPACE |
26 | |
27 | namespace GLSL { |
28 | |
29 | class Q_QUICK3DGLSLPARSER_EXPORT Parser: public GLSLParserTable |
30 | { |
31 | public: |
32 | union Value { |
33 | void *ptr; |
34 | const QString *string; |
35 | AST *ast; |
36 | List<AST *> *ast_list; |
37 | DeclarationAST *declaration; |
38 | List<DeclarationAST *> *declaration_list; |
39 | ExpressionAST *expression; |
40 | List<ExpressionAST *> *expression_list; |
41 | StatementAST *statement; |
42 | List<StatementAST *> *statement_list; |
43 | TypeAST *type; |
44 | StructTypeAST::Field *field; |
45 | List<StructTypeAST::Field *> *field_list; |
46 | TranslationUnitAST *translation_unit; |
47 | FunctionIdentifierAST *function_identifier; |
48 | AST::Kind kind; |
49 | TypeAST::Precision precision; |
50 | struct { |
51 | StatementAST *thenClause; |
52 | StatementAST *elseClause; |
53 | } ifstmt; |
54 | struct { |
55 | ExpressionAST *condition; |
56 | ExpressionAST *increment; |
57 | } forstmt; |
58 | struct { |
59 | FunctionIdentifierAST *id; |
60 | List<ExpressionAST *> *arguments; |
61 | } function; |
62 | int qualifier; |
63 | LayoutQualifierAST *layout; |
64 | List<LayoutQualifierAST *> *layout_list; |
65 | struct { |
66 | int qualifier; |
67 | List<LayoutQualifierAST *> *layout_list; |
68 | } type_qualifier; |
69 | struct { |
70 | TypeAST *type; |
71 | const QString *name; |
72 | } param_declarator; |
73 | ParameterDeclarationAST *param_declaration; |
74 | FunctionDeclarationAST *function_declaration; |
75 | }; |
76 | |
77 | Parser(Engine *engine, const char *source, unsigned size, int variant); |
78 | ~Parser(); |
79 | |
80 | TranslationUnitAST *parse() { |
81 | if (AST *u = parse(startToken: T_FEED_GLSL)) |
82 | return u->asTranslationUnit(); |
83 | return nullptr; |
84 | } |
85 | |
86 | ExpressionAST *parseExpression() { |
87 | if (AST *u = parse(startToken: T_FEED_EXPRESSION)) |
88 | return u->asExpression(); |
89 | return nullptr; |
90 | } |
91 | |
92 | AST *parse(int startToken); |
93 | |
94 | private: |
95 | // 1-based |
96 | int &location(int n) { return _locationStack[_tos + n - 1]; } |
97 | Value &sym(int n) { return _symStack[_tos + n - 1]; } |
98 | AST *&ast(int n) { return _symStack[_tos + n - 1].ast; } |
99 | const QString *&string(int n) { return _symStack[_tos + n - 1].string; } |
100 | ExpressionAST *&expression(int n) { return _symStack[_tos + n - 1].expression; } |
101 | StatementAST *&statement(int n) { return _symStack[_tos + n - 1].statement; } |
102 | TypeAST *&type(int n) { return _symStack[_tos + n - 1].type; } |
103 | FunctionDeclarationAST *&function(int n) { return _symStack[_tos + n - 1].function_declaration; } |
104 | |
105 | inline int consumeToken() { |
106 | if (_index < int(_tokens.size())) |
107 | return _index++; |
108 | return static_cast<int>(_tokens.size()) - 1; |
109 | } |
110 | inline const Token &tokenAt(int index) const { |
111 | if (index == 0) |
112 | return _startToken; |
113 | return _tokens.at(n: index); |
114 | } |
115 | inline int tokenKind(int index) const { |
116 | if (index == 0) |
117 | return _startToken.kind; |
118 | return _tokens.at(n: index).kind; |
119 | } |
120 | void reduce(int ruleno); |
121 | |
122 | void warning(int line, const QString &message) |
123 | { |
124 | _engine->warning(line, message); |
125 | } |
126 | |
127 | void error(int line, const QString &message) |
128 | { |
129 | _engine->error(line, message); |
130 | } |
131 | |
132 | template <typename T> |
133 | T *makeAstNode() |
134 | { |
135 | T *node = new (_engine->pool()) T (); |
136 | node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0; |
137 | return node; |
138 | } |
139 | |
140 | template <typename T, typename A1> |
141 | T *makeAstNode(A1 a1) |
142 | { |
143 | T *node = new (_engine->pool()) T (a1); |
144 | node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0; |
145 | return node; |
146 | } |
147 | |
148 | template <typename T, typename A1, typename A2> |
149 | T *makeAstNode(A1 a1, A2 a2) |
150 | { |
151 | T *node = new (_engine->pool()) T (a1, a2); |
152 | node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0; |
153 | return node; |
154 | } |
155 | |
156 | template <typename T, typename A1, typename A2, typename A3> |
157 | T *makeAstNode(A1 a1, A2 a2, A3 a3) |
158 | { |
159 | T *node = new (_engine->pool()) T (a1, a2, a3); |
160 | node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0; |
161 | return node; |
162 | } |
163 | |
164 | template <typename T, typename A1, typename A2, typename A3, typename A4> |
165 | T *makeAstNode(A1 a1, A2 a2, A3 a3, A4 a4) |
166 | { |
167 | T *node = new (_engine->pool()) T (a1, a2, a3, a4); |
168 | node->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0; |
169 | return node; |
170 | } |
171 | |
172 | TypeAST *makeBasicType(int token) |
173 | { |
174 | TypeAST *type = new (_engine->pool()) BasicTypeAST(token, spell[token]); |
175 | type->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0; |
176 | return type; |
177 | } |
178 | |
179 | private: |
180 | Engine *_engine; |
181 | int _tos; |
182 | int _index; |
183 | int yyloc; |
184 | int yytoken; |
185 | int yyrecovering; |
186 | bool _recovered; |
187 | Token _startToken; |
188 | std::vector<int> _stateStack; |
189 | std::vector<int> _locationStack; |
190 | std::vector<Value> _symStack; |
191 | std::vector<Token> _tokens; |
192 | }; |
193 | Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, GLSLParserTable::VariousConstants, Lexer::Variant) |
194 | } // namespace GLSL |
195 | |
196 | QT_END_NAMESPACE |
197 | |
198 | #endif // QSSG_GLSLPARSER_H |
199 | |