single item in rule body results in infinite loop.
sriram-srinivasan opened this issue · comments
The following code runs into an infinite loop when value
is called.
grammar X
rule item
num {
num.value
}
end
rule num
/[0-9]+/ {to_i * 1000}
end
end
x = X.parse("100")
x.value
It is likely that item.value and num.value are somehow conflated and that it calls itself.
The following does not have a problem.
grammar X
rule item
(n1:num ',' n2:num) {
n1.value + n2.value
}
end
rule num
/[0-9]+/ {to_i}
end
end
x=X.parse("100,200")
x.value # no problem.
When you call num.value
inside the semantic block, it will look for a match named num
and take the value of it. In this case, the match named num
is the match itself, which will simply call the block again, causing your loop. The thing is, you don't need a semantic block at all for the match contained in item
as it is written in the first example. Consider the following ruby script:
require 'citrus'
Citrus.eval(<<CITRUS)
grammar X
rule item
num
end
rule num
/[0-9]+/ {to_i * 1000}
end
end
CITRUS
puts X.parse('5').value
When you call the value
of an item
match, it will simply return the value of its inner num
match since item
is merely an alias for num
.
This is probably a bit too brief an example, but what I really wanted was to create a separate ast node from "item", and hide the fact that it called "num".
You can do that too. Try something like this:
require 'citrus'
Citrus.eval(<<CITRUS)
grammar X
rule item
num {super() - 1}
end
rule num
/[0-9]+/ {to_i * 1000}
end
end
CITRUS
puts X.parse('5').value
In this example, you can use super()
to call the original num
value. You can then modify the value to be whatever item
wants it to be.