Идея состоит в том, чтобы заставить ее генерировать функцию 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)) + ''
}; }
Итак, эти 3 вещи (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
.