From: Caleb Clausen Date: 2005-11-19T04:57:43+09:00 Subject: [ANN] Reg - Ruby Extended Grammar 0.4.6 I am pleased to announce version 0.4.6 of Reg, the Ruby Extended Grammar, a tool for matching patterns in ruby object graphs. Reg is a mini-language that's embedded directly in ruby because it does all its tricks with operator overloading. Reg attempts to emulate both the obscurity and compact power of regular expressions. Reg is a library for matching patterns in all the important core data structures as well as tools for extending the match criteria to include just about any ruby data type you could want. Reg provides matchers for Strings (via Regexps), Symbols, Hashes, and several alternatives for matching Objects, but the main feature is the ability to match Arrays of arbitrary ruby data using vaguely Regexp-like syntax. This version of Reg brings many exciting new features: item_that, a mini-library for constructing method-based object queries a greatly expanded user guide (regguide.txt), about half-finished now. an ordered hash matcher a method-signature matcher, like respond_to? a working object matcher (which I had thought was working before, but it turns out (to my chagrin) was not) But by far the most important new feature is one that's mostly not user-visible: the re-vamped backtracking engine, now named Reg::Progress. (Actually, a lot more classes participate in backtracking... but never mind that.) Reg::Progress is a more object oriented interface to what was a nest of arrays before. Like the arrays, it keeps track of match progress through the data, and also will enable some new (but badly needed) features like backreferences/variable bindings, substitutions, positions, and lookahead/lookback. 0.4.6 examples: Matches a single item whose method 'length' returns a Fixnum: item_that.length.is_a? Fixnum There's a new way to match hashes; it looks more-or-less like the old way and behaves a little differently. The old type of hash matcher (now called an unordered hash matcher) looked like: +{/fo+/=>8, /ba+r/=>9} The new syntax uses +[] instead of +{} and ** instead of =>. It's called an ordered hash matcher. The order of filter pairs given in an ordered matcher is the order comparisons are done in. The same is not true within unordered matchers, where order is inferred from the nature of the key matchers. The ordered equivalent of the last example is: +[/fo+/**8, /ba+r/**9] Both match hashes whose keys match /fo+/ with value of 8 or match /ba+r/ with value of 9 (and nothing else). But if the data looks like: {"foobar"=>8}, then it is guaranteed to match the second (because /fo+/ is always given a chance first), but might or might not match the first (because the order isunspecified). Here's an example of a Reg::Knows matcher, which matches objects that have the #slice method: -:slice 0.4.5 examples: Matches array containing exactly 2 elements; 1st is another array, 2nd is integer: +[Array,Integer] Like above, but 1st is array of arrays of symbol +[+[+[Symbol+0]+0],Integer] Matches array of at least 3 consecutive symbols and nothing else: +[Symbol+3] Matches array with at least 3 consecutive symbols in it somewhere: +[OBS, Symbol+3, OBS] Matches array of at most 6 strings starting with 'g' +[/^g/-6] #no .reg necessary for regexp Matches array of between 5 and 9 hashes containing a key :k pointing to something non-nil: +[ +{:k=>~nil.reg}*(5..9) ] Matches an object with Integer instance variable @k and property (ie method) foobar that returns a string with 'baz' somewhere in it: -{:@k=>Integer, :foobar=>/baz/} Matches array of 6 hashes with 6 as a value of every key, followed by 18 objects with an attribute @s which is a String: +[ +{OB=>6}*6, -{:@s=>String}*18 ] Many other new features are sketched out now, but not fully implemented or tested (much less documented!), so don't expect them to work. (A lot of these depend on a further refactoring of the engine's internal interface.) Internally, Reg::Progress uses Eric Mahurin's Cursor, since it provides a unified interface over arrays, strings, and files. Right now of these only array is supported by Reg. What this means is that Reg::Array can still match only arrays, but in the future it will be able to match strings and files as well. Due to the use of Cursor, this version of Reg is substantially slower than the last, especially when there's lots of backtracking. Using Reg for traditional lexing and parsing tasks is still unsupported. (However, Reg is much closer now to a solution for both these features than in previous releases. Matching Strings and Files against Reg::Array amounts to lexing. Parsing is even closer: all that's needed is substitution, which is my next major goal.) Reg is a rubyforge project. You can find the main page here: http://www.rubyforge.org/projects/reg For the first time, Reg is now available as a ruby gem. Those with rubygems can install Reg via this command: 'gem install reg'. The .gem file can also be found here: http://rubyforge.org/frs/download.php/7198/reg-0.4.6.gem The latest tarball can be downloaded here: http://rubyforge.org/frs/download.php/7199/reg-0.4.6.tar.gz