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,165 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'antlr3/test/functional'
|
5
|
+
|
6
|
+
class TestProfileMode < ANTLR3::Test::Functional
|
7
|
+
compile_options :profile => true
|
8
|
+
|
9
|
+
inline_grammar(<<-'END')
|
10
|
+
grammar SimpleC;
|
11
|
+
|
12
|
+
options { language = Ruby; }
|
13
|
+
|
14
|
+
program
|
15
|
+
: declaration+
|
16
|
+
;
|
17
|
+
|
18
|
+
/** In this rule, the functionHeader left prefix on the last two
|
19
|
+
* alternatives is not LL(k) for a fixed k. However, it is
|
20
|
+
* LL(*). The LL(*) algorithm simply scans ahead until it sees
|
21
|
+
* either the ';' or the '{' of the block and then it picks
|
22
|
+
* the appropriate alternative. Lookhead can be arbitrarily
|
23
|
+
* long in theory, but is <=10 in most cases. Works great.
|
24
|
+
* Use ANTLRWorks to see the lookahead use (step by Location)
|
25
|
+
* and look for blue tokens in the input window pane. :)
|
26
|
+
*/
|
27
|
+
declaration
|
28
|
+
: variable
|
29
|
+
| functionHeader ';'
|
30
|
+
| functionHeader block
|
31
|
+
;
|
32
|
+
|
33
|
+
variable
|
34
|
+
: type declarator ';'
|
35
|
+
;
|
36
|
+
|
37
|
+
declarator
|
38
|
+
: ID
|
39
|
+
;
|
40
|
+
|
41
|
+
functionHeader
|
42
|
+
: type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
|
43
|
+
;
|
44
|
+
|
45
|
+
formalParameter
|
46
|
+
: type declarator
|
47
|
+
;
|
48
|
+
|
49
|
+
type
|
50
|
+
: 'int'
|
51
|
+
| 'char'
|
52
|
+
| 'void'
|
53
|
+
| ID
|
54
|
+
;
|
55
|
+
|
56
|
+
block
|
57
|
+
: '{'
|
58
|
+
variable*
|
59
|
+
stat*
|
60
|
+
'}'
|
61
|
+
;
|
62
|
+
|
63
|
+
stat: forStat
|
64
|
+
| expr ';'
|
65
|
+
| block
|
66
|
+
| assignStat ';'
|
67
|
+
| ';'
|
68
|
+
;
|
69
|
+
|
70
|
+
forStat
|
71
|
+
: 'for' '(' assignStat ';' expr ';' assignStat ')' block
|
72
|
+
;
|
73
|
+
|
74
|
+
assignStat
|
75
|
+
: ID '=' expr
|
76
|
+
;
|
77
|
+
|
78
|
+
expr: condExpr
|
79
|
+
;
|
80
|
+
|
81
|
+
condExpr
|
82
|
+
: aexpr ( ('==' | '<') aexpr )?
|
83
|
+
;
|
84
|
+
|
85
|
+
aexpr
|
86
|
+
: atom ( '+' atom )*
|
87
|
+
;
|
88
|
+
|
89
|
+
atom
|
90
|
+
: ID
|
91
|
+
| INT
|
92
|
+
| '(' expr ')'
|
93
|
+
;
|
94
|
+
|
95
|
+
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
|
96
|
+
;
|
97
|
+
|
98
|
+
INT : ('0'..'9')+
|
99
|
+
;
|
100
|
+
|
101
|
+
WS : ( ' '
|
102
|
+
| '\t'
|
103
|
+
| '\r'
|
104
|
+
| '\n'
|
105
|
+
)+
|
106
|
+
{ $channel=HIDDEN; }
|
107
|
+
;
|
108
|
+
END
|
109
|
+
|
110
|
+
example 'profile mode output' do
|
111
|
+
input = <<-END.fixed_indent(0)
|
112
|
+
char c;
|
113
|
+
int x;
|
114
|
+
|
115
|
+
void bar(int x);
|
116
|
+
|
117
|
+
int foo(int y, char d) {
|
118
|
+
int i;
|
119
|
+
for (i=0; i<3; i=i+1) {
|
120
|
+
x=3;
|
121
|
+
y=5;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
END
|
125
|
+
|
126
|
+
lexer = SimpleC::Lexer.new(input)
|
127
|
+
tokens = ANTLR3::CommonTokenStream.new(lexer)
|
128
|
+
parser = SimpleC::Parser.new(tokens)
|
129
|
+
parser.program
|
130
|
+
|
131
|
+
profile_data = parser.profile
|
132
|
+
profile_data.rule_invocations.should == 60
|
133
|
+
profile_data.guessing_rule_invocations.should == 0
|
134
|
+
profile_data.rule_invocation_depth.should == 12
|
135
|
+
|
136
|
+
profile_data.fixed_decisions.should == 40
|
137
|
+
fixed_data = profile_data.fixed_looks
|
138
|
+
fixed_data.min.should == 1
|
139
|
+
fixed_data.max.should == 2
|
140
|
+
fixed_data.average.should == 1.075
|
141
|
+
fixed_data.standard_deviation.should == 0.26674678283691855
|
142
|
+
|
143
|
+
profile_data.cyclic_decisions.should == 4
|
144
|
+
cyclic_data = profile_data.cyclic_looks
|
145
|
+
cyclic_data.min.should == 3
|
146
|
+
cyclic_data.max.should == 10
|
147
|
+
cyclic_data.average.should == 5.75
|
148
|
+
cyclic_data.standard_deviation.should == 3.4034296427770228
|
149
|
+
|
150
|
+
profile_data.syntactic_predicates.should == 0
|
151
|
+
|
152
|
+
profile_data.memoization_cache_entries.should == 0
|
153
|
+
profile_data.memoization_cache_hits.should == 0
|
154
|
+
profile_data.memoization_cache_misses.should == 0
|
155
|
+
|
156
|
+
profile_data.semantic_predicates.should == 0
|
157
|
+
profile_data.tokens.should == 77
|
158
|
+
profile_data.hidden_tokens.should == 24
|
159
|
+
profile_data.characters_matched.should == 118
|
160
|
+
profile_data.hidden_characters_matched.should == 40
|
161
|
+
profile_data.reported_errors.should == 0
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'antlr3/test/functional'
|
5
|
+
|
6
|
+
class TestRuleTracing < ANTLR3::Test::Functional
|
7
|
+
|
8
|
+
inline_grammar(<<-'END')
|
9
|
+
grammar Traced;
|
10
|
+
options {
|
11
|
+
language = Ruby;
|
12
|
+
}
|
13
|
+
|
14
|
+
@parser::init {
|
15
|
+
@stack = nil
|
16
|
+
@traces = []
|
17
|
+
}
|
18
|
+
|
19
|
+
@parser::members {
|
20
|
+
attr_accessor :stack, :traces
|
21
|
+
|
22
|
+
def trace_in(rule_name, rule_index)
|
23
|
+
@traces << ">#{rule_name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def trace_out(rule_name, rule_index)
|
27
|
+
@traces << "<#{rule_name}"
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
@lexer::init {
|
32
|
+
@stack = nil
|
33
|
+
@traces = []
|
34
|
+
}
|
35
|
+
|
36
|
+
@lexer::members {
|
37
|
+
attr_accessor :stack, :traces
|
38
|
+
|
39
|
+
def trace_in(rule_name, rule_index)
|
40
|
+
@traces << ">#{rule_name}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def trace_out(rule_name, rule_index)
|
44
|
+
@traces << "<#{rule_name}"
|
45
|
+
end
|
46
|
+
}
|
47
|
+
|
48
|
+
a: '<' ((INT '+')=>b|c) '>';
|
49
|
+
b: c ('+' c)*;
|
50
|
+
c: INT ;
|
51
|
+
|
52
|
+
INT: ('0'..'9')+;
|
53
|
+
WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;};
|
54
|
+
END
|
55
|
+
|
56
|
+
compile_options :trace => true
|
57
|
+
|
58
|
+
example "setting up rule tracing" do
|
59
|
+
lexer = Traced::Lexer.new('< 1 + 2 + 3 >')
|
60
|
+
parser = Traced::Parser.new lexer
|
61
|
+
parser.a
|
62
|
+
lexer.traces.should == [
|
63
|
+
'>t__6!', '<t__6!', '>ws!', '<ws!', '>int!', '<int!', '>ws!', '<ws!',
|
64
|
+
'>t__8!', '<t__8!', '>ws!', '<ws!', '>int!', '<int!', '>ws!', '<ws!',
|
65
|
+
'>t__8!', '<t__8!', '>ws!', '<ws!', '>int!', '<int!', '>ws!', '<ws!',
|
66
|
+
'>t__7!', '<t__7!'
|
67
|
+
]
|
68
|
+
parser.traces.should == [
|
69
|
+
'>a', '>synpred_1_traced!', '<synpred_1_traced!',
|
70
|
+
'>b', '>c', '<c', '>c', '<c', '>c', '<c', '<b', '<a'
|
71
|
+
]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,379 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'antlr3/test/functional'
|
5
|
+
|
6
|
+
class TestImportedGrammars < ANTLR3::Test::Functional
|
7
|
+
|
8
|
+
def load(grammar)
|
9
|
+
grammar.compile
|
10
|
+
$:.unshift(grammar.output_directory) unless $:.include?(grammar.output_directory)
|
11
|
+
for file in grammar.target_files(false)
|
12
|
+
require File.basename(file, '.rb')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
example 'delegator invokes delegate rule' do
|
17
|
+
inline_grammar(<<-'END')
|
18
|
+
parser grammar DIDRSlave;
|
19
|
+
options { language=Ruby; }
|
20
|
+
@members {
|
21
|
+
def capture(t)
|
22
|
+
@didr_master.capture(t)
|
23
|
+
end
|
24
|
+
}
|
25
|
+
a : B { capture("S.a") } ;
|
26
|
+
END
|
27
|
+
load inline_grammar(<<-'END')
|
28
|
+
grammar DIDRMaster;
|
29
|
+
options { language=Ruby; }
|
30
|
+
import DIDRSlave;
|
31
|
+
|
32
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
33
|
+
|
34
|
+
s : a ;
|
35
|
+
B : 'b' ;
|
36
|
+
WS : (' '|'\n') { skip() } ;
|
37
|
+
END
|
38
|
+
|
39
|
+
lexer = DIDRMaster::Lexer.new( 'b' )
|
40
|
+
tokens = ANTLR3::CommonTokenStream.new( lexer )
|
41
|
+
parser = DIDRMaster::Parser.new( tokens )
|
42
|
+
parser.s
|
43
|
+
parser.output.should == 'S.a'
|
44
|
+
end
|
45
|
+
|
46
|
+
example 'delegator invokes delegate rule with args' do
|
47
|
+
inline_grammar(<<-'END')
|
48
|
+
parser grammar Slave2;
|
49
|
+
options {
|
50
|
+
language=Ruby;
|
51
|
+
}
|
52
|
+
@members {
|
53
|
+
def capture(t)
|
54
|
+
@master_2.capture(t)
|
55
|
+
end
|
56
|
+
}
|
57
|
+
a[x] returns [y] : B {capture("S.a"); $y="1000";} ;
|
58
|
+
END
|
59
|
+
load inline_grammar(<<-'END')
|
60
|
+
grammar Master2;
|
61
|
+
options {language=Ruby;}
|
62
|
+
import Slave2;
|
63
|
+
|
64
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
65
|
+
|
66
|
+
s : label=a[3] {capture($label.y)} ;
|
67
|
+
B : 'b' ;
|
68
|
+
WS : (' '|'\n') {skip} ;
|
69
|
+
END
|
70
|
+
lexer = Master2::Lexer.new( 'b' )
|
71
|
+
tokens = ANTLR3::CommonTokenStream.new( lexer )
|
72
|
+
parser = Master2::Parser.new( tokens )
|
73
|
+
parser.s
|
74
|
+
parser.output.should == 'S.a1000'
|
75
|
+
end
|
76
|
+
|
77
|
+
example "delegator accesses delegate members" do
|
78
|
+
inline_grammar(<<-'END')
|
79
|
+
parser grammar Slave3;
|
80
|
+
options {
|
81
|
+
language=Ruby;
|
82
|
+
}
|
83
|
+
@members {
|
84
|
+
def capture(t)
|
85
|
+
@master_3.capture(t)
|
86
|
+
end
|
87
|
+
|
88
|
+
def whatevs
|
89
|
+
capture("whatevs")
|
90
|
+
end
|
91
|
+
}
|
92
|
+
a : B ;
|
93
|
+
END
|
94
|
+
load inline_grammar(<<-'END')
|
95
|
+
grammar Master3;
|
96
|
+
options {
|
97
|
+
language=Ruby;
|
98
|
+
}
|
99
|
+
import Slave3;
|
100
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
101
|
+
|
102
|
+
s : 'b' {@slave_3.whatevs} ;
|
103
|
+
WS : (' '|'\n') {skip()} ;
|
104
|
+
END
|
105
|
+
|
106
|
+
parser = Master3::Parser.new( Master3::Lexer.new( 'b' ) )
|
107
|
+
parser.s
|
108
|
+
parser.output.should == 'whatevs'
|
109
|
+
end
|
110
|
+
|
111
|
+
example "delegator invokes first version of delegate rule" do
|
112
|
+
inline_grammar(<<-'END')
|
113
|
+
parser grammar Slave4A;
|
114
|
+
options {
|
115
|
+
language=Ruby;
|
116
|
+
}
|
117
|
+
@members {
|
118
|
+
def capture(t)
|
119
|
+
@master_4.capture(t)
|
120
|
+
end
|
121
|
+
}
|
122
|
+
a : b {capture("S.a")} ;
|
123
|
+
b : B ;
|
124
|
+
END
|
125
|
+
inline_grammar(<<-'END')
|
126
|
+
parser grammar Slave4B;
|
127
|
+
options {
|
128
|
+
language=Ruby;
|
129
|
+
}
|
130
|
+
@members {
|
131
|
+
def capture(t)
|
132
|
+
@master_4.capture(t)
|
133
|
+
end
|
134
|
+
}
|
135
|
+
a : B {capture("T.a")} ;
|
136
|
+
END
|
137
|
+
load inline_grammar(<<-'END')
|
138
|
+
grammar Master4;
|
139
|
+
options {
|
140
|
+
language=Ruby;
|
141
|
+
}
|
142
|
+
import Slave4A, Slave4B;
|
143
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
144
|
+
s : a ;
|
145
|
+
B : 'b' ;
|
146
|
+
WS : (' '|'\n') {skip} ;
|
147
|
+
END
|
148
|
+
|
149
|
+
parser = Master4::Parser.new( Master4::Lexer.new( 'b' ) )
|
150
|
+
parser.s
|
151
|
+
parser.output.should == 'S.a'
|
152
|
+
end
|
153
|
+
|
154
|
+
example "delegates see same token type" do
|
155
|
+
inline_grammar(<<-'END')
|
156
|
+
parser grammar Slave5A; // A, B, C token type order
|
157
|
+
options {
|
158
|
+
language=Ruby;
|
159
|
+
}
|
160
|
+
tokens { A; B; C; }
|
161
|
+
@members {
|
162
|
+
def capture(t)
|
163
|
+
@master_5.capture(t)
|
164
|
+
end
|
165
|
+
}
|
166
|
+
x : A {capture("S.x ")} ;
|
167
|
+
END
|
168
|
+
inline_grammar(<<-'END')
|
169
|
+
parser grammar Slave5B;
|
170
|
+
options {
|
171
|
+
language=Ruby;
|
172
|
+
}
|
173
|
+
tokens { C; B; A; } /// reverse order
|
174
|
+
@members {
|
175
|
+
def capture(t)
|
176
|
+
@master_5.capture(t)
|
177
|
+
end
|
178
|
+
}
|
179
|
+
y : A {capture("T.y")} ;
|
180
|
+
END
|
181
|
+
load inline_grammar(<<-'END')
|
182
|
+
grammar Master5;
|
183
|
+
options {
|
184
|
+
language=Ruby;
|
185
|
+
}
|
186
|
+
import Slave5A, Slave5B;
|
187
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
188
|
+
s : x y ; // matches AA, which should be "aa"
|
189
|
+
B : 'b' ; // another order: B, A, C
|
190
|
+
A : 'a' ;
|
191
|
+
C : 'c' ;
|
192
|
+
WS : (' '|'\n') {skip} ;
|
193
|
+
END
|
194
|
+
|
195
|
+
lexer = Master5::Lexer.new( 'aa' )
|
196
|
+
tokens = ANTLR3::CommonTokenStream.new( lexer )
|
197
|
+
parser = Master5::Parser.new( tokens )
|
198
|
+
parser.s
|
199
|
+
parser.output.should == 'S.x T.y'
|
200
|
+
end
|
201
|
+
|
202
|
+
example "delegator rule overrides delegate" do
|
203
|
+
inline_grammar(<<-'END')
|
204
|
+
parser grammar Slave6;
|
205
|
+
options {
|
206
|
+
language=Ruby;
|
207
|
+
}
|
208
|
+
@members {
|
209
|
+
def capture(t)
|
210
|
+
@master_6.capture(t)
|
211
|
+
end
|
212
|
+
}
|
213
|
+
a : b {capture("S.a")} ;
|
214
|
+
b : B ;
|
215
|
+
END
|
216
|
+
load inline_grammar(<<-'END')
|
217
|
+
grammar Master6;
|
218
|
+
options { language=Ruby; }
|
219
|
+
import Slave6;
|
220
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
221
|
+
b : 'b'|'c' ;
|
222
|
+
WS : (' '|'\n') {skip} ;
|
223
|
+
END
|
224
|
+
|
225
|
+
parser = Master6::Parser.new( Master6::Lexer.new( 'c' ) )
|
226
|
+
parser.a
|
227
|
+
parser.output.should == 'S.a'
|
228
|
+
end
|
229
|
+
|
230
|
+
example "lexer delegator invokes delegate rule" do
|
231
|
+
inline_grammar(<<-'END')
|
232
|
+
lexer grammar Slave7;
|
233
|
+
options {
|
234
|
+
language=Ruby;
|
235
|
+
}
|
236
|
+
@members {
|
237
|
+
def capture(t)
|
238
|
+
@master_7.capture(t)
|
239
|
+
end
|
240
|
+
}
|
241
|
+
A : 'a' {capture("S.A ")} ;
|
242
|
+
C : 'c' ;
|
243
|
+
END
|
244
|
+
load inline_grammar(<<-'END')
|
245
|
+
lexer grammar Master7;
|
246
|
+
options {
|
247
|
+
language=Ruby;
|
248
|
+
}
|
249
|
+
import Slave7;
|
250
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
251
|
+
B : 'b' ;
|
252
|
+
WS : (' '|'\n') {skip} ;
|
253
|
+
END
|
254
|
+
|
255
|
+
lexer = Master7::Lexer.new( 'abc' )
|
256
|
+
lexer.map { |tk| lexer.capture(tk.text) }
|
257
|
+
lexer.output.should == 'S.A abc'
|
258
|
+
end
|
259
|
+
|
260
|
+
example "lexer delegator rule overrides delegate" do
|
261
|
+
inline_grammar(<<-'END')
|
262
|
+
lexer grammar Slave8;
|
263
|
+
options {language=Ruby;}
|
264
|
+
@members {
|
265
|
+
def capture(t)
|
266
|
+
@master_8.capture(t)
|
267
|
+
end
|
268
|
+
}
|
269
|
+
A : 'a' {capture("S.A")} ;
|
270
|
+
END
|
271
|
+
load inline_grammar(<<-'END')
|
272
|
+
lexer grammar Master8;
|
273
|
+
options {language=Ruby;}
|
274
|
+
import Slave8;
|
275
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
276
|
+
A : 'a' {capture("M.A ")} ;
|
277
|
+
WS : (' '|'\n') {skip} ;
|
278
|
+
END
|
279
|
+
|
280
|
+
lexer = Master8::Lexer.new('a')
|
281
|
+
lexer.map { |tk| lexer.capture(tk.text) }
|
282
|
+
lexer.output.should == 'M.A a'
|
283
|
+
end
|
284
|
+
|
285
|
+
example "delegator rule with syntactic predicates" do
|
286
|
+
inline_grammar(<<-'END')
|
287
|
+
parser grammar Slave9;
|
288
|
+
options { language=Ruby; }
|
289
|
+
@members {
|
290
|
+
def capture(t)
|
291
|
+
@master_9.capture(t)
|
292
|
+
end
|
293
|
+
}
|
294
|
+
a : b c;
|
295
|
+
c : ('c' 'b')=> 'c' 'b' { capture("(cb)") }
|
296
|
+
| ('c' 'c')=> 'c'
|
297
|
+
;
|
298
|
+
END
|
299
|
+
load inline_grammar(<<-'END')
|
300
|
+
grammar Master9;
|
301
|
+
options { language=Ruby; }
|
302
|
+
import Slave9;
|
303
|
+
@members { include ANTLR3::Test::CaptureOutput }
|
304
|
+
b : ('b' 'b')=> 'b' 'b'
|
305
|
+
| ('b' 'c')=> 'b' {capture("(bc)")}
|
306
|
+
;
|
307
|
+
WS : (' '|'\n') {skip} ;
|
308
|
+
END
|
309
|
+
|
310
|
+
parser = Master9::Parser.new( Master9::Lexer.new( 'bcb' ) )
|
311
|
+
parser.a
|
312
|
+
parser.output.should == '(bc)(cb)'
|
313
|
+
end
|
314
|
+
|
315
|
+
example "lots of imported lexers" do
|
316
|
+
inline_grammar(<<-'END')
|
317
|
+
lexer grammar SlaveOfSlaves;
|
318
|
+
options { language=Ruby; }
|
319
|
+
|
320
|
+
INTEGER: ('+'|'-')? DIGITS;
|
321
|
+
FLOAT: INTEGER '.' DIGITS (('e'|'E') INTEGER)?;
|
322
|
+
fragment DIGITS: ('0'..'9')+;
|
323
|
+
END
|
324
|
+
inline_grammar(<<-'END')
|
325
|
+
lexer grammar FirstSlave;
|
326
|
+
options { language=Ruby; }
|
327
|
+
|
328
|
+
import SlaveOfSlaves;
|
329
|
+
|
330
|
+
ID: ('A'..'Z')+;
|
331
|
+
OPS: '+' | '-' | '*' | '/';
|
332
|
+
END
|
333
|
+
inline_grammar(<<-'END')
|
334
|
+
lexer grammar SecondSlave;
|
335
|
+
options { language=Ruby; }
|
336
|
+
|
337
|
+
INT: ('0'..'9')+;
|
338
|
+
ID: ('a'..'z'|'A'..'Z'|'_')+;
|
339
|
+
END
|
340
|
+
load inline_grammar(<<-'END')
|
341
|
+
lexer grammar MasterOfAll;
|
342
|
+
options { language=Ruby; }
|
343
|
+
|
344
|
+
import FirstSlave, SecondSlave;
|
345
|
+
|
346
|
+
ID: ('a'..'z'|'A'..'Z'|'_')+;
|
347
|
+
WS: ' '+ { $channel=HIDDEN };
|
348
|
+
END
|
349
|
+
|
350
|
+
MasterOfAll::Lexer.master_grammars.should == []
|
351
|
+
MasterOfAll::Lexer.imported_grammars.should == Set[ :FirstSlave, :SecondSlave ]
|
352
|
+
MasterOfAll::Lexer.master.should be_nil
|
353
|
+
|
354
|
+
MasterOfAll::FirstSlave.master_grammars.should == [ :MasterOfAll ]
|
355
|
+
MasterOfAll::FirstSlave.imported_grammars.should == Set[ :SlaveOfSlaves ]
|
356
|
+
MasterOfAll::FirstSlave.master.should == :MasterOfAll
|
357
|
+
|
358
|
+
MasterOfAll::SecondSlave.master_grammars.should == [ :MasterOfAll ]
|
359
|
+
MasterOfAll::SecondSlave.imported_grammars.should == Set[ ]
|
360
|
+
MasterOfAll::SecondSlave.master.should == :MasterOfAll
|
361
|
+
|
362
|
+
MasterOfAll::FirstSlave::SlaveOfSlaves.master_grammars.should == [ :MasterOfAll, :FirstSlave ]
|
363
|
+
MasterOfAll::FirstSlave::SlaveOfSlaves.imported_grammars.should == Set[ ]
|
364
|
+
MasterOfAll::FirstSlave::SlaveOfSlaves.master.should == :FirstSlave
|
365
|
+
|
366
|
+
master = MasterOfAll::Lexer.new( 'blah de blah' )
|
367
|
+
master.should respond_to :first_slave
|
368
|
+
master.should respond_to :second_slave
|
369
|
+
master.first_slave.should respond_to :slave_of_slaves
|
370
|
+
master.first_slave.should respond_to :master_of_all
|
371
|
+
master.first_slave.slave_of_slaves.should respond_to :first_slave
|
372
|
+
master.first_slave.slave_of_slaves.should respond_to :master_of_all
|
373
|
+
dels = master.each_delegate.map { |d| d }
|
374
|
+
dels.should have(2).things
|
375
|
+
dels.should include master.first_slave
|
376
|
+
dels.should include master.second_slave
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|