Match#method_missing is unsafe as illustrated in Github issue #41. In particular, it makes composing a grammar with aribitrary gems unsafe when the latter make core extensions, leads to unexpected results with labels matching Kernel methods (e.g. `p`), and prevents the Match class from getting new methods in a backward compatible way. This commit therefore removes it. A convenient method is provided to get a single capture by label name. Calling string operators must now be done via Match#to_str.
The added test case shows that Kernel::p is actually called in place of Match#method_missing when 'p' is used as a label or rule name. As any gem might contribute private methods to Object, using Citrus labels (or even rule names, actually) in semantic productions without doing so with Match#captures is unsafe. Moreover, the addition of any method/helper to the Match class may potentially break an existing grammar, so it breaks Citrus's public API and should probably increment the MAJOR version number.
This method allows locating the original parsed source during the production of semantic values. It is roughly a shortcut for `input.source` but is robust to situations where matches would be created with strings (such as in the tests).
This commit makes the Input class supporting various text sources, such as a String, a Path, a File, etc. The real source passed at construction is kept under @source for traceability. Common rubyisms are used to recognize those sources. In particular, Pathname instances will be recognized through respond_to?(:to_path), which is standard in ruby 1.9.x. Files and IO are recognized through :read. Strings and StringIO through :to_str.
Instead of successively slicing strings in matches, we keep the parsed text under @source, and an offset in the later in @offset. Btw, that @offset might be very useful for keeping trace of the localisation of the match in the source text (e.g. for subsequent semantic passes; semantic error detection for instance).
…from the cache. Also update tests to verify this behavior.
A common point of confusion for some Citrus users is that they are not able to retrieve a match by calling its own name on itself. This commit adds self to the internal @captures Hash in the first position. Also, Match#to_a and Match# were added for convenience when retrieving captures and submatches.
All example test suites are run with the default Rake test task. This ensures that examples are always working with the current version of the code. Also, Citrus.require should raise Citrus::LoadError if it cannot find a suitable file to load.
This restores the former behavior to matches that are the results of a Choice rule, which is that they are essentially the same match as is returned by the first matching rule of that choice. This largely eliminates the need to call Match#first in the value blocks of choices, which feels more natural when writing them.
This makes it convenient to use `captures` in an extension method, for example. It also allows us to refactor both Match#matches and Match#first to use Match#captures, ensuring that we're using the same match objects regardless of how they're accessed. Also in this commit I've removed Match#names, Match#name, and Match#has_name?. These methods existed to support Match#find, which has also been removed in favor of the more powerful Match#captures.
Instead of defaulting to false, the consume option now defaults to true. This is the behavior that many users expect the first time they use Citrus because it is the way that Treetop works. It used to be expensive to calculate the length of a Match, so we defaulted to false. It is now trivial, so it shouldn't slow things down to default to true.