Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

xpath_stream.h

Go to the documentation of this file.
00001 /*
00002 www.sourceforge.net/projects/tinyxpath
00003 Copyright (c) 2002-2004 Yves Berquin (yvesb@users.sourceforge.net)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
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                      // [XML:4] NCName  ::= (Letter | '_') (NCNameChar)* 
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                         // [30]   Number                ::=   Digits ('.' Digits?)? | '.' Digits 
00099                         // [31]   Digits                ::=   [0-9]+ 
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                      // [29]   Literal              ::=   '"' [^"]* '"' | "'" [^']* "'" 
00114                      u_size = 0;
00115                      b_pop ();
00116                      state = s_literal_1;
00117                      break;
00118 
00119                   case lex_2_quote :
00120                      // [29]   Literal              ::=   '"' [^"]* '"' | "'" [^']* "'" 
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                // [29]   Literal                ::=   '"' [^"]* '"' | "'" [^']* "'" 
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                // [29]   Literal                ::=   '"' [^"]* '"' | "'" [^']* "'" 
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                   // [XML:5] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
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                   // [30]   Number              ::=   Digits ('.' Digits?)? | '.' Digits 
00186                   // [31]   Digits              ::=   [0-9]+ 
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 } ;     // class xpath_stream
00231 
00232 }
00233 
00234 #endif

Generated for TinyXPath by doxygen SourceForge Logo