1

ANTLR (解析用) と Pentaho Kettle (ルールの実行用) を使用するカスタム ルール エンジン用の文法を作成しようとしています。

パーサーの有効な入力は次のようなものです。
(<Attribute_name> <Relational_Operator> <Value>) AND/OR (<Attribute_name> <Relational_Operator> <Value>)
つまり、PERSON_PHONE = 123456789 です。

これが私の文法です:

grammar RuleGrammar;
options{
language=Java;
}

prog                : condition;

condition
                                :  LHSOPERAND RELATIONOPERATOR RHSOPERAND
                                ;

LHSOPERAND
                                :  STRINGVALUE
                                ;

RHSOPERAND
                                :  NUMBERVALUE    |
                                   STRINGVALUE
                                ;


RELATIONOPERATOR
                                :   '>'    |
                                     '=>'  |
                                     '<'   |
                                     '<='  |
                                     '='   |
                                     '<>'
                                ;

fragment NUMBERVALUE
                              : '0'..'9'+
                              ;

fragment STRINGVALUE
                              :  ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_')*
                              ;


fragment LOGICALOPERATOR
                              :  'AND' |
                                 'OR'  |
                                 'NOT'
                              ;

私が直面している問題は、文字列値と比較することです。つまり、PERSON_NAME=1 は文法を通過しますが、値PERSON_NAME=BATMANは機能しません。私は ANTLRWorks を使用しており、 のデバッグでRHS 値PERSON_NAME=BATMANを取得しています。MismatchTokenException

誰かが私が間違っているところを教えてもらえますか?

4

1 に答える 1

3

BATMANトークンとしてトークン化されていLHSOPERANDます。レクサーは、特定の時点でパーサーが「必要とする」ものを考慮しないことに注意してください。lexer は単純にできるだけ多くの一致を試みます。2 つ (またはそれ以上) のルールが同じ量の文字に一致する場合 (LHSOPERANDおよびRHSOPERANDあなたの場合)、最初に定義されたルールが「勝ち」ます。これがLHSOPERANDルールです。

編集

次のように見てください。まず、レクサーは文字ストリームを受け取り、それをトークンのストリームに変換します。すべてのトークンが作成されると、パーサーはこれらのトークンを受け取り、それを理解しようとします。トークンは解析中に (パーサー ルールで) 作成されるのではなく、その前に作成されます。

あなたがそれを行う方法の簡単なデモ:

grammar RuleGrammar;

prog
 : condition EOF
 ;

condition
 : logical
 ;

logical
 : relational ((AND | OR) relational)*
 ;

relational
 : STRINGVALUE ((GT | GTEQ | LT | LTEQ | EQ | NEQ) term)?
 ;

term
 : STRINGVALUE
 | NUMBERVALUE
 | '(' condition ')'
 ;

GT          : '>';
GTEQ        : '>=';
LT          : '<';
LTEQ        : '<=';
EQ          : '=';
NEQ         : '<>';
NUMBERVALUE : '0'..'9'+;
AND         : 'AND';
OR          : 'OR';
STRINGVALUE : ('a'..'z' | 'A'..'Z' | '_')+;
SPACE       : ' ' {skip();};

EQ( andNEQは実際には関係演算子ではないことに注意してください...)

次のような入力の解析:

PERSON_NAME = BATMAN OR age <> 42

次の解析が行われます。

ここに画像の説明を入力

于 2012-02-21T18:42:06.807 に答える