3 var rrr
= exports
.rrr
|| require('./rrr');
5 var grammar
= new rrr
.Grammar({
6 // Canonical expression/term/factor grammar.
7 Expr
: ['<Term>', '<Term> + <Term>', '<Term> - <Term>'],
8 Term
: ['<Fact>', '<Fact> * <Fact>', '<Fact> / <Fact>'],
11 // If a parenthesized expression is as likely as a number, the
12 // expansion explodes and overflows the stack. You can prove
13 // this by multiplying out the probabilities: On average, Expr
14 // produces 5/3 Terms, Terms produce 5/3 Facts, and Fact
15 // produces 1/2 Exprs.
17 // So with equal weights Expr produces, on average,
18 // (5/3)*(5/3)*(1/2) ~= 1.4 Exprs.
20 // That means Expr must be weighed at _most_ 1/1.4 ~= 0.72
21 // relative to the other option to produce one Expr, and in
22 // practice should be even less to avoid "lucky" stack
24 Fact
: { '<Number>': 1, '<Sign>(<Expr>)': 0.4 },
26 // A numeral may not begin with a 0.
27 Number
: ['<Sign><digit><digit0>*'],
32 exports
.randomEquation
= grammar
.expand
.bind(grammar
);
33 })(typeof module
!== 'undefined' ? module
.exports
: this);