在《使用Antlr实现表达式引擎 》中写了主要的类,实现表达式的语法定义文件如下(使用的Antlr为3.0发布版本):
1
grammar XExpression;
2
3
options {
4
language=CSharp;
5
superClass=XExpressionBaseParser;
6
}
7
8
@header {
9
using XSoft.XExpression;
10
}
11
12
@members {
13
public XExpressionParser()
14
: base(null)
15
{
16
}
17
18
public override void Compile()
19
{
20
TokenStream = new CommonTokenStream(new XExpressionLexer(new ANTLRStringStream(Expression)));
21
ResultNode = xExpression();
22
}
23
}
24
25
xExpression returns[ExprNode value]
26
: a= logicalOrExpression {$value=a;};
27
28
logicalOrExpression returns[ExprNode value]
29
: a=logicalAndExpression {$value=a;}
30
(f=OR b=logicalAndExpression {GetNestedResultNode(ref $value, f, b);} )* ;
31
32
logicalAndExpression returns[ExprNode value]
33
: a=relationalExpression {$value=a;}
34
(f=AND b=relationalExpression {GetNestedResultNode(ref $value, f, b);} )* ;
35
36
relationalExpression returns[ExprNode value]
37
: a=additiveExpression {$value=a;}
38
((f=EQUAL | f=NOT_EQUAL | f=LESS_THAN | f=LESS_THAN_OR_EQUAL | f=GREATER_THAN | f=GREATER_THAN_OR_EQUAL) b=additiveExpression {GetNestedResultNode(ref $value, f, b);} )?
39
;
40
41
additiveExpression returns[ExprNode value]
42
: a=multiplyExpression {$value=a;}
43
((f=PLUS|f=MINUS) b=multiplyExpression {GetNestedResultNode(ref $value, f, b);} )*
44
;
45
46
47
multiplyExpression returns[ExprNode value]
48
: a=powExpr {$value=a;}
49
((f=STAR| f=DIV | f=MOD) b=powExpr {GetNestedResultNode(ref $value, f, b);} )* ;
50
51
powExpr returns[ExprNode value]
52
: a=unaryExpression {$value=a;}
53
(f=POWER b=unaryExpression {GetNestedResultNode(ref $value, f, b);} )? ;
54
55
unaryExpression returns[ExprNode value]
56
: (f=PLUS | f=MINUS | f=NOT) b=unaryExpression {GetNestedResultNodeArgsNotIncludeValue(ref $value, f, b);}
57
| a=primaryExpression {$value=a;}
58
;
59
60
primaryExpression returns[ExprNode value]
61
: (a=parenExpr|a=literal | a=function) {$value=a;};
62
63
parenExpr returns[ExprNode value]
64
: LPAREN a=xExpression RPAREN {$value=a;};
65
66
literal returns[ExprNode value]
67
: (a=numbericLiteral| a= stringLiteral | a=datetimeLiteral) {$value=a;};
68
69
function returns[ExprNode value]
70
@init { ArrayList list_arg = new ArrayList(); }
71
: f=IDENTIFIER LPAREN (arg=argument {list_arg.Add(arg);} (COMMA arg=argument { list_arg.Add(arg); } )*)? RPAREN
72
{ $value = GetNestedResultNode(f, list_arg); }
73
;
74
75
argument returns[ExprNode value]
76
: a=xExpression {$value=a;};
77
78
numbericLiteral returns[ExprNode value]
79
: a=INTEGER_LITERAL {$value = new ConstNode(new IntegerExprData(Convert.ToInt32(a.Text)));}
80
| a=DECIMAL_LITERAL {$value = new ConstNode(new DecimalExprData(Convert.ToDecimal(Convert.ToDouble(a.Text)))); }
81
;
82
83
datetimeLiteral returns[ExprNode value]
84
: a=DATETIME_LITERAL
85
{$value = new ConstNode(new DateTimeExprData(DateTime.Parse(a.Text.Substring(1, a.Text.Length - 2))));}
86
87
;
88
89
stringLiteral returns[ExprNode value]
90
: a=STRING_LITERAL
91
{$value = new ConstNode(new StringExprData(a.Text.Substring(1, a.Text.Length - 2)));}
92
;
93
94
AND: 'and';
95
OR: 'or';
96
97
NOT: 'not';
98
99
COMMA : ',' ;
100
101
PLUS: '+' ;
102
MINUS: '-' ;
103
DIV: '/' ;
104
STAR: '*' ;
105
MOD: '%' ;
106
POWER: '^' ;
107
108
EQUAL: '=';
109
NOT_EQUAL: '<>' ;
110
LESS_THAN: '<' ;
111
LESS_THAN_OR_EQUAL: '<=' ;
112
GREATER_THAN: '>' ;
113
GREATER_THAN_OR_EQUAL: '>=' ;
114
115
LPAREN: '(';
116
RPAREN: ')';
117
118
DATETIME_LITERAL: '\'' Digit Digit Digit Digit '-' Digit (Digit)? '-' Digit (Digit)? '\'';
119
120
STRING_LITERAL : '"'(~'"')* '"' ;
121
122
IDENTIFIER: LETTER (LETTER|Digit)* ;
123
124
fragment
125
LETTER : 'A'..'Z'|'a'..'z'|'_';
126
127
DECIMAL_LITERAL: (INTEGER_LITERAL)? '.' Digit* Exponent? ;
128
fragment
129
Exponent : ('e'|'E') INTEGER_LITERAL;
130
131
INTEGER_LITERAL : Digit+ ;
132
133
fragment
134
Digit :'0'..'9';
135
136
fragment
137
SIGN : '+' | '-';
138
139
WS : (' '|'\t')+ { $channel=HIDDEN; } ;
140
grammar XExpression;2

