我有复杂的逻辑表达式,如下所示:
((((!((cond1) || (cond2) || (cond3)) && (cond4))) && (cond5)) <= (((cond6) || (cond7) || (cond8)) || (cond9)))
每行都有几十个表达式。允许的逻辑符号为
||
, &&
, !
和 <=
. <=
表示潜在客户,如 a <= b
意味着 b 导致 a。我需要检查这些语句并检查条件,因为其中一些不再有效。我希望能够将其解析为一棵树,然后检查它的每个叶子(其中每个叶子都是一个条件),删除不需要的叶子并构建完整且正确的表达式。
我知道树的每个节点都是由一对第一个括号和关闭它的括号定义的,但我不知道如何识别这些对以及如何识别它们之间的逻辑符号。
除
!
外的所有标志介于两个表达式之间。
最佳答案
听起来像是 Parse::RecDescent 的案例:
use strict;
use warnings;
use Parse::RecDescent;
my $text = '((((!((cond1) || (cond2) || (cond3)) && (cond4))) && (cond5)) <= (((cond6) || (cond7) || (cond8)) || (cond9)))';
#$::RD_TRACE=1;
my $grammar = q{
startrule: expr
expr: operand operation(s?)
{ $return = @{$item[2]} ? { 'operations' => $item[2], 'lvalue' => $item[1] } : $item[1] }
operation: /\|\||&&|<=/ operand
{ $return = { 'op' => $item[1], 'rvalue' => $item[2] } }
operand: '(' expr ')'
{ $return = $item[2] }
operand: '!' operand
{ $return = { 'op' => '!', 'value' => $item[2] } }
operand: /\w+/
};
my $parser = Parse::RecDescent->new($grammar);
my $result = $parser->startrule($text) or die "Couldn't parse!\n";
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Sortkeys = 1;
print Dumper $result;
语法,英语:
整个事情就是一个表达。表达式是一个操作数,后跟零个或多个二元运算符及其操作数。每个操作数都是一个带括号的表达式,“!”后跟一个操作数或一个单词(例如
cond1
)。生成树中的每个节点都是以下形式之一:
cond1
- 条件{ 'op' => '!', 'value' => 'node' }
- !应用于另一个节点 { 'lvalue' => 'node', 'operations' => [ one or more of: { 'op' => 'binop', 'rvalue' => 'node' } ] }
- 代表节点 binop 节点 binop 节点 ... 我没有将一系列二元运算(例如
((cond1) || (cond2) || (cond3))
)分解为二叉树,因为您没有提供有关优先级或关联性的信息。您的示例的输出是:
$VAR1 = {
'lvalue' => {
'lvalue' => {
'lvalue' => {
'op' => '!',
'value' => {
'lvalue' => 'cond1',
'operations' => [
{
'op' => '||',
'rvalue' => 'cond2'
},
{
'op' => '||',
'rvalue' => 'cond3'
}
]
}
},
'operations' => [
{
'op' => '&&',
'rvalue' => 'cond4'
}
]
},
'operations' => [
{
'op' => '&&',
'rvalue' => 'cond5'
}
]
},
'operations' => [
{
'op' => '<=',
'rvalue' => {
'lvalue' => {
'lvalue' => 'cond6',
'operations' => [
{
'op' => '||',
'rvalue' => 'cond7'
},
{
'op' => '||',
'rvalue' => 'cond8'
}
]
},
'operations' => [
{
'op' => '||',
'rvalue' => 'cond9'
}
]
}
}
]
};
关于perl - 解析逻辑表达式并将其转换为 Perl 中的树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4517721/