Tutorial > Generating with Grammars


A more detailed tutorial on Observable

RiTa's RiGrammar object is a probabilistic context-free grammar with extensions for text-generation. This is a rather formal definition, but for this tutorial, it just means that we can use a grammar to generate texts according to simple rules that we define.

For example, if we want to generate simple sentences following a Subject-Verb-Object pattern, the grammar might look like this:


{
  "start":    "$subject $verb $object",
  "subject":  "I | You | They",
  "object":   "coffee | bread | milk",
  "verb":     "want | hate | like | love"
}

One generation from this grammar would be I hate milk. Another would be They want bread.

The first line above defines the whole structure of your grammar. In this case, it will generate a subject, followed by a verb and then an object. For each part, RiTa looks into the grammar for the corresponding rule and then randomly chooses a string from the options listed.

The grammars on this page are written as JSON, but we can also use JavaScript objects for grammars, which are a bit simpler to define. Note that the $ (dollar sign) char is only required for the right side of rules, and should be omitted from the left.

Aside: it is important to note that using rules related to English grammar (subject, verb, etc. as in our example above) is just one one of many ways to use grammars. One can construct rules based on any textual features (syllable-count, as in the linked example, or phonemes as we might in a rhyming grammar), or even use grammars to generate images or sounds.

To run the grammar, you can use RiGrammar's expand() function. By default, it will run the grammar from the start symbol, or you can specify your own starting point:

  grammar.expand(ruleName);

By default, RiTa will assign equal weights to all choices in a rule. However, one can adjust the weights by adding 'multipliers' with square brackets, as follows:

{
  "$start": "coffee[2] | bread | milk"
}

This says that the word “coffee” should be chosen, on average, twice as often as either “bread” or “milk”.

We can also make the grammar more complex by adding rules within rules (or even recursive rules):


  {
    "start":    "$subject $verb $object",
    "subject":  "I | You | They",
    "object":   "$food | $animals",
    "verb":     "want | hate | like | love",
    "food":     "coffee | bread | milk",
    "animals":  "cats | dogs | fish"
  }

Now you might get You love coffee or They want fish ...

To get a better sense of how it all works, check out this example sketch using RiTa grammars...

💡 You can also include valid RiScript statements (assignments, transforms, sequences) within your RiTa grammar and they will be executed automatically when you expand your grammar.