antlr3 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ANTLR-LICENSE.txt +26 -0
- data/History.txt +66 -0
- data/README.txt +139 -0
- data/bin/antlr4ruby +33 -0
- data/java/RubyTarget.java +524 -0
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3.rb +176 -0
- data/lib/antlr3/constants.rb +88 -0
- data/lib/antlr3/debug.rb +701 -0
- data/lib/antlr3/debug/event-hub.rb +210 -0
- data/lib/antlr3/debug/record-event-listener.rb +25 -0
- data/lib/antlr3/debug/rule-tracer.rb +55 -0
- data/lib/antlr3/debug/socket.rb +360 -0
- data/lib/antlr3/debug/trace-event-listener.rb +92 -0
- data/lib/antlr3/dfa.rb +247 -0
- data/lib/antlr3/dot.rb +174 -0
- data/lib/antlr3/error.rb +657 -0
- data/lib/antlr3/main.rb +561 -0
- data/lib/antlr3/modes/ast-builder.rb +41 -0
- data/lib/antlr3/modes/filter.rb +56 -0
- data/lib/antlr3/profile.rb +322 -0
- data/lib/antlr3/recognizers.rb +1280 -0
- data/lib/antlr3/streams.rb +985 -0
- data/lib/antlr3/streams/interactive.rb +91 -0
- data/lib/antlr3/streams/rewrite.rb +412 -0
- data/lib/antlr3/test/call-stack.rb +57 -0
- data/lib/antlr3/test/config.rb +23 -0
- data/lib/antlr3/test/core-extensions.rb +269 -0
- data/lib/antlr3/test/diff.rb +165 -0
- data/lib/antlr3/test/functional.rb +207 -0
- data/lib/antlr3/test/grammar.rb +371 -0
- data/lib/antlr3/token.rb +592 -0
- data/lib/antlr3/tree.rb +1415 -0
- data/lib/antlr3/tree/debug.rb +163 -0
- data/lib/antlr3/tree/visitor.rb +84 -0
- data/lib/antlr3/tree/wizard.rb +481 -0
- data/lib/antlr3/util.rb +149 -0
- data/lib/antlr3/version.rb +27 -0
- data/samples/ANTLRv3Grammar.g +621 -0
- data/samples/Cpp.g +749 -0
- data/templates/AST.stg +335 -0
- data/templates/ASTDbg.stg +40 -0
- data/templates/ASTParser.stg +153 -0
- data/templates/ASTTreeParser.stg +272 -0
- data/templates/Dbg.stg +192 -0
- data/templates/Ruby.stg +1514 -0
- data/test/functional/ast-output/auto-ast.rb +797 -0
- data/test/functional/ast-output/construction.rb +555 -0
- data/test/functional/ast-output/hetero-nodes.rb +753 -0
- data/test/functional/ast-output/rewrites.rb +1327 -0
- data/test/functional/ast-output/tree-rewrite.rb +1662 -0
- data/test/functional/debugging/debug-mode.rb +689 -0
- data/test/functional/debugging/profile-mode.rb +165 -0
- data/test/functional/debugging/rule-tracing.rb +74 -0
- data/test/functional/delegation/import.rb +379 -0
- data/test/functional/lexer/basic.rb +559 -0
- data/test/functional/lexer/filter-mode.rb +245 -0
- data/test/functional/lexer/nuances.rb +47 -0
- data/test/functional/lexer/properties.rb +104 -0
- data/test/functional/lexer/syn-pred.rb +32 -0
- data/test/functional/lexer/xml.rb +206 -0
- data/test/functional/main/main-scripts.rb +245 -0
- data/test/functional/parser/actions.rb +224 -0
- data/test/functional/parser/backtracking.rb +244 -0
- data/test/functional/parser/basic.rb +282 -0
- data/test/functional/parser/calc.rb +98 -0
- data/test/functional/parser/ll-star.rb +143 -0
- data/test/functional/parser/nuances.rb +165 -0
- data/test/functional/parser/predicates.rb +103 -0
- data/test/functional/parser/properties.rb +242 -0
- data/test/functional/parser/rule-methods.rb +132 -0
- data/test/functional/parser/scopes.rb +274 -0
- data/test/functional/token-rewrite/basic.rb +318 -0
- data/test/functional/token-rewrite/via-parser.rb +100 -0
- data/test/functional/tree-parser/basic.rb +750 -0
- data/test/unit/sample-input/file-stream-1 +2 -0
- data/test/unit/sample-input/teststreams.input2 +2 -0
- data/test/unit/test-dfa.rb +52 -0
- data/test/unit/test-exceptions.rb +44 -0
- data/test/unit/test-recognizers.rb +55 -0
- data/test/unit/test-scheme.rb +62 -0
- data/test/unit/test-streams.rb +459 -0
- data/test/unit/test-tree-wizard.rb +535 -0
- data/test/unit/test-trees.rb +854 -0
- metadata +205 -0
@@ -0,0 +1,1327 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'antlr3/test/functional'
|
5
|
+
|
6
|
+
class TestASTViaRewriteRules < ANTLR3::Test::Functional
|
7
|
+
|
8
|
+
def parse(grammar, rule, input, expect_errors = false)
|
9
|
+
@grammar = inline_grammar(grammar)
|
10
|
+
compile_and_load @grammar
|
11
|
+
grammar_module = self.class.const_get(@grammar.name)
|
12
|
+
|
13
|
+
grammar_module::Lexer.send(:include, ANTLR3::Test::CollectErrors)
|
14
|
+
grammar_module::Lexer.send(:include, ANTLR3::Test::CaptureOutput)
|
15
|
+
grammar_module::Parser.send(:include, ANTLR3::Test::CollectErrors)
|
16
|
+
grammar_module::Parser.send(:include, ANTLR3::Test::CaptureOutput)
|
17
|
+
|
18
|
+
lexer = grammar_module::Lexer.new( input )
|
19
|
+
parser = grammar_module::Parser.new( lexer )
|
20
|
+
|
21
|
+
r = parser.send(rule)
|
22
|
+
parser.reported_errors.should be_empty unless expect_errors
|
23
|
+
result = ''
|
24
|
+
|
25
|
+
unless r.nil?
|
26
|
+
result += r.result if r.respond_to?(:result)
|
27
|
+
result += r.tree.inspect if r.tree
|
28
|
+
end
|
29
|
+
return(expect_errors ? [result, parser.reported_errors] : result)
|
30
|
+
end
|
31
|
+
|
32
|
+
def tree_parse(grammar, tree_grammar, rule, tree_rule, input)
|
33
|
+
@grammar = inline_grammar(grammar)
|
34
|
+
@tree_grammar = inline_grammar(tree_grammar)
|
35
|
+
compile_and_load @grammar
|
36
|
+
compile_and_load @tree_grammar
|
37
|
+
|
38
|
+
grammar_module = self.class.const_get(@grammar.name)
|
39
|
+
tree_grammar_module = self.class.const_get(@tree_grammar.name)
|
40
|
+
|
41
|
+
grammar_module::Lexer.send(:include, ANTLR3::Test::CollectErrors)
|
42
|
+
grammar_module::Lexer.send(:include, ANTLR3::Test::CaptureOutput)
|
43
|
+
grammar_module::Parser.send(:include, ANTLR3::Test::CollectErrors)
|
44
|
+
grammar_module::Parser.send(:include, ANTLR3::Test::CaptureOutput)
|
45
|
+
tree_grammar_module::TreeParser.send(:include, ANTLR3::Test::CollectErrors)
|
46
|
+
tree_grammar_module::TreeParser.send(:include, ANTLR3::Test::CaptureOutput)
|
47
|
+
|
48
|
+
lexer = grammar_module::Lexer.new( input )
|
49
|
+
parser = grammar.module::Parser.new( lexer )
|
50
|
+
r = parser.send(rule)
|
51
|
+
nodes = ANTLR3::CommonTreeNodeStream( r.tree )
|
52
|
+
nodes.token_stream = parser.input
|
53
|
+
walker = tree_grammar_module::TreeParser.new( nodes )
|
54
|
+
r = walker.send(tree_rule)
|
55
|
+
|
56
|
+
return(r ? r.tree.inspect : '')
|
57
|
+
end
|
58
|
+
|
59
|
+
example "delete" do
|
60
|
+
result = parse(<<-'END', :a, 'abc 34')
|
61
|
+
grammar Delete;
|
62
|
+
options {language=Ruby;output=AST;}
|
63
|
+
a : ID INT -> ;
|
64
|
+
ID : 'a'..'z'+ ;
|
65
|
+
INT : '0'..'9'+;
|
66
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
67
|
+
END
|
68
|
+
result.should == ''
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
example "single token" do
|
73
|
+
result = parse(<<-'END', :a, 'abc')
|
74
|
+
grammar SingleToken;
|
75
|
+
options {language=Ruby;output=AST;}
|
76
|
+
a : ID -> ID;
|
77
|
+
ID : 'a'..'z'+ ;
|
78
|
+
INT : '0'..'9'+;
|
79
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
80
|
+
|
81
|
+
END
|
82
|
+
result.should == 'abc'
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
example "single token to new node" do
|
87
|
+
result = parse(<<-'END', :a, 'abc')
|
88
|
+
grammar SingleTokenToNewNode;
|
89
|
+
options {language=Ruby;output=AST;}
|
90
|
+
a : ID -> ID["x"];
|
91
|
+
ID : 'a'..'z'+ ;
|
92
|
+
INT : '0'..'9'+;
|
93
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
94
|
+
|
95
|
+
END
|
96
|
+
result.should == 'x'
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
example "single token to new node root" do
|
101
|
+
result = parse(<<-'END', :a, 'abc')
|
102
|
+
grammar SingleTokenToNewNodeRoot;
|
103
|
+
options {language=Ruby;output=AST;}
|
104
|
+
a : ID -> ^(ID["x"] INT);
|
105
|
+
ID : 'a'..'z'+ ;
|
106
|
+
INT : '0'..'9'+;
|
107
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
108
|
+
|
109
|
+
END
|
110
|
+
result.should == '(x INT)'
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
example "single token to new node2" do
|
115
|
+
result = parse(<<-'END', :a, 'abc')
|
116
|
+
grammar SingleTokenToNewNode2;
|
117
|
+
options {language=Ruby;output=AST;}
|
118
|
+
a : ID -> ID[ ];
|
119
|
+
ID : 'a'..'z'+ ;
|
120
|
+
INT : '0'..'9'+;
|
121
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
122
|
+
END
|
123
|
+
result.should == 'ID'
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
example "single char literal" do
|
128
|
+
result = parse(<<-'END', :a, 'c')
|
129
|
+
grammar SingleCharLiteral;
|
130
|
+
options {language=Ruby;output=AST;}
|
131
|
+
a : 'c' -> 'c';
|
132
|
+
ID : 'a'..'z'+ ;
|
133
|
+
INT : '0'..'9'+;
|
134
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
135
|
+
|
136
|
+
END
|
137
|
+
result.should == 'c'
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
example "single string literal" do
|
142
|
+
result = parse(<<-'END', :a, 'ick')
|
143
|
+
grammar SingleStringLiteral;
|
144
|
+
options {language=Ruby;output=AST;}
|
145
|
+
a : 'ick' -> 'ick';
|
146
|
+
ID : 'a'..'z'+ ;
|
147
|
+
INT : '0'..'9'+;
|
148
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
149
|
+
|
150
|
+
END
|
151
|
+
result.should == 'ick'
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
example "single rule" do
|
156
|
+
result = parse(<<-'END', :a, 'abc')
|
157
|
+
grammar SingleRule;
|
158
|
+
options {language=Ruby;output=AST;}
|
159
|
+
a : b -> b;
|
160
|
+
b : ID ;
|
161
|
+
ID : 'a'..'z'+ ;
|
162
|
+
INT : '0'..'9'+;
|
163
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
164
|
+
|
165
|
+
END
|
166
|
+
result.should == 'abc'
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
example "reorder tokens" do
|
171
|
+
result = parse(<<-'END', :a, 'abc 34')
|
172
|
+
grammar ReorderTokens;
|
173
|
+
options {language=Ruby;output=AST;}
|
174
|
+
a : ID INT -> INT ID;
|
175
|
+
ID : 'a'..'z'+ ;
|
176
|
+
INT : '0'..'9'+;
|
177
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
178
|
+
|
179
|
+
END
|
180
|
+
result.should == '34 abc'
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
example "reorder token and rule" do
|
185
|
+
result = parse(<<-'END', :a, 'abc 34')
|
186
|
+
grammar ReorderTokenAndRule;
|
187
|
+
options {language=Ruby;output=AST;}
|
188
|
+
a : b INT -> INT b;
|
189
|
+
b : ID ;
|
190
|
+
ID : 'a'..'z'+ ;
|
191
|
+
INT : '0'..'9'+;
|
192
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
193
|
+
|
194
|
+
END
|
195
|
+
result.should == '34 abc'
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
example "token tree" do
|
200
|
+
result = parse(<<-'END', :a, 'abc 34')
|
201
|
+
grammar TokenTree;
|
202
|
+
options {language=Ruby;output=AST;}
|
203
|
+
a : ID INT -> ^(INT ID);
|
204
|
+
ID : 'a'..'z'+ ;
|
205
|
+
INT : '0'..'9'+;
|
206
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
207
|
+
|
208
|
+
END
|
209
|
+
result.should == '(34 abc)'
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
example "token tree after other stuff" do
|
214
|
+
result = parse(<<-'END', :a, 'void abc 34')
|
215
|
+
grammar TokenTreeAfterOtherStuff;
|
216
|
+
options {language=Ruby;output=AST;}
|
217
|
+
a : 'void' ID INT -> 'void' ^(INT ID);
|
218
|
+
ID : 'a'..'z'+ ;
|
219
|
+
INT : '0'..'9'+;
|
220
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
221
|
+
|
222
|
+
END
|
223
|
+
result.should == 'void (34 abc)'
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
example "nested token tree with outer loop" do
|
228
|
+
result = parse(<<-'END', :a, 'a 1 b 2')
|
229
|
+
grammar NestedTokenTreeWithOuterLoop;
|
230
|
+
options {language=Ruby;output=AST;}
|
231
|
+
tokens {DUH;}
|
232
|
+
a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ;
|
233
|
+
ID : 'a'..'z'+ ;
|
234
|
+
INT : '0'..'9'+;
|
235
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
236
|
+
|
237
|
+
END
|
238
|
+
result.should == '(DUH a (DUH 1)) (DUH b (DUH 2))'
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
example "optional single token" do
|
243
|
+
result = parse(<<-'END', :a, 'abc')
|
244
|
+
grammar OptionalSingleToken;
|
245
|
+
options {language=Ruby;output=AST;}
|
246
|
+
a : ID -> ID? ;
|
247
|
+
ID : 'a'..'z'+ ;
|
248
|
+
INT : '0'..'9'+;
|
249
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
250
|
+
|
251
|
+
END
|
252
|
+
result.should == 'abc'
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
example "closure single token" do
|
257
|
+
result = parse(<<-'END', :a, 'a b')
|
258
|
+
grammar ClosureSingleToken;
|
259
|
+
options {language=Ruby;output=AST;}
|
260
|
+
a : ID ID -> ID* ;
|
261
|
+
ID : 'a'..'z'+ ;
|
262
|
+
INT : '0'..'9'+;
|
263
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
264
|
+
|
265
|
+
END
|
266
|
+
result.should == 'a b'
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
example "positive closure single token" do
|
271
|
+
result = parse(<<-'END', :a, 'a b')
|
272
|
+
grammar PositiveClosureSingleToken;
|
273
|
+
options {language=Ruby;output=AST;}
|
274
|
+
a : ID ID -> ID+ ;
|
275
|
+
ID : 'a'..'z'+ ;
|
276
|
+
INT : '0'..'9'+;
|
277
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
278
|
+
|
279
|
+
END
|
280
|
+
result.should == 'a b'
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
example "optional single rule" do
|
285
|
+
result = parse(<<-'END', :a, 'abc')
|
286
|
+
grammar OptionalSingleRule;
|
287
|
+
options {language=Ruby;output=AST;}
|
288
|
+
a : b -> b?;
|
289
|
+
b : ID ;
|
290
|
+
ID : 'a'..'z'+ ;
|
291
|
+
INT : '0'..'9'+;
|
292
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
293
|
+
|
294
|
+
END
|
295
|
+
result.should == 'abc'
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
example "closure single rule" do
|
300
|
+
result = parse(<<-'END', :a, 'a b')
|
301
|
+
grammar ClosureSingleRule;
|
302
|
+
options {language=Ruby;output=AST;}
|
303
|
+
a : b b -> b*;
|
304
|
+
b : ID ;
|
305
|
+
ID : 'a'..'z'+ ;
|
306
|
+
INT : '0'..'9'+;
|
307
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
308
|
+
|
309
|
+
END
|
310
|
+
result.should == 'a b'
|
311
|
+
end
|
312
|
+
|
313
|
+
|
314
|
+
example "closure of label" do
|
315
|
+
result = parse(<<-'END', :a, 'a b')
|
316
|
+
grammar ClosureOfLabel;
|
317
|
+
options {language=Ruby;output=AST;}
|
318
|
+
a : x+=b x+=b -> $x*;
|
319
|
+
b : ID ;
|
320
|
+
ID : 'a'..'z'+ ;
|
321
|
+
INT : '0'..'9'+;
|
322
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
323
|
+
|
324
|
+
END
|
325
|
+
result.should == 'a b'
|
326
|
+
end
|
327
|
+
|
328
|
+
|
329
|
+
example "optional label no list label" do
|
330
|
+
result = parse(<<-'END', :a, 'a')
|
331
|
+
grammar OptionalLabelNoListLabel;
|
332
|
+
options {language=Ruby;output=AST;}
|
333
|
+
a : (x=ID)? -> $x?;
|
334
|
+
ID : 'a'..'z'+ ;
|
335
|
+
INT : '0'..'9'+;
|
336
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
337
|
+
|
338
|
+
END
|
339
|
+
result.should == 'a'
|
340
|
+
end
|
341
|
+
|
342
|
+
|
343
|
+
example "positive closure single rule" do
|
344
|
+
result = parse(<<-'END', :a, 'a b')
|
345
|
+
grammar PositiveClosureSingleRule;
|
346
|
+
options {language=Ruby;output=AST;}
|
347
|
+
a : b b -> b+;
|
348
|
+
b : ID ;
|
349
|
+
ID : 'a'..'z'+ ;
|
350
|
+
INT : '0'..'9'+;
|
351
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
352
|
+
|
353
|
+
END
|
354
|
+
result.should == 'a b'
|
355
|
+
end
|
356
|
+
|
357
|
+
|
358
|
+
example "single predicate t" do
|
359
|
+
result = parse(<<-'END', :a, 'abc')
|
360
|
+
grammar SinglePredicateT;
|
361
|
+
options {language=Ruby;output=AST;}
|
362
|
+
a : ID -> {true}? ID -> ;
|
363
|
+
ID : 'a'..'z'+ ;
|
364
|
+
INT : '0'..'9'+;
|
365
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
366
|
+
|
367
|
+
END
|
368
|
+
result.should == 'abc'
|
369
|
+
end
|
370
|
+
|
371
|
+
|
372
|
+
example "single predicate f" do
|
373
|
+
result = parse(<<-'END', :a, 'abc')
|
374
|
+
grammar SinglePredicateF;
|
375
|
+
options {language=Ruby;output=AST;}
|
376
|
+
a : ID -> {false}? ID -> ;
|
377
|
+
ID : 'a'..'z'+ ;
|
378
|
+
INT : '0'..'9'+;
|
379
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
380
|
+
|
381
|
+
END
|
382
|
+
result.should == ''
|
383
|
+
end
|
384
|
+
|
385
|
+
|
386
|
+
example "multiple predicate" do
|
387
|
+
result = parse(<<-'END', :a, 'a 2')
|
388
|
+
grammar MultiplePredicate;
|
389
|
+
options {language=Ruby;output=AST;}
|
390
|
+
a : ID INT -> {false}? ID
|
391
|
+
-> {true}? INT
|
392
|
+
->
|
393
|
+
;
|
394
|
+
ID : 'a'..'z'+ ;
|
395
|
+
INT : '0'..'9'+;
|
396
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
397
|
+
|
398
|
+
END
|
399
|
+
result.should == '2'
|
400
|
+
end
|
401
|
+
|
402
|
+
|
403
|
+
example "multiple predicate trees" do
|
404
|
+
result = parse(<<-'END', :a, 'a 2')
|
405
|
+
grammar MultiplePredicateTrees;
|
406
|
+
options {language=Ruby;output=AST;}
|
407
|
+
a : ID INT -> {false}? ^(ID INT)
|
408
|
+
-> {true}? ^(INT ID)
|
409
|
+
-> ID
|
410
|
+
;
|
411
|
+
ID : 'a'..'z'+ ;
|
412
|
+
INT : '0'..'9'+;
|
413
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
414
|
+
|
415
|
+
END
|
416
|
+
result.should == '(2 a)'
|
417
|
+
end
|
418
|
+
|
419
|
+
|
420
|
+
example "simple tree" do
|
421
|
+
result = parse(<<-'END', :a, '-34')
|
422
|
+
grammar SimpleTree;
|
423
|
+
options {language=Ruby;output=AST;}
|
424
|
+
a : op INT -> ^(op INT);
|
425
|
+
op : '+'|'-' ;
|
426
|
+
ID : 'a'..'z'+ ;
|
427
|
+
INT : '0'..'9'+;
|
428
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
429
|
+
|
430
|
+
END
|
431
|
+
result.should == '(- 34)'
|
432
|
+
end
|
433
|
+
|
434
|
+
|
435
|
+
example "simple tree2" do
|
436
|
+
result = parse(<<-'END', :a, '+ 34')
|
437
|
+
grammar SimpleTree2;
|
438
|
+
options {language=Ruby;output=AST;}
|
439
|
+
a : op INT -> ^(INT op);
|
440
|
+
op : '+'|'-' ;
|
441
|
+
ID : 'a'..'z'+ ;
|
442
|
+
INT : '0'..'9'+;
|
443
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
444
|
+
|
445
|
+
END
|
446
|
+
result.should == '(34 +)'
|
447
|
+
end
|
448
|
+
|
449
|
+
|
450
|
+
example "nested trees" do
|
451
|
+
result = parse(<<-'END', :a, 'var a:int; b:float;')
|
452
|
+
grammar NestedTrees;
|
453
|
+
options {language=Ruby;output=AST;}
|
454
|
+
a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ;
|
455
|
+
type : 'int' | 'float' ;
|
456
|
+
ID : 'a'..'z'+ ;
|
457
|
+
INT : '0'..'9'+;
|
458
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
459
|
+
|
460
|
+
END
|
461
|
+
result.should == '(var (: a int) (: b float))'
|
462
|
+
end
|
463
|
+
|
464
|
+
|
465
|
+
example "imaginary token copy" do
|
466
|
+
result = parse(<<-'END', :a, 'a,b,c')
|
467
|
+
grammar ImaginaryTokenCopy;
|
468
|
+
options {language=Ruby;output=AST;}
|
469
|
+
tokens {VAR;}
|
470
|
+
a : ID (',' ID)*-> ^(VAR ID)+ ;
|
471
|
+
type : 'int' | 'float' ;
|
472
|
+
ID : 'a'..'z'+ ;
|
473
|
+
INT : '0'..'9'+;
|
474
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
475
|
+
|
476
|
+
END
|
477
|
+
result.should == '(VAR a) (VAR b) (VAR c)'
|
478
|
+
end
|
479
|
+
|
480
|
+
|
481
|
+
example "token unreferenced on left but defined" do
|
482
|
+
result = parse(<<-'END', :a, 'a')
|
483
|
+
grammar TokenUnreferencedOnLeftButDefined;
|
484
|
+
options {language=Ruby;output=AST;}
|
485
|
+
tokens {VAR;}
|
486
|
+
a : b -> ID ;
|
487
|
+
b : ID ;
|
488
|
+
ID : 'a'..'z'+ ;
|
489
|
+
INT : '0'..'9'+;
|
490
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
491
|
+
|
492
|
+
END
|
493
|
+
result.should == 'ID'
|
494
|
+
end
|
495
|
+
|
496
|
+
|
497
|
+
example "imaginary token copy set text" do
|
498
|
+
result = parse(<<-'END', :a, 'a,b,c')
|
499
|
+
grammar ImaginaryTokenCopySetText;
|
500
|
+
options {language=Ruby;output=AST;}
|
501
|
+
tokens {VAR;}
|
502
|
+
a : ID (',' ID)*-> ^(VAR["var"] ID)+ ;
|
503
|
+
type : 'int' | 'float' ;
|
504
|
+
ID : 'a'..'z'+ ;
|
505
|
+
INT : '0'..'9'+;
|
506
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
507
|
+
|
508
|
+
END
|
509
|
+
result.should == '(var a) (var b) (var c)'
|
510
|
+
end
|
511
|
+
|
512
|
+
|
513
|
+
example "imaginary token no copy from token" do
|
514
|
+
result = parse(<<-'END', :a, '{a b c}')
|
515
|
+
grammar ImaginaryTokenNoCopyFromToken;
|
516
|
+
options {language=Ruby;output=AST;}
|
517
|
+
tokens {BLOCK;}
|
518
|
+
a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
|
519
|
+
type : 'int' | 'float' ;
|
520
|
+
ID : 'a'..'z'+ ;
|
521
|
+
INT : '0'..'9'+;
|
522
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
523
|
+
|
524
|
+
END
|
525
|
+
result.should == '({ a b c)'
|
526
|
+
end
|
527
|
+
|
528
|
+
|
529
|
+
example "imaginary token no copy from token set text" do
|
530
|
+
result = parse(<<-'END', :a, '{a b c}')
|
531
|
+
grammar ImaginaryTokenNoCopyFromTokenSetText;
|
532
|
+
options {language=Ruby;output=AST;}
|
533
|
+
tokens {BLOCK;}
|
534
|
+
a : lc='{' ID+ '}' -> ^(BLOCK[$lc,"block"] ID+) ;
|
535
|
+
type : 'int' | 'float' ;
|
536
|
+
ID : 'a'..'z'+ ;
|
537
|
+
INT : '0'..'9'+;
|
538
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
539
|
+
|
540
|
+
END
|
541
|
+
result.should == '(block a b c)'
|
542
|
+
end
|
543
|
+
|
544
|
+
|
545
|
+
example "mixed rewrite and auto ast" do
|
546
|
+
result = parse(<<-'END', :a, 'a 1 2')
|
547
|
+
grammar MixedRewriteAndAutoAST;
|
548
|
+
options {language=Ruby;output=AST;}
|
549
|
+
tokens {BLOCK;}
|
550
|
+
a : b b^ ; // 2nd b matches only an INT; can make it root
|
551
|
+
b : ID INT -> INT ID
|
552
|
+
| INT
|
553
|
+
;
|
554
|
+
ID : 'a'..'z'+ ;
|
555
|
+
INT : '0'..'9'+;
|
556
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
557
|
+
END
|
558
|
+
result.should == '(2 1 a)'
|
559
|
+
end
|
560
|
+
|
561
|
+
|
562
|
+
example "subrule with rewrite" do
|
563
|
+
result = parse(<<-'END', :a, 'a 1 2 3')
|
564
|
+
grammar SubruleWithRewrite;
|
565
|
+
options {language=Ruby;output=AST;}
|
566
|
+
tokens {BLOCK;}
|
567
|
+
a : b b ;
|
568
|
+
b : (ID INT -> INT ID | INT INT -> INT+ )
|
569
|
+
;
|
570
|
+
ID : 'a'..'z'+ ;
|
571
|
+
INT : '0'..'9'+;
|
572
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
573
|
+
|
574
|
+
END
|
575
|
+
result.should == '1 a 2 3'
|
576
|
+
end
|
577
|
+
|
578
|
+
|
579
|
+
example "subrule with rewrite2" do
|
580
|
+
result = parse(<<-'END', :a, 'int a; int b=3;')
|
581
|
+
grammar SubruleWithRewrite2;
|
582
|
+
options {language=Ruby;output=AST;}
|
583
|
+
tokens {TYPE;}
|
584
|
+
a : b b ;
|
585
|
+
b : 'int'
|
586
|
+
( ID -> ^(TYPE 'int' ID)
|
587
|
+
| ID '=' INT -> ^(TYPE 'int' ID INT)
|
588
|
+
)
|
589
|
+
';'
|
590
|
+
;
|
591
|
+
ID : 'a'..'z'+ ;
|
592
|
+
INT : '0'..'9'+;
|
593
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
594
|
+
|
595
|
+
END
|
596
|
+
result.should == '(TYPE int a) (TYPE int b 3)'
|
597
|
+
end
|
598
|
+
|
599
|
+
|
600
|
+
example "nested rewrite shuts off auto ast" do
|
601
|
+
result = parse(<<-'END', :a, 'a b c d; 42')
|
602
|
+
grammar NestedRewriteShutsOffAutoAST;
|
603
|
+
options {language=Ruby;output=AST;}
|
604
|
+
tokens {BLOCK;}
|
605
|
+
a : b b ;
|
606
|
+
b : ID ( ID (last=ID -> $last)+ ) ';' // get last ID
|
607
|
+
| INT // should still get auto AST construction
|
608
|
+
;
|
609
|
+
ID : 'a'..'z'+ ;
|
610
|
+
INT : '0'..'9'+;
|
611
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
612
|
+
|
613
|
+
END
|
614
|
+
result.should == 'd 42'
|
615
|
+
end
|
616
|
+
|
617
|
+
|
618
|
+
example "rewrite actions" do
|
619
|
+
result = parse(<<-'END', :a, '3')
|
620
|
+
grammar RewriteActions;
|
621
|
+
options {language=Ruby;output=AST;}
|
622
|
+
a : atom -> ^({ @adaptor.create!(INT,"9") } atom) ;
|
623
|
+
atom : INT ;
|
624
|
+
ID : 'a'..'z'+ ;
|
625
|
+
INT : '0'..'9'+;
|
626
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
627
|
+
|
628
|
+
END
|
629
|
+
result.should == '(9 3)'
|
630
|
+
end
|
631
|
+
|
632
|
+
|
633
|
+
example "rewrite actions2" do
|
634
|
+
result = parse(<<-'END', :a, '3')
|
635
|
+
grammar RewriteActions2;
|
636
|
+
options {language=Ruby;output=AST;}
|
637
|
+
a : atom -> { @adaptor.create!(INT,"9") } atom ;
|
638
|
+
atom : INT ;
|
639
|
+
ID : 'a'..'z'+ ;
|
640
|
+
INT : '0'..'9'+;
|
641
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
642
|
+
|
643
|
+
END
|
644
|
+
result.should == '9 3'
|
645
|
+
end
|
646
|
+
|
647
|
+
|
648
|
+
example "ref to old value" do
|
649
|
+
result = parse(<<-'END', :a, '3+4+5')
|
650
|
+
grammar RefToOldValue;
|
651
|
+
options {language=Ruby;output=AST;}
|
652
|
+
tokens {BLOCK;}
|
653
|
+
a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ;
|
654
|
+
atom : INT ;
|
655
|
+
ID : 'a'..'z'+ ;
|
656
|
+
INT : '0'..'9'+;
|
657
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
658
|
+
|
659
|
+
END
|
660
|
+
result.should == '(+ (+ 3 4) 5)'
|
661
|
+
end
|
662
|
+
|
663
|
+
|
664
|
+
example "copy semantics for rules" do
|
665
|
+
result = parse(<<-'END', :a, '3')
|
666
|
+
grammar CopySemanticsForRules;
|
667
|
+
options {language=Ruby;output=AST;}
|
668
|
+
tokens {BLOCK;}
|
669
|
+
a : atom -> ^(atom atom) ; // NOT CYCLE! (dup atom)
|
670
|
+
atom : INT ;
|
671
|
+
ID : 'a'..'z'+ ;
|
672
|
+
INT : '0'..'9'+;
|
673
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
674
|
+
|
675
|
+
END
|
676
|
+
result.should == '(3 3)'
|
677
|
+
end
|
678
|
+
|
679
|
+
|
680
|
+
example "copy semantics for rules2" do
|
681
|
+
result = parse(<<-'END', :a, 'int a,b,c;')
|
682
|
+
grammar CopySemanticsForRules2;
|
683
|
+
options {language=Ruby;output=AST;}
|
684
|
+
a : type ID (',' ID)* ';' -> ^(type ID)+ ;
|
685
|
+
type : 'int' ;
|
686
|
+
ID : 'a'..'z'+ ;
|
687
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
688
|
+
|
689
|
+
END
|
690
|
+
result.should == '(int a) (int b) (int c)'
|
691
|
+
end
|
692
|
+
|
693
|
+
|
694
|
+
example "copy semantics for rules3" do
|
695
|
+
result = parse(<<-'END', :a, 'public int a,b,c;')
|
696
|
+
grammar CopySemanticsForRules3;
|
697
|
+
options {language=Ruby;output=AST;}
|
698
|
+
a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ;
|
699
|
+
type : 'int' ;
|
700
|
+
modifier : 'public' ;
|
701
|
+
ID : 'a'..'z'+ ;
|
702
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
703
|
+
|
704
|
+
END
|
705
|
+
result.should == '(int public a) (int public b) (int public c)'
|
706
|
+
end
|
707
|
+
|
708
|
+
|
709
|
+
example "copy semantics for rules3 double" do
|
710
|
+
result = parse(<<-'END', :a, 'public int a,b,c;')
|
711
|
+
grammar CopySemanticsForRules3Double;
|
712
|
+
options {language=Ruby;output=AST;}
|
713
|
+
a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ;
|
714
|
+
type : 'int' ;
|
715
|
+
modifier : 'public' ;
|
716
|
+
ID : 'a'..'z'+ ;
|
717
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
718
|
+
|
719
|
+
END
|
720
|
+
result.should == '(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)'
|
721
|
+
end
|
722
|
+
|
723
|
+
|
724
|
+
example "copy semantics for rules4" do
|
725
|
+
result = parse(<<-'END', :a, 'public int a,b,c;')
|
726
|
+
grammar CopySemanticsForRules4;
|
727
|
+
options {language=Ruby;output=AST;}
|
728
|
+
tokens {MOD;}
|
729
|
+
a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ;
|
730
|
+
type : 'int' ;
|
731
|
+
modifier : 'public' ;
|
732
|
+
ID : 'a'..'z'+ ;
|
733
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
734
|
+
|
735
|
+
END
|
736
|
+
result.should == '(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)'
|
737
|
+
end
|
738
|
+
|
739
|
+
|
740
|
+
example "copy semantics lists" do
|
741
|
+
result = parse(<<-'END', :a, 'a,b,c;')
|
742
|
+
grammar CopySemanticsLists;
|
743
|
+
options {language=Ruby;output=AST;}
|
744
|
+
tokens {MOD;}
|
745
|
+
a : ID (',' ID)* ';' -> ID+ ID+ ;
|
746
|
+
ID : 'a'..'z'+ ;
|
747
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
748
|
+
|
749
|
+
END
|
750
|
+
result.should == 'a b c a b c'
|
751
|
+
end
|
752
|
+
|
753
|
+
|
754
|
+
example "copy rule label" do
|
755
|
+
result = parse(<<-'END', :a, 'a')
|
756
|
+
grammar CopyRuleLabel;
|
757
|
+
options {language=Ruby;output=AST;}
|
758
|
+
tokens {BLOCK;}
|
759
|
+
a : x=b -> $x $x;
|
760
|
+
b : ID ;
|
761
|
+
ID : 'a'..'z'+ ;
|
762
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
763
|
+
|
764
|
+
END
|
765
|
+
result.should == 'a a'
|
766
|
+
end
|
767
|
+
|
768
|
+
|
769
|
+
example "copy rule label2" do
|
770
|
+
result = parse(<<-'END', :a, 'a')
|
771
|
+
grammar CopyRuleLabel2;
|
772
|
+
options {language=Ruby;output=AST;}
|
773
|
+
tokens {BLOCK;}
|
774
|
+
a : x=b -> ^($x $x);
|
775
|
+
b : ID ;
|
776
|
+
ID : 'a'..'z'+ ;
|
777
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
778
|
+
|
779
|
+
END
|
780
|
+
result.should == '(a a)'
|
781
|
+
end
|
782
|
+
|
783
|
+
|
784
|
+
example "queueing of tokens" do
|
785
|
+
result = parse(<<-'END', :a, 'int a,b,c;')
|
786
|
+
grammar QueueingOfTokens;
|
787
|
+
options {language=Ruby;output=AST;}
|
788
|
+
a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ;
|
789
|
+
op : '+'|'-' ;
|
790
|
+
ID : 'a'..'z'+ ;
|
791
|
+
INT : '0'..'9'+;
|
792
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
793
|
+
|
794
|
+
END
|
795
|
+
result.should == '(int a b c)'
|
796
|
+
end
|
797
|
+
|
798
|
+
|
799
|
+
example "copy of tokens" do
|
800
|
+
result = parse(<<-'END', :a, 'int a;')
|
801
|
+
grammar CopyOfTokens;
|
802
|
+
options {language=Ruby;output=AST;}
|
803
|
+
a : 'int' ID ';' -> 'int' ID 'int' ID ;
|
804
|
+
op : '+'|'-' ;
|
805
|
+
ID : 'a'..'z'+ ;
|
806
|
+
INT : '0'..'9'+;
|
807
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
808
|
+
|
809
|
+
END
|
810
|
+
result.should == 'int a int a'
|
811
|
+
end
|
812
|
+
|
813
|
+
|
814
|
+
example "token copy in loop" do
|
815
|
+
result = parse(<<-'END', :a, 'int a,b,c;')
|
816
|
+
grammar TokenCopyInLoop;
|
817
|
+
options {language=Ruby;output=AST;}
|
818
|
+
a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ;
|
819
|
+
op : '+'|'-' ;
|
820
|
+
ID : 'a'..'z'+ ;
|
821
|
+
INT : '0'..'9'+;
|
822
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
823
|
+
|
824
|
+
END
|
825
|
+
result.should == '(int a) (int b) (int c)'
|
826
|
+
end
|
827
|
+
|
828
|
+
|
829
|
+
example "token copy in loop against two others" do
|
830
|
+
result = parse(<<-'END', :a, 'int a:1,b:2,c:3;')
|
831
|
+
grammar TokenCopyInLoopAgainstTwoOthers;
|
832
|
+
options {language=Ruby;output=AST;}
|
833
|
+
a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ;
|
834
|
+
op : '+'|'-' ;
|
835
|
+
ID : 'a'..'z'+ ;
|
836
|
+
INT : '0'..'9'+;
|
837
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
838
|
+
|
839
|
+
END
|
840
|
+
result.should == '(int a 1) (int b 2) (int c 3)'
|
841
|
+
end
|
842
|
+
|
843
|
+
|
844
|
+
example "list refd one at a time" do
|
845
|
+
result = parse(<<-'END', :a, 'a b c')
|
846
|
+
grammar ListRefdOneAtATime;
|
847
|
+
options {language=Ruby;output=AST;}
|
848
|
+
a : ID+ -> ID ID ID ; // works if 3 input IDs
|
849
|
+
op : '+'|'-' ;
|
850
|
+
ID : 'a'..'z'+ ;
|
851
|
+
INT : '0'..'9'+;
|
852
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
853
|
+
|
854
|
+
END
|
855
|
+
result.should == 'a b c'
|
856
|
+
end
|
857
|
+
|
858
|
+
|
859
|
+
example "split list with labels" do
|
860
|
+
result = parse(<<-'END', :a, 'a b c')
|
861
|
+
grammar SplitListWithLabels;
|
862
|
+
options {language=Ruby;output=AST;}
|
863
|
+
tokens {VAR;}
|
864
|
+
a : first=ID others+=ID* -> $first VAR $others+ ;
|
865
|
+
op : '+'|'-' ;
|
866
|
+
ID : 'a'..'z'+ ;
|
867
|
+
INT : '0'..'9'+;
|
868
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
869
|
+
|
870
|
+
END
|
871
|
+
result.should == 'a VAR b c'
|
872
|
+
end
|
873
|
+
|
874
|
+
|
875
|
+
example "complicated melange" do
|
876
|
+
result = parse(<<-'END', :a, 'a a b b b c c c d')
|
877
|
+
grammar ComplicatedMelange;
|
878
|
+
options {language=Ruby;output=AST;}
|
879
|
+
tokens {BLOCK;}
|
880
|
+
a : A A b=B B b=B c+=C C c+=C D {s=$D.text} -> A+ B+ C+ D ;
|
881
|
+
type : 'int' | 'float' ;
|
882
|
+
A : 'a' ;
|
883
|
+
B : 'b' ;
|
884
|
+
C : 'c' ;
|
885
|
+
D : 'd' ;
|
886
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
887
|
+
|
888
|
+
END
|
889
|
+
result.should == 'a a b b b c c c d'
|
890
|
+
end
|
891
|
+
|
892
|
+
|
893
|
+
example "rule label" do
|
894
|
+
result = parse(<<-'END', :a, 'a')
|
895
|
+
grammar RuleLabel;
|
896
|
+
options {language=Ruby;output=AST;}
|
897
|
+
tokens {BLOCK;}
|
898
|
+
a : x=b -> $x;
|
899
|
+
b : ID ;
|
900
|
+
ID : 'a'..'z'+ ;
|
901
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
902
|
+
|
903
|
+
END
|
904
|
+
result.should == 'a'
|
905
|
+
end
|
906
|
+
|
907
|
+
|
908
|
+
example "ambiguous rule" do
|
909
|
+
result = parse(<<-'END', :a, 'abc 34')
|
910
|
+
grammar AmbiguousRule;
|
911
|
+
options {language=Ruby;output=AST;}
|
912
|
+
a : ID a -> a | INT ;
|
913
|
+
ID : 'a'..'z'+ ;
|
914
|
+
INT: '0'..'9'+ ;
|
915
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
916
|
+
|
917
|
+
END
|
918
|
+
result.should == '34'
|
919
|
+
end
|
920
|
+
|
921
|
+
|
922
|
+
example "rule list label" do
|
923
|
+
result = parse(<<-'END', :a, 'a b')
|
924
|
+
grammar RuleListLabel;
|
925
|
+
options {language=Ruby;output=AST;}
|
926
|
+
tokens {BLOCK;}
|
927
|
+
a : x+=b x+=b -> $x+;
|
928
|
+
b : ID ;
|
929
|
+
ID : 'a'..'z'+ ;
|
930
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
931
|
+
|
932
|
+
END
|
933
|
+
result.should == 'a b'
|
934
|
+
end
|
935
|
+
|
936
|
+
|
937
|
+
example "rule list label2" do
|
938
|
+
result = parse(<<-'END', :a, 'a b')
|
939
|
+
grammar RuleListLabel2;
|
940
|
+
options {language=Ruby;output=AST;}
|
941
|
+
tokens {BLOCK;}
|
942
|
+
a : x+=b x+=b -> $x $x*;
|
943
|
+
b : ID ;
|
944
|
+
ID : 'a'..'z'+ ;
|
945
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
946
|
+
|
947
|
+
END
|
948
|
+
result.should == 'a b'
|
949
|
+
end
|
950
|
+
|
951
|
+
|
952
|
+
example "optional" do
|
953
|
+
result = parse(<<-'END', :a, 'a')
|
954
|
+
grammar Optional;
|
955
|
+
options {language=Ruby;output=AST;}
|
956
|
+
tokens {BLOCK;}
|
957
|
+
a : x=b (y=b)? -> $x $y?;
|
958
|
+
b : ID ;
|
959
|
+
ID : 'a'..'z'+ ;
|
960
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
961
|
+
|
962
|
+
END
|
963
|
+
result.should == 'a'
|
964
|
+
end
|
965
|
+
|
966
|
+
|
967
|
+
example "optional2" do
|
968
|
+
result = parse(<<-'END', :a, 'a b')
|
969
|
+
grammar Optional2;
|
970
|
+
options {language=Ruby;output=AST;}
|
971
|
+
tokens {BLOCK;}
|
972
|
+
a : x=ID (y=b)? -> $x $y?;
|
973
|
+
b : ID ;
|
974
|
+
ID : 'a'..'z'+ ;
|
975
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
976
|
+
|
977
|
+
END
|
978
|
+
result.should == 'a b'
|
979
|
+
end
|
980
|
+
|
981
|
+
|
982
|
+
example "optional3" do
|
983
|
+
result = parse(<<-'END', :a, 'a b')
|
984
|
+
grammar Optional3;
|
985
|
+
options {language=Ruby;output=AST;}
|
986
|
+
tokens {BLOCK;}
|
987
|
+
a : x=ID (y=b)? -> ($x $y)?;
|
988
|
+
b : ID ;
|
989
|
+
ID : 'a'..'z'+ ;
|
990
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
991
|
+
|
992
|
+
END
|
993
|
+
result.should == 'a b'
|
994
|
+
end
|
995
|
+
|
996
|
+
|
997
|
+
example "optional4" do
|
998
|
+
result = parse(<<-'END', :a, 'a b')
|
999
|
+
grammar Optional4;
|
1000
|
+
options {language=Ruby;output=AST;}
|
1001
|
+
tokens {BLOCK;}
|
1002
|
+
a : x+=ID (y=b)? -> ($x $y)?;
|
1003
|
+
b : ID ;
|
1004
|
+
ID : 'a'..'z'+ ;
|
1005
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1006
|
+
END
|
1007
|
+
result.should == 'a b'
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
|
1011
|
+
example "optional5" do
|
1012
|
+
result = parse(<<-'END', :a, 'a')
|
1013
|
+
grammar Optional5;
|
1014
|
+
options {language=Ruby;output=AST;}
|
1015
|
+
tokens {BLOCK;}
|
1016
|
+
a : ID -> ID? ; // match an ID to optional ID
|
1017
|
+
b : ID ;
|
1018
|
+
ID : 'a'..'z'+ ;
|
1019
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1020
|
+
|
1021
|
+
END
|
1022
|
+
result.should == 'a'
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
|
1026
|
+
example "arbitrary expr type" do
|
1027
|
+
result = parse(<<-'END', :a, 'a b')
|
1028
|
+
grammar ArbitraryExprType;
|
1029
|
+
options {language=Ruby;output=AST;}
|
1030
|
+
tokens {BLOCK;}
|
1031
|
+
a : x+=b x+=b -> {ANTLR3::CommonTree.new(nil)};
|
1032
|
+
b : ID ;
|
1033
|
+
ID : 'a'..'z'+ ;
|
1034
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1035
|
+
|
1036
|
+
END
|
1037
|
+
result.should == ''
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
|
1041
|
+
example "set" do
|
1042
|
+
result = parse(<<-'END', :a, '2 a 34 de')
|
1043
|
+
grammar SetT;
|
1044
|
+
options {language=Ruby;output=AST;}
|
1045
|
+
a: (INT|ID)+ -> INT+ ID+ ;
|
1046
|
+
INT: '0'..'9'+;
|
1047
|
+
ID : 'a'..'z'+;
|
1048
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1049
|
+
|
1050
|
+
END
|
1051
|
+
result.should == '2 34 a de'
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
|
1055
|
+
example "set2" do
|
1056
|
+
result = parse(<<-'END', :a, '2')
|
1057
|
+
grammar Set2;
|
1058
|
+
options {language=Ruby;output=AST;}
|
1059
|
+
a: (INT|ID) -> INT? ID? ;
|
1060
|
+
INT: '0'..'9'+;
|
1061
|
+
ID : 'a'..'z'+;
|
1062
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1063
|
+
|
1064
|
+
END
|
1065
|
+
result.should == '2'
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
|
1069
|
+
example "set with label" do
|
1070
|
+
warn('test SetWithLabel officially broken')
|
1071
|
+
#result = parse(<<-'END', :a, '2')
|
1072
|
+
# grammar SetWithLabel;
|
1073
|
+
# options {language=Ruby;output=AST;}
|
1074
|
+
# a : x=(INT|ID) -> $x ;
|
1075
|
+
# INT: '0'..'9'+;
|
1076
|
+
# ID : 'a'..'z'+;
|
1077
|
+
# WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1078
|
+
#
|
1079
|
+
#END
|
1080
|
+
#result.should == '2'
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
|
1084
|
+
example "rewrite action" do
|
1085
|
+
result = parse(<<-'END', :r, '25')
|
1086
|
+
grammar RewriteAction;
|
1087
|
+
options {language=Ruby;output=AST;}
|
1088
|
+
tokens { FLOAT; }
|
1089
|
+
r
|
1090
|
+
: INT -> {ANTLR3::CommonTree.new(create_token(FLOAT, nil, "#{$INT.text}.0"))}
|
1091
|
+
;
|
1092
|
+
INT : '0'..'9'+;
|
1093
|
+
WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;};
|
1094
|
+
|
1095
|
+
END
|
1096
|
+
result.should == '25.0'
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
|
1100
|
+
example "optional subrule without real elements" do
|
1101
|
+
result = parse(<<-'END', :modulo, 'modulo abc (x y #)')
|
1102
|
+
grammar OptionalSubruleWithoutRealElements;
|
1103
|
+
options {language=Ruby;output=AST;}
|
1104
|
+
tokens {PARMS;}
|
1105
|
+
|
1106
|
+
modulo
|
1107
|
+
: 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?)
|
1108
|
+
;
|
1109
|
+
parms : '#'|ID;
|
1110
|
+
ID : ('a'..'z' | 'A'..'Z')+;
|
1111
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1112
|
+
|
1113
|
+
END
|
1114
|
+
result.should == '(modulo abc (PARMS x y #))'
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
|
1118
|
+
example "wildcard" do
|
1119
|
+
result = parse(<<-'END', :a, 'abc 34')
|
1120
|
+
grammar Wildcard;
|
1121
|
+
options {language=Ruby;output=AST;}
|
1122
|
+
a : ID c=. -> $c;
|
1123
|
+
ID : 'a'..'z'+ ;
|
1124
|
+
INT : '0'..'9'+;
|
1125
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1126
|
+
|
1127
|
+
END
|
1128
|
+
result.should == '34'
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
|
1132
|
+
example "extra token in simple decl" do
|
1133
|
+
result, errors = parse(<<-'END', :decl, 'int 34 x=1;', true)
|
1134
|
+
grammar ExtraTokenInSimpleDecl;
|
1135
|
+
options {language=Ruby;output=AST;}
|
1136
|
+
tokens {EXPR;}
|
1137
|
+
decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
|
1138
|
+
type : 'int' | 'float' ;
|
1139
|
+
ID : 'a'..'z'+ ;
|
1140
|
+
INT : '0'..'9'+;
|
1141
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1142
|
+
|
1143
|
+
END
|
1144
|
+
errors.should == ['line 1:4 extraneous input "34" expecting ID']
|
1145
|
+
result.should == '(EXPR int x 1)'
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
|
1149
|
+
example "missing id in simple decl" do
|
1150
|
+
result, errors = parse(<<-'END', :decl, 'int =1;', true)
|
1151
|
+
grammar MissingIDInSimpleDecl;
|
1152
|
+
options {language=Ruby;output=AST;}
|
1153
|
+
tokens {EXPR;}
|
1154
|
+
decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
|
1155
|
+
type : 'int' | 'float' ;
|
1156
|
+
ID : 'a'..'z'+ ;
|
1157
|
+
INT : '0'..'9'+;
|
1158
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1159
|
+
|
1160
|
+
END
|
1161
|
+
errors.should == ['line 1:4 missing ID at "="']
|
1162
|
+
result.should == '(EXPR int <missing ID> 1)'
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
|
1166
|
+
example "missing set in simple decl" do
|
1167
|
+
result, errors = parse(<<-'END', :decl, 'x=1;', true)
|
1168
|
+
grammar MissingSetInSimpleDecl;
|
1169
|
+
options {language=Ruby;output=AST;}
|
1170
|
+
tokens {EXPR;}
|
1171
|
+
decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
|
1172
|
+
type : 'int' | 'float' ;
|
1173
|
+
ID : 'a'..'z'+ ;
|
1174
|
+
INT : '0'..'9'+;
|
1175
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1176
|
+
|
1177
|
+
END
|
1178
|
+
errors.should == ['line 1:0 mismatched input "x" expecting set nil']
|
1179
|
+
result.should == '(EXPR <error: x> x 1)'
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
|
1183
|
+
example "missing token gives error node" do
|
1184
|
+
result, errors = parse(<<-'END', :a, 'abc', true)
|
1185
|
+
grammar MissingTokenGivesErrorNode;
|
1186
|
+
options {language=Ruby;output=AST;}
|
1187
|
+
a : ID INT -> ID INT ;
|
1188
|
+
ID : 'a'..'z'+ ;
|
1189
|
+
INT : '0'..'9'+;
|
1190
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1191
|
+
|
1192
|
+
END
|
1193
|
+
errors.should == ["line 0:-1 missing INT at \"<EOF>\""]
|
1194
|
+
result.should == 'abc <missing INT>'
|
1195
|
+
#end
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
|
1199
|
+
example "extra token gives error node" do
|
1200
|
+
result, errors = parse(<<-'END', :a, 'abc ick 34', true)
|
1201
|
+
grammar ExtraTokenGivesErrorNode;
|
1202
|
+
options {language=Ruby;output=AST;}
|
1203
|
+
a : b c -> b c;
|
1204
|
+
b : ID -> ID ;
|
1205
|
+
c : INT -> INT ;
|
1206
|
+
ID : 'a'..'z'+ ;
|
1207
|
+
INT : '0'..'9'+;
|
1208
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1209
|
+
|
1210
|
+
END
|
1211
|
+
errors.should == ['line 1:4 extraneous input "ick" expecting INT']
|
1212
|
+
result.should == 'abc 34'
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
|
1216
|
+
example "missing first token gives error node" do
|
1217
|
+
result, errors = parse(<<-'END', :a, '34', true)
|
1218
|
+
grammar MissingFirstTokenGivesErrorNode;
|
1219
|
+
options {language=Ruby;output=AST;}
|
1220
|
+
a : ID INT -> ID INT ;
|
1221
|
+
ID : 'a'..'z'+ ;
|
1222
|
+
INT : '0'..'9'+;
|
1223
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1224
|
+
|
1225
|
+
END
|
1226
|
+
errors.should == ['line 1:0 missing ID at "34"']
|
1227
|
+
result.should == '<missing ID> 34'
|
1228
|
+
end
|
1229
|
+
|
1230
|
+
|
1231
|
+
example "missing first token gives error node2" do
|
1232
|
+
result, errors = parse(<<-'END', :a, '34', true)
|
1233
|
+
grammar MissingFirstTokenGivesErrorNode2;
|
1234
|
+
options {language=Ruby;output=AST;}
|
1235
|
+
a : b c -> b c;
|
1236
|
+
b : ID -> ID ;
|
1237
|
+
c : INT -> INT ;
|
1238
|
+
ID : 'a'..'z'+ ;
|
1239
|
+
INT : '0'..'9'+;
|
1240
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1241
|
+
|
1242
|
+
END
|
1243
|
+
errors.should == ['line 1:0 missing ID at "34"']
|
1244
|
+
result.should == '<missing ID> 34'
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
|
1248
|
+
example "no viable alt gives error node" do
|
1249
|
+
result, errors = parse(<<-'END', :a, '*', true)
|
1250
|
+
grammar NoViableAltGivesErrorNode;
|
1251
|
+
options {language=Ruby;output=AST;}
|
1252
|
+
a : b -> b | c -> c;
|
1253
|
+
b : ID -> ID ;
|
1254
|
+
c : INT -> INT ;
|
1255
|
+
ID : 'a'..'z'+ ;
|
1256
|
+
S : '*' ;
|
1257
|
+
INT : '0'..'9'+;
|
1258
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1259
|
+
|
1260
|
+
END
|
1261
|
+
errors.should == ['line 1:0 no viable alternative at input "*"']
|
1262
|
+
result.should == '<unexpected: 0 S["*"] @ line 1 col 0 (0..0), resync = *>'
|
1263
|
+
end
|
1264
|
+
|
1265
|
+
|
1266
|
+
example "cardinality" do
|
1267
|
+
lambda do
|
1268
|
+
parse(<<-'END', :a, "a b 3 4 5")
|
1269
|
+
grammar Cardinality;
|
1270
|
+
options {language=Ruby;output=AST;}
|
1271
|
+
tokens {BLOCK;}
|
1272
|
+
a : ID ID INT INT INT -> (ID INT)+;
|
1273
|
+
ID : 'a'..'z'+ ;
|
1274
|
+
INT : '0'..'9'+;
|
1275
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1276
|
+
END
|
1277
|
+
end.should raise_error(ANTLR3::Error::RewriteCardinalityError)
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
example "cardinality2" do
|
1281
|
+
lambda do
|
1282
|
+
parse(<<-'END', :a, "a b")
|
1283
|
+
grammar Cardinality2;
|
1284
|
+
options {language=Ruby;output=AST;}
|
1285
|
+
tokens {BLOCK;}
|
1286
|
+
a : ID+ -> ID ID ID ; // only 2 input IDs
|
1287
|
+
op : '+'|'-' ;
|
1288
|
+
ID : 'a'..'z'+ ;
|
1289
|
+
INT : '0'..'9'+;
|
1290
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1291
|
+
END
|
1292
|
+
end.should raise_error(ANTLR3::Error::RewriteCardinalityError)
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
example "cardinality3" do
|
1296
|
+
lambda do
|
1297
|
+
parse(<<-'END', :a, "3")
|
1298
|
+
grammar Cardinality3;
|
1299
|
+
options {language=Ruby;output=AST;}
|
1300
|
+
tokens {BLOCK;}
|
1301
|
+
a : ID? INT -> ID INT ;
|
1302
|
+
op : '+'|'-' ;
|
1303
|
+
ID : 'a'..'z'+ ;
|
1304
|
+
INT : '0'..'9'+;
|
1305
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1306
|
+
END
|
1307
|
+
end.should raise_error(ANTLR3::Error::RewriteEmptyStream)
|
1308
|
+
end
|
1309
|
+
|
1310
|
+
example "loop cardinality" do
|
1311
|
+
lambda do
|
1312
|
+
parse(<<-'END', :a, "3")
|
1313
|
+
grammar LoopCardinality;
|
1314
|
+
options {language=Ruby;output=AST;}
|
1315
|
+
a : ID? INT -> ID+ INT ;
|
1316
|
+
op : '+'|'-' ;
|
1317
|
+
ID : 'a'..'z'+ ;
|
1318
|
+
INT : '0'..'9'+;
|
1319
|
+
WS : (' '|'\n') {$channel=HIDDEN;} ;
|
1320
|
+
END
|
1321
|
+
end.should raise_error(ANTLR3::Error::RewriteEarlyExit)
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
|
1325
|
+
|
1326
|
+
end
|
1327
|
+
|