perl - 解析逻辑表达式并将其转换为 Perl 中的树

标签 perl parsing logic

我有复杂的逻辑表达式,如下所示:

((((!((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/

    相关文章:

    perl - 如何在 Perl 中打印文本文件的行时保持适当的列间距

    ios - 需要过滤来自 URL 的结果

    c - Flex 无法识别的规则

    java - 我想知道这是否是一个好的编程习惯,否则我如何才能更优化和高效地编写程序

    perl - 将哈希排序为数组中的键

    perl - 如何判断网页是否存在?

    c - 如何在 C 语言中对数字数组进行排序而不将它们移动?

    Javascript 比较逻辑 - 让 a = 1 。 a === (3 || 1 ) 错误,为什么?

    regex - 尝试在 Perl 中匹配两个都包含特殊字符的变量

    java - 页面上有两个字符集标签,该采用哪个?