2010-12-23 18 views
7

將其轉換爲一棵樹我有一個看起來像這樣複雜的邏輯表達式:一個邏輯表達式的解析和在Perl

((((!((cond1) || (cond2) || (cond3)) && (cond4))) && (cond5)) <= (((cond6) || (cond7) || (cond8)) || (cond9))) 

每一行都有幾十表達式。允許的邏輯符號是||,&&,!<=<=意味着領導,如在a <= b意味着b導致a。

我需要檢查這些語句並檢查條件,因爲其中一些不再有效。我希望能夠解析它到一棵樹上,然後檢查它的每一片葉子(每片葉子是一個條件),刪除不需要的葉子並返回完整和正確的表達式。

我知道樹的每個節點都由一對第一個括號和關閉它的括號定義,但我不知道如何識別這些對以及如何識別它們之間的邏輯符號。

!之外的所有符號都在兩個表達式之間。

+0

是用Perl這些表達式或者是從另一種語言?這是隻有一個鏡頭代碼清理? – VGE 2010-12-23 10:33:43

+0

它不在Perl中,它是一個.va文件,我不確定它是什麼語言。我想編寫一個解析它們的Perl腳本。 – SIMEL 2010-12-23 10:43:40

回答

11

聽起來像是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' 
      } 
     ] 
     } 
    } 
    ] 
};