blob: 8caf36bfc87fbe4f822b1af848712c97c61c14a7 [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)
Jamie Madillb3584fb2015-04-09 17:34:21 +000031#pragma warning(disable: 4065 4701 4702)
alokp@chromium.org04d7d222012-05-16 19:24:07 +000032#endif
33
34#include "ExpressionParser.h"
35
Jamie Madilla738f082013-11-01 17:45:04 -040036#if defined(_MSC_VER)
Jamie Madilld7f21352013-10-30 17:53:15 -040037#include <malloc.h>
Jamie Madilla738f082013-11-01 17:45:04 -040038#else
39#include <stdlib.h>
40#endif
41
alokp@chromium.org04d7d222012-05-16 19:24:07 +000042#include <cassert>
43#include <sstream>
44
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000045#include "DiagnosticsBase.h"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000046#include "Lexer.h"
47#include "Token.h"
48
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000049#if defined(_MSC_VER)
50typedef __int64 YYSTYPE;
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000051#else
52#include <stdint.h>
53typedef intmax_t YYSTYPE;
54#endif // _MSC_VER
daniel@transgaming.comb3077d02013-01-11 04:12:09 +000055#define YYENABLE_NLS 0
56#define YYLTYPE_IS_TRIVIAL 1
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000057#define YYSTYPE_IS_TRIVIAL 1
58#define YYSTYPE_IS_DECLARED 1
59
alokp@chromium.org04d7d222012-05-16 19:24:07 +000060namespace {
61struct Context
62{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000063 pp::Diagnostics* diagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +000064 pp::Lexer* lexer;
65 pp::Token* token;
66 int* result;
67};
68} // namespace
69%}
70
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000071%pure-parser
Jamie Madill185de882014-12-22 15:17:52 -050072%name-prefix "pp"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000073%parse-param {Context *context}
74%lex-param {Context *context}
75
76%{
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000077static int yylex(YYSTYPE* lvalp, Context* context);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000078static void yyerror(Context* context, const char* reason);
79%}
80
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000081%token TOK_CONST_INT
82%left TOK_OP_OR
83%left TOK_OP_AND
alokp@chromium.org04d7d222012-05-16 19:24:07 +000084%left '|'
85%left '^'
86%left '&'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000087%left TOK_OP_EQ TOK_OP_NE
88%left '<' '>' TOK_OP_LE TOK_OP_GE
89%left TOK_OP_LEFT TOK_OP_RIGHT
alokp@chromium.org04d7d222012-05-16 19:24:07 +000090%left '+' '-'
91%left '*' '/' '%'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000092%right TOK_UNARY
alokp@chromium.org04d7d222012-05-16 19:24:07 +000093
94%%
95
96input
97 : expression {
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000098 *(context->result) = static_cast<int>($1);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000099 YYACCEPT;
100 }
101;
102
103expression
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000104 : TOK_CONST_INT
105 | expression TOK_OP_OR expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000106 $$ = $1 || $3;
107 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000108 | expression TOK_OP_AND expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000109 $$ = $1 && $3;
110 }
111 | expression '|' expression {
112 $$ = $1 | $3;
113 }
114 | expression '^' expression {
115 $$ = $1 ^ $3;
116 }
117 | expression '&' expression {
118 $$ = $1 & $3;
119 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000120 | expression TOK_OP_NE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000121 $$ = $1 != $3;
122 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000123 | expression TOK_OP_EQ expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000124 $$ = $1 == $3;
125 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000126 | expression TOK_OP_GE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000127 $$ = $1 >= $3;
128 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000129 | expression TOK_OP_LE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000130 $$ = $1 <= $3;
131 }
132 | expression '>' expression {
133 $$ = $1 > $3;
134 }
135 | expression '<' expression {
136 $$ = $1 < $3;
137 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000138 | expression TOK_OP_RIGHT expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000139 $$ = $1 >> $3;
140 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000141 | expression TOK_OP_LEFT expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000142 $$ = $1 << $3;
143 }
144 | expression '-' expression {
145 $$ = $1 - $3;
146 }
147 | expression '+' expression {
148 $$ = $1 + $3;
149 }
150 | expression '%' expression {
151 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000152 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000153 stream << $1 << " % " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000154 std::string text = stream.str();
Jamie Madillc9f140d2014-02-18 15:27:21 -0500155 context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000156 context->token->location,
157 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000158 YYABORT;
159 } else {
160 $$ = $1 % $3;
161 }
162 }
163 | expression '/' expression {
164 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000165 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000166 stream << $1 << " / " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000167 std::string text = stream.str();
Jamie Madillc9f140d2014-02-18 15:27:21 -0500168 context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000169 context->token->location,
170 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000171 YYABORT;
172 } else {
173 $$ = $1 / $3;
174 }
175 }
176 | expression '*' expression {
177 $$ = $1 * $3;
178 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000179 | '!' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000180 $$ = ! $2;
181 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000182 | '~' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000183 $$ = ~ $2;
184 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000185 | '-' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000186 $$ = - $2;
187 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000188 | '+' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000189 $$ = + $2;
190 }
191 | '(' expression ')' {
192 $$ = $2;
193 }
194;
195
196%%
197
Zhenyao Mod526f982014-05-13 14:51:19 -0700198int yylex(YYSTYPE *lvalp, Context *context)
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000199{
200 int type = 0;
201
Zhenyao Mod526f982014-05-13 14:51:19 -0700202 pp::Token *token = context->token;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000203 switch (token->type)
204 {
Zhenyao Mod526f982014-05-13 14:51:19 -0700205 case pp::Token::CONST_INT: {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000206 unsigned int val = 0;
207 if (!token->uValue(&val))
208 {
Jamie Madillc9f140d2014-02-18 15:27:21 -0500209 context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW,
alokp@chromium.org2e818912012-06-29 21:26:03 +0000210 token->location, token->text);
211 }
212 *lvalp = static_cast<YYSTYPE>(val);
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000213 type = TOK_CONST_INT;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000214 break;
alokp@chromium.org2e818912012-06-29 21:26:03 +0000215 }
Zhenyao Mod526f982014-05-13 14:51:19 -0700216 case pp::Token::OP_OR:
217 type = TOK_OP_OR;
218 break;
219 case pp::Token::OP_AND:
220 type = TOK_OP_AND;
221 break;
222 case pp::Token::OP_NE:
223 type = TOK_OP_NE;
224 break;
225 case pp::Token::OP_EQ:
226 type = TOK_OP_EQ;
227 break;
228 case pp::Token::OP_GE:
229 type = TOK_OP_GE;
230 break;
231 case pp::Token::OP_LE:
232 type = TOK_OP_LE;
233 break;
234 case pp::Token::OP_RIGHT:
235 type = TOK_OP_RIGHT;
236 break;
237 case pp::Token::OP_LEFT:
238 type = TOK_OP_LEFT;
239 break;
240 case '|':
241 case '^':
242 case '&':
243 case '>':
244 case '<':
245 case '-':
246 case '+':
247 case '%':
248 case '/':
249 case '*':
250 case '!':
251 case '~':
252 case '(':
253 case ')':
254 type = token->type;
255 break;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000256
Zhenyao Mod526f982014-05-13 14:51:19 -0700257 default:
258 break;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000259 }
260
261 // Advance to the next token if the current one is valid.
Zhenyao Mod526f982014-05-13 14:51:19 -0700262 if (type != 0)
263 context->lexer->lex(token);
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000264
265 return type;
266}
267
Zhenyao Mod526f982014-05-13 14:51:19 -0700268void yyerror(Context *context, const char *reason)
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000269{
Jamie Madillc9f140d2014-02-18 15:27:21 -0500270 context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION,
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000271 context->token->location,
272 reason);
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000273}
274
275namespace pp {
276
Zhenyao Mod526f982014-05-13 14:51:19 -0700277ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
278 : mLexer(lexer),
279 mDiagnostics(diagnostics)
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000280{
281}
282
Zhenyao Mod526f982014-05-13 14:51:19 -0700283bool ExpressionParser::parse(Token *token, int *result)
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000284{
285 Context context;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000286 context.diagnostics = mDiagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000287 context.lexer = mLexer;
288 context.token = token;
289 context.result = result;
290 int ret = yyparse(&context);
291 switch (ret)
292 {
293 case 0:
294 case 1:
295 break;
296
297 case 2:
Jamie Madillc9f140d2014-02-18 15:27:21 -0500298 mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000299 break;
300
301 default:
302 assert(false);
Jamie Madillc9f140d2014-02-18 15:27:21 -0500303 mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000304 break;
305 }
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000306
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000307 return ret == 0;
308}
309
310} // namespace pp