| 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 |
} |
|---|