Pergunta

Como avaliar expressões booleanas complexas geradas em tempo de execução em um programa Java?

Exemplo:

(xey ou z) es

com variáveis booleanas x, y, z ...

Obrigado

Foi útil?

Solução

Use http://docs.codehaus.org/display/JANINO/Home para trabalho mínimo.Posso fazer muito mais do que simples expressões.

Outras dicas

Resumidamente, você precisa de uma "representação intermediária" das expressões booleanas. Esta é uma árvore formada por objetos Node. Node tem estas subclasses AndNode, OrNode, NotNode e VariableNode. Um AndNode tem dois Nodes filho, um OrNode tem dois Nodes filho e um NotNode tem um Node filho.

Um VariableNode tem apenas um nome de variável String, por exemplo, "x". Você teria um HashMap<String, Boolean> onde cada chave de nome de variável tem um valor booleano associado.

Cada classe Node possui um método eval() que avalia sua expressão e retorna um boolean. O método VariableNode.eval() procura o valor da variável em seu HashMap e o retorna. NotNode.eval() retorna !child.eval(). AndNode.evaluate() retorna child1.eval() && child2.eval(), enquanto OrNode.evaluate() retorna child1.eval() || child2.eval(). Para avaliar uma árvore de expressão booleana inteira, basta chamar o método eval() do nó raiz.

Você pode construir essas árvores de expressão booleana programaticamente, usando construtores Java, etc.

Se você deseja construir suas árvores de expressão a partir de strings, você precisará escrever um analisador que produza uma árvore a partir de strings. Os Padrões de implementação de linguagem de Terence Parr são uma introdução muito simples e clara a isso.

Como avaliar uma expressão lógica?Expressões lógicas como essas podem ser avaliadas como uma árvore de sintaxe, e acho que há algumas boas informações nesta questão relacionada Lógicaanalisador de expressão

Outra coisa que vem à mente é que você deseja ser capaz de lidar com expressões lógicas como dados, o que parece algo mais adequado para uma linguagem de script como, talvez, Jython, JRuby, Groovy ou Scala (assumindo que você está restrito aa JVM).Embora eu duvide que seja muito difícil escrever um analisador para lidar com expressões básicas e / ou não lógicas.

Você terá que gerar uma árvore de expressão e vincular cada folha a um valor booleano.Para analisar essa expressão e gerar um AST, dê uma olhada no algoritmo Shunting Yard de Dijkstra.Tudo é explicado lá e é bastante simples de implementar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top