这个想法是让它生成一个JavaScript函数,它在执行时会根据掩码返回一个随机字符串。
文字数字是0到9之间的任何字符,因此使其生成一个返回自身的函数。
literal_number
= num:[0-9]
{ return function() {
return num;
}; }
然后n
是一个随机数。同样,这会生成一个返回随机数的函数。我添加了+ ''
在返回之前将其转换为字符串。
random_number
= "n"
{ return function() {
return Math.floor(Math.random() * 10) + '';
}; }
在(a,b)
语法,a
和b
是数字,所以我们需要让它解析,并返回一个数字。从计算器示例使用声明:
number
= digits:[0-9]+ { return parseInt(digits.join(""), 10); }
然后我们就可以转移到创建一个规则(a,b)
语法。
random_number_between
= "(" a:number "," b:number ")"
{ return function() {
return a + Math.floor(Math.random() * (b - a + 1)) + ''
}; }
因此,这些三件事情(literal_number,RANDOM_NUMBER,random_number_between)组合成生成一个有效的功能的单个表达式。
single_expression
= random_number
/random_number_between
/literal_number
单个表达,随后{n}
或{a,b}
形式重复表达式。单一表达也是重复表达,重复一次。
重复表达式的思想是,给定一个函数,返回一个调用输入函数N次的函数,收集结果并返回它。
repeated_expression
= ex:single_expression "{" n:number "}" {
return function() {
var result = '';
for (var i = 0; i < n; i ++) {
result += ex();
}
return result;
};
}
/ex:single_expression "{" a:number "," b:number "}" {
return function() {
var result = '';
var n = a + Math.floor(Math.random() * (b - a + 1))
for (var i = 0; i < n; i ++) {
result += ex();
}
return result;
};
}
/ex:single_expression
最后,重复的表达式可以放在一起以便连接。
expression
= list:repeated_expression* {
return function() {
var result = '';
for (var i = 0; i < list.length; i ++) {
result += list[i]();
}
return result;
};
}
最后,您需要一个起点,它定义了一个掩码。最后一位扫描返回的表达式生成一个函数,然后调用它。 将以下内容放在顶部,当您在线试用时,它会根据您的面具生成一串数字。
mask
= ex:expression
{ return ex() }
实施例运行:027n(5,9){4}n12{2,8}(2,4)
给出0271568891222224
。
哇, 这实际上应该在peg.js文档中 这是一个比他们有更好的教程! 非常感谢。 – Hailwood 2011-03-09 20:54:57
顺便说一句,我想你在你的例子答案中有几个流氓'11'。 – Hailwood 2011-03-09 21:03:12
嗯,即时通讯仍然困惑了一下,我试图做出一个规则说,如果它不符合任何其他规则只是返回自己。我怎么能这样做? – Hailwood 2011-03-10 00:55:13