root/trunk/tokenlist.d

Revision 28, 5.6 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 /**
26     \file tokenlist.h
27     \author Yves Berquin
28     XPath Syntax analyzer for TinyXPath project : token list handling
29 */
30 module xpath.tokenlist;
31 private import xpath.lex_util;
32 private import xpath.lex_token;
33 private import std.stdio;
34 public
35 {
36
37 /**
38     A token list class. This is the output of the lexical analysis   \n
39     Note that the empty list consist of a single null element in order to speed
40     up later insertions
41 */
42 class token_list
43 {
44     protected {
45         /// Pointer to first element
46         lex_token ltp_first;
47         /// Pointer to last element
48         lex_token ltp_last;
49         /// Pointer to current element. This is for external usage : we keep track of where it
50         /// is, but it's not needed to manage the list structure
51         lex_token ltp_current;
52     }
53     public {
54         /// constructor
55         this()
56     {
57         ltp_first = new lex_token (lexico.lex_null, null, 0);
58         ltp_last = ltp_first;
59         ltp_first.v_set_prev (ltp_first);
60         ltp_first.v_set_next (ltp_first);
61         ltp_current = null;
62     }
63     /// destructor
64     ~this()
65     {
66         ltp_current = ltp_first.ltp_get_next ();
67         while (ltp_current.o_is_valid ())
68             v_delete_current ();
69         delete ltp_first;
70     }
71     /// Adds a lexical token
72     void v_add_token (lexico l_in_enum, ubyte[] bp_in_value, uint u_in_size)
73     {
74         lex_token ltp_new;
75         debug writefln("New Token: %s (%s[%d])", cp_disp_class_lex(l_in_enum), cast(char[])bp_in_value, u_in_size);
76
77         ltp_new = new lex_token (l_in_enum, bp_in_value, u_in_size);
78         ltp_last.v_set_next (ltp_new);
79         ltp_new.v_set_next (ltp_first);
80         ltp_first.v_set_prev (ltp_new);
81         ltp_new.v_set_prev (ltp_last);
82         ltp_last = ltp_new;
83     }
84
85     /// Set current to first real element
86     void v_set_current_top ()
87     {
88         ltp_current = ltp_first.ltp_get_next (1);
89     }
90
91     /// Set current
92     void v_set_current (lex_token ltp_cur)
93     {
94         ltp_current = ltp_cur;
95     }
96
97     /// Return the current token
98     lex_token ltp_freeze ()
99     {
100         return ltp_current;
101     }
102
103     /// Get next X linear token
104     lex_token ltp_get (int i_offset)
105     {
106         if (! ltp_current)
107             return null;
108         return ltp_current.ltp_get_next (i_offset);
109     }
110
111     /// Increments the linear counter
112     void v_inc_current (int i_rel)
113     {
114         if (! ltp_current)
115             return;
116         ltp_current = ltp_current.ltp_get_next (i_rel);
117     }
118
119     /// Replaces the current element
120     void v_replace_current (lexico lex_in, char[] cp_rep)
121     {
122         if (! ltp_current)
123             return;
124         ltp_current.v_set (lex_in, cp_rep);
125     }
126
127     /// Deletes the current element
128     void v_delete_current ()
129     {
130         lex_token ltp_temp;
131
132         ltp_temp = ltp_current;
133         ltp_temp.ltp_get_prev ().v_set_next (ltp_temp.ltp_get_next ());
134         ltp_temp.ltp_get_next ().v_set_prev (ltp_temp.ltp_get_prev ());
135         ltp_current = ltp_temp.ltp_get_next ();
136         delete ltp_temp;
137     }
138
139     /// Deletes the next element
140     void v_delete_next ()
141     {
142         lex_token ltp_temp;
143
144         assert (ltp_current);
145         ltp_temp = ltp_current.ltp_get_next ();
146         ltp_current.v_set_next (ltp_temp.ltp_get_next ());
147         ltp_temp.ltp_get_next ().v_set_prev (ltp_current);
148         delete ltp_temp;
149     }
150     void v_tokenize_expression ()
151     {
152         v_set_current_top ();
153         while (ltp_get (1))
154         {
155             switch (ltp_get (0).lex_get_value ())
156             {
157                 case lexico.lex_colon :
158                     if (ltp_get (1).lex_get_value () == lexico.lex_colon)
159                     {
160                         v_replace_current (lexico.lex_2_colon, "::");
161                         v_delete_next ();
162                     }
163                     else
164                         v_inc_current (1);
165                     break;
166                 case lexico.lex_slash :
167                     if (ltp_get (1).lex_get_value () == lexico.lex_slash)
168                     {
169                         v_replace_current (lexico.lex_2_slash, "//");
170                         v_delete_next ();
171                     }
172                     else
173                         v_inc_current (1);
174                     break;
175                 case lexico.lex_exclam :
176                     if (ltp_get (1).lex_get_value () == lexico.lex_equal)
177                     {
178                         v_replace_current (lexico.lex_not_equal, "!=");
179                         v_delete_next ();
180                     }
181                     else
182                         v_inc_current (1);
183                     break;
184                 case lexico.lex_lt :
185                     if (ltp_get (1).lex_get_value () == lexico.lex_equal)
186                     {
187                         v_replace_current (lexico.lex_lt_equal, "<=");
188                         v_delete_next ();
189                     }
190                     else
191                         v_inc_current (1);
192                     break;
193                 case lexico.lex_gt :
194                     if (ltp_get (1).lex_get_value () == lexico.lex_equal)
195                     {
196                         v_replace_current (lexico.lex_gt_equal, ">=");
197                         v_delete_next ();
198                     }
199                     else
200                         v_inc_current (1);
201                     break;
202                 case lexico.lex_dot :
203                     if (ltp_get (1).lex_get_value () == lexico.lex_dot)
204                     {
205                         v_replace_current (lexico.lex_2_dot, "..");
206                         v_delete_next ();
207                     }
208                     else
209                         v_inc_current (1);
210                     break;
211                 case lexico.lex_space :
212                     v_delete_current ();
213                     break;
214                 default :
215                     v_inc_current (1);
216                     break;
217                 }       // switch
218             }       // while
219         }
220     }
221 } ;
222
223
224 }
Note: See TracBrowser for help on using the browser.