00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 #ifndef __TINYXPSTREAM_H
00031 #define __TINYXPSTREAM_H
00032
00033 #include "lex_util.h"
00034 #include "byte_stream.h"
00035 #include "xpath_syntax.h"
00036 #include "tinyxml.h"
00037 #include "tinystr.h"
00038
00039 namespace TinyXPath
00040 {
00041
00045 class xpath_stream : public byte_stream
00046 {
00047 protected :
00049 token_syntax_decoder * tlp_list;
00050
00051 public :
00053 xpath_stream (const char * cp_in);
00055 virtual ~ xpath_stream ()
00056 {
00057 delete tlp_list;
00058 }
00060 void v_lexico_decode ()
00061 {
00062 enum {s_init, s_ncname, s_number, s_literal_1, s_literal_2, s_end} state;
00063 lexico lex_new, lex_next;
00064 unsigned u_size;
00065 bool o_dot_in_number;
00066
00067 u_size = 0;
00068 o_dot_in_number = false;
00069 state = s_init;
00070 while (state != s_end)
00071 {
00072 lex_next = lex_get_class (b_top ());
00073 switch (state)
00074 {
00075 case s_init :
00076 switch (lex_next)
00077 {
00078 case lex_bchar :
00079 case lex_under :
00080
00081
00082 u_size = 1;
00083 state = s_ncname;
00084 b_pop ();
00085 break;
00086 case lex_null :
00087 state = s_end;
00088 break;
00089 case lex_digit :
00090 u_size = 1;
00091 state = s_number;
00092 o_dot_in_number = false;
00093 b_pop ();
00094 break;
00095 case lex_dot :
00096 if (lex_get_class (b_forward (1)) == lex_digit)
00097 {
00098
00099
00100 u_size = 1;
00101 state = s_number;
00102 o_dot_in_number = true;
00103 b_pop ();
00104 }
00105 else
00106 {
00107 tlp_list -> v_add_token (lex_next, bp_get_backward (1), 1);
00108 b_pop ();
00109 }
00110 break;
00111
00112 case lex_1_quote :
00113
00114 u_size = 0;
00115 b_pop ();
00116 state = s_literal_1;
00117 break;
00118
00119 case lex_2_quote :
00120
00121 u_size = 0;
00122 b_pop ();
00123 state = s_literal_2;
00124 break;
00125
00126 default :
00127 tlp_list -> v_add_token (lex_next, bp_get_backward (1), 1);
00128 b_pop ();
00129 break;
00130 }
00131 break;
00132 case s_literal_1 :
00133
00134 switch (lex_next)
00135 {
00136 case lex_1_quote :
00137 tlp_list -> v_add_token (lex_literal, bp_get_backward (u_size + 1), u_size);
00138 b_pop ();
00139 state = s_init;
00140 break;
00141 default :
00142 u_size++;
00143 b_pop ();
00144 break;
00145 }
00146 break;
00147 case s_literal_2 :
00148
00149 switch (lex_next)
00150 {
00151 case lex_2_quote :
00152 tlp_list -> v_add_token (lex_literal, bp_get_backward (u_size + 1), u_size);
00153 b_pop ();
00154 state = s_init;
00155 break;
00156 default :
00157 u_size++;
00158 b_pop ();
00159 break;
00160 }
00161 break;
00162 case s_ncname :
00163 switch (lex_next)
00164 {
00165
00166 case lex_bchar :
00167 case lex_digit :
00168 case lex_dot :
00169 case lex_minus :
00170 case lex_under :
00171 case lex_extend :
00172 u_size++;
00173 b_pop ();
00174 break;
00175 default :
00176 lex_new = lex_test_id (bp_get_backward (u_size + 1), u_size, lex_next);
00177 tlp_list -> v_add_token (lex_new, bp_get_backward (u_size + 1), u_size);
00178 state = s_init;
00179 break;
00180 }
00181 break;
00182 case s_number :
00183 switch (lex_next)
00184 {
00185
00186
00187 case lex_dot :
00188 if (o_dot_in_number)
00189 {
00190 tlp_list -> v_add_token (lex_number, bp_get_backward (u_size + 1), u_size);
00191 state = s_init;
00192 }
00193 else
00194 {
00195 o_dot_in_number = true;
00196 u_size++;
00197 b_pop ();
00198 }
00199 break;
00200 case lex_digit :
00201 u_size++;
00202 b_pop ();
00203 break;
00204 default :
00205 tlp_list -> v_add_token (lex_number, bp_get_backward (u_size + 1), u_size);
00206 state = s_init;
00207 break;
00208 }
00209 break;
00210 }
00211 if (lex_next == lex_null)
00212 state = s_end;
00213 }
00214 }
00215
00218 void v_evaluate ()
00219 {
00220 v_lexico_decode ();
00221 tlp_list -> v_syntax_decode ();
00222 }
00223
00225 virtual void v_action (xpath_construct , unsigned , unsigned , const char * ) = 0;
00226
00229 virtual int i_get_action_counter () = 0;
00230 } ;
00231
00232 }
00233
00234 #endif