| %{ | |
| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file Copyright.txt or https://cmake.org/licensing for details. */ | |
| /* | |
| This file must be translated to C and modified to build everywhere. | |
| Run bison like this: | |
| bison --name-prefix=cmExpr_yy --defines=cmExprParserTokens.h -ocmExprParser.cxx cmExprParser.y | |
| */ | |
| #include "cmConfigure.h" // IWYU pragma: keep | |
| #include <stdint.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <stdexcept> | |
| /*-------------------------------------------------------------------------*/ | |
| #define YYDEBUG 1 | |
| #include "cmExprParserHelper.h" /* Interface to parser object. */ | |
| #include "cmExprLexer.h" /* Interface to lexer object. */ | |
| #include "cmExprParserTokens.h" /* Need YYSTYPE for YY_DECL. */ | |
| /* Forward declare the lexer entry point. */ | |
| YY_DECL; | |
| /* Helper function to forward error callback from parser. */ | |
| static void cmExpr_yyerror(yyscan_t yyscanner, const char* message); | |
| /* Disable some warnings in the generated code. */ | |
| #ifdef _MSC_VER | |
| # pragma warning (disable: 4102) /* Unused goto label. */ | |
| # pragma warning (disable: 4065) /* Switch statement contains default but no case. */ | |
| #endif | |
| #if defined(__GNUC__) && __GNUC__ >= 8 | |
| # pragma GCC diagnostic ignored "-Wconversion" | |
| # pragma GCC diagnostic ignored "-Wfree-nonheap-object" | |
| #endif | |
| #if defined(__clang__) && defined(__has_warning) | |
| # if __has_warning("-Wused-but-marked-unused") | |
| # pragma clang diagnostic ignored "-Wused-but-marked-unused" | |
| # endif | |
| #endif | |
| #if defined(__NVCOMPILER) | |
| # pragma diag_suppress 550 /* variable set but never used */ | |
| #endif | |
| %} | |
| /* Generate a reentrant parser object. */ | |
| %define api.pure | |
| /* Configure the parser to use a lexer object. */ | |
| %lex-param {yyscan_t yyscanner} | |
| %parse-param {yyscan_t yyscanner} | |
| %define parse.error verbose | |
| /*-------------------------------------------------------------------------*/ | |
| /* Tokens */ | |
| %token exp_PLUS | |
| %token exp_MINUS | |
| %token exp_TIMES | |
| %token exp_DIVIDE | |
| %token exp_MOD | |
| %token exp_SHIFTLEFT | |
| %token exp_SHIFTRIGHT | |
| %token exp_OPENPARENT | |
| %token exp_CLOSEPARENT | |
| %token exp_OR; | |
| %token exp_AND; | |
| %token exp_XOR; | |
| %token exp_NOT; | |
| %token exp_NUMBER; | |
| /*-------------------------------------------------------------------------*/ | |
| /* grammar */ | |
| %% | |
| start: | |
| exp { | |
| cmExpr_yyget_extra(yyscanner)->SetResult($<Number>1); | |
| } | |
| exp: | |
| bitwiseor { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | exp exp_OR bitwiseor { | |
| $<Number>$ = $<Number>1 | $<Number>3; | |
| } | |
| bitwiseor: | |
| bitwisexor { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | bitwiseor exp_XOR bitwisexor { | |
| $<Number>$ = $<Number>1 ^ $<Number>3; | |
| } | |
| bitwisexor: | |
| bitwiseand { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | bitwisexor exp_AND bitwiseand { | |
| $<Number>$ = $<Number>1 & $<Number>3; | |
| } | |
| bitwiseand: | |
| shift { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | bitwiseand exp_SHIFTLEFT shift { | |
| $<Number>$ = $<Number>1 << $<Number>3; | |
| } | |
| | bitwiseand exp_SHIFTRIGHT shift { | |
| $<Number>$ = $<Number>1 >> $<Number>3; | |
| } | |
| shift: | |
| term { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | shift exp_PLUS term { | |
| $<Number>$ = $<Number>1 + $<Number>3; | |
| } | |
| | shift exp_MINUS term { | |
| $<Number>$ = $<Number>1 - $<Number>3; | |
| } | |
| term: | |
| unary { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | term exp_TIMES unary { | |
| $<Number>$ = $<Number>1 * $<Number>3; | |
| } | |
| | term exp_DIVIDE unary { | |
| if (yyvsp[0].Number == 0) { | |
| throw std::overflow_error("divide by zero"); | |
| } | |
| $<Number>$ = $<Number>1 / $<Number>3; | |
| } | |
| | term exp_MOD unary { | |
| $<Number>$ = $<Number>1 % $<Number>3; | |
| } | |
| unary: | |
| factor { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | exp_PLUS unary { | |
| $<Number>$ = + $<Number>2; | |
| } | |
| | exp_MINUS unary { | |
| $<Number>$ = - $<Number>2; | |
| } | |
| | exp_NOT unary { | |
| $<Number>$ = ~ $<Number>2; | |
| } | |
| factor: | |
| exp_NUMBER { | |
| $<Number>$ = $<Number>1; | |
| } | |
| | exp_OPENPARENT exp exp_CLOSEPARENT { | |
| $<Number>$ = $<Number>2; | |
| } | |
| ; | |
| %% | |
| /* End of grammar */ | |
| /*--------------------------------------------------------------------------*/ | |
| void cmExpr_yyerror(yyscan_t yyscanner, const char* message) | |
| { | |
| cmExpr_yyget_extra(yyscanner)->Error(message); | |
| } |