Просмотр полной версии : Вычислить условное выражение, если оно представленно как строка
ShamanGood
01.01.2013, 10:45
Здравствуйте.
Зашел в тупик и долго искал в поисковиках, но пока без результатно.
Возможно ли простое/не простое решение следующей задачи:
var A = 5;
var B = 4;
затем из XML приходит строка "A>B", помещенная в пременную var condition = "A>B"
Возможно ли как то превратить condition в действительно условное выражение, чтобы типа:
if ( [какое-то превращение condition в выражение] ) { trace("true") } else { trace("false") }
Спасибо.
Да только парсить строку. Здесь уже все зависит от сложности выражений, допускаются ли комбинированные (типа (A + B) < C), сложные логические (типа (A > B) && (B <= C) || (A == C)) и вообще любое допущение вариантов формата создаст огромные сложности. Ну а если простое сравнение двух операндов, то несложно. Только нужны свойства уровня экземпляра для хранения сравниваемых значений — локальные переменные функции не подходят.
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author wolsh
*/
public class Main extends Sprite
{
public var a:uint = 10;
public var b:uint = 8;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var string:String = "a > b";
var regexp:RegExp = /([\w\d]+)\s?([><!=]+)\s?([\w\d]+)/;
var proper:Boolean = regexp.test(string);
if (proper)
{
var result:Array = string.match(regexp);
var operand1:Object = this[result[1]];
var operator:String = result[2];
var operand2:Object = this[result[3]];
trace(operate(operand1, operand2, operator));
}
}
private function operate(o1:Object, o2:Object, operator:String):Boolean
{
var result:Boolean;
switch(operator)
{
case ">" : result = o1 > o2;
break;
case "<" : result = o1 < o2;
break;
case "==" : result = o1 == o2;
break;
case "!=" : result = o1 != o2;
break;
case "===" : result = o1 === o2;
break;
case "!==" : result = o1 !== o2;
break;
case ">=" :
case "=>" : result = o1 >= o2;
break;
case "<=" :
case "=<" : result = o1 <= o2;
break;
}
return result;
}
}
}
http://code.google.com/p/flash-embedded-language/
Я писал когда-то очень простенький интерпретатор. Можно тут посмотреть, если нужно что-то более продвинутое, чем парсер на основе регулярной грамматики.
Что из вашего вопроса не понятно - так это описание того, чем являются выражения A и B. В зависимости от этого нужно решать проблему. Если известно, что А и В - терминалы, тогда нужно будет только немного переделать код Wolsh'a для того, чтобы он делал ленивые вычисления (т.е. чтобы выражения "А или В" не вычисляли В если А истинно, и "А и Б" не вычисляли Б, если А ложно.
Но если А или Б могут быть не терминалами, тогда все становится гораздо сложнее... И еще сложнее, если А и Б могут зависеть от контекста.
ShamanGood
02.01.2013, 00:37
Спасибо огромное. Многое выяснил.
Но если А или Б могут быть не терминалами, тогда все становится гораздо сложнее... И еще сложнее, если А и Б могут зависеть от контекста.
В то-то и дело, что это очень большое меню, приходящее в виде распарсенного JSON файла. И внутри каждого пункта хотелось выяснять disabled, visible и т.д. путем выполнения условия для каждого пункта. И не писать код для простых условий, а парсить строку из этого JSONa. Условия могут быть разные от "Logged" true/false , до сложных вычислений, результатом, которых будет true/false, поэтому без писания кода в теле класса - никак, наверное.
Я нашел решение пока.
У каждого пункта меню есть имя. Я создал объект, в котором под этими именами будут функции, а в ней уже и условия на disable, visible и т.д. и там же ссылка на функцию CLICK пункта меню.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.