анализатор пользовательских правил - PullRequest
2 голосов
/ 09 марта 2011

У меня есть набор масок .

Маски выглядят так

'09 {2,9} п (6) '
// читаем как 09
// [число от 2 до 9]
// [случайное число] [повторить 6 раз]

029n (7,10) '
// читаем как 029
// [случайное число] [повторение выражения от 7 до 10 раз]

'029n (2,5) {8,15} (7,10) п'
// читаем как 029
// [случайное число] [повторение выражения от 2 до 5 раз]
// [случайное число от 8 до 15] [повторение выражения от 7 до 10 раз]
// [случайное число]

в качестве примера выражение 3 будет работать как
'029n (4) {} 4,9 (7) п'
«029nnnn {4,9} {4,9} {4,9} {4,9} {4,9} {4,9} {4,9} п * * тысяча двадцать пять «029nnnn {5} {9} {4} {8} {5} {9} {9} п * +1026 * '029nnnn5948599n'
'029023559485999'

Мне нужно написать анализатор в javascript, который может генерировать строку на основе этих правил. Обратите внимание, что это не проверка , это генерация строки.

Какой лучший способ сделать это?

1 Ответ

3 голосов
/ 09 марта 2011

Испытание пользовательского парсера.Используйте как,

var generator = new PatternGenerator('09{2,9}n(6)');
generator.generate(); // 096555555
generator.generate(); // 095000000

Оформить заказ пример .

И функция конструктора,

function PatternGenerator(pattern) {
    var tokens = null;

    this.generate = function() {
        var stack = [];
        tokens = pattern.split('');

        // Read each token and add
        while (tokens.length) {
            var token = lookahead();
            if (isDigit(token)) {
                stack.push(consumeNumber());
            }
            else if (token == "n") {
                stack.push(consumeVariableNumber());
            }
            else if (token == "(") {
                var topObject = stack.pop();
                stack.push(consumeRepetition(topObject));
            }
            else if (token == "{") {
                stack.push(consumeVariableRangeNumber());
            }
            else {
                throw new Error("Invalid input");
            }
        }
        return stack.join('');
    }

    // [0-9]+
    function consumeNumber() {
        var number = "";
        while (isDigit(lookahead())) {
            number += consume();
        }
        return number;
    }

    // "n"
    function VariableNumber() {
        var number = generateRandomNumber();

        this.toString = function() {
            return Number(number);
        };
    }

    function consumeVariableNumber() {
        consume();
        return new VariableNumber();
    }

    // {x, y}
    function VariableRangeNumber(start, end) {
        var number = generateRandomNumberBetween(start, end);

        this.toString = function() {
            return Number(number);
        };
    }

    function consumeVariableRangeNumber() {
        consume(); // {
        var firstNumber = consumeNumber();
        consume(); // ,
        var secondNumber = consumeNumber();
        consume(); // }
        return new VariableRangeNumber(firstNumber, secondNumber);
    }

    // <expression>(x)
    function Repeat(object, times) {
        this.toString = function() {
            var string = "";
            for (var i = 0; i < times; i++) {
                string += object;
            }
            return string;
        };
    }

    // <expression>(x, y)
    function RepeatWithRange(object, start, end) {
        var times = generateRandomNumberBetween(start, end);

        this.toString = function() {
            return new Repeat(object, times).toString();
        };
    }

    function consumeRepetition(object) {
        consume(); // (
        var firstNumber, secondNumber;
        var firstNumber = consumeNumber();
        if (lookahead() == ",") {
            consume(); // ,
            secondNumber = consumeNumber();
        }
        consume(); // )

        if (typeof secondNumber == 'undefined') {
            return new Repeat(objectToRepeat, firstNumber);
        }
        else {
            return new RepeatWithRange(object, firstNumber, secondNumber);
        }
    }

    // Helpers to generate random integers
    function generateRandomNumber() {
        var MAX = Math.pow(2, 52);
        return generateRandomNumberBetween(0, MAX);
    }

    function generateRandomNumberBetween(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function lookahead() {
        return tokens[0];
    }

    function consume() {
        return tokens.shift();
    }

    function isDigit(character) {
        return /\d/.test(character);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...