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.
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