antlr3 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/ANTLR-LICENSE.txt +26 -0
  2. data/History.txt +66 -0
  3. data/README.txt +139 -0
  4. data/bin/antlr4ruby +33 -0
  5. data/java/RubyTarget.java +524 -0
  6. data/java/antlr-full-3.2.1.jar +0 -0
  7. data/lib/antlr3.rb +176 -0
  8. data/lib/antlr3/constants.rb +88 -0
  9. data/lib/antlr3/debug.rb +701 -0
  10. data/lib/antlr3/debug/event-hub.rb +210 -0
  11. data/lib/antlr3/debug/record-event-listener.rb +25 -0
  12. data/lib/antlr3/debug/rule-tracer.rb +55 -0
  13. data/lib/antlr3/debug/socket.rb +360 -0
  14. data/lib/antlr3/debug/trace-event-listener.rb +92 -0
  15. data/lib/antlr3/dfa.rb +247 -0
  16. data/lib/antlr3/dot.rb +174 -0
  17. data/lib/antlr3/error.rb +657 -0
  18. data/lib/antlr3/main.rb +561 -0
  19. data/lib/antlr3/modes/ast-builder.rb +41 -0
  20. data/lib/antlr3/modes/filter.rb +56 -0
  21. data/lib/antlr3/profile.rb +322 -0
  22. data/lib/antlr3/recognizers.rb +1280 -0
  23. data/lib/antlr3/streams.rb +985 -0
  24. data/lib/antlr3/streams/interactive.rb +91 -0
  25. data/lib/antlr3/streams/rewrite.rb +412 -0
  26. data/lib/antlr3/test/call-stack.rb +57 -0
  27. data/lib/antlr3/test/config.rb +23 -0
  28. data/lib/antlr3/test/core-extensions.rb +269 -0
  29. data/lib/antlr3/test/diff.rb +165 -0
  30. data/lib/antlr3/test/functional.rb +207 -0
  31. data/lib/antlr3/test/grammar.rb +371 -0
  32. data/lib/antlr3/token.rb +592 -0
  33. data/lib/antlr3/tree.rb +1415 -0
  34. data/lib/antlr3/tree/debug.rb +163 -0
  35. data/lib/antlr3/tree/visitor.rb +84 -0
  36. data/lib/antlr3/tree/wizard.rb +481 -0
  37. data/lib/antlr3/util.rb +149 -0
  38. data/lib/antlr3/version.rb +27 -0
  39. data/samples/ANTLRv3Grammar.g +621 -0
  40. data/samples/Cpp.g +749 -0
  41. data/templates/AST.stg +335 -0
  42. data/templates/ASTDbg.stg +40 -0
  43. data/templates/ASTParser.stg +153 -0
  44. data/templates/ASTTreeParser.stg +272 -0
  45. data/templates/Dbg.stg +192 -0
  46. data/templates/Ruby.stg +1514 -0
  47. data/test/functional/ast-output/auto-ast.rb +797 -0
  48. data/test/functional/ast-output/construction.rb +555 -0
  49. data/test/functional/ast-output/hetero-nodes.rb +753 -0
  50. data/test/functional/ast-output/rewrites.rb +1327 -0
  51. data/test/functional/ast-output/tree-rewrite.rb +1662 -0
  52. data/test/functional/debugging/debug-mode.rb +689 -0
  53. data/test/functional/debugging/profile-mode.rb +165 -0
  54. data/test/functional/debugging/rule-tracing.rb +74 -0
  55. data/test/functional/delegation/import.rb +379 -0
  56. data/test/functional/lexer/basic.rb +559 -0
  57. data/test/functional/lexer/filter-mode.rb +245 -0
  58. data/test/functional/lexer/nuances.rb +47 -0
  59. data/test/functional/lexer/properties.rb +104 -0
  60. data/test/functional/lexer/syn-pred.rb +32 -0
  61. data/test/functional/lexer/xml.rb +206 -0
  62. data/test/functional/main/main-scripts.rb +245 -0
  63. data/test/functional/parser/actions.rb +224 -0
  64. data/test/functional/parser/backtracking.rb +244 -0
  65. data/test/functional/parser/basic.rb +282 -0
  66. data/test/functional/parser/calc.rb +98 -0
  67. data/test/functional/parser/ll-star.rb +143 -0
  68. data/test/functional/parser/nuances.rb +165 -0
  69. data/test/functional/parser/predicates.rb +103 -0
  70. data/test/functional/parser/properties.rb +242 -0
  71. data/test/functional/parser/rule-methods.rb +132 -0
  72. data/test/functional/parser/scopes.rb +274 -0
  73. data/test/functional/token-rewrite/basic.rb +318 -0
  74. data/test/functional/token-rewrite/via-parser.rb +100 -0
  75. data/test/functional/tree-parser/basic.rb +750 -0
  76. data/test/unit/sample-input/file-stream-1 +2 -0
  77. data/test/unit/sample-input/teststreams.input2 +2 -0
  78. data/test/unit/test-dfa.rb +52 -0
  79. data/test/unit/test-exceptions.rb +44 -0
  80. data/test/unit/test-recognizers.rb +55 -0
  81. data/test/unit/test-scheme.rb +62 -0
  82. data/test/unit/test-streams.rb +459 -0
  83. data/test/unit/test-tree-wizard.rb +535 -0
  84. data/test/unit/test-trees.rb +854 -0
  85. metadata +205 -0
