AntLR定义匹配特定模式的规则

时间:2015-05-05 10:38:53

标签: android antlr4

我是antLR的新手,到目前为止,我可以实现所需要的。但我很擅长定义匹配特定模式的规则。 我有以下语法文件

grammar ExpEvalDateParser;



@header {
package com.validationframework;
import com.validationframework.ExpressionBuilder;
import java.util.Calendar;
}


@members {
    private final ExpressionBuilder expressionBuilder = new ExpressionBuilder();
}


/**
 * Parser Rules
 */

ruleString returns [java.lang.String resultExpression]:
       (
         EOF
         |(ruleOperandExpression|ruleOperatorExpression)*

       )
{ resultExpression =expressionBuilder.getExpression(); }
;


ruleOperandExpression :
        fieldEnclosure+ fieldOperand {expressionBuilder.getFieldResponse(Integer.parseInt(!$fieldOperand.text.equals("")?$fieldOperand.text:0));} fieldEnclosure+
;

ruleOperatorExpression:

 ruleOperator {expressionBuilder.addOperand($ruleOperator.text);}
 ;

fieldEnclosure : ENCLOSUREOPEN |ENCLOSURECLOSE;

ENCLOSUREOPEN :'[';

ENCLOSURECLOSE:']';

fieldOperand :
NUMERIC ;

NUMERIC: ('0'..'9')+  ;


ruleOperator :

 LT
 | GT
 | GTE
 | LTE
 | EQ
 | NEQ
;

LT : '<';
GT : '>';
LTE : '<=';
GTE: '>=';
EQ : '==';
NEQ:'!=';

NEWLINE         : '\r'? '\n'        ->channel(HIDDEN) ;
WS              : (' '|'\t')+       ->channel(HIDDEN) ;

我希望我的ruleOperandExpression类似于[10]

我已将ruleOperandExpression定义如下

fieldEnclosure+ fieldOperand {expressionBuilder.getFieldResponse(Integer.parseInt(!$fieldOperand.text.equals("")?$fieldOperand.text:0));} fieldEnclosure+

