1 %{
2 #define yywrap kiotraderwrap
3 
4 #include "yacc.h"
5 #include <string.h>
6 #include <stdlib.h>
7 #define YY_NO_UNPUT
8 
9 char* KTraderParse_putSymbol( char *_name );
10 char *KTraderParse_putSymbolInBrackets( char *_name );
11 char* KTraderParse_putString( char *_name );
12 double KTraderParse_putSimplePositiveFloat( char *_name );
13 int yywrap();
14 int kiotraderlex(YYSTYPE * yylval, yyscan_t scanner);
15 void KTraderParse_initFlex( const char *_code, yyscan_t _scanner );
16 
17 %}
18 %option nomain
19 %option never-interactive
20 %option noalways-interactive
21 %option nostack
22 %option reentrant
23 %option bison-bridge
24 
25 DIGIT    [0-9]
26 
27 %%
28 
29 "==" { return EQ; }
30 "=~" { return EQI; }
31 "!=" { return NEQ; }
32 "!~" { return NEQI; }
33 "<" { return LE; }
34 ">" { return GR; }
35 "<=" { return LEQ; }
36 ">=" { return GEQ; }
37 "~~" { return MATCH_INSENSITIVE; }
38 "subseq" { return MATCH_SUBSEQUENCE; }
39 "~subseq" { return MATCH_SUBSEQUENCE_INSENSITIVE; }
40 "not" { return NOT; }
41 "and" { return AND; }
42 "or" { return OR; }
43 "in" { return TOKEN_IN; }
44 "~in" { return TOKEN_IN_INSENSITIVE; }
45 "subin" { return TOKEN_IN_SUBSTRING; }
46 "~subin" { return TOKEN_IN_SUBSTRING_INSENSITIVE; }
47 "exist" { return EXIST; }
48 "max" { return MAX; }
49 "min" { return MIN; }
50 
51 "~"|"/"|"+"|"-"|"="|"*"|"("|")"|","  { yylval->name = 0L; return (int)(*yytext); }
52 
53 "TRUE" { yylval->valb = 1; return VAL_BOOL; }
54 "FALSE" { yylval->valb = 0; return VAL_BOOL; }
55 
56 "'"[^']*"'" { yylval->name = KTraderParse_putString( yytext ); return VAL_STRING; }
57 
58 "-"{DIGIT}+  { yylval->vali = atoi( yytext ); return VAL_NUM; }
59 {DIGIT}+  { yylval->vali = atoi( yytext ); return VAL_NUM; }
60 
61 {DIGIT}*"\."{DIGIT}+ { yylval->vald = KTraderParse_putSimplePositiveFloat( yytext ); return VAL_FLOAT; }
62 
63 \[[a-zA-Z][a-zA-Z0-9\-]*\] { yylval->name = KTraderParse_putSymbolInBrackets( yytext ); return VAL_ID; }
64 
65 [a-zA-Z][a-zA-Z0-9]* { yylval->name = KTraderParse_putSymbol( yytext ); return VAL_ID; }
66 
67 [ \t\n]+          /* eat up whitespace */
68 
69 . { printf( "Unrecognized character: %s\n", yytext ); }
70 
71 %%
72 
73 char* KTraderParse_putSymbolInBrackets( char *_name )
74 {
75   int l = strlen( _name )-1;
76   char *p = (char *)malloc( l );
77   if (p != NULL)
78   {
79     strncpy( p, _name+1, l-1 );
80     p[l-1] = 0;
81   }
82 
83   return p;
84 }
85 
86 char *KTraderParse_putSymbol( char *_name )
87 {
88   char *p = (char*)malloc( strlen( _name ) + 1 );
89   if (p != NULL)
90   {
91       strcpy( p, _name );
92   }
93   return p;
94 }
95 
96 char* KTraderParse_putString( char *_str )
97 {
98   int l = strlen( _str );
99   char *p = (char*)malloc( l );
100   char *s = _str + 1;
101   char *d = p;
102 
103   if (p == NULL)
104     return NULL;
105 
106   while ( s != _str + l - 1 )
107   {
108      if ( *s != '\\' )
109         *d++ = *s++;
110      else
111      {
112         s++;
113         if ( s != _str + l - 1 )
114         {
115           if ( *s == '\\' )
116              *d++ = '\\';
117            else if ( *s == 'n' )
118              *d++ = '\n';
119            else if ( *s == 'r' )
120              *d++ = '\r';
121            else if ( *s == 't' )
122              *d++ = '\t';
123            s++;
124         }
125      }
126   }
127   *d = 0;
128   return p;
129 }
130 
131 /* Sufficient replacement for atof() to parse [0-9]*\.[0-9]+
132    because atof() consults locale for decimal separator,
133    while we need it always to be the dot. */
134 double KTraderParse_putSimplePositiveFloat( char *_str )
135 {
136   char *p;
137   int f, g, d;
138 
139   f = 0;
140   p = _str;
141   while ( *p >= '0' && *p <= '9' )
142   {
143     f = f * 10 + ( *p - '0' );
144     p++;
145   }
146   if ( *p != '.' )
147     return (double) f;
148   p++;
149   g = 0;
150   d = 1;
151   while ( *p >= '0' && *p <= '9' )
152   {
153     g = g * 10 + ( *p - '0' );
154     d *= 10;
155     p++;
156   }
157   return ( (double) ( f * d + g ) ) / d;
158 }
159 
160 void KTraderParse_initFlex( const char *_code, yyscan_t _scanner )
161 {
162   yy_switch_to_buffer( yy_scan_string( _code, _scanner ), _scanner );
163 }
164 
165 int yywrap( yyscan_t _scanner )
166 {
167   struct yyguts_t * yyg = (struct yyguts_t*)_scanner;
168   yy_delete_buffer( YY_CURRENT_BUFFER, _scanner );
169   return 1;
170 }
171