Project

grammoire

0.0
No commit activity in last 3 years
No release in over 3 years
A context-sensitive grammar library for producing randomised objects
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 1.0.0
~> 1.8.3
 Project Readme

Grammoire

A context-sensitive grammar library for producing randomised objects. Despite being incomplete and dead, it was a fun project idea to explore. Proceed at your own peril.

A more usual use of a grammar is to parse strings into objects and other programming language constructs, to be interpreted. Instead of this, Grammoire allows you to define a grammar for producing objects in randomised ways.

It was inspired by http://www.contextfreeart.org/.

An example of a grammar for generating well-formed parentheses (http://en.wikipedia.org/wiki/Context_free_grammar#Well-formed_parentheses ):

grammar = Grammoire.define do
  rule(:s) { produce { eval(:s) + eval(:s) } }
  rule(:s) { produce { '(' + eval(:s) + ')' } }
  rule(:s) { produce { '()' } }
end

grammar.evaluate(:s) # possible result => ()((())(()))(((())))(((())))

Installation

gem install grammoire

Features

Multiple rules for same symbol

grammar = Grammoire.define do
  rule(:terminal) { produce { 'a' } }
  rule(:terminal) { produce { 'b' } }
end

grammar.evaluate(:terminal) # Equal chances of generating an 'a' or 'b'

Rule weights

grammar = Grammoire.define do
  rule(:weighted) { weights 4; produce { 'a' } }
  rule(:weighted) { weights 2; produce { 'b' } }
end

grammar.evaluate(:weighted) # Twice more likely of generating 'a' rather then 'b'

Data points

grammar = Grammoire.define do
  rule(:full_name) { produce { eval(:first_name) + ' ' + eval(:last_name) } }
  rule(:first_name) { produce { data(:first) } }
  rule(:last_name) { produce { data(:last) } }
end

grammar.evaluate(:full_name, :first => "Jonny", :last => "Data") # => Produces 'Jonny Data'

Rule pre-conditions

grammar = Grammoire.define do
  rule(:conditionals) do
    pre_condition { data(:number) >= 5 }
    produce { 'More then 5!' }
  end
  rule(:conditionals) do
    pre_condition { data(:number) < 5 }
    produce { 'Less then 5.' }
  end      
end

grammar.evaluate(:conditionals, :number => 7) # => Produces 'More then 5!'