-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
61 lines (54 loc) · 1.67 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
var _ = require("lodash");
var randexp = require("randexp");
module.exports = function(grammar, options){
options = options || {};
var override_rule = options.override_rule || {};
var start = options.start || grammar.ParserStart;
var filterRule = options.filterRule || function(){return true};
var max_stack_size = (options.max_stack_size >= 0)
? options.max_stack_size
: 25;
var max_loops = (options.max_loops >= 0)
? options.max_loops
: 500;
var stack = [start];
var output = "";
var stop_recusive_rules = false;
var selectRule = function(currentname){
var rules = grammar.ParserRules.filter(function(x) {
return x.name === currentname;
});
if(rules.length === 0){
throw new Error("Nothing matches rule: "+currentname+"!");
}
return _.sample(_.filter(rules, function(rule){
if(!filterRule(rule)){
return false;
}
if(stop_recusive_rules || stack.length > max_stack_size){
return !_.includes(rule.symbols, currentname);
}
return true;
}));
};
var count = 0;
while(stack.length > 0){
count++;
if(!stop_recusive_rules && count > max_loops){
stop_recusive_rules = true;
}
var currentname = stack.pop();
if(override_rule.hasOwnProperty(currentname)){
stack.push({literal: override_rule[currentname]()});
}else if(typeof currentname === "string"){
_.each(selectRule(currentname).symbols, function(symbol){
stack.push(symbol);
});
}else if(currentname.test){
output = new randexp(currentname).gen() + output;
}else if(currentname.literal){
output = currentname.literal + output;
}
}
return output;
};