Problems parsing nested structures onto ruby objects

54 views
Skip to first unread message

Richard Conroy

unread,
Jul 8, 2014, 6:37:06 AM7/8/14
to treet...@googlegroups.com
In my grammar I am mapping sequences of swift field messages into ruby:

  rule message
    general sub_safekeeping? <Swift::Parsing::MT536File::Message>
  end

The definitions of general and sub_safekeeping are like so:

  rule general
    ..... <Swift::Parsing::MT536File::General>
  end

  rule sub_safekeeping
    ..... <Swift::Parsing::MT536File::SubSafekeeping>
  end

The general section and sub_safekeeping are hierarchical, containing other nested sequences of fields (there are about 4 levels of nesting)

Once parsed however, Message only has query methods for general and not sub_safekeeping which is optional.

Is there any way that I could achieve this? The actual structure of the real data has many repetitive sequences, and I was expecting it
to map sequences of rules onto arrays.

If this is code I have to write myself, how would I go about it?

Paul Madden

unread,
Jul 8, 2014, 10:05:09 AM7/8/14
to treet...@googlegroups.com
Hi Richard,

If I've understood your question correctly, I think I'm seeing the problem you're describing with this toy grammar:

grammar G
  rule s
    a b?
  end
  rule a
    'a'
  end
  rule b
    'b'
  end
end

irb(main):004:0> t=GParser.new.parse('ab')
=> SyntaxNode+S0 offset=0, "ab" (a):
  SyntaxNode offset=0, "a"
  SyntaxNode offset=1, "b"

irb(main):005:0> t.a
=> SyntaxNode offset=0, "a"

irb(main):006:0> t.b
NoMethodError: undefined method `b' for #<Treetop::Runtime::SyntaxNode:0x0000000279f228>
from (irb):6
from /usr/bin/irb:12:in `<main>'

It may be worth noting that you can always access the rule components via the #elements method, rather than by name:

irb(main):008:0> t.elements
=> [SyntaxNode offset=0, "a", SyntaxNode offset=1, "b"]

irb(main):009:0> t.elements[1]
=> SyntaxNode offset=1, "b"

But you can also name any of the accessor rules yourself, and it seems that doing this for the optional component does the trick:

grammar G
  rule s
    a b:b?
  end
  rule a
    'a'
  end
  rule b
    'b'
  end
end

irb(main):004:0> t=GParser.new.parse('ab')
=> SyntaxNode+S0 offset=0, "ab" (a,b):
  SyntaxNode offset=0, "a"
  SyntaxNode offset=1, "b"

irb(main):005:0> t.b
=> SyntaxNode offset=1, "b"

The accessor names are arbitrary. You could just as well have

  rule s
    foo:a bar:b
  end

I hope this helps.

paul
Reply all
Reply to author
Forward
0 new messages