Я создаю симулятор булевой логики. Я опубликовал вопрос об организации и общей настройке приложения, и он находится здесь: Организация Simple Boolean Logic Simulator - Java . Я подумал, что это не относится непосредственно к другому вопросу, поэтому было бы хорошо опубликовать это отдельно. Пожалуйста, извините мой код, я очень плохо знаком с Java.
Организация кода на самом деле довольно проста, но я столкнулся с проблемой, когда пытался присвоить себе переменную в операторе assign.
Например, мы обычно будем использовать такие выражения:
assign input1 * input2 + test3 * input2 to test3;
Когда input1 и input2 имеют высокий уровень, test3 станет высоким. В этот момент input1 может выпасть, а test3 все равно будет высоким, поскольку он ссылается на себя в выражении. (Примечание: * => AND, + => OR) Как вы можете видеть ниже, у меня возникают проблемы, когда переменная ссылается на себя в своем операторе assign, как описано выше. Это потому, что когда я пытаюсь получить значение приведенного выше утверждения, я получаю:
input1 * input2 + (input1 * input2 + (input1 * input2 + test3 * input2) * input2) * input2
Etc. Он просто пытается оценить свое утверждение снова и снова.
public interface Argument {
public boolean evaluate();
}
Вот класс «Бит», который хранит информацию о каждом бите. Бит может быть либо «жестко запрограммированным», либо истинным, либо ложным, либо ему может быть назначен оператор.
public class Bit implements Argument {
private String name;
private boolean value;
private Argument assign;
private boolean assigned;
Bit( String name, boolean value ) {
this.name = name;
this.value = value;
}
@Override
public boolean evaluate() {
if ( assigned == true ) {
return assign.evaluate();
} else {
return value;
}
}
public void setValue( boolean value ) {
this.value = value;
}
public void setAssign( Argument assign ) {
this.assign = assign;
this.assigned = true;
}
}
Это пример класса Operation; остальные очень похожи.
public class OrOperation implements Argument {
private Argument argument1, argument2;
public OrOperation( Argument arg1, Argument arg2 ) {
this.argument1 = arg1;
this.argument2 = arg2;
}
@Override
public boolean evaluate() {
return argument1.evaluate() || argument2.evaluate();
}
}
Класс парсера: я включил только часть этого, так как на самом деле синтаксический анализ не так уж важен. Обратите внимание, что когда я присваиваю себе переменную, возникает ошибка. Во втором тесте ниже я назначил test3 для test3. Я могу сделать вывод, что это потому, что test3 пытается определить значение самого себя, вызывая этот второй оператор снова и снова.
public class Parser {
public HashMap<String, Bit> bits = new HashMap<String, Bit>();
Parser(String file) {
bits.put( "test1", new Bit( "test1", true ) );
bits.put( "test2", new Bit( "test2", true ) );
bits.put( "test3", new Bit( "test3", false ) );
bits.put( "test4", new Bit( "test4", true ) );
// Works great
bits.get("test3").setAssign( parseStatement("test1 * ~test2 + test4 * test2") );
System.out.println( bits.get("test3").evaluate() );
// Produces error
bits.get("test3").setAssign( parseStatement("test1 * test2 + test3 * test2") );
System.out.println( bits.get("test3").evaluate() );
}
}
Синтаксический анализатор в основном создает операторы так: (взято из предыдущего вопроса)
Operand op = new AndOperand( register1, new OrOperand( register2, register3 );
boolean output = op.evaluate(); // this is register1 && (register2 || register3 )
Надеюсь, это было достаточно ясно. Дайте мне знать, если есть какие-либо вопросы относительно того, в чем проблема или что я пытаюсь сделать. Заранее спасибо.