Binary file
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ =begin LICENSE
5
+
6
+ [The "BSD licence"]
7
+ Copyright (c) 2009 Kyle Yetter
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions
12
+ are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in the
18
+ documentation and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ =end
34
+
35
+ =begin rdoc ANTLR3
36
+
37
+ The main namespace for the ANTLR runtime libraries, which are used by
38
+ Ruby-targeted recognizers generated by ANTLR. The entire library is segmented
39
+ into several main components, as well as a few additional utility components,
40
+ each contained within a separate script.
41
+
42
+ == Library Components
43
+
44
+ Not all components of the ANTLR3 library are necessary within ANTLR generated
45
+ code. Some components are only used within specific types of recognizers and
46
+ some are simply extra utilities for use by anyone working with ANTLR code. Thus,
47
+ when requiring 'antlr3', only the essential core components are loaded
48
+ immediately. The rest are configured to autoload when any of the constant names
49
+ they define are referenced.
50
+
51
+ The following list gives a brief introduction to each component of the ANTLR3
52
+ runtime library. The items are loosely ordered by importance.
53
+
54
+ antlr3/recognizers.rb::
55
+ contains the base classes for ANTLR-generated recognizers, and thus, is one of
56
+ the most important components of the runtime library. loaded by default
57
+ antlr3/dfa.rb::
58
+ defines a single DFA class that is used to simulate state machines for certain
59
+ decisions recognizers must make in code generated by ANTLR
60
+ antlr3/streams.rb::
61
+ defines the stream classes used by ANTLR recognizers to walk sequentially
62
+ through strings, tokens, and tree nodes loaded by default
63
+ antlr3/token.rb::
64
+ contains all modules and classes concerned with making tokens, the chunks of
65
+ text and symbol information produced by lexers and used by parsers and ASTs
66
+ loaded by default
67
+ antlr3/error.rb::
68
+ defines the Error module, which contains definitions for most of the many
69
+ error classes used through the runtime library and ANTLR generated
70
+ recognizers. loaded by default
71
+ antlr3/constants.rb::
72
+ just a module used as a namespace for the named constant values used
73
+ throughout the library. loaded by default
74
+ antlr3/tree.rb::
75
+ contains everything pertaining to Abstract Syntax Trees (ASTs). This script is
76
+ not loaded by default when 'antlr3' is required, but it is autloaded on demand
77
+ when any constant defined in the script is referenced. contents are autoloaded
78
+ on demand
79
+ antlr3/debug.rb::
80
+ when code is generated by ANTLR using the '-debug' option, all of the
81
+ additional classes and mixins required by the debug code are contained within
82
+ the Debug module defined by this library. the Debug module is autoloaded on
83
+ demand
84
+ antlr3/main.rb::
85
+ defines the Main module. When ANTLR-generated recognizer code is run directly
86
+ as a script (not loaded as a module), the code will behave as a full
87
+ command-line script by using functionality implemented in the Main module. the
88
+ Main module is autloaded on demand
89
+ antlr3/tree-wizard.rb::
90
+ contains extra tools to easily construct ASTs by parsing descriptions written
91
+ in a special DSL
92
+ antlr3/dot.rb::
93
+ extra utilities to generate DOT map specifications for graphical.
94
+ representations of ASTs
95
+
96
+ =end
97
+
98
+ module ANTLR3
99
+
100
+ LIBRARY_PATH = ::File.expand_path(::File.dirname(__FILE__))
101
+ # :startdoc:
102
+
103
+ # Returns the library path for the module. If any arguments are given,
104
+ # they will be joined to the end of the libray path using
105
+ # <tt>File.join</tt>.
106
+ #
107
+ def self.library_path( *args )
108
+ File.expand_path(::File.join(LIBRARY_PATH, *args))
109
+ end
110
+
111
+ # Returns the lpath for the module. If any arguments are given,
112
+ # they will be joined to the end of the path using
113
+ # <tt>File.join</tt>.
114
+ #
115
+ def self.project_path( *args )
116
+ library_path('..', *args)
117
+ end
118
+
119
+ # This is used internally in a handful of locations in the runtime library
120
+ # where assumptions have been made that a condition will never happen
121
+ # under normal usage conditions and thus an ANTLR3::Bug error will be
122
+ # raised if the condition does occur.
123
+ def self.bug!(message = nil)
124
+ bug = Bug.new(message)
125
+ bug.set_backtrace(caller)
126
+ raise(bug)
127
+ end
128
+
129
+ def self.antlr_jar
130
+ path = project_path "java/antlr-full-#{ANTLR_VERSION_STRING}.jar"
131
+ File.exists?( path ) ? path : nil
132
+ end
133
+
134
+ ##############################################################################################
135
+ ############################### Namespace and Load Path Setup ################################
136
+ ##############################################################################################
137
+
138
+ # Tree classes are only used by tree parsers or AST-building parsers
139
+ # Thus, they're not essential for everything ANTLR generates and
140
+ # are autoloaded on-demand
141
+ tree_classes = [
142
+ :Tree, :TreeAdaptor, :BaseTree, :BaseTreeAdaptor,
143
+ :CommonTree, :CommonErrorNode, :CommonTreeAdaptor,
144
+ :TreeNodeStream, :CommonTreeNodeStream, :TreeParser,
145
+ :TreeVisitor, :RewriteRuleElementStream,
146
+ :RewriteRuleTokenStream, :RewriteRuleSubtreeStream,
147
+ :RewriteRuleNodeStream
148
+ ]
149
+ autoload :AST, 'antlr3/tree'
150
+ for klass in tree_classes
151
+ autoload klass, 'antlr3/tree'
152
+ end
153
+
154
+ # Set up non-essential components to be loaded on-demand
155
+ autoload :TokenRewriteStream, 'antlr3/streams/rewrite'
156
+ autoload :FilterMode, 'antlr3/modes/filter'
157
+ autoload :ASTBuilder, 'antlr3/modes/ast-builder'
158
+ autoload :Main, 'antlr3/main'
159
+ autoload :Debug, 'antlr3/debug'
160
+ autoload :Profile, 'antlr3/profile'
161
+ autoload :DOT, 'antlr3/dot'
162
+ autoload :InteractiveStringStream, 'antlr3/streams/interactive'
163
+
164
+ $LOAD_PATH.include?(library_path) or $LOAD_PATH.unshift(library_path)
165
+
166
+ end # module ANTLR3
167
+
168
+ require 'set'
169
+ require 'antlr3/util'
170
+ require 'antlr3/version'
171
+ require 'antlr3/constants'
172
+ require 'antlr3/error'
173
+ require 'antlr3/token'
174
+ require 'antlr3/recognizers'
175
+ require 'antlr3/dfa'
176
+ require 'antlr3/streams'
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ =begin LICENSE
5
+
6
+ [The "BSD licence"]
7
+ Copyright (c) 2009 Kyle Yetter
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions
12
+ are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in the
18
+ documentation and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ =end
34
+
35
+ module ANTLR3
36
+
37
+
38
+ =begin rdoc ANTLR3::Constants
39
+
40
+ A simple module to keep track of the various built-in token types, channels, and
41
+ token names used by ANTLR throughout the runtime library.
42
+
43
+ =end
44
+ module Constants
45
+ # built-in token channel IDs
46
+
47
+ # the channel to which most tokens will be assigned
48
+ DEFAULT = DEFAULT_CHANNEL = :default
49
+
50
+ # the channel for tokens which should not be passed to a parser by a token stream
51
+ HIDDEN = HIDDEN_CHANNEL = :hidden
52
+
53
+ # built-in token types used internally by ANTLR3
54
+
55
+ INVALID_TOKEN_TYPE = 0
56
+
57
+ # End of File / End of Input character and token type
58
+ EOF = -1
59
+
60
+ # Imaginary tree-navigation token type indicating the ascent after moving through the
61
+ # children of a node
62
+ UP = 3
63
+
64
+ # Imaginary tree-navigation token type indicating a descent into the children of a node
65
+ DOWN = 2
66
+
67
+ # End of Rule (used internally by DFAs)
68
+ EOR_TOKEN_TYPE = 1
69
+
70
+ # The smallest possible value of non-builtin ANTLR-generated token types
71
+ MIN_TOKEN_TYPE = 4
72
+
73
+ # A hash mapping built in token types to their respective names
74
+ # returning a string "<UNKNOWN: #{type}>" for non-builtin token
75
+ # types
76
+ BUILT_IN_TOKEN_NAMES = Hash.new do |h, k|
77
+ "<UNKNOWN: #{k}>"
78
+ end
79
+
80
+ BUILT_IN_TOKEN_NAMES.update(
81
+ 0 => "<invalid>".freeze, 1 => "<EOR>".freeze,
82
+ 2 => "<DOWN>".freeze, 3 => "<UP>".freeze,
83
+ -1 => "<EOF>".freeze
84
+ )
85
+ end
86
+
87
+ include Constants
88
+ end
@@ -0,0 +1,701 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ =begin LICENSE
5
+
6
+ [The "BSD licence"]
7
+ Copyright (c) 2009 Kyle Yetter
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions
12
+ are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in the
18
+ documentation and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ =end
34
+
35
+ module ANTLR3
36
+
37
+ =begin rdoc ANTLR3::Debug
38
+
39
+ Namespace for all debugging-related class and module definitions.
40
+
41
+ =end
42
+
43
+ module Debug
44
+
45
+ DEFAULT_PORT = 49100
46
+
47
+ # since there are many components to the debug-mode
48
+ # section of the antlr3 runtime library, most of which
49
+ # are not used simultaneously, debug.rb contains the
50
+ # base of the debug library and the various listeners
51
+ # and tree-related code are autloaded on-demand
52
+ autoload :EventSocketProxy, 'antlr3/debug/socket'
53
+ autoload :RemoteEventSocketListener, 'antlr3/debug/socket'
54
+ autoload :TraceEventListener, 'antlr3/debug/trace-event-listener'
55
+ autoload :RecordEventListener, 'antlr3/debug/record-event-listener'
56
+ autoload :RuleTracer, 'antlr3/debug/rule-tracer'
57
+ autoload :EventHub, 'antlr3/debug/event-hub'
58
+ autoload :TreeAdaptor, 'antlr3/tree/debug'
59
+ autoload :TreeNodeStream, 'antlr3/tree/debug'
60
+
61
+ RecognizerSharedState = Struct.new(
62
+ # the rule invocation depth
63
+ :rule_invocation_stack,
64
+ # a boolean flag to indicate whether or not the current decision is cyclic
65
+ :cyclic_decision,
66
+ # a stack that tracks follow sets for error recovery
67
+ :following,
68
+ # a flag indicating whether or not the recognizer is in error recovery mode
69
+ :error_recovery,
70
+ # the index in the input stream of the last error
71
+ :last_error_index,
72
+ # tracks the backtracking depth
73
+ :backtracking,
74
+ # if a grammar is compiled with the memoization option, this will
75
+ # be set to a hash mapping previously parsed rules to cached indices
76
+ :rule_memory,
77
+ # tracks the number of syntax errors seen so far
78
+ :syntax_errors,
79
+ # holds newly constructed tokens for lexer rules
80
+ :token,
81
+ # the input stream index at which the token starts
82
+ :token_start_position,
83
+ # the input stream line number at which the token starts
84
+ :token_start_line,
85
+ # the input stream column at which the token starts
86
+ :token_start_column,
87
+ # the channel value of the target token
88
+ :channel,
89
+ # the type value of the target token
90
+ :type,
91
+ # the text of the target token
92
+ :text
93
+ )
94
+
95
+ =begin rdoc ANTLR3::Debug::RecognizerSharedState
96
+
97
+ ANTLR3::Debug::RecognizerSharedState is identical to
98
+ ANTLR3::RecognizerSharedState, but adds additional fields used for recognizers
99
+ generated in debug or profiling mode.
100
+
101
+ =end
102
+ class RecognizerSharedState
103
+ def initialize
104
+ super([], false, [], false, -1, 0, nil, 0, nil, -1)
105
+ # ^-- same as this --v
106
+ # self.following = []
107
+ # self.error_recovery = false
108
+ # self.last_error_index = -1
109
+ # self.backtracking = 0
110
+ # self.syntax_errors = 0
111
+ # self.rule_level = 0
112
+ # self.token_start_position = -1
113
+ end
114
+
115
+ def reset!
116
+ self.following.clear
117
+ self.error_recovery = false
118
+ self.last_error_index = -1
119
+ self.backtracking = 0
120
+ self.rule_memory and rule_memory.clear
121
+ self.syntax_errors = 0
122
+ self.token = nil
123
+ self.token_start_position = -1
124
+ self.token_start_line = nil
125
+ self.token_start_column = nil
126
+ self.channel = nil
127
+ self.type = nil
128
+ self.text = nil
129
+ self.rule_invocation_stack.clear
130
+ end
131
+
132
+ end
133
+
134
+ =begin rdoc ANTLR3::Debug::ParserEvents
135
+
136
+ ParserEvents adds debugging event hook methods and functionality that is
137
+ required by the code ANTLR generated when called with the <tt>-debug</tt>
138
+ switch.
139
+
140
+ =end
141
+ module ParserEvents
142
+ include ANTLR3::Error
143
+
144
+ def self.included(klass)
145
+ super
146
+ if klass.is_a?(::Class)
147
+ def klass.debug?
148
+ true
149
+ end
150
+ end
151
+ end
152
+
153
+
154
+ attr_reader :debug_listener
155
+
156
+ def initialize(stream, options = {})
157
+ @debug_listener = options[:debug_listener] ||= begin
158
+ EventSocketProxy.new( self, options ).handshake
159
+ end
160
+ options[:state] ||= Debug::RecognizerSharedState.new
161
+ super(stream, options)
162
+ if @input.is_a?(Debug::TokenStream)
163
+ @input.debug_listener ||= @debug_listener
164
+ else
165
+ @input = Debug::TokenStream.wrap(@input, @debug_listener)
166
+ end
167
+ end
168
+
169
+ def rule_level
170
+ @state.rule_invocation_stack.length
171
+ end
172
+
173
+ def cyclic_decision?
174
+ @state.cyclic_decision
175
+ end
176
+
177
+ def cyclic_decision=(flag)
178
+ @state.cyclic_decision = flag
179
+ end
180
+
181
+ # custom attribute writer for debug_listener
182
+ # propegates the change in listener to the
183
+ # parser's debugging input stream
184
+ def debug_listener=(dbg)
185
+ @debug_listener = dbg
186
+ @input.debug_listener = dbg rescue nil
187
+ end
188
+
189
+ def begin_resync
190
+ @debug_listener.begin_resync
191
+ super
192
+ end
193
+
194
+ def end_resync
195
+ @debug_listener.end_resync
196
+ super
197
+ end
198
+
199
+ # TO-DO: is this pointless?
200
+ def resync
201
+ begin_resync
202
+ yield(self)
203
+ ensure
204
+ end_resync
205
+ end
206
+
207
+ def begin_backtrack
208
+ @debug_listener.begin_backtrack(@state.backtracking)
209
+ end
210
+
211
+ def end_backtrack(successful)
212
+ @debug_listener.end_backtrack(@state.backtracking, successful)
213
+ end
214
+
215
+ def backtrack
216
+ @state.backtracking += 1
217
+ @debug_listener.begin_backtrack(@state.backtracking)
218
+ start = @input.mark
219
+ success =
220
+ begin yield
221
+ rescue BacktrackingFailed then false
222
+ else true
223
+ end
224
+ return success
225
+ ensure
226
+ @input.rewind(start)
227
+ @debug_listener.end_backtrack(@state.backtracking, (success rescue nil))
228
+ @state.backtracking -= 1
229
+ end
230
+
231
+ def report_error(exc)
232
+ case exc
233
+ when ANTLR3::Error::RecognitionError
234
+ @debug_listener.recognition_exception(exc)
235
+ else
236
+ $stderr.puts(exc)
237
+ $stderr.puts(exc.backtrace)
238
+ end
239
+ super
240
+ end
241
+
242
+ def missing_symbol(error, expected_type, follow)
243
+ symbol = super
244
+ @debug_listener.consume_node(symbol)
245
+ return(symbol)
246
+ end
247
+
248
+ def in_rule(grammar_file, rule_name)
249
+ @state.rule_invocation_stack.empty? and @debug_listener.commence
250
+ @debug_listener.enter_rule(grammar_file, rule_name)
251
+ @state.rule_invocation_stack.push(grammar_file, rule_name)
252
+ yield
253
+ ensure
254
+ @state.rule_invocation_stack.pop(2)
255
+ @debug_listener.exit_rule(grammar_file, rule_name)
256
+ @state.rule_invocation_stack.empty? and @debug_listener.terminate
257
+ end
258
+
259
+ def rule_invocation_stack
260
+ @state.rule_invocation_stack.each_slice(2).to_a
261
+ end
262
+
263
+ def predicate?(description)
264
+ result = yield
265
+ @debug_listener.semantic_predicate(result, description)
266
+ return result
267
+ end
268
+
269
+ def in_alternative(alt_number)
270
+ @debug_listener.enter_alternative(alt_number)
271
+ end
272
+
273
+ def in_subrule(decision_number)
274
+ @debug_listener.enter_subrule(decision_number)
275
+ yield
276
+ ensure
277
+ @debug_listener.exit_subrule(decision_number)
278
+ end
279
+
280
+ def in_decision(decision_number)
281
+ @debug_listener.enter_decision(decision_number)
282
+ yield
283
+ ensure
284
+ @debug_listener.exit_decision(decision_number)
285
+ end
286
+ end
287
+
288
+
289
+ =begin rdoc ANTLR3::Debug::TokenStream
290
+
291
+ A module that wraps token stream methods with debugging event code. A debuggable
292
+ parser will <tt>extend</tt> its input stream with this module if the stream is
293
+ not already a Debug::TokenStream.
294
+
295
+ =end
296
+ module TokenStream
297
+
298
+ def self.wrap(stream, debug_listener = nil)
299
+ stream.extend(self)
300
+ stream.instance_eval do
301
+ @initial_stream_state = true
302
+ @debug_listener = debug_listener
303
+ @last_marker = nil
304
+ end
305
+ return(stream)
306
+ end
307
+ attr_reader :last_marker
308
+ attr_accessor :debug_listener
309
+
310
+ def consume
311
+ @initial_stream_state and consume_initial_hidden_tokens
312
+ a = index + 1 # the next position IF there are no hidden tokens in between
313
+ t = super
314
+ b = index # the actual position after consuming
315
+ @debug_listener.consume_token(t) if @debug_listener
316
+
317
+ # if b > a, report the consumption of hidden tokens
318
+ for i in a...b
319
+ @debug_listener.consume_hidden_token at(i)
320
+ end
321
+ end
322
+
323
+
324
+ # after a token stream fills up its buffer
325
+ # by exhausting its token source, it may
326
+ # skip to an initial position beyond the first
327
+ # actual token, if there are hidden tokens
328
+ # at the beginning of the stream.
329
+ #
330
+ # This private method is used to
331
+ # figure out if any hidden tokens
332
+ # were skipped initially, and then
333
+ # report their consumption to
334
+ # the debug listener
335
+ def consume_initial_hidden_tokens
336
+ first_on_channel_token_index = self.index
337
+ first_on_channel_token_index.times do |index|
338
+ @debug_listener.consume_hidden_token at(index)
339
+ end
340
+ @initial_stream_state = false
341
+ end
342
+
343
+ private :consume_initial_hidden_tokens
344
+
345
+ ############################################################################################
346
+ ###################################### Stream Methods ######################################
347
+ ############################################################################################
348
+
349
+ def look(steps = 1)
350
+ @initial_stream_state and consume_initial_hidden_tokens
351
+ token = super(steps)
352
+ @debug_listener.look(steps, token)
353
+ return token
354
+ end
355
+
356
+ def peek(steps = 1)
357
+ look(steps).type
358
+ end
359
+
360
+ def mark
361
+ @last_marker = super
362
+ @debug_listener.mark(@last_marker)
363
+ return @last_marker
364
+ end
365
+
366
+ def rewind(marker = nil)
367
+ @debug_listener.rewind(marker)
368
+ super
369
+ end
370
+
371
+ end
372
+
373
+ =begin rdoc ANTLR3::Debug::EventListener
374
+
375
+ A listener that simply records text representations of the events. Useful for debugging the
376
+ debugging facility ;) Subclasses can override the record() method (which defaults to printing
377
+ to stdout) to record the events in a different way.
378
+
379
+ =end
380
+ module EventListener
381
+ PROTOCOL_VERSION = '2'
382
+ # The parser has just entered a rule. No decision has been made about
383
+ # which alt is predicted. This is fired AFTER init actions have been
384
+ # executed. Attributes are defined and available etc...
385
+ # The grammarFileName allows composite grammars to jump around among
386
+ # multiple grammar files.
387
+
388
+ def enter_rule(grammar_file, rule_name)
389
+ # do nothing
390
+ end
391
+
392
+ # Because rules can have lots of alternatives, it is very useful to
393
+ # know which alt you are entering. This is 1..n for n alts.
394
+
395
+ def enter_alternative(alt)
396
+ # do nothing
397
+ end
398
+
399
+ # This is the last thing executed before leaving a rule. It is
400
+ # executed even if an exception is thrown. This is triggered after
401
+ # error reporting and recovery have occurred (unless the exception is
402
+ # not caught in this rule). This implies an "exitAlt" event.
403
+ # The grammarFileName allows composite grammars to jump around among
404
+ # multiple grammar files.
405
+
406
+ def exit_rule(grammar_file, rule_name)
407
+ # do nothing
408
+ end
409
+
410
+ # Track entry into any (...) subrule other EBNF construct
411
+
412
+ def enter_subrule( decision_number )
413
+ # do nothing
414
+ end
415
+
416
+ def exit_subrule( decision_number )
417
+ # do nothing
418
+ end
419
+
420
+ # Every decision, fixed k or arbitrary, has an enter/exit event
421
+ # so that a GUI can easily track what look/consume events are
422
+ # associated with prediction. You will see a single enter/exit
423
+ # subrule but multiple enter/exit decision events, one for each
424
+ # loop iteration.
425
+
426
+ def enter_decision( decision_number )
427
+ # do nothing
428
+ end
429
+
430
+ def exit_decision( decision_number )
431
+ # do nothing
432
+ end
433
+
434
+ # An input token was consumed; matched by any kind of element.
435
+ # Trigger after the token was matched by things like match(), matchAny().
436
+
437
+ def consume_token( tree )
438
+ # do nothing
439
+ end
440
+
441
+ # An off-channel input token was consumed.
442
+ # Trigger after the token was matched by things like match(), matchAny().
443
+ # (unless of course the hidden token is first stuff in the input stream).
444
+
445
+ def consume_hidden_token( tree )
446
+ # do nothing
447
+ end
448
+
449
+ # Somebody (anybody) looked ahead. Note that this actually gets
450
+ # triggered by both peek and look calls. The debugger will want to know
451
+ # which Token object was examined. Like consumeToken, this indicates
452
+ # what token was seen at that depth. A remote debugger cannot look
453
+ # ahead into a file it doesn't have so look events must pass the token
454
+ # even if the info is redundant.
455
+
456
+ def look( i, tree )
457
+ # do nothing
458
+ end
459
+
460
+ # The parser is going to look arbitrarily ahead; mark this location,
461
+ # the token stream's marker is sent in case you need it.
462
+
463
+ def mark( marker )
464
+ # do nothing
465
+ end
466
+
467
+ # After an arbitrairly long look as with a cyclic DFA (or with
468
+ # any backtrack), this informs the debugger that stream should be
469
+ # rewound to the position associated with marker.
470
+
471
+ def rewind( marker = nil )
472
+ # do nothing
473
+ end
474
+
475
+ def begin_backtrack( level )
476
+ # do nothing
477
+ end
478
+
479
+ def end_backtrack( level, successful )
480
+ # do nothing
481
+ end
482
+
483
+ def backtrack( level )
484
+ begin_backtrack( level )
485
+ successful = yield(self)
486
+ end_backtrack( level, successful )
487
+ end
488
+
489
+ # To watch a parser move through the grammar, the parser needs to
490
+ # inform the debugger what line/charPos it is passing in the grammar.
491
+ # For now, this does not know how to switch from one grammar to the
492
+ # other and back for island grammars etc...
493
+ # This should also allow breakpoints because the debugger can stop
494
+ # the parser whenever it hits this line/pos.
495
+
496
+ def location( line, position )
497
+ # do nothing
498
+ end
499
+
500
+ # A recognition exception occurred such as NoViableAltError. I made
501
+ # this a generic event so that I can alter the exception hierachy later
502
+ # without having to alter all the debug objects.
503
+ # Upon error, the stack of enter rule/subrule must be properly unwound.
504
+ # If no viable alt occurs it is within an enter/exit decision, which
505
+ # also must be rewound. Even the rewind for each mark must be unwount.
506
+ # In the Java target this is pretty easy using try/finally, if a bit
507
+ # ugly in the generated code. The rewind is generated in DFA.predict()
508
+ # actually so no code needs to be generated for that. For languages
509
+ # w/o this "finally" feature (C++?), the target implementor will have
510
+ # to build an event stack or something.
511
+ # Across a socket for remote debugging, only the RecognitionError
512
+ # data fields are transmitted. The token object or whatever that
513
+ # caused the problem was the last object referenced by look. The
514
+ # immediately preceding look event should hold the unexpected Token or
515
+ # char.
516
+ # Here is a sample event trace for grammar:
517
+ # b : C ({;}A|B) // {;} is there to prevent A|B becoming a set
518
+ # | D
519
+ # ;
520
+ # The sequence for this rule (with no viable alt in the subrule) for
521
+ # input 'c c' (there are 3 tokens) is:
522
+ # commence
523
+ # look
524
+ # enterRule b
525
+ # location 7 1
526
+ # enter decision 3
527
+ # look
528
+ # exit decision 3
529
+ # enterAlt1
530
+ # location 7 5
531
+ # look
532
+ # consumeToken [c/<4>,1:0]
533
+ # location 7 7
534
+ # enterSubRule 2
535
+ # enter decision 2
536
+ # look
537
+ # look
538
+ # recognitionError NoViableAltError 2 1 2
539
+ # exit decision 2
540
+ # exitSubRule 2
541
+ # beginResync
542
+ # look
543
+ # consumeToken [c/<4>,1:1]
544
+ # look
545
+ # endResync
546
+ # look(-1)
547
+ # exitRule b
548
+ # terminate
549
+
550
+ def recognition_exception( exception )
551
+ # do nothing
552
+ end
553
+
554
+ # Indicates the recognizer is about to consume tokens to resynchronize
555
+ # the parser. Any consume events from here until the recovered event
556
+ # are not part of the parse--they are dead tokens.
557
+
558
+ def begin_resync()
559
+ # do nothing
560
+ end
561
+
562
+ # Indicates that the recognizer has finished consuming tokens in order
563
+ # to resychronize. There may be multiple beginResync/endResync pairs
564
+ # before the recognizer comes out of errorRecovery mode (in which
565
+ # multiple errors are suppressed). This will be useful
566
+ # in a gui where you want to probably grey out tokens that are consumed
567
+ # but not matched to anything in grammar. Anything between
568
+ # a beginResync/endResync pair was tossed out by the parser.
569
+
570
+ def end_resync()
571
+ # do nothing
572
+ end
573
+
574
+ def resync
575
+ begin_resync
576
+ yield(self)
577
+ end_resync
578
+ end
579
+
580
+ # A semantic predicate was evaluate with this result and action text
581
+
582
+ def semantic_predicate( result, predicate )
583
+ # do nothing
584
+ end
585
+
586
+ # Announce that parsing has begun. Not technically useful except for
587
+ # sending events over a socket. A GUI for example will launch a thread
588
+ # to connect and communicate with a remote parser. The thread will want
589
+ # to notify the GUI when a connection is made. ANTLR parsers
590
+ # trigger this upon entry to the first rule (the ruleLevel is used to
591
+ # figure this out).
592
+
593
+ def commence( )
594
+ # do nothing
595
+ end
596
+
597
+ # Parsing is over; successfully or not. Mostly useful for telling
598
+ # remote debugging listeners that it's time to quit. When the rule
599
+ # invocation level goes to zero at the end of a rule, we are done
600
+ # parsing.
601
+
602
+ def terminate( )
603
+ # do nothing
604
+ end
605
+
606
+ # Input for a tree parser is an AST, but we know nothing for sure
607
+ # about a node except its type and text (obtained from the adaptor).
608
+ # This is the analog of the consumeToken method. Again, the ID is
609
+ # the hashCode usually of the node so it only works if hashCode is
610
+ # not implemented. If the type is UP or DOWN, then
611
+ # the ID is not really meaningful as it's fixed--there is
612
+ # just one UP node and one DOWN navigation node.
613
+
614
+ def consume_node( tree )
615
+ # do nothing
616
+ end
617
+
618
+ # A nil was created (even nil nodes have a unique ID...
619
+ # they are not "null" per se). As of 4/28/2006, this
620
+ # seems to be uniquely triggered when starting a new subtree
621
+ # such as when entering a subrule in automatic mode and when
622
+ # building a tree in rewrite mode.
623
+ # If you are receiving this event over a socket via
624
+ # RemoteDebugEventSocketListener then only tree.ID is set.
625
+
626
+ def flat_node( tree )
627
+ # do nothing
628
+ end
629
+
630
+ # Upon syntax error, recognizers bracket the error with an error node
631
+ # if they are building ASTs.
632
+
633
+ def error_node( tree )
634
+ # do nothing
635
+ end
636
+
637
+ # Announce a new node built from token elements such as type etc...
638
+ # If you are receiving this event over a socket via
639
+ # RemoteDebugEventSocketListener then only tree.ID, type, text are
640
+ # set.
641
+
642
+ def create_node( node, token = nil )
643
+ # do nothing
644
+ end
645
+
646
+ # Make a node the new root of an existing root.
647
+ # Note: the newRootID parameter is possibly different
648
+ # than the TreeAdaptor.becomeRoot() newRoot parameter.
649
+ # In our case, it will always be the result of calling
650
+ # TreeAdaptor.becomeRoot() and not root_n or whatever.
651
+ # The listener should assume that this event occurs
652
+ # only when the current subrule (or rule) subtree is
653
+ # being reset to newRootID.
654
+ # If you are receiving this event over a socket via
655
+ # RemoteDebugEventSocketListener then only IDs are set.
656
+ # @see antlr3.tree.TreeAdaptor.becomeRoot()
657
+
658
+ def become_root( new_root, old_root )
659
+ # do nothing
660
+ end
661
+
662
+ # Make childID a child of rootID.
663
+ # If you are receiving this event over a socket via
664
+ # RemoteDebugEventSocketListener then only IDs are set.
665
+ # @see antlr3.tree.TreeAdaptor.addChild()
666
+
667
+ def add_child( root, child )
668
+ # do nothing
669
+ end
670
+
671
+ # Set the token start/stop token index for a subtree root or node.
672
+ # If you are receiving this event over a socket via
673
+ # RemoteDebugEventSocketListener then only tree.ID is set.
674
+
675
+ def set_token_boundaries( tree, token_start_index, token_stop_index )
676
+ # do nothing
677
+ end
678
+
679
+ def examine_rule_memoization(rule)
680
+ # do nothing
681
+ end
682
+
683
+ def on(event_name, &block)
684
+ sclass = class << self; self; end
685
+ sclass.send(:define_method, event_name, &block)
686
+ end
687
+
688
+ EVENTS = [
689
+ :add_child, :backtrack, :become_root, :begin_backtrack,
690
+ :begin_resync, :commence, :consume_hidden_token,
691
+ :consume_node, :consume_token, :create_node, :end_backtrack,
692
+ :end_resync, :enter_alternative, :enter_decision, :enter_rule,
693
+ :enter_sub_rule, :error_node, :exit_decision, :exit_rule,
694
+ :exit_sub_rule, :flat_node, :location, :look, :mark,
695
+ :recognition_exception, :resync, :rewind,
696
+ :semantic_predicate, :set_token_boundaries, :terminate
697
+ ].freeze
698
+
699
+ end
700
+ end
701
+ end