Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Closed
sriram-srinivasan opened this Issue · 3 comments

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

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

@mjackson mjackson closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.