Help in Defining Access methods for nodes in treetop

115 views
Skip to first unread message

Swapna

unread,
Oct 3, 2011, 3:29:17 PM10/3/11
to Treetop Development
Hi,

I am new to treetop parser. I was looking for an asm parser for which
i have a well defined grammar. I wrote the grammar and the parser is
able to parse through all the intructions. But I am having issues
while writing methods for these rules. An example code is provided
below.

rule Expression
Instruction / comment
{
def to_array
return self.elements.to_array
end
}
end

rule Instruction
Unary / Tri / Binary
{
def to_array
return self.elements.map {|e| e.to_array}
end
}

end

rule Unary
UnaryInst space?

def_to_array
self.elements[0].to_array # I get an error here saying
self.elements is nil. But my parser successfully parses the
instruction. I am unable to call the function beyond this point.
end
end

rule UnaryInst
UnaryOp sat?
{
def to_array()
return 1
end
}
end


Looks like something basic. Thanks in advance for the help.

Swapna

unread,
Oct 4, 2011, 3:56:31 PM10/4/11
to Treetop Development
I tried something similar to this working example

rule assignment
identifier '=' number {
def ast ()
Operation.new(:assignment, identifier.ast, number.ast)
end
}
end

rule identifier
[a-zA-Z_] [a-zA-Z0-9_]* { def ast () Identifier.new(text_value)
end }
end


What I tried was following

rule Instruction
Unary / Tri / Binary
{
def to_array
return self.elements.map {|e| e.to_array}
end
}

end

rule Unary
UnaryInst space?
{
def to_array
UnaryInst.to_array # I am unable to call this function here. I
cann access it through self.elements[0].to_array. how to i access
methods of particular rules directly?
end
}

end

rule UnaryInst
UnaryOp space?
{
def to_array
return 1
end
}
end

even in I access UnaryInst.to_array using self.elements[0].to-array. i
would like to call UnaryOp.to_array in the next step. What i see is an
error : uninitialized constant ASM::UnaryInst1::UnaryOp (NameError)

Clifford Heath

unread,
Oct 3, 2011, 5:39:15 PM10/3/11
to treet...@googlegroups.com
On 04/10/2011, at 6:29 AM, Swapna wrote:
> I am having issues while writing methods for these rules. An example code is provided
> below.
>
> rule Expression
> Instruction / comment
> {

This block only applies to comment, not to Instruction. Use parentheses around (Instruction/comment) to make it apply to both.

> def to_array
> return self.elements.to_array

You don't need to say "self".
"elements" is already an array. Did you mean "elements.map{|e| e.to_array}"?

> end
> }
> end
>
> rule Instruction
> Unary / Tri / Binary

Use parentheses.

> {


> def to_array
> return self.elements.map {|e| e.to_array}
> end
> }
>
> end
>
> rule Unary
> UnaryInst space?
>
> def_to_array
> self.elements[0].to_array # I get an error here saying
> self.elements is nil. But my parser successfully parses the
> instruction. I am unable to call the function beyond this point.

I don't understand that. elements[1] might be nil, because it's optional, but not elements[0].
Normally you should use the element names (or tags) to access the elements, so instead of saying "elements[0]" you can just say "UnaryInst".

Try these things and report back.

Clifford Heath.

> end
> end
>
> rule UnaryInst
> UnaryOp sat?
> {
> def to_array()
> return 1
> end
> }
> end
>
>
> Looks like something basic. Thanks in advance for the help.
>

> --
> You received this message because you are subscribed to the Google Groups "Treetop Development" group.
> To post to this group, send email to treet...@googlegroups.com.
> To unsubscribe from this group, send email to treetop-dev...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/treetop-dev?hl=en.
>

Swapna Raj

unread,
Oct 4, 2011, 9:00:05 PM10/4/11
to treet...@googlegroups.com
Hi Clifford,

Yes I meant elements.map{|e| e.to_array}

Anyways, those issues are resolved now. UnaryOp was a set of terminals which I had defines as "abc"/"cde"/"efg"...

The issue got resolved when I changed this to ("abc"/"cde"/"efg"...). Now I am able to use UnaryOp.to_array. Not sure how this matters, since we are defining the method inside {..}


Another issue I had was in accessing methods for optional non-terminals. This failed regardless of if C was in the parsed text or not.

For eG;

Rule B

A C?
{
def to_array
return C.to_array
end
}
end

rule C

D "abd"
{
def to_array
return text_value
end
}
end

But works if I change this to



Rule A

B C
{
def to_array
return C.to_array
end
}
end
rule C

D? "abd"?
{
def to_array
return text_value
end
}
end

I am just noting it here, since it might help some one else who is new to treetop. 

Clifford Heath

unread,
Oct 4, 2011, 10:20:46 PM10/4/11
to treet...@googlegroups.com
On 05/10/2011, at 12:00 PM, Swapna Raj wrote:
> Anyways, those issues are resolved now. UnaryOp was a set of terminals which I had defines as "abc"/"cde"/"efg"...
> The issue got resolved when I changed this to ("abc"/"cde"/"efg"...). Now I am able to use UnaryOp.to_array. Not sure how this matters, since we are defining the method inside {..}

rule
A / B / C { def foo; …; end }
end

defines foo only for the C path. You can even do this:

rule
(A / B / C { def foo; …; end }) { def bar; …; end}
end

which defines foo for C, but bar for all paths. Note that
the two modules will be mixed in to the same SyntaxNode
in this case.

> Another issue I had was in accessing methods for optional non-terminals.

This is a known trap. The accessor method for C is defined
only if the rule was matched. I think this is a bug; the method
should be defined regardless, but return nil if C was not
matched. You can work around it using labels and .empty?,
because the label is always defined.

A fix for this would be welcome, if anyone has time.

Clifford Heath.

Reply all
Reply to author
Forward
0 new messages