-
Notifications
You must be signed in to change notification settings - Fork 2
/
rcp019.g4
220 lines (184 loc) · 4 KB
/
rcp019.g4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
MIT License https://github.com/darnjo/rcp019/blob/master/LICENSE
Copyright (c) 2018 Joshua Darnell (josh@kurotek.com)
NOTE: this file is written with the intent of preserving the structure of the original RETS 1.9 VE grammar
so that anyone who has implemented their systems using it shouldn't have to make any changes unless they
are wanting to support the new features. In other words, all changes made to this grammar so far have been additive.
There are more optimal representations of this file that will accept the RESO RCP-019 grammar, and as long as your
parser supports an equivalent set of symbols and expressions, then the internals of your system are for you to decide.
This example grammar should already perform reasonably well in most situations.
*/
grammar rcp019;
exp
: orExp
| collectionExp
| funcExp
;
orExp
: andExp (OR andExp)*
;
andExp
: notExp (AND notExp)*
;
notExp
: NOT notExp
| eqExp
;
eqExp
: cmpExp
| cmpExp (NE | EQ) cmpExp
;
cmpExp
: cntExp
| cntExp (LTE | GTE | LT | GT) cntExp
;
cntExp
: sumExp
| sumExp (CONTAINS | IN) sumExp
;
sumExp
: prodExp ((PLUS | MINUS | CONCAT) prodExp)*
;
prodExp
: atomExp ((ASTERISK | SLASH | MOD) atomExp)*
;
// NOTE: original VE writing had that all lists of size 1 were atomExp, not list.
// LIST() and SET() were created instead as a top-level item called 'collection' and should be used instead.
atomExp
: LPAREN exp RPAREN
| list
| value
;
// this was left in for backwards compatibility with the first production rule, LPAREN exp RPAREN
list
: LPAREN (exp (COMMA exp)*)? RPAREN
;
// this was previously an atomExp, but was moved to the top-level for faster parsing (10x speedup)
funcExp
: func LPAREN (param (COMMA param)*)? RPAREN
;
collectionExp
: (LIST | SET) LPAREN (exp (COMMA exp)*)? RPAREN
| (UNION | INTERSECTION | DIFFERENCE) LPAREN (collectionExp COMMA collectionExp (COMMA collectionExp)*)? RPAREN
;
// SPECFUNC was added. LOCALFUNC could be added as well, with corresponding known local functions
func
: SPECFUNC
| ALPHANUM
;
param
: exp
;
value
: fieldName
| specValue
| charValue
| intValue
| floatValue
| timeValue
;
fieldName
: (LAST)? RETSNAME
| LBRACKET (LAST)? RETSNAME RBRACKET
;
specValue : DOT RETSNAME DOT;
charValue : QUOTED_TERM;
timeValue : HASH RETSDATETIME HASH;
intValue : (PLUS | MINUS)? DIGIT+ ;
floatValue : intValue DOT DIGIT+;
// Tokens - may be moved to lexer file
CONCAT : PIPE;
LPAREN : '(' ;
RPAREN : ')' ;
SQUOTE : '\'' ;
QUOTE : '"' ;
DOT : '.' ;
ASTERISK : '*';
SLASH : '/';
EXCLAMATION : '!';
OR : '.OR.';
AND : '.AND.';
NOT : '.NOT.';
EQ : '=';
NE : EXCLAMATION EQ;
LT : '<';
LTE : LT EQ;
GT : '>';
GTE : GT EQ;
CONTAINS : '.CONTAINS.';
IN : '.IN.';
COMMA: ',';
PLUS: '+';
MINUS: '-';
MOD: '.MOD.';
PIPE: '|';
LBRACKET: '[';
RBRACKET: ']';
HASH: '#';
IIF: 'IIF';
LAST: 'LAST';
LIST: 'LIST';
SET: 'SET';
DIFFERENCE: 'DIFFERENCE';
INTERSECTION: 'INTERSECTION';
UNION: 'UNION';
TRUE: 'TRUE';
FALSE: 'FALSE';
EMPTY: 'EMPTY';
TODAY: 'TODAY';
NOW: 'NOW';
ENTRY: 'ENTRY';
OLDVALUE: 'OLDVALUE';
USERID: 'USERID';
USERCLASS: 'USERCLASS';
USERLEVEL: 'USERLEVEL';
AGENTCODE: 'AGENTCODE';
BROKERCODE: 'BROKERCODE';
BROKERBRANCH: 'BROKERBRANCH';
UPDATEACTION: 'UPDATEACTION';
ANY: 'any';
// special tokens
RETSNAME
: DICTNAME
| SPECOP
;
// TODO: dynamically fill in your dictnames here
DICTNAME
: 'ListPrice'
| 'Status'
| 'CloseDate'
| 'Bedrooms'
| 'Bathrooms'
;
SPECFUNC
: IIF
;
SPECOP
: EMPTY
| TRUE
| FALSE
| TODAY
| NOW
| ENTRY
| OLDVALUE
| USERID
| USERCLASS
| USERLEVEL
| AGENTCODE
| BROKERCODE
| BROKERBRANCH
| UPDATEACTION
| ANY
;
RETSDATETIME: '##TODO##';
ALPHA: ('a'..'z' | 'A'..'Z');
DIGIT: ('0'..'9');
ALPHANUM: ALPHA (ALPHA|DIGIT)*;
QUOTED_TERM
: QUOTE (~[\\"])*? QUOTE
| SQUOTE (~[\\'])*? SQUOTE
;
//added support for c++ style comments
SLASH_STAR_COMMENT : '/*' .+? '*/' -> skip ;
SLASH_SLASH_COMMENT : '//' .+? ('\n'|EOF) -> skip ;
WS : [ \t\n\r]+ -> skip ;