gfx/angle/src/compiler/preprocessor/ExpressionParser.y

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/angle/src/compiler/preprocessor/ExpressionParser.y	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,285 @@
     1.4 +/*
     1.5 +//
     1.6 +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
     1.7 +// Use of this source code is governed by a BSD-style license that can be
     1.8 +// found in the LICENSE file.
     1.9 +//
    1.10 +
    1.11 +This file contains the Yacc grammar for GLSL ES preprocessor expression.
    1.12 +
    1.13 +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
    1.14 +WHICH GENERATES THE GLSL ES preprocessor expression parser.
    1.15 +*/
    1.16 +
    1.17 +%{
    1.18 +//
    1.19 +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
    1.20 +// Use of this source code is governed by a BSD-style license that can be
    1.21 +// found in the LICENSE file.
    1.22 +//
    1.23 +
    1.24 +// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
    1.25 +
    1.26 +#if defined(__GNUC__)
    1.27 +// Triggered by the auto-generated pplval variable.
    1.28 +#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
    1.29 +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
    1.30 +#else
    1.31 +#pragma GCC diagnostic ignored "-Wuninitialized"
    1.32 +#endif
    1.33 +#elif defined(_MSC_VER)
    1.34 +#pragma warning(disable: 4065 4701)
    1.35 +#endif
    1.36 +
    1.37 +#include "ExpressionParser.h"
    1.38 +
    1.39 +#include <cassert>
    1.40 +#include <sstream>
    1.41 +
    1.42 +#include "DiagnosticsBase.h"
    1.43 +#include "Lexer.h"
    1.44 +#include "Token.h"
    1.45 +
    1.46 +#if defined(_MSC_VER)
    1.47 +typedef __int64 YYSTYPE;
    1.48 +#else
    1.49 +#include <stdint.h>
    1.50 +typedef intmax_t YYSTYPE;
    1.51 +#endif  // _MSC_VER
    1.52 +#define YYENABLE_NLS 0
    1.53 +#define YYLTYPE_IS_TRIVIAL 1
    1.54 +#define YYSTYPE_IS_TRIVIAL 1
    1.55 +#define YYSTYPE_IS_DECLARED 1
    1.56 +
    1.57 +namespace {
    1.58 +struct Context
    1.59 +{
    1.60 +    pp::Diagnostics* diagnostics;
    1.61 +    pp::Lexer* lexer;
    1.62 +    pp::Token* token;
    1.63 +    int* result;
    1.64 +};
    1.65 +}  // namespace
    1.66 +%}
    1.67 +
    1.68 +%pure-parser
    1.69 +%name-prefix="pp"
    1.70 +%parse-param {Context *context}
    1.71 +%lex-param {Context *context}
    1.72 +
    1.73 +%{
    1.74 +static int yylex(YYSTYPE* lvalp, Context* context);
    1.75 +static void yyerror(Context* context, const char* reason);
    1.76 +%}
    1.77 +
    1.78 +%token TOK_CONST_INT
    1.79 +%left TOK_OP_OR
    1.80 +%left TOK_OP_AND
    1.81 +%left '|'
    1.82 +%left '^'
    1.83 +%left '&'
    1.84 +%left TOK_OP_EQ TOK_OP_NE
    1.85 +%left '<' '>' TOK_OP_LE TOK_OP_GE
    1.86 +%left TOK_OP_LEFT TOK_OP_RIGHT
    1.87 +%left '+' '-'
    1.88 +%left '*' '/' '%'
    1.89 +%right TOK_UNARY
    1.90 +
    1.91 +%%
    1.92 +
    1.93 +input
    1.94 +    : expression {
    1.95 +        *(context->result) = static_cast<int>($1);
    1.96 +        YYACCEPT;
    1.97 +    }
    1.98 +;
    1.99 +
   1.100 +expression
   1.101 +    : TOK_CONST_INT
   1.102 +    | expression TOK_OP_OR expression {
   1.103 +        $$ = $1 || $3;
   1.104 +    }
   1.105 +    | expression TOK_OP_AND expression {
   1.106 +        $$ = $1 && $3;
   1.107 +    }
   1.108 +    | expression '|' expression {
   1.109 +        $$ = $1 | $3;
   1.110 +    }
   1.111 +    | expression '^' expression {
   1.112 +        $$ = $1 ^ $3;
   1.113 +    }
   1.114 +    | expression '&' expression {
   1.115 +        $$ = $1 & $3;
   1.116 +    }
   1.117 +    | expression TOK_OP_NE expression {
   1.118 +        $$ = $1 != $3;
   1.119 +    }
   1.120 +    | expression TOK_OP_EQ expression {
   1.121 +        $$ = $1 == $3;
   1.122 +    }
   1.123 +    | expression TOK_OP_GE expression {
   1.124 +        $$ = $1 >= $3;
   1.125 +    }
   1.126 +    | expression TOK_OP_LE expression {
   1.127 +        $$ = $1 <= $3;
   1.128 +    }
   1.129 +    | expression '>' expression {
   1.130 +        $$ = $1 > $3;
   1.131 +    }
   1.132 +    | expression '<' expression {
   1.133 +        $$ = $1 < $3;
   1.134 +    }
   1.135 +    | expression TOK_OP_RIGHT expression {
   1.136 +        $$ = $1 >> $3;
   1.137 +    }
   1.138 +    | expression TOK_OP_LEFT expression {
   1.139 +        $$ = $1 << $3;
   1.140 +    }
   1.141 +    | expression '-' expression {
   1.142 +        $$ = $1 - $3;
   1.143 +    }
   1.144 +    | expression '+' expression {
   1.145 +        $$ = $1 + $3;
   1.146 +    }
   1.147 +    | expression '%' expression {
   1.148 +        if ($3 == 0) {
   1.149 +            std::ostringstream stream;
   1.150 +            stream << $1 << " % " << $3;
   1.151 +            std::string text = stream.str();
   1.152 +            context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
   1.153 +                                         context->token->location,
   1.154 +                                         text.c_str());
   1.155 +            YYABORT;
   1.156 +        } else {
   1.157 +            $$ = $1 % $3;
   1.158 +        }
   1.159 +    }
   1.160 +    | expression '/' expression {
   1.161 +        if ($3 == 0) {
   1.162 +            std::ostringstream stream;
   1.163 +            stream << $1 << " / " << $3;
   1.164 +            std::string text = stream.str();
   1.165 +            context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO,
   1.166 +                                         context->token->location,
   1.167 +                                         text.c_str());
   1.168 +            YYABORT;
   1.169 +        } else {
   1.170 +            $$ = $1 / $3;
   1.171 +        }
   1.172 +    }
   1.173 +    | expression '*' expression {
   1.174 +        $$ = $1 * $3;
   1.175 +    }
   1.176 +    | '!' expression %prec TOK_UNARY {
   1.177 +        $$ = ! $2;
   1.178 +    }
   1.179 +    | '~' expression %prec TOK_UNARY {
   1.180 +        $$ = ~ $2;
   1.181 +    }
   1.182 +    | '-' expression %prec TOK_UNARY {
   1.183 +        $$ = - $2;
   1.184 +    }
   1.185 +    | '+' expression %prec TOK_UNARY {
   1.186 +        $$ = + $2;
   1.187 +    }
   1.188 +    | '(' expression ')' {
   1.189 +        $$ = $2;
   1.190 +    }
   1.191 +;
   1.192 +
   1.193 +%%
   1.194 +
   1.195 +int yylex(YYSTYPE* lvalp, Context* context)
   1.196 +{
   1.197 +    int type = 0;
   1.198 +
   1.199 +    pp::Token* token = context->token;
   1.200 +    switch (token->type)
   1.201 +    {
   1.202 +      case pp::Token::CONST_INT:
   1.203 +      {
   1.204 +        unsigned int val = 0;
   1.205 +        if (!token->uValue(&val))
   1.206 +        {
   1.207 +            context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW,
   1.208 +                                         token->location, token->text);
   1.209 +        }
   1.210 +        *lvalp = static_cast<YYSTYPE>(val);
   1.211 +        type = TOK_CONST_INT;
   1.212 +        break;
   1.213 +      }
   1.214 +      case pp::Token::OP_OR: type = TOK_OP_OR; break;
   1.215 +      case pp::Token::OP_AND: type = TOK_OP_AND; break;
   1.216 +      case pp::Token::OP_NE: type = TOK_OP_NE; break;
   1.217 +      case pp::Token::OP_EQ: type = TOK_OP_EQ; break;
   1.218 +      case pp::Token::OP_GE: type = TOK_OP_GE; break;
   1.219 +      case pp::Token::OP_LE: type = TOK_OP_LE; break;
   1.220 +      case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break;
   1.221 +      case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break;
   1.222 +      case '|': type = '|'; break;
   1.223 +      case '^': type = '^'; break;
   1.224 +      case '&': type = '&'; break;
   1.225 +      case '>': type = '>'; break;
   1.226 +      case '<': type = '<'; break;
   1.227 +      case '-': type = '-'; break;
   1.228 +      case '+': type = '+'; break;
   1.229 +      case '%': type = '%'; break;
   1.230 +      case '/': type = '/'; break;
   1.231 +      case '*': type = '*'; break;
   1.232 +      case '!': type = '!'; break;
   1.233 +      case '~': type = '~'; break;
   1.234 +      case '(': type = '('; break;
   1.235 +      case ')': type = ')'; break;
   1.236 +
   1.237 +      default: break;
   1.238 +    }
   1.239 +
   1.240 +    // Advance to the next token if the current one is valid.
   1.241 +    if (type != 0) context->lexer->lex(token);
   1.242 +
   1.243 +    return type;
   1.244 +}
   1.245 +
   1.246 +void yyerror(Context* context, const char* reason)
   1.247 +{
   1.248 +    context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION,
   1.249 +                                 context->token->location,
   1.250 +                                 reason);
   1.251 +}
   1.252 +
   1.253 +namespace pp {
   1.254 +
   1.255 +ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) :
   1.256 +    mLexer(lexer),
   1.257 +    mDiagnostics(diagnostics)
   1.258 +{
   1.259 +}
   1.260 +
   1.261 +bool ExpressionParser::parse(Token* token, int* result)
   1.262 +{
   1.263 +    Context context;
   1.264 +    context.diagnostics = mDiagnostics;
   1.265 +    context.lexer = mLexer;
   1.266 +    context.token = token;
   1.267 +    context.result = result;
   1.268 +    int ret = yyparse(&context);
   1.269 +    switch (ret)
   1.270 +    {
   1.271 +      case 0:
   1.272 +      case 1:
   1.273 +        break;
   1.274 +
   1.275 +      case 2:
   1.276 +        mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, "");
   1.277 +        break;
   1.278 +
   1.279 +      default:
   1.280 +        assert(false);
   1.281 +        mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, "");
   1.282 +        break;
   1.283 +    }
   1.284 +
   1.285 +    return ret == 0;
   1.286 +}
   1.287 +
   1.288 +}  // namespace pp

mercurial