1/*
2[The "BSD licence"]
3Copyright (c) 2007-2008 Leon Jen-Yuan Su
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions
8are met:
9
10 1. Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15 3. The name of the author may not be used to endorse or promote products
16    derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30grammar StGUnit;
31
32options {language=Java;}
33
34tokens {
35	OK = 'OK';
36	FAIL = 'FAIL';
37	DOC_COMMENT;
38}
39
40@header {
41package org.antlr.gunit.swingui.parsers;
42import org.antlr.gunit.swingui.model.*;
43import org.antlr.gunit.swingui.runner.*;
44}
45
46@lexer::header {package org.antlr.gunit.swingui.parsers;}
47
48@members {
49public TestSuiteAdapter adapter ;;
50}
51
52gUnitDef
53	:	'gunit' name=id {adapter.setGrammarName($name.text);}
54	    ('walks' id)? ';'
55		header? suite*
56	;
57
58header
59	:	'@header' ACTION
60	;
61
62suite
63	:	(	parserRule=RULE_REF ('walks' RULE_REF)?
64	        {adapter.startRule($parserRule.text);}
65		|	lexerRule=TOKEN_REF
66			{adapter.startRule($lexerRule.text);}
67		)
68		':'
69		test+
70		{adapter.endRule();}
71	;
72
73test
74	:	input expect
75		{adapter.addTestCase($input.in, $expect.out);}
76	;
77
78expect returns [ITestCaseOutput out]
79	:	OK			{$out = adapter.createBoolOutput(true);}
80	|	FAIL		{$out = adapter.createBoolOutput(false);}
81	|	'returns' RETVAL {$out = adapter.createReturnOutput($RETVAL.text);}
82	|	'->' output {$out = adapter.createStdOutput($output.text);}
83	|	'->' AST	{$out = adapter.createAstOutput($AST.text);}
84	;
85
86input returns [ITestCaseInput in]
87	:	STRING 		{$in = adapter.createStringInput($STRING.text);}
88	|	ML_STRING	{$in = adapter.createMultiInput($ML_STRING.text);}
89	|	fileInput	{$in = adapter.createFileInput($fileInput.path);}
90	;
91
92output
93	:	STRING
94	|	ML_STRING
95	|	ACTION
96	;
97
98fileInput returns [String path]
99	:	id {$path = $id.text;} (EXT {$path += $EXT.text;})?
100	;
101
102id 	:	TOKEN_REF
103	|	RULE_REF
104	;
105
106// L E X I C A L   R U L E S
107
108SL_COMMENT
109 	:	'//' ~('\r'|'\n')* '\r'? '\n' {$channel=HIDDEN;}
110	;
111
112ML_COMMENT
113	:	'/*' {$channel=HIDDEN;} .* '*/'
114	;
115
116STRING
117	:	'"' ( ESC | ~('\\'|'"') )* '"'
118	;
119
120ML_STRING
121	:	'<<' .* '>>'
122	;
123
124TOKEN_REF
125	:	'A'..'Z' ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
126	;
127
128RULE_REF
129	:	'a'..'z' ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
130	;
131
132EXT	:	'.'('a'..'z'|'A'..'Z'|'0'..'9')+;
133
134RETVAL	:	NESTED_RETVAL
135	;
136
137fragment
138NESTED_RETVAL :
139	'['
140	(	options {greedy=false;}
141	:	NESTED_RETVAL
142	|	.
143	)*
144	']'
145	;
146
147AST	:	NESTED_AST (' '? NESTED_AST)*;
148
149fragment
150NESTED_AST :
151	'('
152	(	options {greedy=false;}
153	:	NESTED_AST
154	|	.
155	)*
156	')'
157	;
158
159ACTION
160	:	NESTED_ACTION
161	;
162
163fragment
164NESTED_ACTION :
165	'{'
166	(	options {greedy=false; k=3;}
167	:	NESTED_ACTION
168	|	STRING_LITERAL
169	|	CHAR_LITERAL
170	|	.
171	)*
172	'}'
173	;
174
175fragment
176CHAR_LITERAL
177	:	'\'' ( ESC | ~('\''|'\\') ) '\''
178	;
179
180fragment
181STRING_LITERAL
182	:	'"' ( ESC | ~('\\'|'"') )* '"'
183	;
184
185fragment
186ESC	:	'\\'
187		(	'n'
188		|	'r'
189		|	't'
190		|	'b'
191		|	'f'
192		|	'"'
193		|	'\''
194		|	'\\'
195		|	'>'
196		|	'u' XDIGIT XDIGIT XDIGIT XDIGIT
197		|	. // unknown, leave as it is
198		)
199	;
200
201fragment
202XDIGIT :
203		'0' .. '9'
204	|	'a' .. 'f'
205	|	'A' .. 'F'
206	;
207
208WS	:	(	' '
209		|	'\t'
210		|	'\r'? '\n'
211		)+
212		{$channel=HIDDEN;}
213	;
214