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