single item in rule body results in infinite loop. #32

Closed
sriram-srinivasan opened this Issue Oct 17, 2011 · 3 comments

Comments

Projects
None yet
2 participants
@sriram-srinivasan

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.
@mjackson

This comment has been minimized.

Show comment Hide comment
@mjackson

mjackson Oct 27, 2011

Owner

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.

Owner

mjackson commented Oct 27, 2011

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.

@sriram-srinivasan

This comment has been minimized.

Show comment Hide comment
@sriram-srinivasan

sriram-srinivasan Oct 27, 2011

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".

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".

@mjackson

This comment has been minimized.

Show comment Hide comment
@mjackson

mjackson Oct 27, 2011

Owner

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.

Owner

mjackson commented Oct 27, 2011

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.

@mjackson mjackson closed this Oct 27, 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment