2

実行時に入力された「VERB1 OR (VERB2 AND VERB3) OR (VERB4)」のような論理式を評価するにはどうすればよいですか。VERB* は、特定の条件を評価するためのプレースホルダーです。たとえば、VERB1 は、データベースにレコードが存在するかどうかのチェックを意味する場合があります。

式「VERB1 OR (VERB2 AND VERB3) OR (VERB4)」では、VERB1 が true の場合、他の動詞は実行されません。

編集: http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language/で説明されている例は、私がやろうとしていることと非常に似ているようです。ただし、最適化ステップ (VERB1 が true の場合、他の動詞は実行されません) は存在しないようです。

4

2 に答える 2

1

||and&&の代わりにANDandを使用できる場合はOR、次のように、groovy の欠落しているプロパティ メソッドとGroovyShell 基本クラス設定を使用できます。

import org.codehaus.groovy.control.CompilerConfiguration

// The command to be executes
def command = "VERB1 || (VERB2 && VERB3) || (VERB4)"

// Set a base class for the GroovyShell
new CompilerConfiguration().with { compiler ->
  compiler.scriptBaseClass = 'VerbHandlingBaseClass'
  new GroovyShell( this.class.classLoader, new Binding(), compiler ).with { shell ->
    // and evaluate the command
    shell.evaluate( command )
  }
}

abstract class VerbHandlingBaseClass extends Script {
  boolean VERB1() {
    System.out.println( 'CHECK THE DATABASE, RETURN FALSE' )
    false
  }

  boolean VERB2() {
    System.out.println( 'WRITE A LOG ENTRY RETURN TRUE' )
    true
  }

  boolean VERB3() {
    System.out.println( 'VALIDATE SOMETHING, RETURN TRUE' )
    true
  }

  boolean VERB4() {
    System.out.println( 'THIS WONT BE REACHED, AS VERB2 && VERB3 == true' )
    true
  }

  def propertyMissing( String name ) {
    "$name"()
  }
}

それは印刷する必要があります:

CHECK THE DATABASE, RETURN FALSE
WRITE A LOG ENTRY RETURN TRUE
VALIDATE SOMETHING, RETURN TRUE
于 2012-07-04T09:06:42.153 に答える
0

タグで ANTLR について言及しましたが、試してみましたか? ANTLR で完全なブール文法を作成することはできますが、動詞を評価する方法のレベルになると、はるかに難しくなります。

照会される動詞の小さな固定セットがある場合は、動詞と関数の間のマッピングを簡単に作成できます。

動詞のより大きなリストがある場合は、リフレクションを使用して特定のメソッドを呼び出してそれらを評価できる場合があります。

動詞に数学的比較を含めることができる場合、数学的レクサーとパーサーも作成するため、これはすべて少し難しくなります。

より具体的な質問と、ANTLR で試したことに関する知識がなければ、これ以上のアドバイスを提供できるかどうかわかりません。

編集:あなたのコメントに基づいて、さらに追加します。構文解析規則を文法に追加できます。

boolean_or returns [boolean b]
    : b1=boolean_and {$b = $b1.b;}
      (OR b2=boolean_and {$b = $b || $b2.b;})* 
    ;

boolean_atom returns [boolean b]
    :
    ((numeric_comparison)=> b1=numeric_comparison {$b = $b1.b;}
    | TRUE {$b = true;} | FALSE {$b = false;}
    | s1=VERB {$b = evalVerb($s1.s);}
    | LPAREN b1=boolean_expr RPAREN {$b = $b1.b;}
    )

;

それは私が現在使用しているブールパーサーのごく一部です。空白を埋めることができます。

そして、次のようなものを使用してパーサーを呼び出します

ANTLRStringStream in = new ANTLRStringStream(booleanString);
ActionLexer lexer = new  ActionLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
BooleanParser parser = new  BooleanParser(tokens);
try {
    return parser.eval();
} catch (Exception e) {
}

これはあなたが早く帰る必要があることを説明していませんが、それを行う方法を理解できると確信しています.

これは物事を行うための最良の方法ではないかもしれませんが、過去に私がうまくいった方法です. お役に立てれば。

于 2012-07-04T02:17:17.160 に答える