我想在peg.js中创建解析器和表达式语法,这将允许我做这些事情
基本上我想传入一个掩码并输出数字。
面具有这些能力。
1)生成0-9之间的随机数(表达式为n
?)
2)在x和y之间产生一个随机数((x,y)用于表达式?)
3)字面数字是有效的(希望没有任何需要的东西?)
4)重复前面的表达式x次({x}表达式?)
5)重复x和y次之间的前一个表达式({x,y}表达式?)
所以示例表达式可能是
027n(5,9){4}n12{2,8}(2,4)
上面提出的表达式语法只是一个例子,它可以改变。
任何人都可以在peg.js中为此创建解析器提供帮助吗?
答案 0 :(得分:17)
这个想法是让它生成一个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;
};
}
最后,您需要一个定义遮罩的起点。最后一位扫描表达式,返回a生成一个函数,然后调用它。 将以下内容放在顶部,当您在线尝试时,它会根据您的面具生成一串数字。
mask
= ex:expression
{ return ex() }
示例运行:027n(5,9){4}n12{2,8}(2,4)
提供0271568891222224
。