帮助创建peg.js解析器

Hai*_*ood 6 javascript parsing expression

我想在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中为此创建解析器提供帮助吗?

Tha*_*hai 17

我们的想法是让它生成一个JavaScript函数,该函数在执行时将根据掩码返回一个随机字符串.

文字数字是介于0到9之间的任何字符,因此要生成一个返回自身的函数.

literal_number
 = num:[0-9]
 { return function() {
     return num;
 }; }
Run Code Online (Sandbox Code Playgroud)

然后n是一个随机数.同样,这会生成一个返回随机数的函数.我+ ''在返回之前添加了将其转换为字符串.

random_number
 = "n"
 { return function() {
     return Math.floor(Math.random() * 10) + '';
 }; }
Run Code Online (Sandbox Code Playgroud)

(a,b)语法中,a并且b是数字,所以我们需要使其解析并返回一个数字.使用计算器示例中的声明:

number
 = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
Run Code Online (Sandbox Code Playgroud)

然后我们可以继续创建(a,b)语法规则.

random_number_between
 = "(" a:number "," b:number ")"
 { return function() {
     return a + Math.floor(Math.random() * (b - a + 1)) + ''
 }; }
Run Code Online (Sandbox Code Playgroud)

因此,这三件事(literal_number,random_number,random_number_between)组合成一个生成有效函数的表达式.

single_expression
 = random_number
 / random_number_between
 / literal_number
Run Code Online (Sandbox Code Playgroud)

单个表达式,后跟{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
Run Code Online (Sandbox Code Playgroud)

最后,重复的表达式可以彼此相邻以进行连接.

expression
 = list:repeated_expression* {
       return function() {
           var result = '';
           for (var i = 0; i < list.length; i ++) {
               result += list[i]();
           }
           return result;
       };
   }
Run Code Online (Sandbox Code Playgroud)

最后,您需要一个定义遮罩的起点.最后一位扫描表达式,返回a生成一个函数,然后调用它.将以下内容放在顶部,当您在线尝试时,它将根据您的掩码生成一串数字.

mask
 = ex:expression
 { return ex() }
Run Code Online (Sandbox Code Playgroud)

示例运行:027n(5,9){4}n12{2,8}(2,4)给出0271568891222224.

  • 你还可以有另一个匹配任何字符的规则,比如`literal_char = char:.`然后像`literal_number`那样返回函数,并将`literal_char`追加到`single_expression`规则,使它接受`literal_char`. (2认同)