3
options {4
language=CSharp;5
superClass=XExpressionBaseParser;6
}7

8
@header {9
using XSoft.XExpression;10
}11

12
@members {13
public XExpressionParser()14
: base(null)15
{16
}17
18
public override void Compile()19
{20
TokenStream = new CommonTokenStream(new XExpressionLexer(new ANTLRStringStream(Expression))); 21
ResultNode = xExpression();22
}23
}24

25
xExpression returns[ExprNode value]26
: a= logicalOrExpression {$value=a;};27

28
logicalOrExpression returns[ExprNode value]29
: a=logicalAndExpression {$value=a;}30
(f=OR b=logicalAndExpression {GetNestedResultNode(ref $value, f, b);} )* ;31
32
logicalAndExpression returns[ExprNode value]33
: a=relationalExpression {$value=a;}34
(f=AND b=relationalExpression {GetNestedResultNode(ref $value, f, b);} )* ; 35

36
relationalExpression returns[ExprNode value]37
: a=additiveExpression {$value=a;}38
((f=EQUAL | f=NOT_EQUAL | f=LESS_THAN | f=LESS_THAN_OR_EQUAL | f=GREATER_THAN | f=GREATER_THAN_OR_EQUAL) b=additiveExpression {GetNestedResultNode(ref $value, f, b);} )?39
;40
41
additiveExpression returns[ExprNode value]42
: a=multiplyExpression {$value=a;}43
((f=PLUS|f=MINUS) b=multiplyExpression {GetNestedResultNode(ref $value, f, b);} )* 44
;45

46

47
multiplyExpression returns[ExprNode value]48
: a=powExpr {$value=a;}49
((f=STAR| f=DIV | f=MOD) b=powExpr {GetNestedResultNode(ref $value, f, b);} )* ;50
51
powExpr returns[ExprNode value]52
: a=unaryExpression {$value=a;}53
(f=POWER b=unaryExpression {GetNestedResultNode(ref $value, f, b);} )? ; 54

55
unaryExpression returns[ExprNode value]56
: (f=PLUS | f=MINUS | f=NOT) b=unaryExpression {GetNestedResultNodeArgsNotIncludeValue(ref $value, f, b);} 57
| a=primaryExpression {$value=a;}58
;59
60
primaryExpression returns[ExprNode value]61
: (a=parenExpr|a=literal | a=function) {$value=a;};62

63
parenExpr returns[ExprNode value]64
: LPAREN a=xExpression RPAREN {$value=a;}; 65
66
literal returns[ExprNode value]67
: (a=numbericLiteral| a= stringLiteral | a=datetimeLiteral) {$value=a;}; 68

69
function returns[ExprNode value]70
@init { ArrayList list_arg = new ArrayList(); }71
: f=IDENTIFIER LPAREN (arg=argument {list_arg.Add(arg);} (COMMA arg=argument { list_arg.Add(arg); } )*)? RPAREN72
{ $value = GetNestedResultNode(f, list_arg); }73
;74

75
argument returns[ExprNode value]76
: a=xExpression {$value=a;}; 77

78
numbericLiteral returns[ExprNode value]79
: a=INTEGER_LITERAL {$value = new ConstNode(new IntegerExprData(Convert.ToInt32(a.Text)));} 80
| a=DECIMAL_LITERAL {$value = new ConstNode(new DecimalExprData(Convert.ToDecimal(Convert.ToDouble(a.Text)))); }81
;82
83
datetimeLiteral returns[ExprNode value]84
: a=DATETIME_LITERAL 85
{$value = new ConstNode(new DateTimeExprData(DateTime.Parse(a.Text.Substring(1, a.Text.Length - 2))));} 86
87
;88
89
stringLiteral returns[ExprNode value]90
: a=STRING_LITERAL 91
{$value = new ConstNode(new StringExprData(a.Text.Substring(1, a.Text.Length - 2)));} 92
;93
94
AND: 'and';95
OR: 'or';96

97
NOT: 'not';98

99
COMMA : ',' ;100

101
PLUS: '+' ;102
MINUS: '-' ;103
DIV: '/' ;104
STAR: '*' ;105
MOD: '%' ;106
POWER: '^' ;107

108
EQUAL: '=';109
NOT_EQUAL: '<>' ;110
LESS_THAN: '<' ;111
LESS_THAN_OR_EQUAL: '<=' ;112
GREATER_THAN: '>' ;113
GREATER_THAN_OR_EQUAL: '>=' ;114

115
LPAREN: '(';116
RPAREN: ')';117

118
DATETIME_LITERAL: '\'' Digit Digit Digit Digit '-' Digit (Digit)? '-' Digit (Digit)? '\'';119

120
STRING_LITERAL : '"'(~'"')* '"' ;121

122
IDENTIFIER: LETTER (LETTER|Digit)* ;123
124
fragment125
LETTER : 'A'..'Z'|'a'..'z'|'_';126

127
DECIMAL_LITERAL: (INTEGER_LITERAL)? '.' Digit* Exponent? ; 128
fragment129
Exponent : ('e'|'E') INTEGER_LITERAL;130

131
INTEGER_LITERAL : Digit+ ; 132

133
fragment134
Digit :'0'..'9';135

136
fragment137
SIGN : '+' | '-';138

139
WS : (' '|'\t')+ { $channel=HIDDEN; } ;140
