antlr3 1.2.4 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/antlr4ruby +1 -13
- data/java/RubyTarget.java +8 -125
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3/constants.rb +2 -0
- data/lib/antlr3/dfa.rb +18 -15
- data/lib/antlr3/error.rb +3 -3
- data/lib/antlr3/main.rb +8 -9
- data/lib/antlr3/modes/ast-builder.rb +24 -4
- data/lib/antlr3/recognizers.rb +17 -16
- data/lib/antlr3/task.rb +13 -0
- data/lib/antlr3/token.rb +53 -17
- data/lib/antlr3/tree.rb +491 -561
- data/lib/antlr3/tree/wizard.rb +139 -127
- data/lib/antlr3/util.rb +7 -1
- data/lib/antlr3/version.rb +4 -4
- data/samples/{Cpp.g → CPP.g} +1 -1
- data/templates/AST.stg +1 -1
- data/templates/Ruby.stg +29 -42
- data/test/functional/ast-output/auto-ast.rb +3 -3
- data/test/functional/ast-output/tree-rewrite.rb +1 -1
- data/test/functional/debugging/debug-mode.rb +2 -2
- data/test/unit/test-tree-wizard.rb +115 -156
- data/test/unit/test-trees.rb +66 -77
- metadata +4 -5
- data/lib/antlr3/test/config.rb +0 -23
- data/lib/antlr3/test/diff.rb +0 -165
data/samples/{Cpp.g → CPP.g}
RENAMED
data/templates/AST.stg
CHANGED
data/templates/Ruby.stg
CHANGED
@@ -16,9 +16,10 @@ outputFile(LEXER, PARSER, TREE_PARSER, actionScope, actions, docComment, recogni
|
|
16
16
|
#
|
17
17
|
# <fileName>
|
18
18
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
19
|
+
# Generated using ANTLR version: <ANTLRVersion>
|
20
|
+
# Ruby runtime library version: <runtimeLibraryVersion()>
|
21
|
+
# Input grammar file: <fileName>
|
22
|
+
# Generated at: <generatedTimestamp>
|
22
23
|
#
|
23
24
|
|
24
25
|
# ~~~\> start load path setup
|
@@ -29,7 +30,7 @@ antlr_load_failed = proc do
|
|
29
30
|
load_path = $LOAD_PATH.map { |dir| ' - ' \<\< dir }.join( $/ )
|
30
31
|
raise LoadError, \<\<-'END'.strip!
|
31
32
|
|
32
|
-
Failed to load the ANTLR3 runtime library:
|
33
|
+
Failed to load the ANTLR3 runtime library (version <runtimeLibraryVersion()>):
|
33
34
|
|
34
35
|
Ensure the library has been installed on your system and is available
|
35
36
|
on the load path. If rubygems is available on your system, this can
|
@@ -59,7 +60,7 @@ rescue LoadError
|
|
59
60
|
|
60
61
|
# 3: try to activate the antlr3 gem
|
61
62
|
begin
|
62
|
-
Gem.activate( 'antlr3' )
|
63
|
+
Gem.activate( 'antlr3', '= <runtimeLibraryVersion()>' )
|
63
64
|
rescue Gem::LoadError
|
64
65
|
antlr_load_failed.call
|
65
66
|
end
|
@@ -110,20 +111,12 @@ module TokenData
|
|
110
111
|
register_names(<tokenNames:{<it>}; separator=", ", anchor, wrap="\n">)
|
111
112
|
|
112
113
|
<endif>
|
113
|
-
|
114
|
-
|
115
|
-
<
|
116
|
-
|
117
|
-
<endif>
|
118
|
-
<if(actions.token.members)>
|
119
|
-
|
120
|
-
class Token
|
121
|
-
<action(name="token::members",code=actions.token.members)>
|
122
|
-
end
|
123
|
-
|
124
|
-
<endif>
|
114
|
+
|
115
|
+
<placeAction(scope="token",name="scheme")>
|
116
|
+
<placeAction(scope="token",name="members")>
|
125
117
|
end<\n>
|
126
118
|
>>
|
119
|
+
|
127
120
|
rootGrammarOutputFile() ::= <<
|
128
121
|
module <recognizer.grammar.name>
|
129
122
|
<placeAction(scope="module",name="head")>
|
@@ -132,6 +125,7 @@ module <recognizer.grammar.name>
|
|
132
125
|
<placeAction(scope="module",name="foot")>
|
133
126
|
end
|
134
127
|
>>
|
128
|
+
|
135
129
|
delegateGrammarOutputFile() ::= <<
|
136
130
|
require '<recognizer.grammar.delegator.recognizerName>'
|
137
131
|
|
@@ -139,6 +133,7 @@ require '<recognizer.grammar.delegator.recognizerName>'
|
|
139
133
|
<recognizer>
|
140
134
|
<delegateGrammarModuleTail(gram=recognizer.grammar.delegator)>
|
141
135
|
>>
|
136
|
+
|
142
137
|
delegateGrammarModuleHead(gram) ::= <<
|
143
138
|
<if(gram.grammarIsRoot)>
|
144
139
|
module <gram.name>
|
@@ -147,6 +142,7 @@ module <gram.name>
|
|
147
142
|
class <gram.name>
|
148
143
|
<endif>
|
149
144
|
>>
|
145
|
+
|
150
146
|
delegateGrammarModuleTail(gram) ::= <<
|
151
147
|
<if(gram.grammarIsRoot)>
|
152
148
|
end # module <gram.name>
|
@@ -187,6 +183,7 @@ end # class <if(grammar.grammarIsRoot)>TreeParser<else><grammar.name><endif> \<
|
|
187
183
|
at_exit { <if(grammar.grammarIsRoot)>TreeParser<else><grammar.name><endif>.main(ARGV) } if __FILE__ == $0
|
188
184
|
<endif>
|
189
185
|
>>
|
186
|
+
|
190
187
|
parserBody(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets, inputStreamType, superClass, filterMode, ASTLabelType="Object", labelType, members, rewriteElementType, actionScope) ::= <<
|
191
188
|
@grammar_home = <grammar.name>
|
192
189
|
<if(!grammar.grammarIsRoot)><autoloadDelegates()><\n><endif>
|
@@ -205,7 +202,7 @@ imports( <grammar.directDelegates:{d|:<d.name>}; separator=", "> )<\n>
|
|
205
202
|
|
206
203
|
include TokenData
|
207
204
|
|
208
|
-
generated_using("<fileName>", "<ANTLRVersion>")
|
205
|
+
generated_using( "<fileName>", "<ANTLRVersion>", "<runtimeLibraryVersion()>" )
|
209
206
|
|
210
207
|
<if(!grammar.grammarIsRoot)>
|
211
208
|
require '<grammar.composite.rootGrammar.recognizerName>'
|
@@ -235,6 +232,7 @@ end
|
|
235
232
|
<endif>
|
236
233
|
<bitsets:{TOKENS_FOLLOWING_<it.name>_IN_<it.inName>_<it.tokenIndex> = Set[<it.tokenTypes:{<it>}; separator=", ">]<\n>}>
|
237
234
|
>>
|
235
|
+
|
238
236
|
parserConstructor() ::= <<
|
239
237
|
def initialize(<grammar.delegators:{g|<g:delegateName()>, }>input, options = {})
|
240
238
|
super(input, options)
|
@@ -346,6 +344,7 @@ loop do #loop <decisionNumber>
|
|
346
344
|
end
|
347
345
|
end
|
348
346
|
>>
|
347
|
+
|
349
348
|
delegateName() ::= <<
|
350
349
|
<if(it.label)><it.label; format="label"><else><it.name; format="snakecase"><endif>
|
351
350
|
>>
|
@@ -355,10 +354,8 @@ element() ::= <<
|
|
355
354
|
<it.el><\n>
|
356
355
|
>>
|
357
356
|
|
358
|
-
|
359
357
|
execForcedAction(action) ::= "<action>"
|
360
358
|
|
361
|
-
|
362
359
|
globalAttributeScopeClass(scope) ::= <<
|
363
360
|
<if(scope.attributes)>Scope<scope.name> = Struct.new(<scope.attributes:{:<it.decl>}; separator=", ">)<endif>
|
364
361
|
>>
|
@@ -895,6 +892,12 @@ class DFA<dfa.decisionNumber> \< ANTLR3::DFA
|
|
895
892
|
<dfa.javaCompressedTransition:{s|unpack(<s; wrap="\n", anchor, separator=", ">)}; separator=",\n">
|
896
893
|
].freeze
|
897
894
|
|
895
|
+
( 0 ... MIN.length ).zip( MIN, MAX ) do | i, a, z |
|
896
|
+
if a \> 0 and z \< 0
|
897
|
+
MAX[ i ] %= 0x10000
|
898
|
+
end
|
899
|
+
end
|
900
|
+
|
898
901
|
@decision = <dfa.decisionNumber>
|
899
902
|
|
900
903
|
<@errorMethod()>
|
@@ -927,7 +930,7 @@ end
|
|
927
930
|
|
928
931
|
|
929
932
|
cyclicDFASynpred(name) ::= <<
|
930
|
-
def <name
|
933
|
+
def <name>() @recognizer.<name> end<\n>
|
931
934
|
>>
|
932
935
|
|
933
936
|
|
@@ -972,15 +975,6 @@ s = -1
|
|
972
975
|
<endif>
|
973
976
|
>>
|
974
977
|
|
975
|
-
|
976
|
-
/*
|
977
|
-
line_<decisionNumber>_<stateNumber> = input.line
|
978
|
-
col_<decisionNumber>_<stateNumber> = input.column
|
979
|
-
----
|
980
|
-
input.column = col_<decisionNumber>_<stateNumber>
|
981
|
-
input.line = line_<decisionNumber>_<stateNumber>
|
982
|
-
*/
|
983
|
-
|
984
978
|
/** Just like a fixed DFA edge, test the look and indicate
|
985
979
|
* what state to jump to next if successful. Again, this is
|
986
980
|
* for special states.
|
@@ -1002,16 +996,12 @@ e
|
|
1002
996
|
|
1003
997
|
andPredicates(left,right) ::= "( ( <left> ) and ( <right> ) )"
|
1004
998
|
|
1005
|
-
|
1006
|
-
orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | or <o>}>)"
|
1007
|
-
|
999
|
+
orPredicates(operands) ::= "(<first(operands)><rest(operands):{o| or <o>}>)"
|
1008
1000
|
|
1009
1001
|
notPredicate(pred) ::= "not (<evalPredicate(...)>)"
|
1010
1002
|
|
1011
|
-
|
1012
1003
|
evalPredicate(pred,description) ::= "(<pred>)"
|
1013
1004
|
|
1014
|
-
|
1015
1005
|
evalSynPredicate(pred,description) ::= <<
|
1016
1006
|
syntactic_predicate?(<pred:{<it; format="lexerRule">}; format="symbol">)
|
1017
1007
|
>>
|
@@ -1019,7 +1009,6 @@ syntactic_predicate?(<pred:{<it; format="lexerRule">}; format="symbol">)
|
|
1019
1009
|
|
1020
1010
|
lookaheadTest(atom, k, atomAsInt) ::= "look_<decisionNumber>_<stateNumber> == <atom>"
|
1021
1011
|
|
1022
|
-
|
1023
1012
|
/** Sometimes a look test cannot assume that LA(k) is in a
|
1024
1013
|
* temp variable somewhere. Must ask for the look
|
1025
1014
|
* directly.
|
@@ -1161,13 +1150,12 @@ ruleLabelPropertyRef_text(scope, attr) ::= <<
|
|
1161
1150
|
|
1162
1151
|
ruleLabelPropertyRef_st(scope, attr) ::= "(<scope; format=\"label\">.nil? ? nil : <scope; format=\"label\">.st)"
|
1163
1152
|
|
1164
|
-
|
1165
|
-
|
1166
1153
|
/******************************************************************************
|
1167
1154
|
***************** L E X E R - O N L Y T E M P L A T E S ******************
|
1168
1155
|
******************************************************************************/
|
1169
1156
|
|
1170
1157
|
lexerSynpred(name) ::= ""
|
1158
|
+
|
1171
1159
|
lexer(grammar, name, tokens, scopes, rules, numRules, labelType="ANTLR3::Token", filterMode, superClass="ANTLR3::Lexer") ::= <<
|
1172
1160
|
<if(grammar.grammarIsRoot)><autoloadDelegates()><endif>
|
1173
1161
|
|
@@ -1180,7 +1168,7 @@ class <if(grammar.delegator)><grammar.name><else>Lexer<endif> \< <superClass>
|
|
1180
1168
|
<endif>
|
1181
1169
|
<scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScopeClass(scope=it)><\n><endif>}>
|
1182
1170
|
begin
|
1183
|
-
generated_using(
|
1171
|
+
generated_using( "<fileName>", "<ANTLRVersion>", "<runtimeLibraryVersion()>" )
|
1184
1172
|
rescue NoMethodError => error
|
1185
1173
|
error.name.to_sym == :generated_using or raise
|
1186
1174
|
end
|
@@ -1466,7 +1454,7 @@ end
|
|
1466
1454
|
|
1467
1455
|
codeFileExtension() ::= ".rb"
|
1468
1456
|
|
1469
|
-
true()
|
1457
|
+
true() ::= "true"
|
1470
1458
|
false() ::= "false"
|
1471
1459
|
|
1472
1460
|
action(name, code) ::= <<
|
@@ -1510,5 +1498,4 @@ placeAction(scope, name) ::= <<
|
|
1510
1498
|
<endif>
|
1511
1499
|
>>
|
1512
1500
|
|
1513
|
-
|
1514
|
-
|
1501
|
+
runtimeLibraryVersion() ::= "1.3.0"
|
@@ -710,7 +710,7 @@ class TestAutoAST < ANTLR3::Test::Functional
|
|
710
710
|
options {language=Ruby;output=AST;}
|
711
711
|
a returns [result]: x+=b x+=b {
|
712
712
|
t = $x[1]
|
713
|
-
$result = "2nd x=#{t.
|
713
|
+
$result = "2nd x=#{t.inspect},"
|
714
714
|
};
|
715
715
|
b : ID;
|
716
716
|
ID : 'a'..'z'+ ;
|
@@ -726,7 +726,7 @@ class TestAutoAST < ANTLR3::Test::Functional
|
|
726
726
|
grammar RuleListLabelRuleRoot;
|
727
727
|
options {language=Ruby;output=AST;}
|
728
728
|
a returns [result] : ( x+=b^ )+ {
|
729
|
-
$result = "x=%s," \% $x[1].
|
729
|
+
$result = "x=%s," \% $x[1].inspect
|
730
730
|
} ;
|
731
731
|
b : ID;
|
732
732
|
ID : 'a'..'z'+ ;
|
@@ -742,7 +742,7 @@ class TestAutoAST < ANTLR3::Test::Functional
|
|
742
742
|
grammar RuleListLabelBang;
|
743
743
|
options {language=Ruby;output=AST;}
|
744
744
|
a returns [result] : x+=b! x+=b {
|
745
|
-
$result = "1st x=#{$x[0].
|
745
|
+
$result = "1st x=#{$x[0].inspect},"
|
746
746
|
} ;
|
747
747
|
b : ID;
|
748
748
|
ID : 'a'..'z'+ ;
|
@@ -4,7 +4,7 @@
|
|
4
4
|
require 'antlr3'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'antlr3/test/functional'
|
7
|
-
require 'antlr3/test/diff'
|
7
|
+
#require 'antlr3/test/diff'
|
8
8
|
|
9
9
|
class ANTLRDebugger < Thread
|
10
10
|
self.abort_on_exception = true
|
@@ -61,7 +61,7 @@ end # ANTLRDebugger
|
|
61
61
|
class TestDebugGrammars < ANTLR3::Test::Functional
|
62
62
|
compile_options :debug => true
|
63
63
|
|
64
|
-
include ANTLR3::Test::Diff
|
64
|
+
#include ANTLR3::Test::Diff
|
65
65
|
|
66
66
|
def parse(grammar, rule, input, options = {})
|
67
67
|
@grammar = inline_grammar(grammar)
|
@@ -6,24 +6,23 @@ require 'antlr3/tree/wizard'
|
|
6
6
|
require 'test/unit'
|
7
7
|
require 'spec'
|
8
8
|
|
9
|
-
|
10
9
|
include ANTLR3
|
11
10
|
include ANTLR3::AST
|
12
11
|
|
13
|
-
class
|
12
|
+
class TestPatternLexer < Test::Unit::TestCase
|
14
13
|
|
15
14
|
# vvvvvvvv tests vvvvvvvvv
|
16
15
|
|
17
16
|
def test_open
|
18
|
-
lexer = Wizard::
|
17
|
+
lexer = Wizard::PatternLexer.new( '(' )
|
19
18
|
type = lexer.next_token
|
20
|
-
assert_equal(type, :open)
|
21
|
-
assert_equal(lexer.text, '')
|
22
|
-
assert_equal(lexer.error, false)
|
19
|
+
assert_equal( type, :open )
|
20
|
+
assert_equal( lexer.text, '' )
|
21
|
+
assert_equal( lexer.error, false )
|
23
22
|
end
|
24
23
|
|
25
24
|
def test_close
|
26
|
-
lexer = Wizard::
|
25
|
+
lexer = Wizard::PatternLexer.new(')')
|
27
26
|
type = lexer.next_token
|
28
27
|
assert_equal(type, :close)
|
29
28
|
assert_equal(lexer.text, '')
|
@@ -31,7 +30,7 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
31
30
|
end
|
32
31
|
|
33
32
|
def test_percent
|
34
|
-
lexer = Wizard::
|
33
|
+
lexer = Wizard::PatternLexer.new('%')
|
35
34
|
type = lexer.next_token
|
36
35
|
assert_equal(type, :percent)
|
37
36
|
assert_equal(lexer.text, '')
|
@@ -39,7 +38,7 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
39
38
|
end
|
40
39
|
|
41
40
|
def test_dot
|
42
|
-
lexer = Wizard::
|
41
|
+
lexer = Wizard::PatternLexer.new('.')
|
43
42
|
type = lexer.next_token
|
44
43
|
assert_equal(type, :dot)
|
45
44
|
assert_equal(lexer.text, '')
|
@@ -47,7 +46,7 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def test_eof
|
50
|
-
lexer = Wizard::
|
49
|
+
lexer = Wizard::PatternLexer.new(" \n \r \t ")
|
51
50
|
type = lexer.next_token
|
52
51
|
assert_equal(type, EOF)
|
53
52
|
assert_equal(lexer.text, '')
|
@@ -55,7 +54,7 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
55
54
|
end
|
56
55
|
|
57
56
|
def test_id
|
58
|
-
lexer = Wizard::
|
57
|
+
lexer = Wizard::PatternLexer.new('__whatever_1__')
|
59
58
|
type = lexer.next_token
|
60
59
|
assert_equal(:identifier, type)
|
61
60
|
assert_equal('__whatever_1__', lexer.text)
|
@@ -63,7 +62,7 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
63
62
|
end
|
64
63
|
|
65
64
|
def test_arg
|
66
|
-
lexer = Wizard::
|
65
|
+
lexer = Wizard::PatternLexer.new('[ \]bla\n]')
|
67
66
|
type = lexer.next_token
|
68
67
|
assert_equal(type, :argument)
|
69
68
|
assert_equal(' ]bla\n', lexer.text)
|
@@ -71,7 +70,7 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
71
70
|
end
|
72
71
|
|
73
72
|
def test_error
|
74
|
-
lexer = Wizard::
|
73
|
+
lexer = Wizard::PatternLexer.new("1")
|
75
74
|
type = lexer.next_token
|
76
75
|
assert_equal(type, EOF)
|
77
76
|
assert_equal(lexer.text, '')
|
@@ -81,96 +80,75 @@ class TestTreePatternLexer < Test::Unit::TestCase
|
|
81
80
|
end
|
82
81
|
|
83
82
|
|
84
|
-
class
|
83
|
+
class TestPatternParser < Test::Unit::TestCase
|
84
|
+
Tokens = TokenScheme.build %w(A B C D E ID VAR)
|
85
|
+
include Tokens
|
86
|
+
|
85
87
|
def setup
|
86
|
-
@adaptor = CommonTreeAdaptor.new
|
87
|
-
@pattern_adaptor = Wizard::
|
88
|
-
@
|
89
|
-
@wizard = Wizard.new(@adaptor, @tokens)
|
88
|
+
@adaptor = CommonTreeAdaptor.new( Tokens.token_class )
|
89
|
+
@pattern_adaptor = Wizard::PatternAdaptor.new( Tokens.token_class )
|
90
|
+
@wizard = Wizard.new( :adaptor => @adaptor, :token_scheme => Tokens )
|
90
91
|
end
|
91
92
|
|
92
93
|
# vvvvvvvv tests vvvvvvvvv
|
93
94
|
def test_single_node
|
94
|
-
|
95
|
-
|
96
|
-
tree = parser.pattern
|
97
|
-
|
95
|
+
tree = Wizard::PatternParser.parse( 'ID', Tokens, @adaptor )
|
96
|
+
|
98
97
|
assert_instance_of(CommonTree, tree)
|
99
|
-
assert_equal(
|
100
|
-
assert_equal('ID', tree.text)
|
98
|
+
assert_equal( ID, tree.type )
|
99
|
+
assert_equal( 'ID', tree.text )
|
101
100
|
end
|
102
101
|
|
103
102
|
def test_single_node_with_arg
|
104
|
-
|
105
|
-
|
106
|
-
tree
|
107
|
-
|
108
|
-
|
109
|
-
assert_equal(10, tree.type)
|
110
|
-
assert_equal('foo', tree.text)
|
103
|
+
tree = Wizard::PatternParser.parse( 'ID[foo]', Tokens, @adaptor )
|
104
|
+
|
105
|
+
assert_instance_of( CommonTree, tree )
|
106
|
+
assert_equal( ID, tree.type )
|
107
|
+
assert_equal( 'foo', tree.text )
|
111
108
|
end
|
112
109
|
|
113
110
|
def test_single_level_tree
|
114
|
-
|
115
|
-
|
116
|
-
tree
|
117
|
-
|
118
|
-
assert_instance_of(CommonTree, tree)
|
119
|
-
assert_equal(5, tree.type)
|
111
|
+
tree = Wizard::PatternParser.parse( '(A B)', Tokens, @adaptor )
|
112
|
+
|
113
|
+
assert_instance_of( CommonTree, tree )
|
114
|
+
assert_equal(A, tree.type)
|
120
115
|
assert_equal('A', tree.text)
|
121
116
|
assert_equal(tree.child_count, 1)
|
122
|
-
assert_equal(tree.child(0).type,
|
117
|
+
assert_equal(tree.child(0).type, B)
|
123
118
|
assert_equal(tree.child(0).text, 'B')
|
124
119
|
end
|
125
120
|
|
126
121
|
def test_nil
|
127
|
-
|
128
|
-
|
129
|
-
tree = parser.pattern
|
130
|
-
|
122
|
+
tree = Wizard::PatternParser.parse( 'nil', Tokens, @adaptor )
|
123
|
+
|
131
124
|
assert_instance_of(CommonTree, tree)
|
132
125
|
assert_equal(0, tree.type)
|
133
126
|
assert_nil tree.text
|
134
127
|
end
|
135
128
|
|
136
129
|
def test_wildcard
|
137
|
-
|
138
|
-
|
139
|
-
tree = parser.pattern
|
140
|
-
|
141
|
-
assert_instance_of(Wizard::WildcardTreePattern, tree)
|
130
|
+
tree = Wizard::PatternParser.parse( '(.)', Tokens, @adaptor )
|
131
|
+
assert_instance_of( Wizard::WildcardPattern, tree )
|
142
132
|
end
|
143
133
|
|
144
134
|
def test_label
|
145
|
-
|
146
|
-
|
147
|
-
tree = parser.pattern
|
148
|
-
|
149
|
-
assert_instance_of(Wizard::TreePattern, tree)
|
135
|
+
tree = Wizard::PatternParser.parse( '(%a:A)', Tokens, @pattern_adaptor )
|
136
|
+
assert_instance_of(Wizard::Pattern, tree)
|
150
137
|
assert_equal('a', tree.label)
|
151
138
|
end
|
152
139
|
|
153
140
|
def test_error_1
|
154
|
-
|
155
|
-
parser = Wizard::TreePatternParser.new(lexer, @wizard, @adaptor)
|
156
|
-
tree = parser.pattern
|
157
|
-
|
141
|
+
tree = Wizard::PatternParser.parse( ')', Tokens, @adaptor )
|
158
142
|
assert_nil tree
|
159
143
|
end
|
160
144
|
|
161
145
|
def test_error_2
|
162
|
-
|
163
|
-
parser = Wizard::TreePatternParser.new(lexer, @wizard, @adaptor)
|
164
|
-
tree = parser.pattern
|
165
|
-
|
146
|
+
tree = Wizard::PatternParser.parse( '()', Tokens, @adaptor )
|
166
147
|
assert_nil tree
|
167
148
|
end
|
168
149
|
|
169
150
|
def test_error_3
|
170
|
-
|
171
|
-
parser = Wizard::TreePatternParser.new(lexer, @wizard, @adaptor)
|
172
|
-
tree = parser.pattern
|
173
|
-
|
151
|
+
tree = Wizard::PatternParser.parse( '(A ])', Tokens, @adaptor )
|
174
152
|
assert_nil tree
|
175
153
|
end
|
176
154
|
|
@@ -178,75 +156,60 @@ end
|
|
178
156
|
|
179
157
|
|
180
158
|
class TestTreeWizard < Test::Unit::TestCase
|
159
|
+
Tokens = TokenScheme.build %w(A B C D E ID VAR)
|
160
|
+
include Tokens
|
181
161
|
|
182
162
|
def setup
|
183
|
-
@adaptor =
|
184
|
-
@
|
185
|
-
|
163
|
+
@adaptor = CommonTreeAdaptor.new( Tokens.token_class )
|
164
|
+
@wizard = Wizard.new( :adaptor => @adaptor, :token_scheme => Tokens )
|
165
|
+
end
|
166
|
+
|
167
|
+
def create_wizard( tokens )
|
168
|
+
Wizard.new( :tokens => tokens )
|
186
169
|
end
|
187
170
|
|
188
171
|
# vvvvvvvv tests vvvvvvvvv
|
189
172
|
def test_init
|
190
|
-
|
173
|
+
@wizard = Wizard.new( :tokens => %w(A B), :adaptor => @adaptor )
|
191
174
|
|
192
|
-
assert_equal(
|
193
|
-
|
175
|
+
assert_equal( @wizard.adaptor, @adaptor )
|
176
|
+
assert_kind_of( ANTLR3::TokenScheme, @wizard.token_scheme )
|
194
177
|
end
|
195
178
|
|
196
|
-
def test_token_type
|
197
|
-
wiz = Wizard.new(@adaptor, @tokens)
|
198
|
-
assert_equal(wiz.token_type('A'), 5)
|
199
|
-
assert_equal(wiz.token_type('VAR'), 11)
|
200
|
-
assert_equal(wiz.token_type('invalid'), INVALID_TOKEN_TYPE)
|
201
|
-
end
|
202
|
-
|
203
179
|
def test_single_node
|
204
|
-
|
205
|
-
t
|
206
|
-
|
207
|
-
assert_equal(t.to_string_tree, 'ID')
|
180
|
+
t = @wizard.create("ID")
|
181
|
+
assert_equal(t.inspect, 'ID')
|
208
182
|
end
|
209
183
|
|
210
184
|
def test_single_node_with_arg
|
211
|
-
|
212
|
-
t = wiz.create("ID[foo]")
|
185
|
+
t = @wizard.create("ID[foo]")
|
213
186
|
|
214
|
-
assert_equal(t.
|
187
|
+
assert_equal(t.inspect, 'foo')
|
215
188
|
end
|
216
189
|
|
217
190
|
def test_single_node_tree
|
218
|
-
|
219
|
-
t
|
220
|
-
|
221
|
-
assert_equal(t.to_string_tree, 'A')
|
191
|
+
t = @wizard.create("(A)")
|
192
|
+
assert_equal(t.inspect, 'A')
|
222
193
|
end
|
223
194
|
|
224
195
|
def test_single_level_tree
|
225
|
-
|
226
|
-
t
|
227
|
-
|
228
|
-
assert_equal(t.to_string_tree, '(A B C D)')
|
196
|
+
t = @wizard.create("(A B C D)")
|
197
|
+
assert_equal(t.inspect, '(A B C D)')
|
229
198
|
end
|
230
199
|
|
231
200
|
def test_list_tree
|
232
|
-
|
233
|
-
t
|
234
|
-
|
235
|
-
assert_equal(t.to_string_tree, 'A B C')
|
201
|
+
t = @wizard.create("(nil A B C)")
|
202
|
+
assert_equal(t.inspect, 'A B C')
|
236
203
|
end
|
237
204
|
|
238
205
|
def test_invalid_list_tree
|
239
|
-
|
240
|
-
t = wiz.create("A B C")
|
241
|
-
|
206
|
+
t = @wizard.create("A B C")
|
242
207
|
assert_nil t
|
243
208
|
end
|
244
209
|
|
245
210
|
def test_double_level_tree
|
246
|
-
|
247
|
-
t
|
248
|
-
|
249
|
-
assert_equal(t.to_string_tree, "(A (B C) (B D) E)")
|
211
|
+
t = @wizard.create("(A (B C) (B D) E)")
|
212
|
+
assert_equal(t.inspect, "(A (B C) (B D) E)")
|
250
213
|
end
|
251
214
|
|
252
215
|
SIMPLIFY_MAP = lambda do |imap|
|
@@ -256,33 +219,30 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
256
219
|
end
|
257
220
|
|
258
221
|
def test_single_node_index
|
259
|
-
|
260
|
-
|
261
|
-
index_map = SIMPLIFY_MAP[wiz.index(tree)]
|
222
|
+
tree = @wizard.create("ID")
|
223
|
+
index_map = SIMPLIFY_MAP[@wizard.index(tree)]
|
262
224
|
|
263
|
-
assert_equal(index_map,
|
225
|
+
assert_equal(index_map, ID => %w(ID))
|
264
226
|
end
|
265
227
|
|
266
228
|
|
267
229
|
def test_no_repeats_index
|
268
|
-
|
269
|
-
|
270
|
-
index_map = SIMPLIFY_MAP[wiz.index(tree)]
|
230
|
+
tree = @wizard.create("(A B C D)")
|
231
|
+
index_map = SIMPLIFY_MAP[@wizard.index(tree)]
|
271
232
|
|
272
233
|
assert_equal(index_map,
|
273
|
-
|
274
|
-
|
234
|
+
D => %w(D), B => %w(B),
|
235
|
+
C => %w(C), A => %w(A)
|
275
236
|
)
|
276
237
|
end
|
277
238
|
|
278
239
|
def test_repeats_index
|
279
|
-
|
280
|
-
|
281
|
-
index_map = SIMPLIFY_MAP[wiz.index(tree)]
|
240
|
+
tree = @wizard.create("(A B (A C B) B D D)")
|
241
|
+
index_map = SIMPLIFY_MAP[@wizard.index(tree)]
|
282
242
|
|
283
243
|
assert_equal(index_map,
|
284
|
-
|
285
|
-
|
244
|
+
D => %w(D D), B => %w(B B B),
|
245
|
+
C => %w(C), A => %w(A A)
|
286
246
|
)
|
287
247
|
end
|
288
248
|
|
@@ -291,11 +251,11 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
291
251
|
tree = @wizard.create("(A B C D)")
|
292
252
|
|
293
253
|
elements = []
|
294
|
-
@wizard.visit(tree,
|
254
|
+
@wizard.visit( tree, B ) do |node, parent, child_index, labels|
|
295
255
|
elements << node.to_s
|
296
256
|
end
|
297
257
|
|
298
|
-
assert_equal(%w(B), elements)
|
258
|
+
assert_equal( %w(B), elements )
|
299
259
|
end
|
300
260
|
|
301
261
|
|
@@ -303,7 +263,7 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
303
263
|
tree = @wizard.create("(A B (A C B) B D D)")
|
304
264
|
|
305
265
|
elements = []
|
306
|
-
@wizard.visit(tree,
|
266
|
+
@wizard.visit( tree, C ) do |node, parent, child_index, labels|
|
307
267
|
elements << node.to_s
|
308
268
|
end
|
309
269
|
|
@@ -315,7 +275,7 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
315
275
|
tree = @wizard.create("(A B (A C B) B D D)")
|
316
276
|
|
317
277
|
elements = []
|
318
|
-
@wizard.visit(tree,
|
278
|
+
@wizard.visit( tree, B ) do |node, parent, child_index, labels|
|
319
279
|
elements << node.to_s
|
320
280
|
end
|
321
281
|
|
@@ -327,7 +287,7 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
327
287
|
tree = @wizard.create("(A B (A C B) B D D)")
|
328
288
|
|
329
289
|
elements = []
|
330
|
-
@wizard.visit(tree,
|
290
|
+
@wizard.visit( tree, A ) do |node, parent, child_index, labels|
|
331
291
|
elements << node.to_s
|
332
292
|
end
|
333
293
|
|
@@ -342,7 +302,7 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
342
302
|
tree = @wizard.create("(A B (A C B) B D D)")
|
343
303
|
|
344
304
|
elements = []
|
345
|
-
@wizard.visit(tree,
|
305
|
+
@wizard.visit( tree, B ) do |node, parent, child_index, labels|
|
346
306
|
elements << context(node, parent, child_index)
|
347
307
|
end
|
348
308
|
|
@@ -354,14 +314,13 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
354
314
|
tree = @wizard.create("(A B (A C B) B D D)")
|
355
315
|
|
356
316
|
elements = []
|
357
|
-
@wizard.visit(tree,
|
317
|
+
@wizard.visit( tree, A ) do |node, parent, child_index, labels|
|
358
318
|
elements << context(node, parent, child_index)
|
359
319
|
end
|
360
320
|
|
361
|
-
assert_equal(['A@nil[
|
321
|
+
assert_equal(['A@nil[-1]', 'A@A[1]'], elements)
|
362
322
|
end
|
363
323
|
|
364
|
-
|
365
324
|
def test_visit_pattern
|
366
325
|
tree = @wizard.create("(A B C (A B) D)")
|
367
326
|
|
@@ -402,83 +361,83 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
402
361
|
end
|
403
362
|
|
404
363
|
|
405
|
-
def
|
364
|
+
def test_match
|
406
365
|
tree = @wizard.create("(A B C)")
|
407
|
-
assert @wizard.
|
366
|
+
assert @wizard.match(tree, "(A B C)")
|
408
367
|
end
|
409
368
|
|
410
|
-
def
|
369
|
+
def test_match_single_node
|
411
370
|
tree = @wizard.create('A')
|
412
|
-
assert @wizard.
|
371
|
+
assert @wizard.match(tree, 'A')
|
413
372
|
end
|
414
373
|
|
415
|
-
def
|
374
|
+
def test_match_single_node_fails
|
416
375
|
tree = @wizard.create('A')
|
417
|
-
assert( !(@wizard.
|
376
|
+
assert( !(@wizard.match(tree, 'B')) )
|
418
377
|
end
|
419
378
|
|
420
379
|
|
421
|
-
def
|
380
|
+
def test_match_flat_tree
|
422
381
|
tree = @wizard.create('(nil A B C)')
|
423
|
-
assert @wizard.
|
382
|
+
assert @wizard.match(tree, '(nil A B C)')
|
424
383
|
end
|
425
384
|
|
426
|
-
def
|
385
|
+
def test_match_flat_tree_fails
|
427
386
|
tree = @wizard.create('(nil A B C)')
|
428
|
-
assert( !(@wizard.
|
387
|
+
assert( !(@wizard.match(tree, '(nil A B)')) )
|
429
388
|
end
|
430
389
|
|
431
|
-
def
|
390
|
+
def test_match_flat_tree_fails2
|
432
391
|
tree = @wizard.create('(nil A B C)')
|
433
|
-
assert( !(@wizard.
|
392
|
+
assert( !(@wizard.match(tree, '(nil A B A)')) )
|
434
393
|
end
|
435
394
|
|
436
395
|
def test_wildcard
|
437
396
|
tree = @wizard.create('(A B C)')
|
438
|
-
assert @wizard.
|
397
|
+
assert @wizard.match(tree, '(A . .)')
|
439
398
|
end
|
440
399
|
|
441
|
-
def
|
400
|
+
def test_match_with_text
|
442
401
|
tree = @wizard.create('(A B[foo] C[bar])')
|
443
|
-
assert @wizard.
|
402
|
+
assert @wizard.match(tree, '(A B[foo] C)')
|
444
403
|
end
|
445
404
|
|
446
|
-
def
|
405
|
+
def test_match_with_text_fails
|
447
406
|
tree = @wizard.create('(A B C)')
|
448
|
-
assert( !(@wizard.
|
407
|
+
assert( !(@wizard.match(tree, '(A[foo] B C)')) )
|
449
408
|
end
|
450
409
|
|
451
|
-
def
|
410
|
+
def test_match_labels
|
452
411
|
tree = @wizard.create('(A B C)')
|
453
|
-
labels =
|
454
|
-
|
412
|
+
labels = @wizard.match( tree, '(%a:A %b:B %c:C)' )
|
413
|
+
|
455
414
|
assert_equal('A', labels['a'].to_s)
|
456
415
|
assert_equal('B', labels['b'].to_s)
|
457
416
|
assert_equal('C', labels['c'].to_s)
|
458
417
|
end
|
459
418
|
|
460
|
-
def
|
419
|
+
def test_match_with_wildcard_labels
|
461
420
|
tree = @wizard.create('(A B C)')
|
462
|
-
labels =
|
463
|
-
|
421
|
+
labels = @wizard.match(tree, '(A %b:. %c:.)')
|
422
|
+
assert_kind_of( Hash, labels )
|
464
423
|
assert_equal('B', labels['b'].to_s)
|
465
424
|
assert_equal('C', labels['c'].to_s)
|
466
425
|
end
|
467
426
|
|
468
427
|
|
469
|
-
def
|
428
|
+
def test_match_labels_and_test_text
|
470
429
|
tree = @wizard.create('(A B[foo] C)')
|
471
|
-
labels =
|
472
|
-
|
430
|
+
labels = @wizard.match( tree, '(%a:A %b:B[foo] %c:C)' )
|
431
|
+
assert_kind_of( Hash, labels )
|
473
432
|
assert_equal('A', labels['a'].to_s)
|
474
433
|
assert_equal('foo', labels['b'].to_s)
|
475
434
|
assert_equal('C', labels['c'].to_s)
|
476
435
|
end
|
477
436
|
|
478
|
-
def
|
437
|
+
def test_match_labels_in_nested_tree
|
479
438
|
tree = @wizard.create('(A (B C) (D E))')
|
480
|
-
labels =
|
481
|
-
|
439
|
+
labels = @wizard.match( tree, '(%a:A (%b:B %c:C) (%d:D %e:E))' )
|
440
|
+
assert_kind_of( Hash, labels )
|
482
441
|
assert_equal('A', labels['a'].to_s)
|
483
442
|
assert_equal('B', labels['b'].to_s)
|
484
443
|
assert_equal('C', labels['c'].to_s)
|
@@ -528,7 +487,7 @@ class TestTreeWizard < Test::Unit::TestCase
|
|
528
487
|
|
529
488
|
def test_find_token_type
|
530
489
|
tree = @wizard.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))")
|
531
|
-
subtrees = @wizard.find(tree,
|
490
|
+
subtrees = @wizard.find( tree, A ).map { |t| t.to_s }
|
532
491
|
assert_equal(%w(A foo big), subtrees)
|
533
492
|
end
|
534
493
|
end
|