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
25QT_BEGIN_NAMESPACE
26
27namespace GLSL {
28
29class Q_QUICK3DGLSLPARSER_EXPORT Parser: public GLSLParserTable
30{
31public:
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
94private:
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
179private:
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};
193Q_DECLARE_MIXED_ENUM_OPERATORS_SYMMETRIC(int, GLSLParserTable::VariousConstants, Lexer::Variant)
194} // namespace GLSL
195
196QT_END_NAMESPACE
197
198#endif // QSSG_GLSLPARSER_H
199

source code of qtquick3d/src/glslparser/glslparser_p.h