1/*
2 * Copyright (C) 2009-2010 Julien BLACHE <jb@jblache.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19grammar RSP;
20
21options {
22	output = AST;
23	ASTLabelType = pANTLR3_BASE_TREE;
24	language = C;
25}
26
27query	:	expr NEWLINE? EOF		->	expr
28	;
29	
30expr	:	aexpr (OR^ aexpr)*
31	;
32
33aexpr	:	crit (AND^ crit)*
34	;
35
36crit	:	LPAR expr RPAR			->	expr
37	|	strcrit
38	|	intcrit
39	|	datecrit
40	;
41
42strcrit	:	FIELD strop STR			->	^(strop FIELD STR)
43	|	FIELD NOT strop STR		->	^(NOT ^(strop FIELD STR))
44	;
45
46strop	:	EQUAL
47	|	INCLUDES
48	|	STARTSW
49	|	ENDSW
50	;
51
52intcrit	:	FIELD intop INT			->	^(intop FIELD INT)
53	|	FIELD NOT intop INT		->	^(NOT ^(intop FIELD INT))
54	;
55
56intop	:	EQUAL
57	|	LESS
58	|	GREATER
59	|	LTE
60	|	GTE
61	;
62
63datecrit:	FIELD dateop datespec		->	^(dateop FIELD datespec)
64	;
65
66dateop	:	BEFORE
67	|	AFTER
68	;
69
70datespec:	dateref
71	|	INT dateintval dateop dateref	->	^(dateop dateref INT dateintval)
72	;
73
74dateref	:	DATE
75	|	TODAY
76	;
77
78dateintval
79	:	DAY
80	|	WEEK
81	|	MONTH
82	|	YEAR
83	;
84
85QUOTE	:	'"';
86LPAR	:	'(';
87RPAR	:	')';
88
89AND	:	'and';
90OR	:	'or';
91NOT	:	'!';
92
93/* Both string & int */
94EQUAL	:	'=';
95
96/* String */
97INCLUDES:	'includes';
98STARTSW	:	'startswith';
99ENDSW	:	'endswith';
100
101/* Int */
102GREATER	:	'>';
103LESS	:	'<';
104GTE	:	'>=';
105LTE	:	'<=';
106
107/* Date */
108BEFORE	:	'before';
109AFTER	:	'after';
110DAY	:	'day'	| 'days';
111WEEK	:	'week'	| 'weeks';
112MONTH	:	'month'	| 'months';
113YEAR	:	'year'	| 'years';
114TODAY	:	'today';
115
116NEWLINE	:	'\r'? '\n';
117
118WS	:	(' ' | '\t') { $channel = HIDDEN; };
119
120FIELD	:	'a'..'z' ('a'..'z' | '_')* 'a'..'z';
121
122INT	:	DIGIT19 DIGIT09*;
123
124/* YYYY-MM-DD */
125DATE	:	DIGIT19 DIGIT09 DIGIT09 DIGIT09 '-' ('0' DIGIT19 | '1' '0'..'2') '-' ('0' DIGIT19 | '1'..'2' DIGIT09 | '3' '0'..'1');
126
127/*
128Unescaping adapted from (ported to the C runtime)
129<http://stackoverflow.com/questions/504402/how-to-handle-escape-sequences-in-string-literals-in-antlr-3>
130*/
131STR
132@init{ pANTLR3_STRING unesc = GETTEXT()->factory->newRaw(GETTEXT()->factory); }
133	:	QUOTE ( reg = ~('\\' | '"') { unesc->addc(unesc, reg); }
134			| esc = ESCAPED { unesc->appendS(unesc, GETTEXT()); } )+ QUOTE { SETTEXT(unesc); }
135	;
136
137fragment
138ESCAPED	:	'\\'
139		( '\\' { SETTEXT(GETTEXT()->factory->newStr8(GETTEXT()->factory, (pANTLR3_UINT8)"\\")); }
140		| '"' { SETTEXT(GETTEXT()->factory->newStr8(GETTEXT()->factory, (pANTLR3_UINT8)"\"")); }
141		)
142	;
143
144fragment
145DIGIT09	:	'0'..'9';
146
147fragment
148DIGIT19	:	'1'..'9';
149