1 <?xml version="1.0" encoding="iso-8859-1"?>
3 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
8 <title>Class: MCollective::Matcher::Parser</title>
9 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10 <meta http-equiv="Content-Script-Type" content="text/javascript" />
11 <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
12 <script type="text/javascript">
15 function popupCode( url ) {
16 window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
19 function toggleCode( id ) {
20 if ( document.getElementById )
21 elem = document.getElementById( id );
22 else if ( document.all )
23 elem = eval( "document.all." + id );
27 elemStyle = elem.style;
29 if ( elemStyle.display != "block" ) {
30 elemStyle.display = "block"
32 elemStyle.display = "none"
38 // Make codeblocks hidden by default
39 document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
49 <div id="classHeader">
50 <table class="header-table">
51 <tr class="top-aligned-row">
52 <td><strong>Class</strong></td>
53 <td class="class-name-in-header">MCollective::Matcher::Parser</td>
55 <tr class="top-aligned-row">
56 <td><strong>In:</strong></td>
58 <a href="../../../files/lib/mcollective/matcher/parser_rb.html">
59 lib/mcollective/matcher/parser.rb
65 <tr class="top-aligned-row">
66 <td><strong>Parent:</strong></td>
73 <!-- banner header -->
75 <div id="bodyContent">
79 <div id="contextContent">
85 <div id="method-list">
86 <h3 class="section-bar">Methods</h3>
88 <div class="name-list">
89 <a href="#M000151">exit_with_paren_errors</a>
90 <a href="#M000150">exit_with_parse_errors</a>
91 <a href="#M000149">exit_with_token_errors</a>
92 <a href="#M000148">new</a>
93 <a href="#M000152">parse</a>
108 <div id="attribute-list">
109 <h3 class="section-bar">Attributes</h3>
111 <div class="name-list">
113 <tr class="top-aligned-row context-row">
114 <td class="context-item-name">execution_stack</td>
115 <td class="context-item-value"> [R] </td>
116 <td class="context-item-desc"></td>
118 <tr class="top-aligned-row context-row">
119 <td class="context-item-name">scanner</td>
120 <td class="context-item-value"> [R] </td>
121 <td class="context-item-desc"></td>
129 <!-- if method_list -->
131 <h3 class="section-bar">Public Class methods</h3>
133 <div id="method-M000148" class="method-detail">
134 <a name="M000148"></a>
136 <div class="method-heading">
137 <a href="#M000148" class="method-signature">
138 <span class="method-name">new</span><span class="method-args">(args)</span>
142 <div class="method-description">
143 <p><a class="source-toggle" href="#"
144 onclick="toggleCode('M000148-source');return false;">[Source]</a></p>
145 <div class="method-source-code" id="M000148-source">
147 <span class="ruby-comment cmt"># File lib/mcollective/matcher/parser.rb, line 6</span>
148 6: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">args</span>)
149 7: <span class="ruby-ivar">@scanner</span> = <span class="ruby-constant">Scanner</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">args</span>)
150 8: <span class="ruby-ivar">@execution_stack</span> = []
151 9: <span class="ruby-ivar">@parse_errors</span> = []
152 10: <span class="ruby-ivar">@token_errors</span> = []
153 11: <span class="ruby-ivar">@paren_errors</span> = []
154 12: <span class="ruby-identifier">parse</span>
155 13: <span class="ruby-identifier">exit_with_token_errors</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@token_errors</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
156 14: <span class="ruby-identifier">exit_with_parse_errors</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@parse_errors</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
157 15: <span class="ruby-identifier">exit_with_paren_errors</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@paren_errors</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-value">0</span>
158 16: <span class="ruby-keyword kw">end</span>
164 <h3 class="section-bar">Public Instance methods</h3>
166 <div id="method-M000151" class="method-detail">
167 <a name="M000151"></a>
169 <div class="method-heading">
170 <a href="#M000151" class="method-signature">
171 <span class="method-name">exit_with_paren_errors</span><span class="method-args">()</span>
175 <div class="method-description">
176 <p><a class="source-toggle" href="#"
177 onclick="toggleCode('M000151-source');return false;">[Source]</a></p>
178 <div class="method-source-code" id="M000151-source">
180 <span class="ruby-comment cmt"># File lib/mcollective/matcher/parser.rb, line 37</span>
181 37: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">exit_with_paren_errors</span>
182 38: <span class="ruby-ivar">@paren_errors</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
183 39: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">arguments</span>[<span class="ruby-identifier">i</span>] = <span class="ruby-constant">Util</span>.<span class="ruby-identifier">colorize</span>(<span class="ruby-identifier">:red</span>, <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">arguments</span>[<span class="ruby-identifier">i</span>])
184 40: <span class="ruby-keyword kw">end</span>
185 41: <span class="ruby-identifier">raise</span> <span class="ruby-node">"Missing parenthesis found while parsing -S input #{@scanner.arguments.join}"</span>
186 42: <span class="ruby-keyword kw">end</span>
192 <div id="method-M000150" class="method-detail">
193 <a name="M000150"></a>
195 <div class="method-heading">
196 <a href="#M000150" class="method-signature">
197 <span class="method-name">exit_with_parse_errors</span><span class="method-args">()</span>
201 <div class="method-description">
202 <p><a class="source-toggle" href="#"
203 onclick="toggleCode('M000150-source');return false;">[Source]</a></p>
204 <div class="method-source-code" id="M000150-source">
206 <span class="ruby-comment cmt"># File lib/mcollective/matcher/parser.rb, line 28</span>
207 28: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">exit_with_parse_errors</span>
208 29: <span class="ruby-ivar">@parse_errors</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">error_range</span><span class="ruby-operator">|</span>
209 30: (<span class="ruby-identifier">error_range</span>[<span class="ruby-value">0</span>]<span class="ruby-operator">..</span><span class="ruby-identifier">error_range</span>[<span class="ruby-value">1</span>]).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
210 31: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">arguments</span>[<span class="ruby-identifier">i</span>] = <span class="ruby-constant">Util</span>.<span class="ruby-identifier">colorize</span>(<span class="ruby-identifier">:red</span>, <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">arguments</span>[<span class="ruby-identifier">i</span>])
211 32: <span class="ruby-keyword kw">end</span>
212 33: <span class="ruby-keyword kw">end</span>
213 34: <span class="ruby-identifier">raise</span> <span class="ruby-node">"Parse errors found while parsing -S input #{ @scanner.arguments.join}"</span>
214 35: <span class="ruby-keyword kw">end</span>
220 <div id="method-M000149" class="method-detail">
221 <a name="M000149"></a>
223 <div class="method-heading">
224 <a href="#M000149" class="method-signature">
225 <span class="method-name">exit_with_token_errors</span><span class="method-args">()</span>
229 <div class="method-description">
231 Exit and highlight any malformed tokens
233 <p><a class="source-toggle" href="#"
234 onclick="toggleCode('M000149-source');return false;">[Source]</a></p>
235 <div class="method-source-code" id="M000149-source">
237 <span class="ruby-comment cmt"># File lib/mcollective/matcher/parser.rb, line 19</span>
238 19: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">exit_with_token_errors</span>
239 20: <span class="ruby-ivar">@token_errors</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">error_range</span><span class="ruby-operator">|</span>
240 21: (<span class="ruby-identifier">error_range</span>[<span class="ruby-value">0</span>]<span class="ruby-operator">..</span><span class="ruby-identifier">error_range</span>[<span class="ruby-value">1</span>]).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
241 22: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">arguments</span>[<span class="ruby-identifier">i</span>] = <span class="ruby-constant">Util</span>.<span class="ruby-identifier">colorize</span>(<span class="ruby-identifier">:red</span>, <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">arguments</span>[<span class="ruby-identifier">i</span>])
242 23: <span class="ruby-keyword kw">end</span>
243 24: <span class="ruby-keyword kw">end</span>
244 25: <span class="ruby-identifier">raise</span> <span class="ruby-node">"Malformed token(s) found while parsing -S input #{@scanner.arguments.join}"</span>
245 26: <span class="ruby-keyword kw">end</span>
251 <div id="method-M000152" class="method-detail">
252 <a name="M000152"></a>
254 <div class="method-heading">
255 <a href="#M000152" class="method-signature">
256 <span class="method-name">parse</span><span class="method-args">()</span>
260 <div class="method-description">
262 Parse the input string, one token at a time a contruct the call stack
264 <p><a class="source-toggle" href="#"
265 onclick="toggleCode('M000152-source');return false;">[Source]</a></p>
266 <div class="method-source-code" id="M000152-source">
268 <span class="ruby-comment cmt"># File lib/mcollective/matcher/parser.rb, line 45</span>
269 45: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parse</span>
270 46: <span class="ruby-identifier">pre_index</span> = <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">token_index</span>
271 47: <span class="ruby-identifier">p_token</span>,<span class="ruby-identifier">p_token_value</span> = <span class="ruby-keyword kw">nil</span>
272 48: <span class="ruby-identifier">c_token</span>,<span class="ruby-identifier">c_token_value</span> = <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">get_token</span>
273 49: <span class="ruby-identifier">parenth</span> = <span class="ruby-value">0</span>
275 51: <span class="ruby-keyword kw">while</span> (<span class="ruby-identifier">c_token</span> <span class="ruby-operator">!=</span> <span class="ruby-keyword kw">nil</span>)
276 52: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
277 53: <span class="ruby-identifier">n_token</span>, <span class="ruby-identifier">n_token_value</span> = <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">get_token</span>
279 55: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">n_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">" "</span>
280 56: <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">c_token</span>
281 57: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">"bad_token"</span>
282 58: <span class="ruby-ivar">@token_errors</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">c_token_value</span>
284 60: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">"and"</span>
285 61: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">n_token</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/not|fstatement|statement|\(/</span>) <span class="ruby-operator">||</span> (<span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">size</span>) <span class="ruby-operator">&&</span> <span class="ruby-operator">!</span>(<span class="ruby-identifier">n_token</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">nil</span>)
286 62: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
287 63: <span class="ruby-keyword kw">end</span>
289 65: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">p_token</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">nil</span>
290 66: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">c_token</span>.<span class="ruby-identifier">size</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
291 67: <span class="ruby-keyword kw">elsif</span> (<span class="ruby-identifier">p_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"and"</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">p_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"or"</span>)
292 68: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">p_token</span>.<span class="ruby-identifier">size</span>, <span class="ruby-identifier">pre_index</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>]
293 69: <span class="ruby-keyword kw">end</span>
295 71: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">"or"</span>
296 72: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">n_token</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/not|fstatement|statement|\(/</span>) <span class="ruby-operator">||</span> (<span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">size</span>) <span class="ruby-operator">&&</span> <span class="ruby-operator">!</span>(<span class="ruby-identifier">n_token</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">nil</span>)
297 73: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
298 74: <span class="ruby-keyword kw">end</span>
300 76: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">p_token</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">nil</span>
301 77: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">c_token</span>.<span class="ruby-identifier">size</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
302 78: <span class="ruby-keyword kw">elsif</span> (<span class="ruby-identifier">p_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"and"</span> <span class="ruby-operator">||</span> <span class="ruby-identifier">p_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"or"</span>)
303 79: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">p_token</span>.<span class="ruby-identifier">size</span>, <span class="ruby-identifier">pre_index</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>]
304 80: <span class="ruby-keyword kw">end</span>
306 82: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">"not"</span>
307 83: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">n_token</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/fstatement|statement|\(|not/</span> <span class="ruby-operator">&&</span> <span class="ruby-operator">!</span>(<span class="ruby-identifier">n_token</span> <span class="ruby-operator">==</span> <span class="ruby-keyword kw">nil</span>)
308 84: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
309 85: <span class="ruby-keyword kw">end</span>
311 87: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">"statement"</span>,<span class="ruby-value str">"fstatement"</span>
312 88: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">n_token</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/and|or|\)/</span>
313 89: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">size</span>
314 90: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
315 91: <span class="ruby-keyword kw">end</span>
316 92: <span class="ruby-keyword kw">end</span>
318 94: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">")"</span>
319 95: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">n_token</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/|and|or|not|\(/</span>)
320 96: <span class="ruby-keyword kw">unless</span>(<span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">arguments</span>.<span class="ruby-identifier">size</span>)
321 97: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
322 98: <span class="ruby-keyword kw">end</span>
323 99: <span class="ruby-keyword kw">end</span>
324 100: <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@paren_errors</span>.<span class="ruby-identifier">empty?</span>
325 101: <span class="ruby-ivar">@paren_errors</span>.<span class="ruby-identifier">pop</span>
326 102: <span class="ruby-keyword kw">else</span>
327 103: <span class="ruby-ivar">@paren_errors</span>.<span class="ruby-identifier">push</span>((<span class="ruby-identifier">n_token</span>.<span class="ruby-identifier">nil?</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span><span class="ruby-operator">:</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">n_token_value</span>.<span class="ruby-identifier">size</span>)
328 104: <span class="ruby-keyword kw">end</span>
330 106: <span class="ruby-keyword kw">when</span> <span class="ruby-value str">"("</span>
331 107: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">n_token</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/fstatement|statement|not|\(/</span>
332 108: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
333 109: <span class="ruby-keyword kw">end</span>
334 110: <span class="ruby-ivar">@paren_errors</span>.<span class="ruby-identifier">push</span>((<span class="ruby-identifier">n_token</span>.<span class="ruby-identifier">nil?</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span><span class="ruby-operator">:</span> <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">n_token_value</span>.<span class="ruby-identifier">size</span>)
336 112: <span class="ruby-keyword kw">else</span>
337 113: <span class="ruby-ivar">@parse_errors</span> <span class="ruby-operator"><<</span> [<span class="ruby-identifier">pre_index</span>, <span class="ruby-identifier">scanner</span>.<span class="ruby-identifier">token_index</span>]
338 114: <span class="ruby-keyword kw">end</span>
340 116: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">n_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">" "</span> <span class="ruby-operator">||</span><span class="ruby-identifier">c_token</span> <span class="ruby-operator">==</span> <span class="ruby-value str">"bad_token"</span>
341 117: <span class="ruby-ivar">@execution_stack</span> <span class="ruby-operator"><<</span> {<span class="ruby-identifier">c_token</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">c_token_value</span>}
342 118: <span class="ruby-keyword kw">end</span>
344 120: <span class="ruby-identifier">p_token</span>, <span class="ruby-identifier">p_token_value</span> = <span class="ruby-identifier">c_token</span>, <span class="ruby-identifier">c_token_value</span>
345 121: <span class="ruby-identifier">c_token</span>, <span class="ruby-identifier">c_token_value</span> = <span class="ruby-identifier">n_token</span>, <span class="ruby-identifier">n_token_value</span>
346 122: <span class="ruby-keyword kw">end</span>
347 123: <span class="ruby-identifier">pre_index</span> = <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">token_index</span>
348 124: <span class="ruby-keyword kw">end</span>
349 125: <span class="ruby-keyword kw">end</span>
362 <div id="validator-badges">
363 <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>