3

比較的単純なIF/THEN言語を評価していますが、問題が発生しました。YYYYMMDD形式の整数と日付の両方を一致させる必要があります。本当の正規表現を書くことができれば、これはかなり簡単に解決できますが、ANTLRの解決策はわかりません。

文法は次のようになります。

//overall rule to evaluate a single expression
singleEvaluation returns [boolean evalResult]
  : integerEvaluation {$evalResult = $integerEvaluation.evalResult;}
  | dateEvaluation {$evalResult = $dateEvaluation.evalResult;}
  // etc
  ;


dateEvaluation returns [boolean evalResult]
  : expr1=(INTEGER|'TODAY'|DATE_FIELD_IDENTIFIER) (leftOp=('+'|'-') leftModifier=INTEGER leftQualifier=DATE_QUALIFIER)? 
    operator=(EQ|NE|LT|LE|GT|GE) 
    expr2=(INTEGER|'TODAY'|DATE_FIELD_IDENTIFIER) (rightOp=('+'|'-') rightModifier=INTEGER rightQualifier=DATE_QUALIFIER)?
{ // code }

integerEvaluation returns [boolean evalResult]
  : expr1=(NUM_FIELD_IDENTIFIER|INTEGER) 
    operator=(EQ|NE|LT|LE|GT|GE) 
    expr2=(NUM_FIELD_IDENTIFIER|INTEGER)
  { // code
  }
  ;

fragment DIGIT: '0'..'9';
INTEGER: DIGIT+;
DATE_FIELD_IDENTIFIER: ('DOB'|'DATE_OF_HIRE');
NUM_FIELD_IDENTIFIER: ('AGE'|'DEPARTMENT_ID');
DATE_QUALIFIER:('YEAR'|'YEARS'|'MONTH'|'MONTHS'|'DAY'|'DAYS'|'TODAY');
EQ:'=';
NE: '<>';
LT: '<';
LE: '<=';
GT: '>';
GE: '>=';

解析する必要のあるステートメントの例は、「65> AGE」、「AGE <65」、または「DOB>19500101」のようなものです。

パーサーにINTEGERと8桁の日付形式を区別する方法を誰かが提案できますか?

4

1 に答える 1

4

レクサーがに一致した後、INTEGER一致したテキスト(を介して参照$text)を検査し、そのカスタムチェックに基づいて、タイプをからに変更することを決定できINTEGERますDATEDATEルールは空のルールとして作成fragmentでき、通常のレクサールールであるかのようにパーサールール内で使用できます。

簡単なデモ:

INTEGER
 : DIGIT+
   {
     // If this token starts with either '19' or '20', followed 
     // by 6 digits, change it to a DATE-token.
     if ($text.matches("(19|20)\\d{6}")) {
       $type = DATE;
     }
   }
 ;

fragment DATE : /* empty! */ ;

そして、パーサールールでは、次を使用できますDATE

dateEvaluation
 : DATE ...
 ;
于 2012-11-14T19:41:16.003 に答える