<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mundo Ruby &#187; Tokens</title>
	<atom:link href="http://www.mundoruby.com.ar/tag/tokens/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mundoruby.com.ar</link>
	<description>Ruby Artists, Hackers y otras yerbas ...</description>
	<lastBuildDate>Wed, 12 Aug 2009 23:02:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tokenizer de rapidito</title>
		<link>http://www.mundoruby.com.ar/2009/06/07/tokenizer-de-rapidito/</link>
		<comments>http://www.mundoruby.com.ar/2009/06/07/tokenizer-de-rapidito/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 15:31:36 +0000</pubDate>
		<dc:creator>FreedomCoder</dc:creator>
				<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tokens]]></category>

		<guid isPermaLink="false">http://www.mundoruby.com.ar/?p=94</guid>
		<description><![CDATA[Después de mirar un rato el estado de las bibliotecas para hacer wikis en Ruby, y descubrir que ninguna me servía, Decidí que tenía que poner cartas en el asunto y hacer la mía. Mi idea es implementar el markup de Trac, haciéndolo extensible, y agregarle un par de cositas que por ahora son un [...]]]></description>
			<content:encoded><![CDATA[<p>Después de mirar un rato el estado de las bibliotecas para hacer wikis en Ruby, y descubrir que ninguna me servía, Decidí que tenía que poner cartas en el asunto y hacer la mía. Mi idea es implementar el markup de Trac, haciéndolo extensible, y agregarle un par de cositas que por ahora son un secreto :-p.</p>
<p>Lo importante del asunto es que puse manos en el asunto. Al final, después de un intento fallido de hackear mi camino al andar, decidí que lo mejor es armar un tokenizer y un parser que use esos tokens para generar el árbol del que extraeré el HTML.</p>
<p>Así que me puse a programar. Como no encontré ningún tokenizer en ruby, programé uno. El tokenizer se contruye con un montón de expresiones regulares que definen cada delimitador. Después se le setea una fuente de caracteres (un string) y separa el string en los delimitadores de arriba (que se devuelven como símbolos) y cadenas que no matchean con ninguno de los delimitadores (que devuelve como strings).</p>
<p>Bueno, basta de cháchara, acá tá el código:</p>
<pre><strong>module</strong> <span style="color: #800000">Rapidito</span>
  <strong>class</strong> <span style="color: #800000">Tokenizer</span>

    <strong>def</strong> initialize( <span style="color: #ff9fec">*</span>delimiters )
      <span style="color: #008000">@regexp</span> <span style="color: #ff9fec">=</span> <span style="color: #800000">Regexp</span><span style="color: #4000a7">.union</span>( <span style="color: #ff9fec">*</span>delimiters  <span style="color: #ff9fec">+</span> <span style="color: #ff9fec">[</span><span style="color: #4a5704">/$/</span><span style="color: #ff9fec">]</span> )
    <strong>end</strong>

    <span style="color: #008000">attr_accessor</span> <span style="color: #d40000">:source</span>

    <strong>def</strong> has_next?
     <span style="color: #ff9fec"> !</span> <span style="color: #008000">@source</span><span style="color: #4000a7">.empty?</span>
    <strong>end</strong>

    <strong>def</strong> next_token
      <span style="color: #000080">p</span> <span style="color: #ff9fec">=</span> (<span style="color: #008000">@source</span> <span style="color: #ff9fec">=~</span> <span style="color: #008000">@regexp</span>)
      <strong>if</strong> <span style="color: #000080">p</span> <span style="color: #ff9fec">==</span> <span style="color: #0000ff">0</span> <span style="color: #808080"><em>#delimiter</em></span>
        token <span style="color: #ff9fec">=</span> <span style="color: #0000ff">nil</span>
        <span style="color: #008000">@source</span><span style="color: #4000a7">.sub!</span>( <span style="color: #008000">@regexp</span> ) <span style="color: #ff9fec">{</span> <span style="color: #ff9fec">|</span>match<span style="color: #ff9fec">|</span> token<span style="color: #ff9fec">=</span>match<span style="color: #4000a7">.to_sym</span>; <span style="color: #dd0000">""</span> <span style="color: #ff9fec">}</span>
        token
      <strong>else</strong> <span style="color: #808080"><em>#text</em></span>
        token <span style="color: #ff9fec">=</span> <span style="color: #008000">@source</span><span style="color: #ff9fec">[</span><span style="color: #0000ff">0</span>,<span style="color: #000080">p</span><span style="color: #ff9fec">]</span>
        <span style="color: #008000">@source</span> <span style="color: #ff9fec">=</span> <span style="color: #008000">@source</span><span style="color: #ff9fec">[</span><span style="color: #000080">p</span>,<span style="color: #008000">@source</span><span style="color: #4000a7">.length</span><span style="color: #ff9fec">]</span>
        token
      <strong>end</strong>
    <strong>end</strong>

    <strong>def</strong> all_tokens
      tokens <span style="color: #ff9fec">=</span> <span style="color: #ff9fec">[]</span>
      <strong>while</strong> has_next?
        tokens <span style="color: #ff9fec">&lt;&lt;</span> next_token
      <strong>end</strong>
      tokens
    <strong>end</strong>

  <strong>end</strong>
<strong>end</strong></pre>
<p>Y, acá abajo la única documentación que hice hasta ahora, o sea los tests de unidad:</p>
<pre><span style="color: #000080">require</span> <span style="color: #dd4a4a">'test/unit'</span>
<span style="color: #000080">require</span> <span style="color: #dd4a4a">'rapidito/tokenizer'</span>

<strong>include</strong> <span style="color: #800000">Rapidito</span>

<strong>class</strong> <span style="color: #800000">TokenizerTest</span> <span style="color: #ff9fec">&lt;</span> <span style="color: #800000">Test</span><span style="color: #ff9fec">::</span><span style="color: #800000">Unit</span><span style="color: #ff9fec">::</span><span style="color: #800000">TestCase</span>

  <strong>def</strong> test_no_token
    tok <span style="color: #ff9fec">=</span> <span style="color: #800000">Tokenizer</span><span style="color: #4000a7">.new</span>
    tok<span style="color: #4000a7">.source</span> <span style="color: #ff9fec">=</span> <span style="color: #dd0000">"aaaa"</span>
    assert_equal <span style="color: #0000ff">true</span>, tok<span style="color: #4000a7">.has_next?</span>
    assert_equal <span style="color: #dd0000">"aaaa"</span>, tok<span style="color: #4000a7">.next_token</span>
    assert_equal <span style="color: #0000ff">false</span>, tok<span style="color: #4000a7">.has_next?</span>
  <strong>end</strong>

  <strong>def</strong> test_two_delimiters
    tok <span style="color: #ff9fec">=</span> <span style="color: #800000">Tokenizer</span><span style="color: #4000a7">.new</span>( <span style="color: #4a5704">/\|/</span>, <span style="color: #4a5704">/;;/</span> )
    tok<span style="color: #4000a7">.source</span> <span style="color: #ff9fec">=</span> <span style="color: #dd0000">"aa|bbb;;;;cccc"</span>
    assert_equal <span style="color: #ff9fec">[</span> <span style="color: #dd0000">"aa"</span>, :<span style="color: #dd0000">"|"</span>, <span style="color: #dd0000">"bbb"</span>, :<span style="color: #dd0000">";;"</span>, :<span style="color: #dd0000">";;"</span>, <span style="color: #dd0000">"cccc"</span> <span style="color: #ff9fec">]</span>, tok<span style="color: #4000a7">.all_tokens</span>

    tok<span style="color: #4000a7">.source</span> <span style="color: #ff9fec">=</span> <span style="color: #dd0000">"aa;;bbb||cccc"</span>
    assert_equal <span style="color: #ff9fec">[</span> <span style="color: #dd0000">"aa"</span>, :<span style="color: #dd0000">";;"</span>, <span style="color: #dd0000">"bbb"</span>, :<span style="color: #dd0000">"|"</span>, :<span style="color: #dd0000">"|"</span>, <span style="color: #dd0000">"cccc"</span> <span style="color: #ff9fec">]</span>, tok<span style="color: #4000a7">.all_tokens</span>
  <strong>end</strong>

  <strong>def</strong> test_choose_first_match
    tok <span style="color: #ff9fec">=</span> <span style="color: #800000">Tokenizer</span><span style="color: #4000a7">.new</span>( <span style="color: #4a5704">/aa/</span>, <span style="color: #4a5704">/aaa/</span> )
    tok<span style="color: #4000a7">.source</span> <span style="color: #ff9fec">=</span> <span style="color: #dd0000">"aaa"</span>
    assert_equal <span style="color: #ff9fec">[</span> <span style="color: #d40000">:aa</span>, <span style="color: #dd0000">"a"</span> <span style="color: #ff9fec">]</span>, tok<span style="color: #4000a7">.all_tokens</span>
  <strong>end</strong>

<strong>end</strong></pre>
<p>Happy hacking,<br />
Aureliano.</p>
<p>PD: ¿Prefieren que ponga el código con syntax highlighting?</p>
<div class="blogger-post-footer"><img src="http://aurelianito.blogspot.com//blogger.googleusercontent.com/tracker/1437970354124720603-4057020437381149676?l=aurelianito.blogspot.com" alt="" width="1" height="1" /></div>
<p>(Via <a href="http://aurelianito.blogspot.com/">aurelianito</a>.) Original Link: <a href="http://aurelianito.blogspot.com/2009/06/tokenizer-de-rapidito.html">Tokenizer de rapidito</a></p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-7949681675937032";
google_ad_slot = "0874687580";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mundoruby.com.ar/2009/06/07/tokenizer-de-rapidito/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

