summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Trader/constraint.l
blob: d8e67d5ad508841398e907e8dc9356e1f328626e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
%{
TAO_END_VERSIONED_NAMESPACE_DECL

// $Id$
// ========================================================================
//
// = LIBRARY
//    orbsvcs
//
// = FILENAME
//    constraint.l
//
// = AUTHOR
//    Seth Widoff <sbw1@cs.wustl.edu>
//
// ========================================================================

#include "orbsvcs/Trader/Constraint_Interpreter.h"
#include "orbsvcs/Trader/Constraint_Nodes.h"
#include "orbsvcs/Trader/Constraint_Tokens.h"

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

static TAO_Literal_Constraint* extract_string(const char*);
static CORBA::LongLong trader_strtoll(const char* str, unsigned int base);
static CORBA::ULongLong trader_strtoull(const char* str, unsigned int base);

#define TAO_YY_LEX_DEBUG

#ifdef TAO_CONSTRAINT_DEBUG
#define TAO_YY_LEX_DEBUG ACE_OS::fprintf(stderr, "%s\n", yytext)
#endif /* TAO_CONSTRAINT_DEBUG */


%}

white_space     [ \t]
letter		[a-zA-Z]
digit		[0-9]
alpha_num	({letter}|{digit})
integer		[-+]?{digit}+
float		[-+]?({digit}*\.{digit}+)([eE][-+]?{digit}+)?
string		'(([^'\\]*)|([^'\\]*\\')|([^'\\]*\\\\))*'
ident		{letter}({alpha_num}|[_])*
newline		\n
unknown         [^ \t]

%%

min             { TAO_YY_LEX_DEBUG; return TAO_MIN; }
max             { TAO_YY_LEX_DEBUG; return TAO_MAX; }
first           { TAO_YY_LEX_DEBUG; return TAO_FIRST; }
random          { TAO_YY_LEX_DEBUG; return TAO_RANDOM; }
with            { TAO_YY_LEX_DEBUG; return TAO_WITH; }
exist		{ TAO_YY_LEX_DEBUG; return TAO_EXIST; }
not		{ TAO_YY_LEX_DEBUG; return TAO_NOT; }
and		{ TAO_YY_LEX_DEBUG; return TAO_AND; }
or		{ TAO_YY_LEX_DEBUG; return TAO_OR; }
in		{ TAO_YY_LEX_DEBUG; return TAO_IN; }
"~"             { TAO_YY_LEX_DEBUG; return TAO_TWIDDLE; }
"+"		{ TAO_YY_LEX_DEBUG; return TAO_PLUS; }
"-"		{ TAO_YY_LEX_DEBUG; return TAO_MINUS; }
"*"		{ TAO_YY_LEX_DEBUG; return TAO_MULT; }
"/"		{ TAO_YY_LEX_DEBUG; return TAO_DIV; }
"<"		{ TAO_YY_LEX_DEBUG; return TAO_LT; }
"<="		{ TAO_YY_LEX_DEBUG; return TAO_LE; }
">"		{ TAO_YY_LEX_DEBUG; return TAO_GT; }
">="		{ TAO_YY_LEX_DEBUG; return TAO_GE; }
"=="		{ TAO_YY_LEX_DEBUG; return TAO_EQ; }
"!="		{ TAO_YY_LEX_DEBUG; return TAO_NE; }
"("             { TAO_YY_LEX_DEBUG; return TAO_LPAREN; }
")"             { TAO_YY_LEX_DEBUG; return TAO_RPAREN; }
TRUE		{
		  yylval.constraint_ =
                    new TAO_Literal_Constraint(true);
		  TAO_YY_LEX_DEBUG; return TAO_BOOLEAN;
		}
FALSE		{
		  yylval.constraint_ =
                    new TAO_Literal_Constraint(false);
		  TAO_YY_LEX_DEBUG; return TAO_BOOLEAN;
		}
{integer}	{
                  if (yytext[0] == '-')
                    {
                      yylval.constraint_ =
		        new TAO_Literal_Constraint(
                              trader_strtoll(yytext, 0));
                    }
                  else
                    {
                       yylval.constraint_ =
                         new TAO_Literal_Constraint(
                               trader_strtoull(yytext, 0));
                    }
		  TAO_YY_LEX_DEBUG; return TAO_NUMBER;
		}
{float}		{
		  yylval.constraint_ =
		    new TAO_Literal_Constraint(ACE_OS::strtod(yytext, 0));
		  TAO_YY_LEX_DEBUG; return TAO_NUMBER;
		}
{string}	{
		  yylval.constraint_ = extract_string(yytext);
		  TAO_YY_LEX_DEBUG; return TAO_STRING;
		}
{ident}		{
		  yylval.constraint_ =
		    new TAO_Property_Constraint(yytext);
		  TAO_YY_LEX_DEBUG; return TAO_IDENT;
		}
{white_space}   {}
{unknown}       {
                  TAO_YY_LEX_DEBUG; return TAO_UNKNOWN;
                }
%%

TAO_Literal_Constraint*
extract_string(const char* total)
{
  int prev_slash = 0,
    ctr = 0;
  char str[BUFSIZ],
   *tmp = (char*) total + 1;

  while (*tmp != '\0')
    {
      if (*tmp == '\\')
        {
          if (prev_slash)
            prev_slash = 0;
          else
            {
              prev_slash = 1;
              continue;
            }
        }
      else if (*tmp == '\'')
        prev_slash = 0;

      str[ctr++] = *tmp;
      tmp++;
    }

  str[ctr - 1] = '\0';
  return new TAO_Literal_Constraint(str);
}

CORBA::ULongLong
trader_strtoull(const char* s, unsigned int base)
{
  CORBA::ULongLong result = 0;
  CORBA::ULongLong previous = 0;

  // Check for a valid base
  if (!(base == 0 || base == 8 || base == 10 || base == 16))
    {
      errno = EINVAL;
      return result;
    }

  if (*s == '+')
    {
      s++;
    }

  if ((base == 0 || base == 16) &&
      *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
    {
      s += 2;
      base = 16;
    }
  else if ((base == 0 || base == 8) && *s == '0')
    {
      s++;
      base = 8;
    }
  else
    {
      base = 10;
    }

  for (; *s; ++s)
    {
      if (base == 8 && *s <= '7' && *s >= '0')
        {
          result = (result * base) + (*s - '0');
        }
      else if (base > 8 && *s <= '9' && *s >= '0')
        {
          result = (result * base) + (*s - '0');
        }
      else if (base > 10 && *s <= 'f' && *s >= 'a')
        {
          result = (result * base) + (*s - 'a' + 10);
        }
      else if (base > 10 && *s <= 'F' && *s >= 'A')
        {
          result = (result * base) + (*s - 'A' + 10);
        }
      else
        { 
          break;
        }

      // If the previous value is greater than result, then we have
      // exceeded the size of a CORBA::ULongLong and the result
      // will be ACE_UINT64_MAX.  However, errno will be set to ERANGE
      if (previous > result)
        {
          errno = ERANGE;
          result = ACE_UINT64_MAX;
          break;
        }
      previous = result;
    }

  return result;
}

CORBA::LongLong
trader_strtoll(const char* s, unsigned int base)
{
  // Check for the negative sign
  bool negative = false;
  if (*s == '-')
    {
      negative = true;
      s++;
    }

  // Convert the raw text into a CORBA::LongLong
  CORBA::LongLong result = static_cast<CORBA::LongLong> (
                                         trader_strtoull(s, base));

  // If the result that comes back is negative, then the value exceeded
  // the maximum for CORBA::LongLong
  if (result < 0)
    {
      errno = ERANGE;
      return (negative ? ACE_INT64_MIN : ACE_INT64_MAX);
    }

  return (negative ? -result : result);
}

int
yywrap (void)
{
  return 1;
}

TAO_END_VERSIONED_NAMESPACE_DECL