root/trunk/xpath_stream.d

Revision 28, 7.2 kB (checked in by yossarian, 2 years ago)

opraveno par bugu

Line 
1 /*
2 www.sourceforge.net/projects/tinyxpath
3 Copyright (c) 2002-2004 Yves Berquin (yvesb@users.sourceforge.net)
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any
7 damages arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any
10 purpose, including commercial applications, and to alter it and
11 redistribute it freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must
14 not claim that you wrote the original software. If you use this
15 software in a product, an acknowledgment in the product documentation
16 would be appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and
19 must not be misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23 */
24 /**
25     \file xpath_stream.h
26     \author Yves Berquin
27     Specialized byte stream for the TinyXPath project
28 */
29
30
31
32
33 private import xpath.byte_stream;
34 private import xpath.xpath_syntax;
35 private import std.stream;
36 private import std.stdio;
37 private import std.string;
38 private import xpath.lex_util;
39
40 private
41 {
42 class token_redef : public token_syntax_decoder
43 {
44 protected :
45     /// pointer to an xpath_stream instance
46     xpath_stream xsp_stream;
47 public :
48     /// constructor
49     this (xpath_stream xsp_in)  ///< Pointer to an xpath_stream instance
50     {
51         xsp_stream = xsp_in;
52     }
53     /// dispatcher of the xpath_stream::v_action
54     final void v_action (xpath_construct xc_rule, uint u_sub, uint u_variable = 0, char[] cp_literal = "")
55     {
56         xsp_stream.v_action (xc_rule, u_sub, u_variable, cp_literal);
57         debug {
58         auto File f = new File("Streamer", FileMode.Append);
59         f.writefln("'%s' ('%d', '%d', '%s')", cp_disp_construct(xc_rule), u_sub, u_variable, replace(cp_literal,"\n","\\n"));
60         }
61     }
62     /// dispatcher of the xpath_stream::i_get_action_counter
63     final int i_get_action_counter () {return xsp_stream.i_get_action_counter;}
64 }
65    
66 }
67
68 public
69 {
70
71 /**
72     A specialized version of byte_stream for XPath
73 */
74 class xpath_stream : public byte_stream
75 {
76 protected :
77     /// List of tokens
78     token_syntax_decoder tlp_list;
79
80 public :
81     /// constructor
82     this (char[] cp_in)
83     {
84         super (cp_in);
85         tlp_list = new token_redef(this);
86     }
87     /// destructor
88     ~ this()
89     {
90         delete tlp_list;
91     }
92     /// Decode the byte stream, and construct the lexical list
93     void v_lexico_decode ()
94     {
95         enum _state {s_init, s_ncname, s_number, s_literal_1, s_literal_2, s_end};
96         _state state;
97         lexico lex_new, lex_next;
98         uint u_size;
99         bool o_dot_in_number;
100
101         u_size = 0;
102         o_dot_in_number = false;
103         state = _state.s_init;
104         while (state != _state.s_end)
105         {
106             lex_next = lex_get_class (b_top ());
107             debug writefln("Parsing: %s [%d] (%s)", cast(char)b_top(), cast(int)b_top(), cp_disp_class_lex(lex_next));
108             switch (state)
109             {
110                 case _state.s_init :
111                     switch (lex_next)
112                     {
113                         case lexico.lex_bchar :
114                         case lexico.lex_under :
115                             // [XML:4] NCName   ::= (Letter | '_') (NCNameChar)*
116
117                             u_size = 1;
118                             state = _state.s_ncname;
119                             b_pop ();
120                             break;
121                         case lexico.lex_null :
122                             state = _state.s_end;
123                             break;
124                         case lexico.lex_digit :
125                             u_size = 1;
126                             state = _state.s_number;
127                             o_dot_in_number = false;
128                             b_pop ();
129                             break;
130                         case lexico.lex_dot :
131                             if (lex_get_class (b_forward (1)) == lexico.lex_digit)
132                             {
133                                 // [30]  Number             ::= Digits ('.' Digits?)? | '.' Digits
134                                 // [31]  Digits             ::= [0-9]+
135                                 u_size = 1;
136                                 state = _state.s_number;
137                                 o_dot_in_number = true;
138                                 b_pop ();
139                             }
140                             else
141                             {
142                                 tlp_list.v_add_token (lex_next, bp_get_backward (1), 1);
143                                 b_pop ();
144                             }
145                             break;
146
147                         case lexico.lex_1_quote :
148                             // [29]  Literal                ::= '"' [^"]* '"' | "'" [^']* "'"
149                             u_size = 0;
150                             b_pop ();
151                             state = _state.s_literal_1;
152                             break;
153
154                         case lexico.lex_2_quote :
155                             // [29]  Literal                ::= '"' [^"]* '"' | "'" [^']* "'"
156                             u_size = 0;
157                             b_pop ();
158                             state = _state.s_literal_2;
159                             break;
160
161                         default :
162                             tlp_list.v_add_token (lex_next, bp_get_backward (1), 1);
163                             b_pop ();
164                             break;
165                     }
166                     break;
167                 case _state.s_literal_1 :
168                     // [29]  Literal                ::= '"' [^"]* '"' | "'" [^']* "'"
169                     switch (lex_next)
170                     {
171                         case lexico.lex_1_quote :
172                             tlp_list.v_add_token (lexico.lex_literal, bp_get_backward (u_size + 1), u_size);
173                             b_pop ();
174                             state = _state.s_init;
175                             break;
176                         default :
177                             u_size++;
178                             b_pop ();
179                             break;
180                     }
181                     break;
182                 case _state.s_literal_2 :
183                     // [29]  Literal                ::= '"' [^"]* '"' | "'" [^']* "'"
184                     switch (lex_next)
185                     {
186                         case lexico.lex_2_quote :
187                             tlp_list.v_add_token (lexico.lex_literal, bp_get_backward (u_size + 1), u_size);
188                             b_pop ();
189                             state = _state.s_init;
190                             break;
191                         default :
192                             u_size++;
193                             b_pop ();
194                             break;
195                     }
196                     break;
197                 case _state.s_ncname :
198                     switch (lex_next)
199                     {
200                         // [XML:5] NCNameChar ::= Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
201                         case lexico.lex_bchar :
202                         case lexico.lex_digit :
203                         case lexico.lex_dot :
204                         case lexico.lex_minus :
205                         case lexico.lex_under :
206                         case lexico.lex_extend :
207                             u_size++;
208                             b_pop ();
209                             debug writefln("Extending wit char: %s", cp_disp_class_lex(lex_next));
210                             break;
211                         default :
212                             lex_new = lex_test_id (bp_get_backward (u_size + 1), u_size, lex_next);
213                             tlp_list.v_add_token (lex_new, bp_get_backward (u_size + 1), u_size);
214                             state = _state.s_init;
215                             break;
216                     }
217                     break;
218                 case _state.s_number :
219                     switch (lex_next)
220                     {
221                         // [30]  Number             ::= Digits ('.' Digits?)? | '.' Digits
222                         // [31]  Digits             ::= [0-9]+
223                         case lexico.lex_dot :
224                             if (o_dot_in_number)
225                             {
226                                 tlp_list.v_add_token (lexico.lex_number, bp_get_backward (u_size + 1), u_size);
227                                 state = _state.s_init;
228                             }
229                             else
230                             {
231                                 o_dot_in_number = true;
232                                 u_size++;
233                                 b_pop ();
234                             }
235                             break;
236                         case lexico.lex_digit :
237                             u_size++;
238                             b_pop ();
239                             break;
240                         default :
241                             tlp_list.v_add_token (lexico.lex_number, bp_get_backward (u_size + 1), u_size);
242                             state = _state.s_init;
243                             break;
244                     }
245                     break;
246             }
247             if (lex_next == lexico.lex_null)
248                 state = _state.s_end;
249         }
250     }
251
252     /// Evaluate a XPath expression \n
253     /// Decodes the lexical and syntax contents.
254     void v_evaluate ()
255     {
256         v_lexico_decode ();
257         tlp_list.v_syntax_decode ();
258     }
259
260    
261
262     /// Callback used by token_syntax_decoder::v_syntax_decode to notify of an action to be made. Pure virtual
263     abstract void v_action (xpath_construct , uint , uint , char[] ) ;
264
265     /// Callback used by token_syntax_decoder::v_syntax_decode to know the action counter position. Pure virtual
266     /// \n This can be any kind of nomenclature, provided that the redefinition is coherent
267     abstract int i_get_action_counter () ;
268 }     // class xpath_stream
269
270 }
Note: See TracBrowser for help on using the browser.