blob: 832ad4001e9402cea2b8827cc8fa1af798f90669 [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.
25#pragma GCC diagnostic ignored "-Wuninitialized"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000026#elif defined(_MSC_VER)
27#pragma warning(disable: 4065 4701)
28#endif
29
30#include "ExpressionParser.h"
31
32#include <cassert>
33#include <sstream>
34
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000035#include "Diagnostics.h"
alokp@chromium.org04d7d222012-05-16 19:24:07 +000036#include "Lexer.h"
37#include "Token.h"
38
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000039#if defined(_MSC_VER)
40typedef __int64 YYSTYPE;
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000041#else
42#include <stdint.h>
43typedef intmax_t YYSTYPE;
44#endif // _MSC_VER
45#define YYSTYPE_IS_TRIVIAL 1
46#define YYSTYPE_IS_DECLARED 1
47
alokp@chromium.org04d7d222012-05-16 19:24:07 +000048namespace {
49struct Context
50{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +000051 pp::Diagnostics* diagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +000052 pp::Lexer* lexer;
53 pp::Token* token;
54 int* result;
55};
56} // namespace
57%}
58
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000059%pure-parser
alokp@chromium.org04d7d222012-05-16 19:24:07 +000060%name-prefix="pp"
61%parse-param {Context *context}
62%lex-param {Context *context}
63
64%{
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000065static int yylex(YYSTYPE* lvalp, Context* context);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000066static void yyerror(Context* context, const char* reason);
67%}
68
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000069%token TOK_CONST_INT
70%left TOK_OP_OR
71%left TOK_OP_AND
alokp@chromium.org04d7d222012-05-16 19:24:07 +000072%left '|'
73%left '^'
74%left '&'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000075%left TOK_OP_EQ TOK_OP_NE
76%left '<' '>' TOK_OP_LE TOK_OP_GE
77%left TOK_OP_LEFT TOK_OP_RIGHT
alokp@chromium.org04d7d222012-05-16 19:24:07 +000078%left '+' '-'
79%left '*' '/' '%'
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000080%right TOK_UNARY
alokp@chromium.org04d7d222012-05-16 19:24:07 +000081
82%%
83
84input
85 : expression {
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +000086 *(context->result) = static_cast<int>($1);
alokp@chromium.org04d7d222012-05-16 19:24:07 +000087 YYACCEPT;
88 }
89;
90
91expression
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000092 : TOK_CONST_INT
93 | expression TOK_OP_OR expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +000094 $$ = $1 || $3;
95 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +000096 | expression TOK_OP_AND expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +000097 $$ = $1 && $3;
98 }
99 | expression '|' expression {
100 $$ = $1 | $3;
101 }
102 | expression '^' expression {
103 $$ = $1 ^ $3;
104 }
105 | expression '&' expression {
106 $$ = $1 & $3;
107 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000108 | expression TOK_OP_NE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000109 $$ = $1 != $3;
110 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000111 | expression TOK_OP_EQ expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000112 $$ = $1 == $3;
113 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000114 | expression TOK_OP_GE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000115 $$ = $1 >= $3;
116 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000117 | expression TOK_OP_LE expression {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000118 $$ = $1 <= $3;
119 }
120 | expression '>' expression {
121 $$ = $1 > $3;
122 }
123 | expression '<' expression {
124 $$ = $1 < $3;
125 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000126 | expression TOK_OP_RIGHT 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_LEFT 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 }
138 | expression '%' expression {
139 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000140 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000141 stream << $1 << " % " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000142 std::string text = stream.str();
143 context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
144 context->token->location,
145 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000146 YYABORT;
147 } else {
148 $$ = $1 % $3;
149 }
150 }
151 | expression '/' expression {
152 if ($3 == 0) {
alokp@chromium.org2e818912012-06-29 21:26:03 +0000153 std::ostringstream stream;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000154 stream << $1 << " / " << $3;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000155 std::string text = stream.str();
156 context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
157 context->token->location,
158 text.c_str());
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000159 YYABORT;
160 } else {
161 $$ = $1 / $3;
162 }
163 }
164 | expression '*' expression {
165 $$ = $1 * $3;
166 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000167 | '!' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000168 $$ = ! $2;
169 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000170 | '~' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000171 $$ = ~ $2;
172 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000173 | '-' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000174 $$ = - $2;
175 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000176 | '+' expression %prec TOK_UNARY {
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000177 $$ = + $2;
178 }
179 | '(' expression ')' {
180 $$ = $2;
181 }
182;
183
184%%
185
alokp@chromium.orgd39ec4c2012-06-26 04:37:55 +0000186int yylex(YYSTYPE* lvalp, Context* context)
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000187{
188 int type = 0;
189
190 pp::Token* token = context->token;
191 switch (token->type)
192 {
193 case pp::Token::CONST_INT:
alokp@chromium.org2e818912012-06-29 21:26:03 +0000194 {
195 unsigned int val = 0;
196 if (!token->uValue(&val))
197 {
198 context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
199 token->location, token->text);
200 }
201 *lvalp = static_cast<YYSTYPE>(val);
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000202 type = TOK_CONST_INT;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000203 break;
alokp@chromium.org2e818912012-06-29 21:26:03 +0000204 }
maxvujovic@gmail.come640ef82012-07-13 18:42:40 +0000205 case pp::Token::OP_OR: type = TOK_OP_OR; break;
206 case pp::Token::OP_AND: type = TOK_OP_AND; break;
207 case pp::Token::OP_NE: type = TOK_OP_NE; break;
208 case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
209 case pp::Token::OP_GE: type = TOK_OP_GE; break;
210 case pp::Token::OP_LE: type = TOK_OP_LE; break;
211 case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
212 case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000213 case '|': type = '|'; break;
214 case '^': type = '^'; break;
215 case '&': type = '&'; break;
216 case '>': type = '>'; break;
217 case '<': type = '<'; break;
218 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
228 default: break;
229 }
230
231 // Advance to the next token if the current one is valid.
232 if (type != 0) context->lexer->lex(token);
233
234 return type;
235}
236
237void yyerror(Context* context, const char* reason)
238{
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000239 context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
240 context->token->location,
241 reason);
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000242}
243
244namespace pp {
245
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000246ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
247 mLexer(lexer),
248 mDiagnostics(diagnostics)
249{
250}
251
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000252bool ExpressionParser::parse(Token* token, int* result)
253{
254 Context context;
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000255 context.diagnostics = mDiagnostics;
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000256 context.lexer = mLexer;
257 context.token = token;
258 context.result = result;
259 int ret = yyparse(&context);
260 switch (ret)
261 {
262 case 0:
263 case 1:
264 break;
265
266 case 2:
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000267 mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000268 break;
269
270 default:
271 assert(false);
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000272 mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000273 break;
274 }
alokp@chromium.org2c958ee2012-05-17 20:35:42 +0000275
alokp@chromium.org04d7d222012-05-16 19:24:07 +0000276 return ret == 0;
277}
278
279} // namespace pp