avaliar a expressão booleana em java, gerar em tempo de execução
-
27-10-2019 - |
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
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 Node
s filho, um OrNode
tem dois Node
s 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.