cmExprParser.y 3.26 KB
Newer Older
1
%{
2
3
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
4
5
6
7
8
9
10
11
12
/*

This file must be translated to C and modified to build everywhere.

Run bison like this:

  bison --yacc --name-prefix=cmExpr_yy --defines=cmExprParserTokens.h -ocmExprParser.cxx cmExprParser.y

Modify cmExprParser.cxx:
Brad King's avatar
Brad King committed
13
  - "#if 0" out yyerrorlab block in range ["goto yyerrlab1", "yyerrlab1:"]
14
15
16
17

*/

/*-------------------------------------------------------------------------*/
Brad King's avatar
Brad King committed
18
#define YYDEBUG 1
19
20
21
22
23
24
25
26
27
#include "cmExprParserHelper.h" /* Interface to parser object.  */
#include "cmExprLexer.h"  /* Interface to lexer object.  */
#include "cmExprParserTokens.h" /* Need YYSTYPE for YY_DECL.  */

#include <math.h>

/* Forward declare the lexer entry point.  */
YY_DECL;

Brad King's avatar
Brad King committed
28
29
/* Helper function to forward error callback from parser.  */
static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
30
31
32
33
34
35
36
37
38

/* 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
%}

/* Generate a reentrant parser object.  */
Brad King's avatar
Brad King committed
39
40
41
42
43
44
45
%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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

/*-------------------------------------------------------------------------*/
/* 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 */
%%


69
70
71
72
start:
  exp {
    cmExpr_yyget_extra(yyscanner)->SetResult($<Number>1);
  }
73
74

exp:
75
76
77
78
79
80
  bitwiseor {
    $<Number>$ = $<Number>1;
  }
| exp exp_OR bitwiseor {
    $<Number>$ = $<Number>1 | $<Number>3;
  }
81
82

bitwiseor:
83
84
85
86
87
88
  bitwisexor {
    $<Number>$ = $<Number>1;
  }
| bitwiseor exp_XOR bitwisexor {
    $<Number>$ = $<Number>1 ^ $<Number>3;
  }
89
90

bitwisexor:
91
92
93
94
95
96
  bitwiseand {
    $<Number>$ = $<Number>1;
  }
| bitwisexor exp_AND bitwiseand {
    $<Number>$ = $<Number>1 & $<Number>3;
  }
97
98

bitwiseand:
99
100
101
102
103
104
105
106
107
  shift {
    $<Number>$ = $<Number>1;
  }
| bitwiseand exp_SHIFTLEFT shift {
    $<Number>$ = $<Number>1 << $<Number>3;
  }
| bitwiseand exp_SHIFTRIGHT shift {
    $<Number>$ = $<Number>1 >> $<Number>3;
  }
Andy Cedilnik's avatar
Andy Cedilnik committed
108
109

shift:
110
111
112
113
114
115
116
117
118
  term {
    $<Number>$ = $<Number>1;
  }
| shift exp_PLUS term {
    $<Number>$ = $<Number>1 + $<Number>3;
  }
| shift exp_MINUS term {
    $<Number>$ = $<Number>1 - $<Number>3;
  }
119
120

term:
121
122
123
124
125
126
127
128
129
130
131
132
  factor {
    $<Number>$ = $<Number>1;
  }
| term exp_TIMES factor {
    $<Number>$ = $<Number>1 * $<Number>3;
  }
| term exp_DIVIDE factor {
    $<Number>$ = $<Number>1 / $<Number>3;
  }
| term exp_MOD factor {
    $<Number>$ = $<Number>1 % $<Number>3;
  }
133
134

factor:
135
136
137
138
139
140
  exp_NUMBER {
    $<Number>$ = $<Number>1;
  }
| exp_OPENPARENT exp exp_CLOSEPARENT {
    $<Number>$ = $<Number>2;
  }
141
142
143
144
145
146
;

%%
/* End of grammar */

/*--------------------------------------------------------------------------*/
Brad King's avatar
Brad King committed
147
void cmExpr_yyerror(yyscan_t yyscanner, const char* message)
148
{
Brad King's avatar
Brad King committed
149
  cmExpr_yyget_extra(yyscanner)->Error(message);
150
151
}