title: How to transform nested arrays string in json like string to structured object using parslet
body: <p>I have a problem with transforming parsed JSON-like string, which contains nested arrays, to structured object. I am using parslet to do this. </p>
  
  <p>I created parser and transformer, presented below. But I can't handle nested arrays situation.</p>
  
  <pre class="lang-rb prettyprint-override"><code>require 'parslet'
  class JSONLikeDataParser &lt; Parslet::Parser
    rule(:l_map_paren) {str('{')}
    rule(:r_map_paren) {str('}')}
    rule(:l_list_paren) {str('[')}
    rule(:r_list_paren) {str(']')}
    rule(:map_entry_delimiter) {str(':')}
    rule(:val_delimiter) {str(',')}
    rule(:quote) {str('"')}
  
    rule(:simple_val) {match('[^",:\.\{\}\[\]]').repeat(1)}
    rule(:quoted_val) {quote &gt;&gt; (quote.absnt? &gt;&gt; any).repeat(0) &gt;&gt; quote}
  
  
    rule(:map) {l_map_paren &gt;&gt; map_entries.maybe.as(:map) &gt;&gt; r_map_paren}
    rule(:map_entries) {map_entry &gt;&gt; (val_delimiter &gt;&gt; map_entry).repeat}
    rule(:map_entry) {map_key &gt;&gt; map_entry_delimiter &gt;&gt; object}
    rule(:map_key) {(match('[A-Za-z_]').repeat(1) &gt;&gt; match('[A-Za-z0-9_]').repeat).as(:key)}
  
    rule(:list) {l_list_paren &gt;&gt; list_values.maybe.as(:list) &gt;&gt; r_list_paren}
    rule(:list_values) {object &gt;&gt; (val_delimiter &gt;&gt; object).repeat}
  
    rule(:object) {map | (simple_val | quoted_val).as(:value) | list }
  
    root(:object)
  end
  
  #TODO doesn't handle properly nested array: [[[1,2],[3]]]
  class JSONLikeDataTransform &lt; Parslet::Transform
    rule(map: subtree(:s)) do
      ret = {}
      if (s.is_a?(Hash))
        ret[s[:key]] = s[:value]
      else
        s.each do |h|
          ret.merge!(h)
        end
      end
      OpenStruct.new(ret)
    end
    rule(key: simple(:k), value: simple(:v)) {{k.str =&gt; v.str}}
    rule(key: simple(:k), list: simple(:v)) {{k.str =&gt; [v]}}
    rule(key: simple(:k), list: sequence(:v)) {{k.str =&gt; v}}
  
    rule(map: simple(:s)) {s ? OpenStruct.new(s) : OpenStruct.new}
  
    rule(list: subtree(:s)) {[s]}
    rule(list: sequence(:s)) {s}
    rule(list: simple(:s)) {s ? [s] : []}
  
    rule(value: subtree(:s)) {s}
    rule(value: sequence(:s)) {s}
    rule(value: simple(:s)) {s.str}
  end
  
  puts JSONLikeDataTransform.new.apply(JSONLikeDataParser.new.parse("[[[1],[2,3]]]")).inspect
  </code></pre>
  
  <p>Problematic string is <code>"[[[1],[2,3]]]"</code>. I expect to receive properly nested structure. But what I get is <code>"[[[[1],[2,3]]]]"</code> one bracket too much.</p>