<?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"
	>

<channel>
	<title>the occasional occurrence</title>
	<atom:link href="http://blog.dowski.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dowski.com</link>
	<description>Unfortunately, Christian had a Thwart, and the Magpie stayed in play.</description>
	<pubDate>Wed, 16 Apr 2008 17:34:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Converting docx Files</title>
		<link>http://blog.dowski.com/2008/04/16/converting-docx-files/</link>
		<comments>http://blog.dowski.com/2008/04/16/converting-docx-files/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 17:34:46 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[computing]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/04/16/converting-docx-files/</guid>
		<description><![CDATA[I&#8217;m working on an OOXML implementation in Python and found this handy utility for converting docx files to rtf.
Docx2Rtf
It seems to open docx files that Word complains about, but at least it let&#8217;s me know that I am on the right track.  Also, it runs under Wine on Linux, so there is no need [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on an OOXML implementation in Python and found this handy utility for converting docx files to rtf.</p>
<p><a href="http://www.nativewinds.montana.com/software/docx2rtf.html">Docx2Rtf</a></p>
<p>It seems to open docx files that Word complains about, but at least it let&#8217;s me know that I am on the right track.  Also, it runs under Wine on Linux, so there is no need for a virtual or non-virtual machine running Windows.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/04/16/converting-docx-files/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Command History</title>
		<link>http://blog.dowski.com/2008/04/12/command-history/</link>
		<comments>http://blog.dowski.com/2008/04/12/command-history/#comments</comments>
		<pubDate>Sat, 12 Apr 2008 14:52:32 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[computing]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/04/12/command-history/</guid>
		<description><![CDATA[Since all the cool kids are doing it &#8230;
Work laptop

christian@yga-dowski:~$ history&#124;awk '{a[$2]++ } END{for(i in a){print a[i] &#8221; &#8221; i}}&#8217; &#124;sort -rn&#124;head
82 sudo
68 vim
51 ls
49 cd
48 exit
20 hg
16 rm
16 ipython
14 py.test
10 ping

Apparently I do a lot of exiting.  I just started using Mercurial for local revision control, hence the presence of hg.
Dev server
 (where [...]]]></description>
			<content:encoded><![CDATA[<p>Since all <a href="http://exilejedi.livejournal.com/198371.html">the</a> <a href="http://michael.susens-schurter.com/blog/2008/04/11/history-meme/">cool</a> <a href="http://blog.extracheese.org/2008/04/shell-meme-wins.html">kids</a> are doing it &#8230;</p>
<h3>Work laptop</h3>
<pre>
christian@yga-dowski:~$ history|awk '{a[$2]++ } END{for(i in a){print a[i] &#8221; &#8221; i}}&#8217; |sort -rn|head
82 sudo
68 vim
51 ls
49 cd
48 exit
20 hg
16 rm
16 ipython
14 py.test
10 ping
</pre>
<p>Apparently I do a lot of exiting.  I just started using <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a> for local revision control, hence the presence of <code>hg</code>.</p>
<h3>Dev server</h3>
<p> (where I actually do most of my work)</p>
<pre>
cmw@watson:~/svn/g2wc$ history|awk '{a[$2]++ } END{for(i in a){print a[i] &#8221; &#8221; i}}&#8217; |sort -rn|head
158 vim
81 make
70 svn
55 rm
34 ls
33 cd
15 sudo
11 exit
7 kinit
7 htop
</pre>
<p>The <code>make</code> commands encapsulate many calls to <code>python</code> and <code>py.test</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/04/12/command-history/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Reading Chunked HTTP/1.1 Responses</title>
		<link>http://blog.dowski.com/2008/04/02/reading-chunked-http11-responses/</link>
		<comments>http://blog.dowski.com/2008/04/02/reading-chunked-http11-responses/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 04:35:28 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[cherrypy]]></category>

		<category><![CDATA[computing]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/04/02/reading-chunked-http11-responses/</guid>
		<description><![CDATA[For work today I wanted a way to iterate over an HTTP response with chunked transfer-coding on a chunk-for-chunk basis.  I didn&#8217;t see a builtin way to do that with httplib.  It supports chunked reads but you have to specify the amount that you want to read if you don&#8217;t want it to [...]]]></description>
			<content:encoded><![CDATA[<p>For work today I wanted a way to iterate over an HTTP response with chunked transfer-coding on a chunk-for-chunk basis.  I didn&#8217;t see a builtin way to do that with <code>httplib</code>.  It supports chunked reads but you have to specify the amount that you want to read if you don&#8217;t want it to buffer.  I just wanted it to read and yield each chunk that it received from the server.</p>
<p>For my first crack at it I really just tried to use the <code>httplib</code> basics:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>
&nbsp;
conn = <span style="color: #dc143c;">httplib</span>.<span style="color: black;">HTTPConnection</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'localhost:8080'</span><span style="color: black;">&#41;</span>
conn.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'GET'</span>, <span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span>
r = conn.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
data = r.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">while</span> data:
    <span style="color: #ff7700;font-weight:bold;">print</span> data
    data = r.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span></pre></div></div>

<p>That worked but since I won&#8217;t know the chunk size in real-life, I would probably get output similar to this:</p>
<pre>
Chunk 0
Ch
unk 1
Chun
k 2
Chunk
3
Chunk 4
...
</pre>
<p>I really wanted that chunk-for-chunk iteration.  After taking a look at the very readable <code>httplib</code> source this evening, it wasn&#8217;t very hard to accomplish.  I basically just took the <code>httplib.HTTPResponse._read_chunked</code> method and modified it to be a generator.  I subclassed <code>HTTPResponse</code> and stuck my generator in an <code>__iter__</code> method.  Behold; now you can do this sort of thing:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>
    <span style="color: #ff7700;font-weight:bold;">import</span> iresponse
    conn = <span style="color: #dc143c;">httplib</span>.<span style="color: black;">HTTPConnection</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'localhost:8080'</span><span style="color: black;">&#41;</span>
    conn.<span style="color: black;">response_class</span> = iresponse.<span style="color: black;">IterableResponse</span>
    conn.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'GET'</span>, <span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span>
    r = conn.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: #dc143c;">chunk</span> <span style="color: #ff7700;font-weight:bold;">in</span> r:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">chunk</span></pre></div></div>

<p>With nice results like this:</p>
<pre>
Chunk 0
Chunk 1
Chunk 2
Chunk 3
Chunk 4
...
</pre>
<p>You can download <a href="http://projects.dowski.com/view/iresponse">the iresponse module</a> from my projects site.  There is also a small CherryPy application that serves some data with chunked transfer-coding in case any of you want to fiddle with it.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/04/02/reading-chunked-http11-responses/feed/</wfw:commentRss>
		</item>
		<item>
		<title>My PyCon 2008 Post</title>
		<link>http://blog.dowski.com/2008/03/27/my-pycon-2008-post/</link>
		<comments>http://blog.dowski.com/2008/03/27/my-pycon-2008-post/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 02:15:06 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[computing]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/03/27/my-pycon-2008-post/</guid>
		<description><![CDATA[WARNING: this is YAPAP (Yet Another Post About PyCon), and a late one at that.  Click to read more, else move along fair netizen.]]></description>
			<content:encoded><![CDATA[<p>WARNING: this is YAPAP (Yet Another Post About PyCon), and a late one at that.  Click to read more, else move along fair netizen.</p>
<p><span id="more-228"></span></p>
<p>I enjoyed every part of <a href="http://us.pycon.org/2008/about/">PyCon 2008</a>.  I guess I&#8217;m easy to please or something.  Maybe I just enjoyed getting out of my home/office for a few days and talking to my coworkers and other online friends face-to-face for a change.  Yeah, that was probably it.</p>
<p>Three of us from <a href="http://groups.google.com/group/clepy">ClePy</a> (<a href="http://kevin.fonner.net">Kevin</a>, <a href="http://blog.extracheese.org/">Gary</a> and me) and the lone member of &#8220;PittPy&#8221; (<a href="http://blag.whit537.org/">Chad</a>) piled into Chad&#8217;s dad&#8217;s CRV and drove for 6+ hours to Chicago on Thursday.  Before I left, my wife asked me what in the world we&#8217;d all be talking about for 6+ hours to and from Chicago.  A valid question since we&#8217;re a bunch of computer nerds.  </p>
<p>Well, funny thing; put an at-home Disney Imagineer, a philosopher-hippie, an opinionated vegetarian and a guy whose typical daytime social outlet is IRC into the same vehicle for a road-trip to PyCon and you have a recipe for some interesting conversation.  Of course we talked plenty about Python but we also covered pumping CO2 into underground oil pockets, <a href="http://www.scienceiq.com/ShowFact.cfm?ID=194">burping lakes</a>, sagging high-tension lines, farming, quantum mechanics and religion amongst many other topics.</p>
<p>I don&#8217;t have too much to say about the talks at the conference.  I went to a few really good ones and a bunch of O.K. ones.  Highlights included the one on &#8220;rolling your own persistence system with Python&#8221; and the one on writing Trac plugins.  I think what made those two talks good was a) a speaker who was excited about the topic and b) the right balance of code and concepts.  I walked away from both of those talks feeling like I could hit the ground running if I wanted to dig further into either topic.</p>
<p>As I mentioned earlier, the best thing about the conference was the people.  Where else can you go where there are over one thousand other people into Python and doing all sorts of interesting things with it?  I got to hang out with the cool group of guys (<a href="http://jamwt.com">Jamie</a>, <a href="http://mrshoe.org">Dave</a> and <a href="http://michael.susens-schurter.com/blog/">Michael</a>) <a href="http://www.polimetrix.com/">that I work with</a> plus the other folks who I have met through Python.  Then there was the <a href="http://www.flickr.com/photos/dowski/2343927319/">&#8220;web dudes&#8221; party</a>, meeting some international Pythonistas, exploring downtown Chicago, hanging out with <a href="http://aminus.org/blogs/index.php/fumanchu">Bob</a> at the <a href="http://cherrypy.org/">CherryPy</a> BOF and copious amounts of pizza at Gino&#8217;s East.</p>
<p>I think that one thing I&#8217;ll do differently next year is get involved with more of the open space talks.  I think that smaller more focused groups with more interaction would make for a better experience.  And maybe I&#8217;ll come up with something to give a lightning talk about.</p>
<p>So yeah, great conference.  Thanks to everyone who worked hard to make it happen.</p>
<p>cw</p>
<p>PS</p>
<p>Check out my <a href="http://www.flickr.com/photos/dowski/tags/pycon2008/">PyCon photos</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/03/27/my-pycon-2008-post/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Life Rundown</title>
		<link>http://blog.dowski.com/2008/02/13/life-rundown/</link>
		<comments>http://blog.dowski.com/2008/02/13/life-rundown/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 06:41:58 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[Family]]></category>

		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/02/13/life-rundown/</guid>
		<description><![CDATA[This blog has probably been pretty boring lately for those of you who aren&#8217;t interested in my technical musings.  The main reason for that is because there has been too much junk going on for us these days.  I kind of had two options:

Whine about our problems.
Sugar coat our problems.

Ok, so I probably [...]]]></description>
			<content:encoded><![CDATA[<p>This blog has probably been pretty boring lately for those of you who aren&#8217;t interested in my technical musings.  The main reason for that is because there has been too much junk going on for us these days.  I kind of had two options:</p>
<ol>
<li>Whine about our problems.</li>
<li>Sugar coat our problems.</li>
</ol>
<p>Ok, so I probably had more options than that, but I think I would have gravitated toward one of those two things.  </p>
<p>In the spirit of not doing either of those things, here is a cold, bulleted list of some of the junk from the past few months so that those of you who are interested but not in the know can be more so in the know.  In no particular order:</p>
<ul>
<li>Moving</li>
<li>Death in the family</li>
<li>Having two houses (and two mortgages!)</li>
<li>Broken bones</li>
<li>All of a sudden having to make our house handicap accessible for my mother-in-law</li>
<li>Our 1 year-old turning 2 and taking it seriously</li>
</ul>
<p>Ok, there you have it.  Maybe now that that is out there I can get on with some more normal life-update sort of posts.  We&#8217;ll see.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/02/13/life-rundown/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Code Farming</title>
		<link>http://blog.dowski.com/2008/02/13/code-farming/</link>
		<comments>http://blog.dowski.com/2008/02/13/code-farming/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 06:31:05 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[computing]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/02/13/code-farming/</guid>
		<description><![CDATA[I read a good article that gave an Organic Metaphor for software development.  Here is a quote:
As I look at what I actually do in my cramped little cubicle, I realize that my work is more akin to farming than construction. I spend my days cultivating information, and growing a program. I can see [...]]]></description>
			<content:encoded><![CDATA[<p>I read a good article that gave an <a href="http://descmath.com/data/organic.html">Organic Metaphor</a> for software development.  Here is a quote:</p>
<blockquote><p>As I look at what I actually do in my cramped little cubicle, I realize that my work is more akin to farming than construction. I spend my days cultivating information, and growing a program. I can see the evolution of my work as it needs to scale through different platforms.</p></blockquote>
<p>I really resonate with that description - writing software is very fluid and organic.  Code is malleable and frequently changing.  During development, there aren&#8217;t necessarily rigid beams and permanent fasteners like in construction.</p>
<p>Perhaps lending credence to both the architectural and organic software development metaphors, the article closes with this thought:</p>
<blockquote><p>
The term &#8220;System Architecture&#8221; is a more fitting in the world of packaged software than it is for the IT department or Internet development. With packaged software, a group of programmers create one major release that they will distribute to hundreds of thousands of users. Since there is no method for evolution, this type of software has much more rigid. Of course, with the Internet explosion, packaged software will take a backseat to organic programming.
</p></blockquote>
<p>Yeah.  The engineering/architectural and the organic metaphors probably both have their places.  Packaged, physically distributed software probably requires more engineering.  The organic metaphor better describes  the survival of the fittest (or survival of the first-to-market) and rapid evolution that is possible (and required) in the internet ecosystem.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/02/13/code-farming/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ohio has been Indexed!</title>
		<link>http://blog.dowski.com/2008/02/07/ohio-has-been-indexed/</link>
		<comments>http://blog.dowski.com/2008/02/07/ohio-has-been-indexed/#comments</comments>
		<pubDate>Thu, 07 Feb 2008 14:00:16 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/02/07/ohio-has-been-indexed/</guid>
		<description><![CDATA[Big pharma hearts Ohio
If only there was such a thing as &#8220;cloud power&#8221; - we&#8217;d tear solar power up.
cw
]]></description>
			<content:encoded><![CDATA[<p><a href="http://indexed.blogspot.com/2008/02/big-pharma-hearts-ohio.html">Big pharma hearts Ohio</a></p>
<p>If only there was such a thing as &#8220;cloud power&#8221; - we&#8217;d tear solar power up.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/02/07/ohio-has-been-indexed/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SimpleParse Presentation and Other ClePy Notes</title>
		<link>http://blog.dowski.com/2008/02/05/simpleparse-presentation-and-other-clepy-notes/</link>
		<comments>http://blog.dowski.com/2008/02/05/simpleparse-presentation-and-other-clepy-notes/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 12:02:17 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2008/02/05/simpleparse-presentation-and-other-clepy-notes/</guid>
		<description><![CDATA[I gave a brief presentation on SimpleParse at the ClePy meeting last night.
The presentation slides and a few example files are available on my site.
Matt Wilson shared some cool stuff about IPython and twill.  
IPython seems like one of those apps where you can always learn one more time-saving trick.  I learned a [...]]]></description>
			<content:encoded><![CDATA[<p>I gave a brief presentation on <a href="http://simpleparse.sourceforge.net/">SimpleParse</a> at the <a href="http://groups.google.com/group/clepy">ClePy</a> meeting last night.</p>
<p>The presentation slides and a few example files are <a href="http://dowski.com/~christian/clepy/parsing/">available on my site</a>.</p>
<p><a href="http://blog.tplus1.com/">Matt Wilson</a> shared some cool stuff about <a href="http://ipython.scipy.org/moin/">IPython</a> and <a href="http://twill.idyll.org/">twill</a>.  </p>
<p>IPython seems like one of those apps where you can always learn one more time-saving trick.  I learned a few more last night even though I use it every day.  </p>
<p>I&#8217;ve never used twill and I&#8217;m still not super-compelled to do so.  It seems like testing with something like <a href="http://selenium.openqa.org/">Selenium</a> will pick up on any errors that twill might catch (and more since it uses a real browser).  The one advantage that I am sure twill has over Selenium is speed.  I guess it might fit in there between library-level unit tests and high-level tests like those using Selenium.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2008/02/05/simpleparse-presentation-and-other-clepy-notes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SimpleParse Plug</title>
		<link>http://blog.dowski.com/2007/12/19/simpleparse-plug/</link>
		<comments>http://blog.dowski.com/2007/12/19/simpleparse-plug/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 05:37:50 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2007/12/19/simpleparse-plug/</guid>
		<description><![CDATA[I&#8217;ve been doing more parsing stuff at work lately.  For my latest project I&#8217;ve been using the SimpleParse library.  It has quickly overtaken PLY as my Python parsing library of choice.
Here&#8217;s a simple calculator example using SimpleParse.  It does basic arithmetic and allows you to store values in single letter variable names. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing more parsing stuff at work lately.  For my latest project I&#8217;ve been using the <a href="http://simpleparse.sourceforge.net/">SimpleParse</a> library.  It has quickly overtaken <a href="http://www.dabeaz.com/ply/">PLY</a> as my Python parsing library of choice.</p>
<p>Here&#8217;s a simple calculator example using SimpleParse.  It does basic arithmetic and allows you to store values in single letter variable names.  It basically just validates the line that you enter and then either evals or execs it as Python code.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">from</span> simpleparse.<span style="color: #dc143c;">parser</span> <span style="color: #ff7700;font-weight:bold;">import</span> Parser
<span style="color: #ff7700;font-weight:bold;">from</span> simpleparse.<span style="color: black;">common</span> <span style="color: #ff7700;font-weight:bold;">import</span> numbers
<span style="color: #ff7700;font-weight:bold;">from</span> simpleparse.<span style="color: black;">error</span> <span style="color: #ff7700;font-weight:bold;">import</span> ParserSyntaxError
&nbsp;
grammar = <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
command     := !, assign/expr
assign      := varname, ts, '</span>=<span style="color: #483d8b;">', !, ts, expr
expr        := (lpar?, 
                ts, operand, ts, (op, !, ts, operand, ts)*, ts, 
               rpar?)+
lpar        := '</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'
rpar        := '</span><span style="color: black;">&#41;</span><span style="color: #483d8b;">'
operand     := lpar?, ts, number/varname, ts, rpar?
varname     := [a-z]
op          := [+-*/]
&lt;ts&gt;        := [ <span style="color: #000099; font-weight: bold;">\t</span>]*
'</span><span style="color: #483d8b;">''</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Calculator<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">scanner</span> = Parser<span style="color: black;">&#40;</span>grammar, <span style="color: #483d8b;">'command'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> parse<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, command<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            success, subtags, nextchar = <span style="color: #008000;">self</span>.<span style="color: black;">scanner</span>.<span style="color: black;">parse</span><span style="color: black;">&#40;</span>command<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> ParserSyntaxError, e:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>e<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> subtags<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'expr'</span>:
                <span style="color: #ff7700;font-weight:bold;">try</span>:
                    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">eval</span><span style="color: black;">&#40;</span>command<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">Exception</span>, e:
                    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Error:&quot;</span>, e.<span style="color: black;">args</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> subtags<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'assign'</span>:
                <span style="color: #ff7700;font-weight:bold;">exec</span> command <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">globals</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    calc = Calculator<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> prompt<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">raw_input</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&gt; '</span><span style="color: black;">&#41;</span>
&nbsp;
    command = prompt<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> command != <span style="color: #483d8b;">&quot;quit&quot;</span>:
        result = calc.<span style="color: black;">parse</span><span style="color: black;">&#40;</span>command<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> result:
            <span style="color: #ff7700;font-weight:bold;">print</span> result
        command = prompt<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&lt;/ts&gt;</pre></div></div>

<p>There it is, in all of its uncommented glory.</p>
<p>Here&#8217;s an example session with the calculator:</p>
<pre>
> 2 + 2
4
> x = 4
> 8 * x
32
> y = 8 * x
> y
32
> 5 +
ParserSyntaxError: Failed parsing production "expr" @pos 3 (~line 1:3).
Expected syntax: operand
Got text: ''
> import shutil
Error: invalid syntax
> quit
</pre>
<p>Here are some of my favorite things about SimpleParse.</p>
<p><strong>The entire grammar is declared in the <a href="http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form">EBNF</a>.</strong><br />
This is a breath of fresh air coming from PLY, where the grammar rules are scattered amongst the action-code (in docstrings).</p>
<p><strong>It has a clean API.</strong><br />
The API is very succinct, and thus you get to know it fairly quickly.  Creating Processors for parsed text is quite straightforward.</p>
<p><strong>It&#8217;s Fast.</strong><br />
It&#8217;s built on the fastfastfast <a href="http://www.egenix.com/products/python/mxBase/mxTextTools/">mx.TextTools</a> library from <a href="http://www.egenix.com/">eGenix</a>.  It converts your EBNF grammar to mx.TextTools tag tables and pushes the heavy lifting off to the mx.TextTools tagging engine.</p>
<p>Some stuff that I found odd includes&#8230;</p>
<p><strong>No Simple Tutorial.</strong><br />
Maybe I&#8217;ll do something about that using the calculator example above.  The library is really great, but there is a fairly steep learning curve at this point due to the lack of a basic tutorial.</p>
<p><strong>No Separate Lexing Stage.</strong><br />
Unlike PLY and other traditional parser generators, you don&#8217;t generate a token stream and then parse that according to your grammar.  SimpleParse generates an mx.TextTools result tree which is then processed (typically) by SimpleParse DispatchProcessor subclass.</p>
<p><strong>Error Handling</strong><br />
SimpleParse seems to like to just stop parsing when it reaches a syntax item that it can&#8217;t parse.  You need to use a special token (an exclamation point, !) in your grammar to denote where you want to get picky about syntax.  Although it is a bit tricky, it seems quite flexible so far.</p>
<p><strong>Whitespace Handling.</strong><br />
There is no way (that I know of) to completely ignore certain characters.  PLY let me define characters that were simply ignored, as if they weren&#8217;t even there.  In the calculator above, I had to insert a <code>ts</code> production wherever I anticipate a potential series of tab or space characters in the input.  However, by putting the production name in &lt;angle brackets&gt; the matched text is kept out of the result tree.</p>
<p>I&#8217;ll end this now by encouraging anyone interested in parsing a little (or big!) language using Python to <a href="http://simpleparse.sourceforge.net/">check out SimpleParse</a>.  It&#8217;s clean API and speed make it very nice to work with.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2007/12/19/simpleparse-plug/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Political Plug</title>
		<link>http://blog.dowski.com/2007/11/29/political-plug/</link>
		<comments>http://blog.dowski.com/2007/11/29/political-plug/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 20:43:38 +0000</pubDate>
		<dc:creator>christian</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.dowski.com/2007/11/29/political-plug/</guid>
		<description><![CDATA[Here&#8217;s an article from the Economist on foreign policy and the race for the White House.
Foreign policy and the presidential race.
It&#8217;s an interesting article, but even more interesting is that the data in the poll came from the organization that I work for.  Ok, maybe more interesting is a bit of a stretch.  [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s an article from the Economist on foreign policy and the race for the White House.</p>
<p><a href="http://economist.com/world/na/displaystory.cfm?story_id=10214921">Foreign policy and the presidential race.</a></p>
<p>It&#8217;s an interesting article, <em>but even more interesting</em> is that the data in the poll came from <a href="http://polimetrix.com/">the organization that I work for</a>.  Ok, maybe <em>more interesting</em> is a bit of a stretch. <img src='http://blog.dowski.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>So there you go - the fruits of my (and <em>many</em> others&#8217;) labor.</p>
<p>cw</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dowski.com/2007/11/29/political-plug/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
