Q:

Ruby parsing tagged string from stanford core nlp into hash

I use Stanford CoreNLP to parse basic dependencies in (french or english) sentences. It gives me string results like this:

"(ROOT  (SENT    (NP (DET Ce) (NC magasin))    (VN (V est))    (AP (ADJ pourri))    (COORD (CC mais)      (Sint        (NP (DET les) (ADJ vendeuses))        (VN (V sont))        (AP (ADJ géniales))))    (PUNC !)))"

Now I need this results to be parsed in ruby hash or struct, json or whatever easy to manipulate.
For example in a hash:
{'ROOT'=>{'SENT'=>{'NP'=>{'DET'=>'Ce'},'NC'=>'Magasin'}etc...}}

I tried several ways to do it but no success.
Could you give me advices or example to achieve this?
Thanks

A:

Here's a really simple parser implementation. tokenize splits the string into its parts, parse groups the tokens into expressions and feeds them to hasherize, which turns them into a tree.
def tokenize(str)
  str.split(/\s+|([()])/).reject(&:empty?)
end

def hasherize(tokens)
  tokens, hsh = tokens.dup, {}

  while expr = tokens.shift
    _, key, val = expr

    if val
      hsh[key] = val
    elsif key
      tokens, hsh[key] = hasherize(tokens)
    else break
    end
  end

  [ tokens, hsh ]
end

def parse(str)
  tokens = tokenize(str)
    .slice_when {|left,right| left == ")" || right == "(" }
  hasherize(tokens.to_a)[1]
end

str = "(ROOT (SENT (NP (DET Ce) (NC magasin)) (VN (V est)) (AP (ADJ pourri)) (COORD (CC mais) (Sint (NP (DET les) (ADJ vendeuses)) (VN (V sont)) (AP (ADJ géniales)))) (PUNC !)))"
p parse(str)
# => { "ROOT" => {
#        "SENT" => {
#          "NP" => { "DET" => "Ce", "NC" => "magasin" },
#          "VN" => { "V" => "est" },
#          "AP" => { "ADJ" => "pourri" },
#          "COORD" => {
#            "CC" => "mais",
#            "Sint" => {
#              "NP" => { "DET" => "les", "ADJ" => "vendeuses" },
#              "VN" => { "V" => "sont" },
#              "AP" => { "ADJ" => "géniales" }
#            }
#          },
#          "PUNC" => "!"
#        }
#      }
#    }

