2011-03-09 122 views
5

我想創建解析器,並在peg.js表達式語法,讓我做這些事幫助創建peg.js解析器

基本上我希望在一個面具來傳遞,並有多個輸出。

面具有這些能力。

1)生成0-9(字符n用於表達之間的隨機數?)
2)生成x和y((X,Y)之間的隨機數用於表達?)
3)文字數是有效(希望什麼需要expession?)
4)重複先前表達式x倍({X}中表達?)
5)重複(x和y倍之間先前表達式{X,Y}中表達?)

所以一個例子表達式可能是

027n(5,9){4}n12{2,8}(2,4)

上面提出的表達式語法只是一個例子,它可以改變。

任何人都可以在peg.js中爲此創建解析器提供幫助嗎?

回答

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)語法,ab是數字,所以我們需要讓它解析,並返回一個數字。從計算器示例使用聲明:

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

+1

哇, 這實際上應該在peg.js文檔中 這是一個比他們有更好的教程! 非常感謝。 – Hailwood 2011-03-09 20:54:57

+0

順便說一句,我想你在你的例子答案中有幾個流氓'11'。 – Hailwood 2011-03-09 21:03:12

+0

嗯,即時通訊仍然困惑了一下,我試圖做出一個規則說,如果它不符合任何其他規則只是返回自己。我怎麼能這樣做? – Hailwood 2011-03-10 00:55:13