Помощник
|
деградационная математика |
Degradator
|
Сообщение
#1
|
||
|
|
||
|
|||
Degradator
|
Сообщение
#2
|
|
Итак, пишем парсер выражения. Он должен разобрать первое попавшееся выражение, будь то число или неизвестное, и сохранить курсор.
[JS] function Variable () { this.value = null; } Variable.prototype.getValue = function () { return this.value; }; Variable.prototype.setValue = function (value) { return this.value = value; }; function VariableParser(expression, cursor) { this.cursor = cursor; this.expression = expression; this.variable = null; this._parse(); } VariableParser.IS_NUMBER = 1; VariableParser.NOT_A_NUMBER = -1; VariableParser.NUMBER_PARSER = /^(-?\s*\d+\.?\d*)/; VariableParser.CHAR_PARSER = /^(-?\s*[a-zA-Z])/; VariableParser.WHITESPACE_LEFT = /^\s*/; VariableParser.WHITESPACE_RIGHT = /\s*$/; VariableParser.prototype.toString = function() { return "Variable: " + this.getVariable().getValue() + "; cursor: " + this.getCursor(); }; VariableParser.prototype.getCursor = function() { return this.cursor; }; VariableParser.prototype.getExpression = function() { return this.expression; }; VariableParser.prototype.getVariable = function() { return this.variable; }; VariableParser.prototype._parse = function() { var expression = this.expression; if(typeof expression !== 'string') { throw "Expression is not a string"; } var trimResult = this._trim(expression); expression = trimResult.expression; if(expression.length === 0) { throw "Expression is empty"; } var rawData = null; var variableType; if(expression.match(VariableParser.NUMBER_PARSER) !== null) { variableType = VariableParser.IS_NUMBER; rawData = VariableParser.NUMBER_PARSER.exec(expression); } else { variableType = VariableParser.NOT_A_NUMBER; rawData = VariableParser.CHAR_PARSER.exec(expression); } if(rawData === null || rawData.length < 2) { throw "Can't parse expression"; } var subExpression = rawData[1]; this.cursor = trimResult.left + subExpression.length; var multiplier = 1; if(subExpression.indexOf("-") === 0) { multiplier = -1; subExpression = subExpression.substring(1); } var variable = new Variable(); subExpression = subExpression.trim(); if(variableType === VariableParser.IS_NUMBER) { subExpression = parseFloat(subExpression) * multiplier; } else { if(multiplier === -1) { subExpression = "-" + subExpression; } } variable.setValue(subExpression); this.variable = variable; }; VariableParser.prototype._trim = function(expression) { var leftMatch = VariableParser.WHITESPACE_LEFT.exec(expression); var rightMatch = VariableParser.WHITESPACE_RIGHT.exec(expression); return { expression: expression.trim(), left: leftMatch && leftMatch[0].length > 0 ? leftMatch[0].length : 0, right: rightMatch && rightMatch[0].length > 0 ? rightMatch[0].length : 0, total: expression.length } }; [/JS] проверяем работу: [JS] ["20x = 0", "x = 0", " x = 0", " 20 x = 0", "-20x = 0", " -20x = 0", " - x = 0"].forEach(v => console.log((new VariableParser(v, 0)).toString())); [/JS] Отлично работает. Теперь надо написать класс, который будет угадывать какое математическое действие следует выбрать для дальнейших вычислений |
|
|
Degradator
|
Сообщение
#3
|
|
В предыдущем посте я отредактировал конструктор VariableParser, теперь он хочет принимать курсор. Это сделано для дальнейшего парсинга выражения.
Раздумываю над тем, как продолжить вычиления, прихожу к выводу, что надо делать какую-то chain конструкцию. Хотелось бы чтобы было примерно так [JS]variable1.multiple(variable2).plus(variable3).equals(0);[/JS] Но не хочется захломлять класс variable. Наверно надо сделать класс Equation, который будет работать так [JS]Equation.start(variable1).multiple(variable2).plus(variable3).equals(0);[/JS] В дальнейшем надо будет дописать класс SubEquation который будет нести примерно такойже смысл как скобки. |
|
|
Degradator
|
Сообщение
#4
|
|
|
в дальнейшем знаки мат действий надо будет заменить на классы. Пока что так
[JS] function Equation() { this.variables = []; this.actions = []; this.pointer = -1; this.isClosed = false; this.isBlock = false; } Equation.prototype.start = function(variable) { this._variableCheck(variable); this.variables.push(variable); this.pointer = 0; }; Equation.prototype.sum = function(variable) { this._action(variable, '+'); }; Equation.prototype.substract = function(variable) { this._action(variable, '-'); }; Equation.prototype.multiple = function(variable) { this._action(variable, '*'); }; Equation.prototype.divide = function(variable) { this._action(variable, '/'); }; Equation.prototype.close = function(variable) { this.isClosed = true; this.isBlock = true; }; Equation.prototype.equals = function(variable) { this._action(variable, '='); this.isClosed = true; this.isBlock = false; }; Equation.prototype._action = function(variable, action) { this._variableCheck(variable); this.variables.push(variable); this.actions.push(action); this.pointer++; }; Equation.prototype._variableCheck = function(variable) { if(!(variable instanceof Variable)) { throw "Invalid arguments exception, should be instance of Variable"; } };[/JS]
|
|
|
||
|
Текстовая версия | Сейчас: 26.4.2024, 7:21 |