但是当我在我的android代码中执行规则时,它接受[以及[10以及[])。我希望规则只匹配[10]。请让我知道如何实现这一目标!

==================================更新语法=========== ====================

grammar ExpEvalDateParser;



@header {
package com.validationframework;
import com.validationframework.ExpressionBuilder;
import java.util.Calendar;
}


@members {
    private final ExpressionBuilder expressionBuilder = new ExpressionBuilder();
}


/**
 * Parser Rules
 */

ruleString returns [java.lang.String resultExpression]:
       (
         EOF
         |(logicalGrouping|ruleOperandExpression|ruleOperatorExpression|fieldOperand|numberLiteral)*

       )
{ resultExpression =expressionBuilder.getExpression(); }
;

logicalGrouping :
(PARANTHESISOPEN {expressionBuilder.addOperand("(");}|PARANTHESISCLOSE {expressionBuilder.addOperand(")");})
;


ruleOperandExpression :
        ENCLOSUREOPEN+ fieldOperand+ ENCLOSURECLOSE+ {expressionBuilder.getFieldResponse(Integer.parseInt(!$fieldOperand.text.equals("")?$fieldOperand.text:"0"));}
;

ruleOperatorExpression:
ruleOperator
 ;

fieldEnclosure : (ENCLOSUREOPEN |ENCLOSURECLOSE);

ENCLOSUREOPEN :'[';

ENCLOSURECLOSE:']';

fieldOperand :
NUMERIC ;

numberLiteral:
NUMERIC ;

NUMERIC: ('0'..'9')+  ;


ruleOperator :

 LT {expressionBuilder.addOperand("<");}
 | GT {expressionBuilder.addOperand(">");}
 | GTE {expressionBuilder.addOperand("<=");}
 | LTE {expressionBuilder.addOperand(">=");}
 | EQ {expressionBuilder.addOperand("==");}
 | NEQ {expressionBuilder.addOperand("!=");}
 |isEqualTo
 |isGreaterThan
 |isGreaterThanOrEqualTo
 |isLessThan
 |isLessThanOrEqualTo
 |isNotEqualTo
 |isAfter
 |isAfterOrEqualTo
 |isBefore
 |isBeforeOrEqualTo
 |trueVal
 |falseVal
 |ADD {expressionBuilder.addOperand("+");}
 |MULTIPLY{expressionBuilder.addOperand("*");}
 |SUBSTRACT{expressionBuilder.addOperand("-");}
 |DEVIDE{expressionBuilder.addOperand("/");}
 //|is
 //|isNot
 //|contains
 //|doesNotContain
 //|startsWith
 //|doesNotStartWith
 //|endsWith
 //|doesNotEndWith
;

LT : '<' ;
GT : '>' ;
LTE : '<=' ;
GTE: '>=' ;
EQ : '==' ;
NEQ:'!=' ;

PARANTHESISOPEN:'(' ;
PARANTHESISCLOSE:')'{expressionBuilder.addOperand(")");};

NEWLINE         : '\r'? '\n'        ->channel(HIDDEN) ;
WS              : (' '|'\t')+       ->channel(HIDDEN) ;

isEqualTo: I S E Q U A L T O {expressionBuilder.addOperand("==");};

isGreaterThan : I S G R E A T E R T H A N {expressionBuilder.addOperand(">");};

isGreaterThanOrEqualTo:I S G R E A T E R T H A N O R E Q U A L T O{expressionBuilder.addOperand(">=");};

isLessThan:I S L E S S T H A N {expressionBuilder.addOperand("<");};

isLessThanOrEqualTo:I S L E S S T H A N O R E Q U A L T O {expressionBuilder.addOperand("<=");};
//hasNoValue:H A S N O V A L U E {expressionBuilder.addOperand('>');};
//hasAnyValue:H A S A N Y V A L U E {expressionBuilder.addOperand('>');};
isNotEqualTo:I S N O T E Q U A L T O {expressionBuilder.addOperand("!=");};

isAfter: I S  A F T E R {expressionBuilder.addOperand(">");};

isAfterOrEqualTo:I S A F T E R O R E Q U A L T O {expressionBuilder.addOperand(">=");};

isBefore:I S B E F O R E {expressionBuilder.addOperand("<");};

isBeforeOrEqualTo:I S B E F O R E O R E Q U A L T O {expressionBuilder.addOperand("<=");};

trueVal:T R U E {expressionBuilder.addOperand("==1.0");};

falseVal:F A L S E {expressionBuilder.addOperand("==0.0");};

//is:I S {expressionBuilder.addOperand('equals');};

//isNot:I S N O T {expressionBuilder.addOperand('notEquals');};

//contains:C O N T A I N S {expressionBuilder.addOperand('contains');};

//doesNotContain:D O E S N O T C O N T A I N S {expressionBuilder.addOperand('!contains');};

//startsWith:S T A R T S W I T H {expressionBuilder.addOperand('startsWith');};

//doesNotStartWith:D O E S N O T S T A R T W I T H{expressionBuilder.addOperand('!startWith');};

//endsWith:E N D S W I T H{expressionBuilder.addOperand('endsWith');};

//doesNotEndWith:D O E S N O T E N D S W I T H{expressionBuilder.addOperand('!endsWith');};

//hasNoValue:H A S N O V A L U E{expressionBuilder.addOperand('==');};
//hasAnyValue:H A S A N Y V A L U E;


A: 'A'|'a' ;
B: 'B'|'b' ;
C: 'C'|'c' ;
D: 'D'|'d' ;
E: 'E'|'e' ;
F: 'F'|'f' ;
G: 'G'|'g' ;
H: 'H'|'h' ;
I: 'I'|'i' ;
J: 'J'|'j' ;
K: 'K'|'k' ;
L: 'L'|'l' ;
M: 'M'|'m' ;
N: 'N'|'n' ;
O: 'O'|'o' ;
P: 'P'|'p' ;
Q: 'Q'|'q' ;
R: 'R'|'r' ;
S: 'S'|'s' ;
T: 'T'|'t' ;
U: 'U'|'u' ;
V: 'V'|'v' ;
W: 'W'|'w' ;
X: 'X'|'x' ;
Y: 'Y'|'y' ;
Z: 'Z'|'z' ;

ADD : '+';
SUBSTRACT : '-';
MULTIPLY:'*';
DEVIDE :'/';

1 个答案:

答案 0 :(得分:0)

您确定ANTLR真的接受您的输入吗?默认情况下,ANTLR尝试从错误中恢复,并且可以“意外”执行该过程中的一些Java代码。见DefaultErrorStrategy。因此,执行代码并不是接受内容的可靠指标。

除了DefaultErrorStrategy陷阱之外,在我看来,识别[10]的直接方法如下:

ruleOperandExpression : ENCLOSUREOPEN fieldOperand ENCLOSURECLOSE {...your code...};

这不接受[10,如下面的解析树所示。

parse tree

您的规则还接受]10[]10][10[,而上述规则则不然。如果这些不寻常的模式也有效,我建议您提供一些有关您要解析的内容的详细信息。