blob: bb2e81a49b287c71c3a3558c8d84f924adf14f7d [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__)
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +000024// Triggered by the auto-generated pplval variable.
shannon.woods@transgaming.comeb68fd02013-02-28 23:20:01 +000025#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000026#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
shannon.woods@transgaming.comeb68fd02013-02-28 23:20:01 +000027#else
28#pragma GCC diagnostic ignored "-Wuninitialized"
shannon.woods@transgaming.come36fddf2013-01-25 21:57:50 +000029#endif
alokp@chromium.org04d7d222012-05-16 19:24:07 +000030#elif defined(_MSC_VER)
31#pragma warning(disable: 4065 4701)
32#endif
33
34#include "ExpressionParser.h"
35
Jamie Madilld7f21352013-10-30 17:53:15 -040036#include <malloc.h>
alokp@chromium.org04d7d222012-05-16 19:24:07 +000037#include <cassert>
38#include <sstream>
39
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000040#include "DiagnosticsBase.h"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000041#include "Lexer.h"
42#include "Token.h"
43
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000044#if defined(_MSC_VER)
45typedef __int64 YYSTYPE;
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000046#else
47#include <stdint.h>
48typedef intmax_t YYSTYPE;
49#endif // _MSC_VER
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000050#define YYENABLE_NLS 0
51#define YYLTYPE_IS_TRIVIAL 1
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000052#define YYSTYPE_IS_TRIVIAL 1
53#define YYSTYPE_IS_DECLARED 1
54
alokp@chromium.org04d7d222012-05-16 19:24:07 +000055namespace {
56struct Context
57{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000058 pp::Diagnostics* diagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +000059 pp::Lexer* lexer;
60 pp::Token* token;
61 int* result;
62};
63} // namespace
64%}
65
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000066%pure-parser
alokp@chromium.org04d7d222012-05-16 19:24:07 +000067%name-prefix="pp"
68%parse-param {Context *context}
69%lex-param {Context *context}
70
71%{
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000072static int yylex(YYSTYPE* lvalp, Context* context);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000073static void yyerror(Context* context, const char* reason);
74%}
75
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000076%token TOK_CONST_INT
77%left TOK_OP_OR
78%left TOK_OP_AND
alokp@chromium.org04d7d222012-05-16 19:24:07 +000079%left '|'
80%left '^'
81%left '&'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000082%left TOK_OP_EQ TOK_OP_NE
83%left '<' '>' TOK_OP_LE TOK_OP_GE
84%left TOK_OP_LEFT TOK_OP_RIGHT
alokp@chromium.org04d7d222012-05-16 19:24:07 +000085%left '+' '-'
86%left '*' '/' '%'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000087%right TOK_UNARY
alokp@chromium.org04d7d222012-05-16 19:24:07 +000088
89%%
90
91input
92 : expression {
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000093 *(context->result) = static_cast<int>($1);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000094 YYACCEPT;
95 }
96;
97
98expression
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000099 : TOK_CONST_INT
100 | expression TOK_OP_OR expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000101 $$ = $1 || $3;
102 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000103 | expression TOK_OP_AND expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000104 $$ = $1 && $3;
105 }
106 | expression '|' expression {
107 $$ = $1 | $3;
108 }
109 | expression '^' expression {
110 $$ = $1 ^ $3;
111 }
112 | expression '&' expression {
113 $$ = $1 & $3;
114 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000115 | expression TOK_OP_NE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000116 $$ = $1 != $3;
117 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000118 | expression TOK_OP_EQ expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000119 $$ = $1 == $3;
120 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000121 | expression TOK_OP_GE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000122 $$ = $1 >= $3;
123 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000124 | expression TOK_OP_LE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000125 $$ = $1 <= $3;
126 }
127 | expression '>' expression {
128 $$ = $1 > $3;
129 }
130 | expression '<' expression {
131 $$ = $1 < $3;
132 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000133 | expression TOK_OP_RIGHT expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000134 $$ = $1 >> $3;
135 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000136 | expression TOK_OP_LEFT expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000137 $$ = $1 << $3;
138 }
139 | expression '-' expression {
140 $$ = $1 - $3;
141 }
142 | expression '+' expression {
143 $$ = $1 + $3;
144 }
145 | expression '%' expression {
146 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000147 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000148 stream << $1 << " % " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000149 std::string text = stream.str();
150 context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
151 context->token->location,
152 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000153 YYABORT;
154 } else {
155 $$ = $1 % $3;
156 }
157 }
158 | expression '/' expression {
159 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000160 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000161 stream << $1 << " / " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000162 std::string text = stream.str();
163 context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
164 context->token->location,
165 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000166 YYABORT;
167 } else {
168 $$ = $1 / $3;
169 }
170 }
171 | expression '*' expression {
172 $$ = $1 * $3;
173 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000174 | '!' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000175 $$ = ! $2;
176 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000177 | '~' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000178 $$ = ~ $2;
179 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000180 | '-' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000181 $$ = - $2;
182 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000183 | '+' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000184 $$ = + $2;
185 }
186 | '(' expression ')' {
187 $$ = $2;
188 }
189;
190
191%%
192
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +0000193int yylex(YYSTYPE* lvalp, Context* context)
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000194{
195 int type = 0;
196
197 pp::Token* token = context->token;
198 switch (token->type)
199 {
200 case pp::Token::CONST_INT:
alokp@chromium.org2e818912012-06-29 21:26:03 +0000201 {
202 unsigned int val = 0;
203 if (!token->uValue(&val))
204 {
205 context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
206 token->location, token->text);
207 }
208 *lvalp = static_cast<YYSTYPE>(val);
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000209 type = TOK_CONST_INT;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000210 break;
alokp@chromium.org2e818912012-06-29 21:26:03 +0000211 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000212 case pp::Token::OP_OR: type = TOK_OP_OR; break;
213 case pp::Token::OP_AND: type = TOK_OP_AND; break;
214 case pp::Token::OP_NE: type = TOK_OP_NE; break;
215 case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
216 case pp::Token::OP_GE: type = TOK_OP_GE; break;
217 case pp::Token::OP_LE: type = TOK_OP_LE; break;
218 case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
219 case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000220 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 case '(': type = '('; break;
233 case ')': type = ')'; break;
234
235 default: break;
236 }
237
238 // Advance to the next token if the current one is valid.
239 if (type != 0) context->lexer->lex(token);
240
241 return type;
242}
243
244void yyerror(Context* context, const char* reason)
245{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000246 context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
247 context->token->location,
248 reason);
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000249}
250
251namespace pp {
252
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000253ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
254 mLexer(lexer),
255 mDiagnostics(diagnostics)
256{
257}
258
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000259bool ExpressionParser::parse(Token* token, int* result)
260{
261 Context context;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000262 context.diagnostics = mDiagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000263 context.lexer = mLexer;
264 context.token = token;
265 context.result = result;
266 int ret = yyparse(&context);
267 switch (ret)
268 {
269 case 0:
270 case 1:
271 break;
272
273 case 2:
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000274 mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000275 break;
276
277 default:
278 assert(false);
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000279 mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000280 break;
281 }
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000282
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000283 return ret == 0;
284}
285
286} // namespace pp