99bottles.lmn: (C) Copyright 2005 Peri Hankey (email@example.com). This source text is published under the terms of the Gnu General Program License. It comes with absolutely no warranty.
These are rules in the lmn language, which is the metalanguage of the language machine - a wide spectrum toolkit for language and grammar, a machine that 'does language and grammar'. The language machine is published as free software under the Gnu GPL, and for a full account you should look at the website where there is a very useful diagram - the lm-diagram - which shows you what happens in a machine that applies unrestricted grammatical rewriting rules.
This is a version of the song '99 bottles of beer' implemented as an lmn ruleset. Recursion is used for repetition, using thing :N as the pattern that triggers each verse. There are rules for thing to deal with the cases 2, 1, and 0, each of which needs special treatment. This version is rather profligate in its use of variable bindings, and would need to be rethought for large values of N. Before version languagemachine-0.2.1 the sync trick was require to force exit from completed right-side recursion levels - see bottles.
Actual code is contained on lines that start with at least one space - anything else is treated as annotation. This is the convention used in the wikipedia for preformatted text, and a subset of the wikimedia markup can be used so that web pages can be generated directly from the source text - as you can see here.
The metalanguage is used to write rules to be applied by an engine. The application of a rule involves a recognition phase and a subsitution phase. Each phase can produce zero or more symbols. Recognition phases can be nested within enclosing recognition phases, and subsitution phases can be nested within enclosing recognition phases. For a full account you should look at the website.
The rules are placed in a grammar called bottles. The first rule to be tried is the rule that matches start and promises to subsitute eor which is the initial goal symbol. In this case the first rule starts the song by providing the first thing.
.bottles() start var N = 99; <- eof - first :N :"s" thing :N song eof; first :A :T song <- eof - ;
- verse eom <- song -;
- out <- eom - ;
sp <- eom - ' ' ; cm <- eom - ', ';
what :S <- eom - "bottle" S sp "of " "beer"; where <- eom - "on " "the " "wall";
a :N :S <- eom - N sp what :S sp where cm N sp what :S '.\n'; b :N :S <- eom - "Take " "one " "down " "and " " pass " "it " "around" cm N sp what :S sp where '.\n\n'; c :N :S <- eom - "Go " "to " "the " "store " "and " "buy " "some " "more" cm N sp what :S sp where '.\n\n';
Each occurrence of thing triggers output of a verse. All except the last produce another thing to generate the next verse.
thing :N <- verse a :N :"s" b :(N-1) :"s" eom thing :(N-1); thing :1 <- verse a :1 :"" b :"no more" :"s" eom thing :0; thing :2 <- verse a :2 :"s" b :1 :"" eom thing :1; thing :0 <- verse a :"No more" :"s" c :A :T eom ;