blob: 7a7f534917452d1058da95d390b67c8c766e6921 [file] [log] [blame]
alokp@chromium.org04d7d222012-05-16 19:24:07 +00001/*
2//
3// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8This file contains the Yacc grammar for GLSL ES preprocessor expression.
9
10IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
11WHICH GENERATES THE GLSL ES preprocessor expression parser.
12*/
13
14%{
15//
16// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
17// Use of this source code is governed by a BSD-style license that can be
18// found in the LICENSE file.
19//
20
21// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
22
23#if defined(__GNUC__)
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000024#pragma GCC diagnostic ignored "-Wunknown-pragmas"
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +000025// Triggered by the auto-generated pplval variable.
26#pragma GCC diagnostic ignored "-Wuninitialized"
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000027#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
28#pragma GCC diagnostic warning "-Wunknown-pragmas"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000029#elif defined(_MSC_VER)
30#pragma warning(disable: 4065 4701)
31#endif
32
33#include "ExpressionParser.h"
34
35#include <cassert>
36#include <sstream>
37
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000038#include "DiagnosticsBase.h"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000039#include "Lexer.h"
40#include "Token.h"
41
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000042#if defined(_MSC_VER)
43typedef __int64 YYSTYPE;
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000044#else
45#include <stdint.h>
46typedef intmax_t YYSTYPE;
47#endif // _MSC_VER
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000048#define YYENABLE_NLS 0
49#define YYLTYPE_IS_TRIVIAL 1
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000050#define YYSTYPE_IS_TRIVIAL 1
51#define YYSTYPE_IS_DECLARED 1
52
alokp@chromium.org04d7d222012-05-16 19:24:07 +000053namespace {
54struct Context
55{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000056 pp::Diagnostics* diagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +000057 pp::Lexer* lexer;
58 pp::Token* token;
59 int* result;
60};
61} // namespace
62%}
63
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000064%pure-parser
alokp@chromium.org04d7d222012-05-16 19:24:07 +000065%name-prefix="pp"
66%parse-param {Context *context}
67%lex-param {Context *context}
68
69%{
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000070static int yylex(YYSTYPE* lvalp, Context* context);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000071static void yyerror(Context* context, const char* reason);
72%}
73
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000074%token TOK_CONST_INT
75%left TOK_OP_OR
76%left TOK_OP_AND
alokp@chromium.org04d7d222012-05-16 19:24:07 +000077%left '|'
78%left '^'
79%left '&'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000080%left TOK_OP_EQ TOK_OP_NE
81%left '<' '>' TOK_OP_LE TOK_OP_GE
82%left TOK_OP_LEFT TOK_OP_RIGHT
alokp@chromium.org04d7d222012-05-16 19:24:07 +000083%left '+' '-'
84%left '*' '/' '%'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000085%right TOK_UNARY
alokp@chromium.org04d7d222012-05-16 19:24:07 +000086
87%%
88
89input
90 : expression {
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000091 *(context->result) = static_cast<int>($1);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000092 YYACCEPT;
93 }
94;
95
96expression
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000097 : TOK_CONST_INT
98 | expression TOK_OP_OR expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +000099 $$ = $1 || $3;
100 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000101 | expression TOK_OP_AND expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000102 $$ = $1 && $3;
103 }
104 | expression '|' expression {
105 $$ = $1 | $3;
106 }
107 | expression '^' expression {
108 $$ = $1 ^ $3;
109 }
110 | expression '&' expression {
111 $$ = $1 & $3;
112 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000113 | expression TOK_OP_NE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000114 $$ = $1 != $3;
115 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000116 | expression TOK_OP_EQ expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000117 $$ = $1 == $3;
118 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000119 | expression TOK_OP_GE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000120 $$ = $1 >= $3;
121 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000122 | expression TOK_OP_LE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000123 $$ = $1 <= $3;
124 }
125 | expression '>' expression {
126 $$ = $1 > $3;
127 }
128 | expression '<' expression {
129 $$ = $1 < $3;
130 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000131 | expression TOK_OP_RIGHT expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000132 $$ = $1 >> $3;
133 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000134 | expression TOK_OP_LEFT expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000135 $$ = $1 << $3;
136 }
137 | expression '-' expression {
138 $$ = $1 - $3;
139 }
140 | expression '+' expression {
141 $$ = $1 + $3;
142 }
143 | expression '%' expression {
144 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000145 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000146 stream << $1 << " % " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000147 std::string text = stream.str();
148 context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
149 context->token->location,
150 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000151 YYABORT;
152 } else {
153 $$ = $1 % $3;
154 }
155 }
156 | expression '/' expression {
157 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000158 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000159 stream << $1 << " / " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000160 std::string text = stream.str();
161 context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
162 context->token->location,
163 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000164 YYABORT;
165 } else {
166 $$ = $1 / $3;
167 }
168 }
169 | expression '*' expression {
170 $$ = $1 * $3;
171 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000172 | '!' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000173 $$ = ! $2;
174 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000175 | '~' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000176 $$ = ~ $2;
177 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000178 | '-' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000179 $$ = - $2;
180 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000181 | '+' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000182 $$ = + $2;
183 }
184 | '(' expression ')' {
185 $$ = $2;
186 }
187;
188
189%%
190
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +0000191int yylex(YYSTYPE* lvalp, Context* context)
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000192{
193 int type = 0;
194
195 pp::Token* token = context->token;
196 switch (token->type)
197 {
198 case pp::Token::CONST_INT:
alokp@chromium.org2e818912012-06-29 21:26:03 +0000199 {
200 unsigned int val = 0;
201 if (!token->uValue(&val))
202 {
203 context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
204 token->location, token->text);
205 }
206 *lvalp = static_cast<YYSTYPE>(val);
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000207 type = TOK_CONST_INT;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000208 break;
alokp@chromium.org2e818912012-06-29 21:26:03 +0000209 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000210 case pp::Token::OP_OR: type = TOK_OP_OR; break;
211 case pp::Token::OP_AND: type = TOK_OP_AND; break;
212 case pp::Token::OP_NE: type = TOK_OP_NE; break;
213 case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
214 case pp::Token::OP_GE: type = TOK_OP_GE; break;
215 case pp::Token::OP_LE: type = TOK_OP_LE; break;
216 case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
217 case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000218 case '|': type = '|'; break;
219 case '^': type = '^'; break;
220 case '&': type = '&'; break;
221 case '>': type = '>'; break;
222 case '<': type = '<'; break;
223 case '-': type = '-'; break;
224 case '+': type = '+'; break;
225 case '%': type = '%'; break;
226 case '/': type = '/'; break;
227 case '*': type = '*'; break;
228 case '!': type = '!'; break;
229 case '~': type = '~'; break;
230 case '(': type = '('; break;
231 case ')': type = ')'; break;
232
233 default: break;
234 }
235
236 // Advance to the next token if the current one is valid.
237 if (type != 0) context->lexer->lex(token);
238
239 return type;
240}
241
242void yyerror(Context* context, const char* reason)
243{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000244 context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
245 context->token->location,
246 reason);
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000247}
248
249namespace pp {
250
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000251ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
252 mLexer(lexer),
253 mDiagnostics(diagnostics)
254{
255}
256
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000257bool ExpressionParser::parse(Token* token, int* result)
258{
259 Context context;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000260 context.diagnostics = mDiagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000261 context.lexer = mLexer;
262 context.token = token;
263 context.result = result;
264 int ret = yyparse(&context);
265 switch (ret)
266 {
267 case 0:
268 case 1:
269 break;
270
271 case 2:
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000272 mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000273 break;
274
275 default:
276 assert(false);
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000277 mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000278 break;
279 }
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000280
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000281 return ret == 0;
282}
283
284} // namespace pp