antlr3 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|