<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-27514475</id><updated>2011-06-08T00:34:12.221-06:00</updated><title type='text'>Spikebucket</title><subtitle type='html'>Brains, Programming Languages, Disconnected Enthusiasms</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-27514475.post-6720808189019410897</id><published>2007-10-01T02:35:00.000-06:00</published><updated>2007-10-01T11:12:44.904-06:00</updated><title type='text'>A simple calculator</title><content type='html'>After a long struggle with some wildly inefficient algorithms, I've given up on Parsnip's more exotic parse strategies. Unfortunately, this means my long held goal of allowing left-recursion is out. To keep Parsnip user code readable (by avoiding left-factoring) I just wrote the OpTableParser class, which implements operator precedence parsing. The syntax of operator parsing is a bit funky, but not so mysterious if you keep in mind that &lt;em&gt;infix_left&lt;/em&gt; returns an OpTableParser pointer. For an example, here's a parser/evaluator for simple mathematical expressions. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;//First we need some functions to evaluate our mathematical expressions &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;double multiply(double x, double y) { return x*y; }&lt;br /&gt;double add(double x, double y) { return x+y; }&lt;br /&gt;double subtract(double x, double y) { return x-y; }&lt;br /&gt;double divide(double x, double y) { return x/y; }&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;// Our parser will accept a string and return a double&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;typedef Parser&amp;lt;string, double&amp;gt;::type NumParser;&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;// Here is the new operator precedence parser&lt;br /&gt;// The infix_left method accepts an operator string, its precedence and &lt;br /&gt;// an associate reducer function&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;NumParser ops = op_table(real)&lt;br /&gt;                 -&gt;infix_left("+", 10, add)&lt;br /&gt;                 -&gt;infix_left("-", 10, subtract)&lt;br /&gt;                 -&gt;infix_left("*", 20, multiply)&lt;br /&gt;                 -&gt;infix_left("/", 20, divide);&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;Our parser will return a double if it succeeds. The returned value, along&lt;br /&gt;with any error info, will be stored in a ParseResult object&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;ParseResult&amp;lt;double&amp;gt; result;&lt;br /&gt; &lt;br /&gt;result = parse("3+4*2", ops);&lt;br /&gt;&lt;br /&gt;if (result.parse_finished())&lt;br /&gt;{&lt;br /&gt;  std::cout &amp;lt;&amp;lt; parse.data(); &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-6720808189019410897?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/6720808189019410897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=6720808189019410897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/6720808189019410897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/6720808189019410897'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/10/simple-calculator.html' title='A simple calculator'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-3658535821159659873</id><published>2007-09-15T01:50:00.001-06:00</published><updated>2007-10-09T22:03:15.305-06:00</updated><title type='text'>Building maps with parsnip</title><content type='html'>To further demonstrate the brevity and power of Parsnip, here is the code for a simple grammar which accepts strings of the format "key1 = value1; key2 = value2;". The return value of the parser is an std::map of the key-value pairs. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Parser&amp;lt;string, Tuple2&amp;lt;string, string&amp;gt;&amp;gt;::type single_pair = letters &amp;gt;&amp;gt; skip(token_ch('=')) &amp;gt;&amp;gt;  letters &amp;gt;&amp;gt; skip_ch(';');&lt;br /&gt;&lt;br /&gt;Parser&amp;lt;string, std::map&amp;lt;string, string&amp;gt;&amp;gt;::type pair_parser = many&amp;lt; BuildMap&amp;lt;string, string&amp;gt; &amp;gt;(token(single_pair));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-3658535821159659873?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/3658535821159659873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=3658535821159659873' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/3658535821159659873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/3658535821159659873'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/09/building-maps-with-parsnip.html' title='Building maps with parsnip'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-3000059660814691220</id><published>2007-09-06T11:57:00.000-06:00</published><updated>2007-09-15T01:49:28.202-06:00</updated><title type='text'>Parsing s-expressions with Parsnip</title><content type='html'>Moving to New York has been quite hectic, but I have found a few spare moments to keep working on &lt;a href="http://parsnip-parser.sourceforge.net/"&gt;Parsnip&lt;/a&gt;. The library is still patchy and probably full of undiscovered bugs, but nonetheless quite powerful.&lt;br /&gt;&lt;br /&gt;As a demonstration of Parsnip's capabilities, I used the library to build a small s-expression parser.&lt;br /&gt;&lt;br /&gt;First, we need some data structures to represent s-expressions in C++:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;//All s-expression objects (nil, cons, number, etc...) derive from LispObject&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;struct LispObject&lt;br /&gt;{&lt;br /&gt;   virtual bool isCons() { return false; }&lt;br /&gt;   virtual bool isNumber() { return false; }&lt;br /&gt;   virtual bool isSymbol() { return false; }&lt;br /&gt;   virtual bool isNil() { return false; }&lt;br /&gt;&lt;br /&gt;   virtual std::string toString()=0;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;typedef ptr&amp;lt;LispObject&amp;gt; ObjPtr;&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/*&lt;br /&gt;Cons cells are the fundamental element of s-expression lists. &lt;br /&gt;Each cell contains a head (which is a data item, in the case of a flat list)&lt;br /&gt;and a tail (which is the next cons cell in the list). &lt;br /&gt;The last cell has a tail which points to nil (like a null-terminated string). &lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;struct Cons : public LispObject&lt;br /&gt;{&lt;br /&gt;   Cons(ObjPtr _head, ObjPtr _tail) : head(_head), tail(_tail) {}&lt;br /&gt;   virtual bool isCons() { return true; }&lt;br /&gt;   virtual std::string toString()&lt;br /&gt;   {&lt;br /&gt;      return "(" + head-&gt;toString() + " . " + tail-&gt;toString() + ")";&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   ObjPtr head;&lt;br /&gt;   ObjPtr tail;&lt;br /&gt;};&lt;br /&gt;typedef ptr&amp;lt;Cons&amp;gt; ConsPtr;&lt;br /&gt;&lt;br /&gt;ObjPtr makeCons(ObjPtr head, ObjPtr tail)&lt;br /&gt;{&lt;br /&gt;   return new Cons(head, tail);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Cons* toCons(ObjPtr obj)&lt;br /&gt;{&lt;br /&gt;   return static_cast&amp;lt;Cons*&amp;gt;(obj.GetRawPointer());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;// Symbols are any variable/identifier&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;struct Symbol : public LispObject&lt;br /&gt;{&lt;br /&gt;   Symbol(const std::string&amp; _name) : name(_name) {}&lt;br /&gt;   virtual bool isSymbol() { return true; }&lt;br /&gt;   std::string toString() { return name; }&lt;br /&gt;&lt;br /&gt;   std::string name;&lt;br /&gt;};&lt;br /&gt;typedef ptr&amp;lt;Symbol&amp;gt; SymPtr;&lt;br /&gt;&lt;br /&gt;ObjPtr makeSymbol(const std::string&amp; str)&lt;br /&gt;{&lt;br /&gt;   return new Symbol(str);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;// Number objects are boxed (or wrapped) floats&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;struct Number : public LispObject&lt;br /&gt;{&lt;br /&gt;   Number(float _val) : value(_val) {}&lt;br /&gt;   virtual bool isNumber() { return true; }&lt;br /&gt;   std::string toString() { return to_string(value); }&lt;br /&gt;   &lt;br /&gt;   float value;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;typedef ptr&amp;lt;Number&amp;gt; NumPtr;&lt;br /&gt;&lt;br /&gt;ObjPtr makeNumber(float val)&lt;br /&gt;{&lt;br /&gt;   return new Number(val);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;// Nil is the terminating element at the end of each list&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;struct NilObject : public LispObject&lt;br /&gt;{&lt;br /&gt;   bool isNil() { return true; }&lt;br /&gt;&lt;br /&gt;   static ObjPtr getNil()&lt;br /&gt;   {&lt;br /&gt;      if (nil) { return nil; }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;         nil = new NilObject;&lt;br /&gt;         return nil;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;   std::string toString() { return "()"; }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;   static ObjPtr nil;&lt;br /&gt;};&lt;br /&gt;ObjPtr NilObject::nil;&lt;br /&gt;&lt;br /&gt;ObjPtr getNil()&lt;br /&gt;{&lt;br /&gt;   return NilObject::getNil();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/*&lt;br /&gt;The BuildCons accumulator class is a template parameter&lt;br /&gt;to the many/many1 parser combinators. &lt;br /&gt;Each ObjPtr accepted by the many/many1 parser is passed&lt;br /&gt;to an instance of BuildCons. &lt;br /&gt;A resulting cons-list can be extracted using the result() method.&lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;struct BuildCons : public Accumulator&lt;objptr, objptr=""&gt;&lt;br /&gt;{&lt;br /&gt;   BuildCons()&lt;br /&gt;   {&lt;br /&gt;      first_cell = getNil();&lt;br /&gt;      last_cell = first_cell;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   virtual void accum(const ObjPtr&amp; o)&lt;br /&gt;   {&lt;br /&gt;     static ObjPtr nil = getNil();&lt;br /&gt;     if(first_cell-&gt;isCons())&lt;br /&gt;     {&lt;br /&gt;        ObjPtr new_cell = makeCons(o, nil);&lt;br /&gt;        toCons(last_cell)-&gt;tail = new_cell;&lt;br /&gt;        last_cell = new_cell;&lt;br /&gt;     }&lt;br /&gt;     else&lt;br /&gt;     {&lt;br /&gt;        first_cell = makeCons(o, nil);&lt;br /&gt;        last_cell = first_cell;&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;   virtual ObjPtr result() { return first_cell; }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;    ObjPtr first_cell;&lt;br /&gt;    ObjPtr last_cell;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next, we construct the parser itself:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;// An ObjParser is any parser which accepts an input std::string and returns an ObjPtr. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;typedef Parser&amp;lt;string, ObjPtr&amp;gt;::type ObjParser;&lt;br /&gt;ObjParser lisp_symbol =  call1(makeSymbol, many1(letters | oneOf("+-/*=@!?&amp;^~:&lt;&gt;%")));&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/*&lt;br /&gt;The 'real' parser accepts strings such as "3.42" and "200".&lt;br /&gt;The utility function makeNumber accepts a string and converts&lt;br /&gt;it to a float. &lt;br /&gt;The function 'call1' creates a parser which takes the result of&lt;br /&gt;its second argument applies to that its first argument. In short,&lt;br /&gt;it calls makeNumber. &lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;ObjParser lisp_number = call1(makeNumber, real);&lt;br /&gt;&lt;br /&gt;typedef Parser&amp;lt;string, void&amp;gt;::type VoidParser;&lt;br /&gt;&lt;br /&gt;VoidParser LP = skip(token_ch('('));&lt;br /&gt;VoidParser RP =  skip(token_ch(')'));&lt;br /&gt;&lt;br /&gt;ObjParser lisp_nil = call0(getNil, LP &amp;gt;&amp;gt; RP);&lt;br /&gt;ObjParser lisp_atom = lisp_symbol | lisp_number | lisp_nil;&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/*&lt;br /&gt;The lisp_cons parser can't refer to itself directly, &lt;br /&gt;so we have to use a proxy LazyParser called cons_self. &lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;ObjParser cons_self = lazy&amp;lt;string, ObjPtr&amp;gt;();&lt;br /&gt;ObjParser lisp_cons =  LP &amp;gt;&amp;gt; many&amp;lt;BuildCons&amp;gt;(token(lisp_atom | cons_self)) &amp;gt;&amp;gt;  RP;&lt;br /&gt;ObjParser lisp_expr = lisp_atom | lisp_cons;&lt;br /&gt;&lt;br /&gt;setLazy(cons_self, lisp_cons);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Lastly, we add an input loop to test how the expressions get parsed:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;std::string input;&lt;br /&gt;&lt;br /&gt;while (true)&lt;br /&gt;{&lt;br /&gt;   std::cout &amp;lt;&amp;lt; "&gt; ";&lt;br /&gt;   std::getline(std::cin, input);&lt;br /&gt;   Result&amp;lt;ObjPtr&amp;gt; result = parse(input, lisp_expr);&lt;br /&gt;   if (input == "exit") break;&lt;br /&gt;   if (parse_finished(result))&lt;br /&gt;   {&lt;br /&gt;      cout &amp;lt;  result.data()-&amp;gt;toString() &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;   else if (input_consumed(result)) &lt;br /&gt;   {&lt;br /&gt;     cout &amp;lt;&amp;lt; "Unexpected end of input string " &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;      int pos = parse_position(result);&lt;br /&gt;      cout &amp;lt;&amp;lt; "Unexpected character '" &amp;lt;&amp;lt; input[pos] &amp;lt;&amp;lt; "' at position " &amp;lt;&amp;lt; pos  &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And that's it! We're now half way to writing an s-expression based language (ie, a mini-lisp or a configuration DSL).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-3000059660814691220?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/3000059660814691220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=3000059660814691220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/3000059660814691220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/3000059660814691220'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/09/parsing-s-expressions-with-parsnip.html' title='Parsing s-expressions with Parsnip'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-6523387147941954630</id><published>2007-05-14T17:06:00.000-06:00</published><updated>2007-05-18T16:27:50.449-06:00</updated><title type='text'>Hyrax and The Parsnip</title><content type='html'>I've been working on and off on a programming language for over a year now. In the beginning it was a nameless C++ implementation of Paul Graham's illusory &lt;a href="http://www.paulgraham.com/arc.html"&gt;Arc&lt;/a&gt;. Under the name &lt;a href="http://hyrax.sourceforge.net/"&gt;Hyrax&lt;/a&gt; my language kept the s-expression syntax and Lisp-like core but donned and shed many poorly implemented language features (type inference, prototype-based Objects, etc..). Finally I found some purpose for the beast as a functional matrix language. With the semantics of Scheme, the mathematical capabilities of &lt;a href="http://www.gnu.org/software/gsl/"&gt;GSL&lt;/a&gt; and &lt;a href="http://www.ginac.de/"&gt;GiNac&lt;/a&gt; and the syntax of Matlab I could give &lt;a href="http://www.scipy.org/"&gt;SciPy&lt;/a&gt; a run for its money. &lt;br /&gt;&lt;br /&gt;The only obstacle in my way is parsing the new syntax. I have thus far been using a kludgy hand-written s-expression parser that is highly immune to improvement. I tried out &lt;a href="http://www.antlr.org/"&gt;ANTLR&lt;/a&gt; and &lt;a href="http://spirit.sourceforge.net/"&gt; Spirit&lt;/a&gt; but found them both cumbersome. In the true spirit of Not Invented Here I have been writing my own parser library in C++: Parsnip.&lt;br /&gt;&lt;br /&gt;Parsnip is a backtracking recursive descent parser combinator library inspired by Parsec. Here's an example of Parsnip in action:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/*&lt;br /&gt;  PARSER types are declared Output, Input&lt;br /&gt;  so this parser accepts strings and return ints. &lt;br /&gt;  The reversal of the usual order seems a little clumsy &lt;br /&gt;  but it makes some code shorter and is easy to get used to.&lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;typedef PARSER(int, string) Parser;&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/* &lt;br /&gt;  plus parses 0 or more spaces followed&lt;br /&gt;  by the '+' character followed by 0 or more &lt;br /&gt;  spaces&lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Parser plus = spaces &gt;&gt; ch('+') &gt;&gt; spaces;&lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;/* &lt;br /&gt;   The sepBy1 parse creates a sequence&lt;br /&gt;   of integer parsers from an input&lt;br /&gt;   of integer strings separated by &lt;br /&gt;   plus parsers. &lt;br /&gt; &lt;br /&gt;   The reduce parser works like&lt;br /&gt;   usual reduce function, it collects&lt;br /&gt;   pairs of values from a sequence and &lt;br /&gt;   applies a function to them. The second&lt;br /&gt;   argument passed to reduce is the default&lt;br /&gt;   in case of an empty sequence. &lt;br /&gt;*/&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Parser sum = reduce(add, 0, sepBy1(integer, plus)); &lt;br /&gt;&lt;br /&gt;&lt;div class="comment"&gt;&lt;br /&gt;//The Maybe struct is modeled after Haskell's Maybe a = Nothing | Just a&lt;br /&gt;//but in this case the Just value can be accessed by Maybe&lt;T&gt;::data&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Maybe&amp;lt;int&amp;gt; result = parse("1 + 2 + 3", sum);&lt;br /&gt; &lt;div class="comment"&gt;// prints "6"&lt;/div&gt;  &lt;br /&gt;if (result) cout &amp;lt;&amp;lt; result.data;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To allow more natural expression of grammars I make heavy use of backtracking in parsnip parsers. All this backtracking comes at the cost of horrible algorithmic bounds, which I partially offset by &lt;a href="http://en.wikipedia.org/wiki/Memoize"&gt;memoizing&lt;/a&gt; the parse results. This makes Parsnip's parsers full-blown &lt;a href="http://en.wikipedia.org/wiki/Packrat_parser"&gt;packrat parsers&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;With this immensely powerful and easy to use parser I plan on turning Hyrax into an unstoppable juggernaut of scientific computing. Now all I need is a new name.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-6523387147941954630?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/6523387147941954630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=6523387147941954630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/6523387147941954630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/6523387147941954630'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/05/hyrax-and-parsnip.html' title='Hyrax and The Parsnip'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-4075667694371068343</id><published>2007-05-14T16:57:00.000-06:00</published><updated>2007-05-14T17:00:54.574-06:00</updated><title type='text'>Blogorevolution: How I Faked The Moon Landing Using Web 3.0</title><content type='html'>I'm commandeering Spikebucket for unbearable programming language nerdiness. I'll say it here so you don't have to hear it at a party. Since neither Weissman nor Sergey are likely to ever check this page again, I don't think this change of course will be a problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-4075667694371068343?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/4075667694371068343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=4075667694371068343' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/4075667694371068343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/4075667694371068343'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/05/blogorevolution-web-40-or-how-i-faked.html' title='Blogorevolution: How I Faked The Moon Landing Using Web 3.0'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-7397702949126461191</id><published>2007-04-26T00:59:00.000-06:00</published><updated>2007-04-26T09:12:27.069-06:00</updated><title type='text'>Redundancy is for chumps</title><content type='html'>&lt;a href="http://www.newyorker.com/archive/2006/07/03/060703fa_fact"&gt;The Deepest Cut&lt;/a&gt;: a New Yorker piece about medical hemispherectomies.&lt;br /&gt;The bulk of the  article documents the lives of doctors and patients. Ignore the fluff and you'll find some good neuroscience. The primary lesson here has been said before but it's worth reiterating: neural plasticity is solely responsible for the anatomical structures of the brain&lt;br /&gt;&lt;blockquote&gt;Leah Krubitzer...removed large pieces of the brains of newborn marsupials. Once the marsupials became adult, she examined the brains again and found that they had organized themselves in such a way that the visual, auditory, and other somatosensory areas were all in the same relative positions that they would occupy in a normal brain, but they were smaller, commensurate with the total space available.&lt;/blockquote&gt;The article contains several anecdotes of people recovering lateralized brain functions after the relevant hemisphere had been removed. Apparently, even the lateralization of language can rewired: if the left hemisphere is removed the right hemisphere will adapt to generate and understand language. In the only cited example a 13-year old had her left hemisphere removed and regained her speaking ability. Presumably this is after the critical period. Could language switch hemispheres even in adults?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-7397702949126461191?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/7397702949126461191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=7397702949126461191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/7397702949126461191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/7397702949126461191'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/04/redundancy-is-for-chumps.html' title='Redundancy is for chumps'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-5022914217886438544</id><published>2007-02-22T01:03:00.000-06:00</published><updated>2007-02-22T01:33:45.768-06:00</updated><title type='text'>The Quest for Consciousness</title><content type='html'>What consciousness is Koch questing after? He purposefully and hastily redefines consciousness  into something irreconcilable with the word's popular definition. To carve out a tractable research area Koch drained consciousness of its most interesting content. Into the bin of  "extended consciousness" Koch places self-awareness, verbal thought and emotion; a category he then immediately discards and forgets. Isn't "sensory perception" a better more accurate term for the group of phenomena Koch calls "core consciousness"? Also, I have a problem with the claim "all the different aspects of consciousness...employ one or perhaps a few common mechanisms" (p.15). It seems to me that core consciousness is shallower (in terms of depth of computation) than extended consciousness. Isn't there a unidirectional flow of influence between conscious sensory perception and conscious verbal thought?&lt;br /&gt;&lt;br /&gt;I think the strength of Koch's theories and frameworks is the lucidity with which he summarizes and rearranges the field of neuroscience. Lifted by his capable pen generalizations and trends are arising from the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;dataswamp&lt;/span&gt; of neurobiology.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-5022914217886438544?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/5022914217886438544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=5022914217886438544' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/5022914217886438544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/5022914217886438544'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/02/quest-for-consciousness.html' title='The Quest for Consciousness'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-116872489396278278</id><published>2007-01-13T15:40:00.000-06:00</published><updated>2007-01-13T15:48:13.973-06:00</updated><title type='text'>Handheld Audio Spectrum Analyzer</title><content type='html'>I'd like to build a small, back-lit, audio spectrum analyzer.  Things I might need:&lt;br /&gt;&lt;br /&gt;1) Micro-controller that does signal processing stuff along with associated software and development kit.  Could be expensive.  Nobody should have to code the FFT in this day and age.  TI?&lt;br /&gt;2) LCD (black and white is probably fine) that has a very simple input/output.  All it needs to do is show the frequency axis and very thing Winamp-like bars for the magnitude.  I guess we can skip the phase entirely and just have two buttons: On/Off and a button to freeze what's currently on the screen so you can examine the current spectrum at your leisure.   Is touchscreen expensive?&lt;br /&gt;3) Tiny microphone.  Directional seems most reasonable, but it would have to work at large ranges, so maybe the tiny mics ones I used for my mini-disc secret headphone recorder would be better.&lt;br /&gt;4) Casing, power supply.  I can probably steal a bunch of stuff from work and might just be able to actually develop this during work.  Hmm.&lt;br /&gt;&lt;br /&gt;Thoughts from the ghosts that read this blog?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-116872489396278278?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/116872489396278278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=116872489396278278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/116872489396278278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/116872489396278278'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2007/01/handheld-audio-spectrum-analyzer.html' title='Handheld Audio Spectrum Analyzer'/><author><name>sergey</name><uri>http://www.blogger.com/profile/10205463807772572852</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://upload.wikimedia.org/wikipedia/commons/c/c7/Fourier.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-116599034700718191</id><published>2006-12-12T23:47:00.000-06:00</published><updated>2006-12-13T11:36:54.306-06:00</updated><title type='text'>The State of Machine-Mediated Telepathy</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;What is Machine-Mediated Telepathy?&lt;br /&gt;&lt;/span&gt;A term I've made up to describe the use of a two-way neural interface to project mental states between two people.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Has any progress been made towards this freakish machine?&lt;/span&gt;&lt;br /&gt;Much of the Brain-Computer Interface research also contributes towards direct Brain-to-Brain communication. A fine grained bi-directional BCI might be all that's necessary. The Johns-Hopkins &lt;a href="http://www.jhu.edu/nthakor/people_pages/hongbo/main.html"&gt;BCI group&lt;/a&gt; seem to already have Brain-to-Brain interaction on their radar. However, even mainstrean BCI research is still embryonic. Still, some of the foundations have already been laid down, making the quest for telepahy not entirely quixotic.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Is this even possible?&lt;br /&gt;&lt;/span&gt;Transmission of mental states (thoughts, memories, emotions, etc...) between brains hinges on advances in three research areas:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Brain "Reading":&lt;/span&gt; Neuroimaging and electrophysiology are both highly developed fields that offer researchers a dizzying variety of techniques for ascertaining brain state. Unfortunately, no single method has satisfactory temporal and spatial resolution. For a comparison of the resolution/invasiveness tradeoffs, see this &lt;a href="http://web.mit.edu/kitmitmeg/MEG_Work_5.jpg"&gt;chart&lt;/a&gt;. Not mentioned in the previous link are (1) electrode recording: highly invasive, spatially limited and temporally extremely precise (2) and &lt;a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&amp;db=PubMed&amp;amp;list_uids=14570164&amp;dopt=Abstract"&gt;EROS&lt;/a&gt;: non-invasive, sub-cm spatial resolution, ~100ms temporal resolution. &lt;a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&amp;amp;db=PubMed&amp;list_uids=12891651&amp;amp;dopt=Abstract"&gt;MRS&lt;/a&gt; is the sole imaging technique which can discriminate neurotransmitter concentrations (I suspect this might be useful).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Brain "Writing":&lt;/span&gt; Not writing, in the sense of permanently altering, but rather the induction of neural activity based on inputs. Aside from direct electrode stimulation, the only technology I'm aware of in this field is &lt;a href="http://pni.unibe.ch/TMS.htm"&gt;Transcranial Magentic Stimulation&lt;/a&gt;. TMS has horrible spatial specificity (could this be improved on?).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Neural Correlates of Consciousness:&lt;/span&gt; Equally important as the mechanisms for brain access is the knowledge of what areas are relevant. I don't think it's necessary (nor possible) to fully map the interplay between brain and mind. Luckily, we could probably get by with a rudimentary knowledge. The activity of one brain will be interpreted by a second, so there's no need to make explicit what that activity means. Still, we *will* have to know which areas are relevant. &lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="FONT-WEIGHT: bold"&gt;How long will it take?&lt;/span&gt;&lt;br /&gt;Optimistically, decades. Of the three fields above, only "reading" (neuroimaging/electrophysiology) is advanced enough to be useful for a brain interface. Brain-effecting technologies will probably increase in the near future (as researchers delve deeper into bi-directional BCI), though their arrival is not certain. The correlation of conscious phenomena with neural activity has already begun in the &lt;a href="http://www.klab.caltech.edu/"&gt;Koch &lt;/a&gt;lab (as well as others). It's unclear how long it will take until such research crystallizes into a clear vision of how the brain implements conscious thoughts. &lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-116599034700718191?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/116599034700718191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=116599034700718191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/116599034700718191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/116599034700718191'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2006/12/state-of-machine-mediated-telepathy.html' title='The State of Machine-Mediated Telepathy'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27514475.post-116581443796349626</id><published>2006-12-10T23:15:00.000-06:00</published><updated>2006-12-10T23:42:31.076-06:00</updated><title type='text'>Emails to Christof Koch: The Highlight Reel</title><content type='html'>Christof Koch is a very erudite visionary Neuroscientist whose emails inspire awe in all who see them. But most especially in Jon Weissman.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27514475-116581443796349626?l=spikebucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://spikebucket.blogspot.com/feeds/116581443796349626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27514475&amp;postID=116581443796349626' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/116581443796349626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27514475/posts/default/116581443796349626'/><link rel='alternate' type='text/html' href='http://spikebucket.blogspot.com/2006/12/emails-to-christof-koch-highlight-reel.html' title='Emails to Christof Koch: The Highlight Reel'/><author><name>Alex</name><uri>http://www.blogger.com/profile/00510887281765406844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://www.edge.org/documents/archive/images/minsky.02.200.jpg'/></author><thr:total>5</thr:total></entry></feed>
