<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: parsing code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 18 May 2008 00:05:30 GMT</pubDate>
    <description>DZone Snippets: parsing code</description>
    <item>
      <title>Tidy Remote HTML (using a web service)</title>
      <link>http://snippets.dzone.com/posts/show/4218</link>
      <description>// Clean up some code using a web service. If you need to do this more quickly I suggest using a local tidy installation&lt;br /&gt;// rather than my web service, but this is nice and easy. :)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function tidied($url) {&lt;br /&gt;  /* Cleans up a page via Tidy, returning the cleaned up html as a string&lt;br /&gt;   * By Logan Koester &lt;logan@logankoester.com&gt; 2007-06-28&lt;br /&gt;   * Props to http://infohound.net/tidy */&lt;br /&gt;  return file_get_contents("http://logankoester.com/tools/tidy.php?q=$url");&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 28 Jun 2007 10:16:46 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4218</guid>
      <author>logankoester (Logan Koester)</author>
    </item>
    <item>
      <title>How to parse a little language in Prolog</title>
      <link>http://snippets.dzone.com/posts/show/3851</link>
      <description>How to parse a token list into functors (structured terms) in Prolog.&lt;br /&gt;The book "Logic in Prolog" by Gibbins has some good example code  &lt;br /&gt;See http://www.ddj.com/184404172, listing 9 for the little language&lt;br /&gt;&lt;code&gt;&lt;br /&gt;%&lt;br /&gt;% This is a simple (nay,trivial!)  "dialect" &lt;br /&gt;% with only two commands.&lt;br /&gt; &lt;br /&gt;% Obviously only scratches the surface - &lt;br /&gt;% Written as a learning exercise!&lt;br /&gt;% First define a grammar using prolog's Definite &lt;br /&gt;% Clause Grammar (DCG) notation&lt;br /&gt;% DCG is a bit like a macro system - &lt;br /&gt;% the grammar rules are expanded into&lt;br /&gt;% ordinary prolog clauses  before execution:&lt;br /&gt;% Thanks to prolog unification, the Cmd variable&lt;br /&gt;% will end up being instantiated to a functor like&lt;br /&gt;% sell(abc,10,5) or buy(xyz,55):&lt;br /&gt;&lt;br /&gt;cmd(Cmd) --&gt; sell,!,amount(Amount),of,stock(Stock),at,price(Price), &lt;br /&gt;             { Cmd = sell(Stock,Amount,Price) }.&lt;br /&gt;cmd(Cmd) --&gt; buy,!,amount(Amount),of,stock(Stock), &lt;br /&gt;             {Cmd = buy(Stock,Amount)}.&lt;br /&gt;sell --&gt; [sell].&lt;br /&gt;of --&gt; [of].&lt;br /&gt;at --&gt; [at].&lt;br /&gt;buy --&gt; [buy].&lt;br /&gt;amount(Amount) --&gt; [Amount].&lt;br /&gt;stock(Stock)   --&gt; [Stock].&lt;br /&gt;price(Price)   --&gt; [Price].&lt;br /&gt;&lt;br /&gt;% mini-evaluator:&lt;br /&gt;&lt;br /&gt;eval(sell(Stock,Amount,Price)) :- &lt;br /&gt; format('Sold ~d ~a shares at $~d.~n',[Amount,Stock,Price]).&lt;br /&gt;eval(buy(Stock,Amount)) :- &lt;br /&gt; format('Bought ~d ~a shares.~n',[Amount,Stock]).&lt;br /&gt;&lt;br /&gt;% parse a statement, if it's a command, &lt;br /&gt;% evaluate it, otherwise write an error&lt;br /&gt;% (NB.  ";" is prolog's % "or".)&lt;br /&gt;&lt;br /&gt;interp(Statement) :- cmd(Cmd,Statement,[]),&lt;br /&gt;             eval(Cmd);write('Unrecognised command!').&lt;br /&gt;&lt;br /&gt;% Examples: &lt;br /&gt;% ( First two match , the last fails.)&lt;br /&gt;&lt;br /&gt;test :-&lt;br /&gt;    interp([sell,100,of,xyx,at,50]),&lt;br /&gt;    interp([buy,45,of,abc]),&lt;br /&gt;    interp([not,accepted]).&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 22 Apr 2007 01:44:35 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3851</guid>
      <author>cratylus (crat)</author>
    </item>
    <item>
      <title>Find every path and it's value in a Hash</title>
      <link>http://snippets.dzone.com/posts/show/3565</link>
      <description>Extends Hash class with each_path method.&lt;br /&gt;&lt;br /&gt;This method takes a block as argument which is called each time a the recursivly searched Hash returns a key that does not point to another Hash.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;paths = []&lt;br /&gt;complex_hash = Hash[&lt;br /&gt;  :a =&gt; { :aa =&gt; '1', :ab =&gt; '2' },&lt;br /&gt;  :b =&gt; { :ba =&gt; '3', :bb =&gt; '4' }&lt;br /&gt;]&lt;br /&gt;complex_hash.each_path { |path, value| paths &lt;&lt; [ path, value ] }&lt;br /&gt;paths.inspect&lt;br /&gt;# =&gt; "[[\"b/ba/\", \"3\"], [\"b/bb/\", \"4\"], [\"a/aa/\", \"1\"], [\"a/ab/\", \"2\"]]"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Hash&lt;br /&gt;  def each_path&lt;br /&gt;    raise ArgumentError unless block_given?&lt;br /&gt;    self.class.each_path( self ) { |path, object| yield path, object }&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  protected&lt;br /&gt;  def self.each_path( object, path = '', &amp;block )&lt;br /&gt;    if object.is_a?( Hash ) then object.each do |key, value|&lt;br /&gt;        self.each_path value, "#{ path }#{ key }/", &amp;block&lt;br /&gt;      end&lt;br /&gt;    else yield path, object&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 22 Feb 2007 14:54:41 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3565</guid>
      <author>boof (Florian A&#223;mann)</author>
    </item>
    <item>
      <title>SQL-Injection save parser generates ORDER BY statement</title>
      <link>http://snippets.dzone.com/posts/show/3563</link>
      <description>Parses a string and generates an SQL order statement.&lt;br /&gt;&lt;br /&gt;Because it's SQL-Injection save you can put it in your link_to method as :order =&gt; '+name' and then call #parse_order( params[:order] ).&lt;br /&gt;&lt;br /&gt;Examples:&lt;br /&gt;'+name' =&gt; 'name'&lt;br /&gt;'+lastname+firstname' =&gt; 'lastname, firstname'&lt;br /&gt;'+lastname-gender' =&gt; 'lastname, gender DESC'&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module ActiveRecord&lt;br /&gt;  class Base&lt;br /&gt;    class &lt;&lt; self&lt;br /&gt;&lt;br /&gt;      def parse_order( order )&lt;br /&gt;        order = order.to_s.gsub /([ \+\-][a-z_]+)/ do |match|&lt;br /&gt;          next unless self.column_names.include?( match[1..-1] )&lt;br /&gt;&lt;br /&gt;          case match[0, 1]&lt;br /&gt;          when '-' then "#{ match[1..-1] } DESC, "&lt;br /&gt;          else "#{ match[1..-1] }, "&lt;br /&gt;          end&lt;br /&gt;        end and order[0..-3]&lt;br /&gt;      end&lt;br /&gt;    &lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 22 Feb 2007 12:26:36 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3563</guid>
      <author>boof (Florian A&#223;mann)</author>
    </item>
    <item>
      <title>Multi-part parameter extractor</title>
      <link>http://snippets.dzone.com/posts/show/2476</link>
      <description>For those times when you want to get a date object out of the multi-part parameters without having to do a mass assignment to a model object. I extracted this code directly from AR so I think it should be pretty solid but I have not tested it so your mileage may vary.&lt;br /&gt;&lt;br /&gt;Take the following and place it into your application helper or whatever helper you'd like. To use it you simply pass in an instance of the object on which the multi-part parameter exists. This is so that the type to instantiate can be reflected from the column information. Then you specify the attribute name of the parameter you're looking to create from the next parameter which is the hash containing the multi-part parameter value.&lt;br /&gt;&lt;br /&gt;example:&lt;br /&gt;for a form containing dude[birth_date] you'd call the method like this:&lt;br /&gt;&lt;br /&gt;extract_date(@the_dude, 'birth_date', params[:dude])&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    def extract_date(parent_object, param_name, atts)&lt;br /&gt;      atts.stringify_keys!&lt;br /&gt;&lt;br /&gt;      multi_parameter_attributes = []&lt;br /&gt;      atts.each do |k, v|&lt;br /&gt;        multi_parameter_attributes &lt;&lt; [ k, v ] if k.include?(param_name+"(")&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      attributes = { }&lt;br /&gt;&lt;br /&gt;      for pair in multi_parameter_attributes&lt;br /&gt;        multiparameter_name, value = pair&lt;br /&gt;        attribute_name = multiparameter_name.split("(").first&lt;br /&gt;        attributes[attribute_name] = [] unless attributes.include?(attribute_name)&lt;br /&gt;&lt;br /&gt;        unless value.empty?&lt;br /&gt;          attributes[attribute_name] &lt;&lt;&lt;br /&gt;            [ find_parameter_position(multiparameter_name), type_cast_attribute_value(multiparameter_name, value) ]&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }&lt;br /&gt;      errors = []&lt;br /&gt;      result = nil&lt;br /&gt;      attributes.each do |name, values|  &lt;br /&gt;        klass = (parent_object.class.reflect_on_aggregation(name.to_sym) || parent_object.column_for_attribute(name)).klass&lt;br /&gt;        result = Time == klass ? klass.local(*values) : klass.new(*values)&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      return result&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def find_parameter_position(multiparameter_name)&lt;br /&gt;      multiparameter_name.scan(/\(([0-9]*).*\)/).first.first&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def type_cast_attribute_value(multiparameter_name, value)&lt;br /&gt;      multiparameter_name =~ /\([0-9]*([a-z])\)/ ? value.send("to_" + $1) : value&lt;br /&gt;    end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 27 Aug 2006 07:12:24 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2476</guid>
      <author>mkovacs ()</author>
    </item>
  </channel>
</rss>
