antlr3 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3.rb +2 -0
- data/lib/antlr3/main.rb +3 -5
- data/lib/antlr3/modes/ast-builder.rb +1 -22
- data/lib/antlr3/streams/rewrite.rb +3 -3
- data/lib/antlr3/task.rb +12 -1
- data/lib/antlr3/template.rb +319 -0
- data/lib/antlr3/template/group-lexer.rb +992 -0
- data/lib/antlr3/template/group-parser.rb +627 -0
- data/lib/antlr3/template/parameter.rb +56 -0
- data/lib/antlr3/test/grammar.rb +9 -11
- data/lib/antlr3/tree.rb +30 -0
- data/lib/antlr3/version.rb +2 -2
- data/templates/Ruby.stg +9 -10
- data/templates/ST.stg +128 -0
- data/test/functional/ast-output/auto-ast.rb +1 -1
- data/test/functional/ast-output/hetero-nodes.rb +2 -1
- data/test/functional/template-output/template-output.rb +404 -0
- data/test/unit/sample-input/template-group +38 -0
- data/test/unit/test-template.rb +248 -0
- metadata +12 -2
data/java/antlr-full-3.2.1.jar
CHANGED
Binary file
|
data/lib/antlr3.rb
CHANGED
@@ -161,6 +161,8 @@ module ANTLR3
|
|
161
161
|
autoload :DOT, 'antlr3/dot'
|
162
162
|
autoload :InteractiveStringStream, 'antlr3/streams/interactive'
|
163
163
|
|
164
|
+
autoload :Template, 'antlr3/template'
|
165
|
+
|
164
166
|
$LOAD_PATH.include?(library_path) or $LOAD_PATH.unshift(library_path)
|
165
167
|
|
166
168
|
end # module ANTLR3
|
data/lib/antlr3/main.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
4
|
=begin LICENSE
|
5
|
-
|
6
5
|
[The "BSD licence"]
|
7
6
|
Copyright (c) 2009 Kyle Yetter
|
8
7
|
All rights reserved.
|
@@ -171,7 +170,8 @@ class Main
|
|
171
170
|
end
|
172
171
|
end
|
173
172
|
|
174
|
-
|
173
|
+
private
|
174
|
+
|
175
175
|
def execute_interactive
|
176
176
|
@output.puts( Util.tidy(<<-END) )
|
177
177
|
| ===================================================================
|
@@ -379,7 +379,6 @@ class LexerMain < Main
|
|
379
379
|
|
380
380
|
end
|
381
381
|
|
382
|
-
|
383
382
|
=begin rdoc ANTLR3::Main::ParserMain
|
384
383
|
|
385
384
|
A class which implements a handy test script which is executed whenever an ANTLR
|
@@ -425,7 +424,7 @@ class ParserMain < Main
|
|
425
424
|
end
|
426
425
|
|
427
426
|
def setup
|
428
|
-
unless @lexer_class ||= fetch_class(@lexer_class_name)
|
427
|
+
unless @lexer_class ||= fetch_class( @lexer_class_name )
|
429
428
|
if @lexer_class_name
|
430
429
|
fail("unable to locate the lexer class ``#@lexer_class_name''")
|
431
430
|
else
|
@@ -468,7 +467,6 @@ class ParserMain < Main
|
|
468
467
|
|
469
468
|
end
|
470
469
|
|
471
|
-
|
472
470
|
=begin rdoc ANTLR3::Main::WalkerMain
|
473
471
|
|
474
472
|
A class which implements a handy test script which is executed whenever an ANTLR
|
@@ -24,38 +24,17 @@ module ASTBuilder
|
|
24
24
|
shared_attribute( :adaptor )
|
25
25
|
|
26
26
|
private
|
27
|
-
|
27
|
+
|
28
28
|
def subtree_stream(desc, element = nil)
|
29
29
|
AST::RewriteRuleSubtreeStream.new( @adaptor, desc, element )
|
30
|
-
#if element.instance_of?( Array )
|
31
|
-
# AST::RewriteRuleSubtreeStream.new( @adaptor, desc, *element )
|
32
|
-
#elsif element
|
33
|
-
# AST::RewriteRuleSubtreeStream.new( @adaptor, desc, element )
|
34
|
-
#else
|
35
|
-
# AST::RewriteRuleSubtreeStream.new( @adaptor, desc )
|
36
|
-
#end
|
37
30
|
end
|
38
31
|
|
39
32
|
def token_stream(desc, element = nil)
|
40
33
|
AST::RewriteRuleTokenStream.new( @adaptor, desc, element )
|
41
|
-
#if element.instance_of?( Array )
|
42
|
-
# AST::RewriteRuleTokenStream.new( @adaptor, desc, *element )
|
43
|
-
#elsif element
|
44
|
-
# AST::RewriteRuleTokenStream.new( @adaptor, desc, element )
|
45
|
-
#else
|
46
|
-
# AST::RewriteRuleTokenStream.new( @adaptor, desc )
|
47
|
-
#end
|
48
34
|
end
|
49
35
|
|
50
36
|
def node_stream(desc, element = nil)
|
51
37
|
AST::RewriteRuleNodeStream.new( @adaptor, desc, element )
|
52
|
-
#if element.instance_of?( Array )
|
53
|
-
# AST::RewriteRuleNodeStream.new( @adaptor, desc, *element )
|
54
|
-
#elsif element
|
55
|
-
# AST::RewriteRuleNodeStream.new( @adaptor, desc, element )
|
56
|
-
#else
|
57
|
-
# AST::RewriteRuleNodeStream.new( @adaptor, desc )
|
58
|
-
#end
|
59
38
|
end
|
60
39
|
end
|
61
40
|
end
|
@@ -99,9 +99,9 @@ class InsertBefore < RewriteOperation
|
|
99
99
|
alias index= location=
|
100
100
|
|
101
101
|
def execute(buffer)
|
102
|
-
buffer << text
|
102
|
+
buffer << text.to_s
|
103
103
|
token = stream[location]
|
104
|
-
buffer << token.text if token
|
104
|
+
buffer << token.text.to_s if token
|
105
105
|
return location + 1
|
106
106
|
end
|
107
107
|
end
|
@@ -132,7 +132,7 @@ class Replace < RewriteOperation
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def execute(buffer)
|
135
|
-
buffer << text unless text.nil?
|
135
|
+
buffer << text.to_s unless text.nil?
|
136
136
|
return(location.end + 1)
|
137
137
|
end
|
138
138
|
|
data/lib/antlr3/task.rb
CHANGED
@@ -49,6 +49,7 @@ class CompileTask < Rake::TaskLib
|
|
49
49
|
@grammar_sets = []
|
50
50
|
@name = options.fetch( :name, 'antlr-grammars' )
|
51
51
|
@options = options
|
52
|
+
@namespace = Rake.application.current_scope
|
52
53
|
grammar_files.empty? or grammar_set( grammar_files )
|
53
54
|
end
|
54
55
|
|
@@ -69,6 +70,16 @@ class CompileTask < Rake::TaskLib
|
|
69
70
|
return( set )
|
70
71
|
end
|
71
72
|
|
73
|
+
def compile_task
|
74
|
+
full_name = ( @namespace + [ @name, 'compile' ] ).join(':')
|
75
|
+
Rake::Task[ full_name ]
|
76
|
+
end
|
77
|
+
|
78
|
+
def clobber_task
|
79
|
+
full_name = ( @namespace + [ @name, 'clobber' ] ).join(':')
|
80
|
+
Rake::Task[ full_name ]
|
81
|
+
end
|
82
|
+
|
72
83
|
def define
|
73
84
|
namespace( @name ) do
|
74
85
|
desc( "trash all ANTLR-generated source code")
|
@@ -108,7 +119,7 @@ class CompileTask::GrammarSet
|
|
108
119
|
@grammars = grammar_files.map do | file |
|
109
120
|
GrammarFile.new( self, file )
|
110
121
|
end
|
111
|
-
@output_directory =
|
122
|
+
@output_directory = '.'
|
112
123
|
dir = options[ :output_directory ] and @output_directory = dir.to_s
|
113
124
|
|
114
125
|
@antlr_jar = options.fetch( :antlr_jar, ANTLR3.antlr_jar )
|
@@ -0,0 +1,319 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'erb'
|
5
|
+
require 'antlr3'
|
6
|
+
|
7
|
+
module ANTLR3
|
8
|
+
module Template
|
9
|
+
module Builder
|
10
|
+
extend ClassMacros
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
attr_writer :template_library
|
14
|
+
|
15
|
+
def template_library
|
16
|
+
@template_library ||= ANTLR3::Template::Group.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def return_scope_members
|
20
|
+
super.push( :template )
|
21
|
+
end
|
22
|
+
|
23
|
+
def define_template( name, source, &block )
|
24
|
+
template_library.define_template( name, source, &block )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.included( klass )
|
29
|
+
super
|
30
|
+
Class === klass and klass.extend( ClassMethods )
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize( input, options = {} )
|
34
|
+
templates = @templates || options.fetch( :templates ) do
|
35
|
+
self.class.template_library or ANTLR3::Template::Group.new
|
36
|
+
end
|
37
|
+
super( input, options )
|
38
|
+
self.templates = templates
|
39
|
+
end
|
40
|
+
|
41
|
+
shared_attribute( :templates )
|
42
|
+
|
43
|
+
def create_template( source, values = {} )
|
44
|
+
@templates.new( source, values )
|
45
|
+
end
|
46
|
+
|
47
|
+
def fetch_template( name, values = {} )
|
48
|
+
@templates.fetch( name, values )
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module RewriteBuilder
|
53
|
+
include Builder
|
54
|
+
|
55
|
+
def self.included( klass )
|
56
|
+
super
|
57
|
+
Class === klass and klass.extend( Builder::ClassMethods )
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def cast_input( input, options )
|
63
|
+
case input
|
64
|
+
when TokenSource then TokenRewriteStream.new( input, options )
|
65
|
+
when IO, String
|
66
|
+
if lexer_class = self.class.associated_lexer
|
67
|
+
TokenRewriteStream.new( lexer_class.new( input, options ), options )
|
68
|
+
else
|
69
|
+
raise ArgumentError, Util.tidy( <<-END, true )
|
70
|
+
| unable to automatically convert input #{ input.inspect }
|
71
|
+
| to a ANTLR3::TokenStream object as #{ self.class }
|
72
|
+
| does not appear to have an associated lexer class
|
73
|
+
END
|
74
|
+
end
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
class Group < Module
|
83
|
+
autoload :Lexer, 'antlr3/template/group-lexer'
|
84
|
+
autoload :Parser, 'antlr3/template/group-parser'
|
85
|
+
|
86
|
+
def self.parse( source, options = {} )
|
87
|
+
namespace = options.fetch( :namespace, ::Object )
|
88
|
+
lexer = Lexer.new( source, options )
|
89
|
+
parser = Parser.new( lexer, options )
|
90
|
+
return( parser.group( namespace ) )
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.load( group_file, options = {} )
|
94
|
+
namespace = options.fetch( :namespace, ::Object )
|
95
|
+
input = ANTLR3::FileStream.new( group_file, options )
|
96
|
+
lexer = Lexer.new( input, options )
|
97
|
+
parser = Parser.new( lexer, options )
|
98
|
+
return( parser.group( namespace ) )
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.new( &block )
|
102
|
+
super do
|
103
|
+
const_set( :TEMPLATES, {} )
|
104
|
+
block_given? and module_eval( &block )
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def new( source, values = {} )
|
109
|
+
erb = ERB.new( source, nil, '%' )
|
110
|
+
template = Context.new( values )
|
111
|
+
template.extend( self )
|
112
|
+
sclass = class << template; self; end
|
113
|
+
erb.def_method( sclass, 'to_s' )
|
114
|
+
return( template )
|
115
|
+
end
|
116
|
+
|
117
|
+
def fetch( name, values = {} )
|
118
|
+
self::TEMPLATES.fetch( name.to_s ).new( values )
|
119
|
+
end
|
120
|
+
|
121
|
+
def templates
|
122
|
+
self::TEMPLATES
|
123
|
+
end
|
124
|
+
|
125
|
+
def template_defined?( name )
|
126
|
+
self::TEMPLATES.has_key?( name.to_s )
|
127
|
+
end
|
128
|
+
|
129
|
+
def define_template( name, source, parameters = nil, &block )
|
130
|
+
name = name.to_s.dup.freeze
|
131
|
+
Context.define( self, name, parameters ) do | tclass |
|
132
|
+
self::TEMPLATES[ name ] = tclass
|
133
|
+
ERB.new( source, nil, '%' ).def_method( tclass, 'to_s' )
|
134
|
+
|
135
|
+
define_template_methods( tclass )
|
136
|
+
end
|
137
|
+
return( self )
|
138
|
+
end
|
139
|
+
|
140
|
+
def alias_template( new_name, old_name )
|
141
|
+
new_name, old_name = new_name.to_s.dup.freeze, old_name.to_s
|
142
|
+
context = self::TEMPLATES.fetch( old_name.to_s ) do
|
143
|
+
raise( NameError,
|
144
|
+
"undefined template `%s' for template group %p" % [ old_name, self ]
|
145
|
+
)
|
146
|
+
end
|
147
|
+
context.define_alias( new_name ) do | tclass |
|
148
|
+
self::TEMPLATES[ new_name ] = tclass
|
149
|
+
define_template_methods( tclass )
|
150
|
+
end
|
151
|
+
return( self )
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def define_template_methods( context )
|
157
|
+
name = context.name
|
158
|
+
if params = context.parameters
|
159
|
+
init = params.names.map do | param |
|
160
|
+
"___[ #{ param.inspect } ] = #{ param }"
|
161
|
+
end.join( "\n" )
|
162
|
+
|
163
|
+
module_eval( <<-END )
|
164
|
+
module_function
|
165
|
+
|
166
|
+
def #{ name }( #{ params } )
|
167
|
+
TEMPLATES[ #{ name.inspect } ].new do | ___ |
|
168
|
+
#{ init }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def #{ name }!( #{ params } )
|
173
|
+
TEMPLATES[ #{ name.inspect } ].new do | ___ |
|
174
|
+
#{ init }
|
175
|
+
end.to_s
|
176
|
+
end
|
177
|
+
END
|
178
|
+
|
179
|
+
else
|
180
|
+
|
181
|
+
module_eval( <<-END )
|
182
|
+
module_function
|
183
|
+
|
184
|
+
def #{ name }( values = {} )
|
185
|
+
TEMPLATES[ #{ name.inspect } ].new( values )
|
186
|
+
end
|
187
|
+
|
188
|
+
def #{ name }!( values = {} )
|
189
|
+
TEMPLATES[ #{ name.inspect } ].new( values ).to_s
|
190
|
+
end
|
191
|
+
END
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class Context
|
198
|
+
VARIABLE_FORM = /^(@)?[a-z_\x80-\xff][\w\x80-\xff]*$/
|
199
|
+
SETTER_FORM = /^([a-z_\x80-\xff][\w\x80-\xff]*)=$/
|
200
|
+
ATTR_FORM = /^[a-z_\x80-\xff][\w\x80-\xff]*$/
|
201
|
+
|
202
|
+
class << self
|
203
|
+
attr_accessor :group, :name, :parameters
|
204
|
+
protected :group=, :name=
|
205
|
+
|
206
|
+
def define_alias( name )
|
207
|
+
new = clone
|
208
|
+
new.name = name
|
209
|
+
new.group = @group
|
210
|
+
block_given? and yield( new )
|
211
|
+
return( new )
|
212
|
+
end
|
213
|
+
|
214
|
+
def define( group, name, parameters )
|
215
|
+
Class.new( self ) do
|
216
|
+
include( group )
|
217
|
+
|
218
|
+
@group = group
|
219
|
+
@name = name
|
220
|
+
@parameters = parameters
|
221
|
+
|
222
|
+
block_given? and yield( self )
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def method_missing( method, *args )
|
228
|
+
case name = method.to_s
|
229
|
+
when SETTER_FORM then return( self[ $1 ] = *args )
|
230
|
+
when ATTR_FORM
|
231
|
+
args.empty? and has_ivar?( name ) and return( self[ name ] )
|
232
|
+
end
|
233
|
+
super
|
234
|
+
end
|
235
|
+
|
236
|
+
def []=( name, value )
|
237
|
+
instance_variable_set( make_ivar( name ), value )
|
238
|
+
end
|
239
|
+
|
240
|
+
def []( name )
|
241
|
+
name = make_ivar( name )
|
242
|
+
instance_variable_defined?( name ) ? instance_variable_get( name ) : nil
|
243
|
+
end
|
244
|
+
|
245
|
+
def <<( variable_map )
|
246
|
+
variable_map.each_pair do | name, value |
|
247
|
+
self[ name ] = value
|
248
|
+
end
|
249
|
+
return( self )
|
250
|
+
end
|
251
|
+
|
252
|
+
def initialize( variable_map = nil )
|
253
|
+
variable_map and self << variable_map
|
254
|
+
block_given? and yield( self )
|
255
|
+
end
|
256
|
+
|
257
|
+
private
|
258
|
+
|
259
|
+
def has_ivar?( name )
|
260
|
+
instance_variable_defined?( make_ivar( name ) )
|
261
|
+
end
|
262
|
+
|
263
|
+
def make_ivar( name )
|
264
|
+
name = name.to_s
|
265
|
+
VARIABLE_FORM =~ name or
|
266
|
+
raise ArgumentError, "cannot convert %p to an instance variable name" % name
|
267
|
+
$1 ? name : "@#{ name }"
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
Parameter = Struct.new( :name, :default )
|
273
|
+
class Parameter
|
274
|
+
def to_s
|
275
|
+
default ? "#{ name } = #{ default }" : "#{ name }"
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
class ParameterList < ::Array
|
280
|
+
attr_accessor :splat, :block
|
281
|
+
|
282
|
+
def self.default
|
283
|
+
new.add( :values ) do | p |
|
284
|
+
p.default = '{}'
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def names
|
289
|
+
names = map { | param | param.name.to_s }
|
290
|
+
@splat and names << @splat.to_s
|
291
|
+
@block and names << @block.to_s
|
292
|
+
return( names )
|
293
|
+
end
|
294
|
+
|
295
|
+
def add( name, options = nil )
|
296
|
+
param =
|
297
|
+
case name
|
298
|
+
when Parameter then name
|
299
|
+
else Parameter.new( name.to_s )
|
300
|
+
end
|
301
|
+
if options
|
302
|
+
default = options[ :default ] and param.default = default
|
303
|
+
param.splat = options.fetch( :splat, false )
|
304
|
+
param.block = options.fetch( :block, false )
|
305
|
+
end
|
306
|
+
block_given? and yield( param )
|
307
|
+
push( param )
|
308
|
+
return( self )
|
309
|
+
end
|
310
|
+
|
311
|
+
def to_s
|
312
|
+
signature = join( ', ' )
|
313
|
+
@splat and signature << ", *" << @splat.to_s
|
314
|
+
@block and signature << ", &" << @block.to_s
|
315
|
+
return( signature )
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|