antlr4-native 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51499ca3096bdcbe0ce2e2231e9574b170a96acedeebc813f0e2c69134aa04f1
4
- data.tar.gz: 485568b468bbaf64646344e239d58191e7025238c824e21b639e8641d953b118
3
+ metadata.gz: f14d05febd863a51c3e111e7ef3493eb2fe1b72fe72b0b3d1c5c114a2947f7c7
4
+ data.tar.gz: e8f3fe771ae21c552a1074e2f0608f9c87da1e7bd9063f2f8e18363531c37e6b
5
5
  SHA512:
6
- metadata.gz: 65ccf82166ff334ac080850448093501c6a371a04f2084a820e3a8298af061af50330fda845815173011c66c08a0ad3e8b2b1026b201d5b419c21d82db8d2b4c
7
- data.tar.gz: fb9a2983e52969af587ccb1e6a401825fade06ed13f437a86f5cb8b6289848ee13c7c9284c13c558e17a5e24a60b7eaecf24854de4465ca7d4ef4bbddd10e0c7
6
+ metadata.gz: 64cf7e6628edbaff365daf278c1e70dccd7ca083128d604efe8fcb4850c77efc621ce204fe250a7ffb91adb5d6cb4d02de9f1f68bbbb32c4c8c79d725c308a26
7
+ data.tar.gz: 1c5ba3ec3908cc1a951794d0e70f87afa0f01694ef623b38269ad5f22569fd8b587c1c6a7e820d32de273f6c87e77d15abcf604e83b0edd13f2a0636c09c5d86
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # antlr4-native
2
+
3
+ Create a Ruby native extension from (almost) any ANTLR4 grammar.
4
+
5
+ ## What is this thing?
6
+
7
+ This gem generates native Ruby extensions from ANTLR grammars, enabling Ruby developers to generate parsers for numerous programming languages, file formats, etc.
8
+
9
+ ## Who needs this?
10
+
11
+ If you're a Ruby programmer who wants to parse and traverse source code written in a plethora of programming languages, antlr4-native might be able to help you. A number of community-developed ANTLR grammars are available in ANTLR's [grammars-v4](https://github.com/antlr/grammars-v4) repo. Grab one, then use antlr4-native to generate a bunch of Ruby-compatible C++ code from it. The C++ code can be compiled and used as a native extension.
12
+
13
+ Rather than use antlr4-native directly, consider using its sister project, the [antlr-gemerator](https://github.com/camertron/antlr-gemerator), which can generate a complete rubygem from an ANTLR grammar.
14
+
15
+ ## Code Generation
16
+
17
+ Here's how to generate a native extension for a given lexer and parser (Python in this case), defined in two .g4 files:
18
+
19
+ ```ruby
20
+ require 'antlr4-native'
21
+
22
+ generator = Antlr4Native::Generator.new(
23
+ grammar_files: ['Python3Lexer.g4', 'Python3Parser.g4'],
24
+ output_dir: 'ext',
25
+ parser_root_method: 'file_input'
26
+ )
27
+
28
+ generator.generate
29
+ ```
30
+
31
+ In the example above, the output directory is set to the standard Ruby native extensions directory, 'ext'. Antlr4-native will generate code into ext/\<name\>, where \<name\> is the name of the parser as defined in the grammar file(s). In this case, PythonParser.g4 contains:
32
+
33
+ ```antlr
34
+ parser grammar Python3Parser;
35
+ ```
36
+
37
+ so antlr4-native will generate code into the ext/python3-parser directory.
38
+
39
+ Finally, the `parser_root_method` option tells antlr4-native which context represents the root of the parse tree. This context functions as the starting point for visitors.
40
+
41
+ ## Using extensions in Ruby
42
+
43
+ Parsers contain several methods for parsing source code. Use `#parse` to parse a string and `#parse_file` to parse the contents of a file:
44
+
45
+
46
+ ```ruby
47
+ parser = Python3Parser::Parser.parse(File.read('path/to/file.py'))
48
+
49
+ # equivalent to:
50
+ parser = Python3Parser::Parser.parse_file('path/to/file.py')
51
+ ```
52
+
53
+ Use the `#visit` method on an instance of `Parser` to make use of a visitor:
54
+
55
+ ```ruby
56
+ visitor = MyVisitor.new
57
+ parser.visit(visitor)
58
+ ```
59
+
60
+ See the next section for more info regarding creating and using visitors.
61
+
62
+ ## Visitors
63
+
64
+ A visitor class is automatically created during code generation. Visitors are just classes with a bunch of special methods, each corresponding to a specific part of the source language's syntax. The methods are essentially callbacks that are triggered in-order as the parser walks over the parse tree. For example, here's a visitor with a method that will be called whenever the parser walks over a Python function definition:
65
+
66
+
67
+ ```ruby
68
+ class FuncDefVisitor < Python3Parser::Visitor
69
+ def visit_func_def(ctx)
70
+ puts ctx.NAME.text # print the name of the method
71
+ visit_children(ctx)
72
+ end
73
+ end
74
+ ```
75
+
76
+ Make sure to always call `#visit_children` at some point in your `visit_*` methods. If you don't, the subtree under the current context won't get visited.
77
+
78
+ Finally, if you override `#initialize` in your visitor subclasses, don't forget to call `super`. If you don't, you'll get a nice big segfault.
79
+
80
+ ## Caveats
81
+
82
+ 1. Avoid retaining references to contexts, tokens, etc anywhere in your Ruby code. Contexts (i.e. the `ctx` variables in the examples above) and other objects that are created by ANTLR's C++ runtime are automatically cleaned up without the Ruby interpreter's knowledge. You'll almost surely see a segfault if you retain a reference to one of these objects and try to use it after the call to `Parser#visit`.
83
+ 2. Due to an ANTLR limitation, parsers cannot be used in a multi-threaded environment, even if each parser instance is used entirely in the context of a single thread (i.e. parsers are not shared between threads). According to the ANTLR C++ developers, parsers should be threadsafe. Unfortunately firsthand experience has proven otherwise. Your mileage may vary.
84
+ 3. The description of this gem says "(almost) any ANTLR4 grammar" because many grammars contain target-specific code. For example, the Python3 grammar referenced in the examples above contains inline Java code that the C++ compiler won't understand. You'll need to port any such code to C++ before you'll be able to compile and use the native extension.
85
+
86
+ ## System Requirements
87
+
88
+ * A Java runtime (version 1.6 or higher) is required to generate parsers, since ANTLR is a Java tool. The ANTLR .jar file is distributed inside the antlr4-native gem, so there's no need to download it separately. You can download a Java runtime [here](https://www.java.com/en/download/).
89
+ * Ruby >= 2.3.
90
+ * A C compiler (like gcc or clang) that supports C++14. If Ruby is working on your machine then you likely already have this.
91
+
92
+ ## License
93
+
94
+ Licensed under the MIT license. See LICENSE.txt for details.
95
+
96
+ ## Authors
97
+
98
+ * Cameron C. Dutro: http://github.com/camertron
@@ -11,8 +11,9 @@ Gem::Specification.new do |s|
11
11
  s.description = s.summary = 'Create a Ruby native extension from any ANTLR4 grammar.'
12
12
 
13
13
  s.platform = Gem::Platform::RUBY
14
- s.has_rdoc = true
15
14
 
16
15
  s.require_path = 'lib'
17
- s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'README.md', 'Rakefile', 'antlr4-native.gemspec']
16
+ s.files = Dir['{lib,spec,vendor}/**/*', 'Gemfile', 'README.md', 'Rakefile', 'antlr4-native.gemspec']
17
+
18
+ s.add_runtime_dependency "rice", "~> 4.0"
18
19
  end
@@ -51,16 +51,24 @@ module Antlr4Native
51
51
 
52
52
  def conversions
53
53
  @class_conversions ||= <<~END
54
- template <>
55
- Object to_ruby<#{parser_ns}::#{name}*>(#{parser_ns}::#{name}* const &x) {
56
- if (!x) return Nil;
57
- return Data_Object<#{parser_ns}::#{name}>(x, #{proxy_class_variable}, nullptr, nullptr);
58
- }
54
+ namespace Rice::detail {
55
+ template <>
56
+ class To_Ruby<#{parser_ns}::#{name}*> {
57
+ public:
58
+ VALUE convert(#{parser_ns}::#{name}* const &x) {
59
+ if (!x) return Nil;
60
+ return Data_Object<#{parser_ns}::#{name}>(x, false, #{proxy_class_variable});
61
+ }
62
+ };
59
63
 
60
- template <>
61
- Object to_ruby<#{name}Proxy*>(#{name}Proxy* const &x) {
62
- if (!x) return Nil;
63
- return Data_Object<#{name}Proxy>(x, #{proxy_class_variable}, nullptr, nullptr);
64
+ template <>
65
+ class To_Ruby<#{name}Proxy*> {
66
+ public:
67
+ VALUE convert(#{name}Proxy* const &x) {
68
+ if (!x) return Nil;
69
+ return Data_Object<#{name}Proxy>(x, false, #{proxy_class_variable});
70
+ }
71
+ };
64
72
  }
65
73
  END
66
74
  end
@@ -88,7 +96,7 @@ module Antlr4Native
88
96
  }
89
97
  }
90
98
 
91
- return a;
99
+ return std::move(a);
92
100
  }
93
101
  END
94
102
  else
@@ -105,7 +113,7 @@ module Antlr4Native
105
113
  }
106
114
 
107
115
  for (auto child : getChildren()) {
108
- if (ctx == from_ruby<ContextProxy>(child).getOriginal()) {
116
+ if (ctx == detail::From_Ruby<ContextProxy>().convert(child.value()).getOriginal()) {
109
117
  return child;
110
118
  }
111
119
  }
@@ -127,17 +135,17 @@ module Antlr4Native
127
135
  Array a;
128
136
 
129
137
  if (orig == nullptr) {
130
- return a;
138
+ return std::move(a);
131
139
  }
132
140
 
133
141
  auto vec = ((#{parser_ns}::#{name}*)orig) -> #{token_mtd.name}(#{params});
134
142
 
135
143
  for (auto it = vec.begin(); it != vec.end(); it ++) {
136
144
  TerminalNodeProxy proxy(*it);
137
- a.push(proxy);
145
+ a.push(detail::To_Ruby<TerminalNodeProxy>().convert(proxy));
138
146
  }
139
147
 
140
- return a;
148
+ return std::move(a);
141
149
  }
142
150
  END
143
151
  else
@@ -148,8 +156,13 @@ module Antlr4Native
148
156
  }
149
157
 
150
158
  auto token = ((#{parser_ns}::#{name}*)orig) -> #{token_mtd.name}(#{params});
159
+
160
+ if (token == nullptr) {
161
+ return Qnil;
162
+ }
163
+
151
164
  TerminalNodeProxy proxy(token);
152
- return to_ruby(proxy);
165
+ return detail::To_Ruby<TerminalNodeProxy>().convert(proxy);
153
166
  }
154
167
  END
155
168
  end
@@ -159,8 +172,7 @@ module Antlr4Native
159
172
  def class_wrapper(module_var)
160
173
  @class_wrapper ||= begin
161
174
  lines = [
162
- "#{proxy_class_variable} = #{module_var}",
163
- ".define_class<#{name}Proxy, ContextProxy>(\"#{name}\")"
175
+ %(#{proxy_class_variable} = define_class_under<#{name}Proxy, ContextProxy>(#{module_var}, "#{name}"))
164
176
  ]
165
177
 
166
178
  each_context_method do |ctx_method|
@@ -63,18 +63,27 @@ module Antlr4Native
63
63
 
64
64
  def interop_code
65
65
  <<~END
66
- #include "iostream"
66
+ #include <iostream>
67
67
 
68
- #include "antlr4-runtime.h"
68
+ #include <antlr4-runtime.h>
69
69
 
70
- #include "#{parser_ns}.h"
71
- #include "#{antlr_ns}BaseVisitor.h"
72
- #include "#{lexer_ns}.h"
70
+ #include "antlrgen/#{parser_ns}.h"
71
+ #include "antlrgen/#{antlr_ns}BaseVisitor.h"
72
+ #include "antlrgen/#{lexer_ns}.h"
73
73
 
74
- #include "rice/Array.hpp"
75
- #include "rice/Class.hpp"
76
- #include "rice/Constructor.hpp"
77
- #include "rice/Director.hpp"
74
+ #include <rice/rice.hpp>
75
+ #include <rice/stl.hpp>
76
+
77
+ #ifdef _WIN32
78
+ #undef OPTIONAL
79
+ #undef IN
80
+ #undef OUT
81
+ #endif
82
+
83
+ #undef FALSE
84
+ #undef TRUE
85
+
86
+ #undef TYPE
78
87
 
79
88
  using namespace std;
80
89
  using namespace Rice;
@@ -82,6 +91,35 @@ module Antlr4Native
82
91
 
83
92
  #{proxy_class_declarations}
84
93
 
94
+ namespace Rice::detail {
95
+ template <>
96
+ class To_Ruby<Token*> {
97
+ public:
98
+ VALUE convert(Token* const &x) {
99
+ if (!x) return Nil;
100
+ return Data_Object<Token>(x, false, rb_cToken);
101
+ }
102
+ };
103
+
104
+ template <>
105
+ class To_Ruby<tree::ParseTree*> {
106
+ public:
107
+ VALUE convert(tree::ParseTree* const &x) {
108
+ if (!x) return Nil;
109
+ return Data_Object<tree::ParseTree>(x, false, rb_cParseTree);
110
+ }
111
+ };
112
+
113
+ template <>
114
+ class To_Ruby<tree::TerminalNode*> {
115
+ public:
116
+ VALUE convert(tree::TerminalNode* const &x) {
117
+ if (!x) return Nil;
118
+ return Data_Object<tree::TerminalNode>(x, false, rb_cTerminalNode);
119
+ }
120
+ };
121
+ }
122
+
85
123
  class ContextProxy {
86
124
  public:
87
125
  ContextProxy(tree::ParseTree* orig) {
@@ -96,6 +134,18 @@ module Antlr4Native
96
134
  return orig -> getText();
97
135
  }
98
136
 
137
+ Object getStart() {
138
+ auto token = ((ParserRuleContext*) orig) -> getStart();
139
+
140
+ return detail::To_Ruby<Token*>().convert(token);
141
+ }
142
+
143
+ Object getStop() {
144
+ auto token = ((ParserRuleContext*) orig) -> getStop();
145
+
146
+ return detail::To_Ruby<Token*>().convert(token);
147
+ }
148
+
99
149
  Array getChildren() {
100
150
  if (children == nullptr) {
101
151
  children = new Array();
@@ -134,7 +184,7 @@ module Antlr4Native
134
184
 
135
185
  bool doubleEquals(Object other) {
136
186
  if (other.is_a(rb_cContextProxy)) {
137
- return from_ruby<ContextProxy*>(other) -> getOriginal() == getOriginal();
187
+ return detail::From_Ruby<ContextProxy*>().convert(other) -> getOriginal() == getOriginal();
138
188
  } else {
139
189
  return false;
140
190
  }
@@ -155,6 +205,7 @@ module Antlr4Native
155
205
  TerminalNodeProxy(tree::ParseTree* tree) : ContextProxy(tree) { }
156
206
  };
157
207
 
208
+
158
209
  #{proxy_class_headers}
159
210
 
160
211
  #{conversions}
@@ -191,31 +242,7 @@ module Antlr4Native
191
242
  end
192
243
 
193
244
  def conversions
194
- @conversions ||= begin
195
- context_conversions = contexts.map(&:conversions).join("\n")
196
-
197
- <<~END
198
- template <>
199
- Object to_ruby<Token*>(Token* const &x) {
200
- if (!x) return Nil;
201
- return Data_Object<Token>(x, rb_cToken, nullptr, nullptr);
202
- }
203
-
204
- template <>
205
- Object to_ruby<tree::ParseTree*>(tree::ParseTree* const &x) {
206
- if (!x) return Nil;
207
- return Data_Object<tree::ParseTree>(x, rb_cParseTree, nullptr, nullptr);
208
- }
209
-
210
- template <>
211
- Object to_ruby<tree::TerminalNode*>(tree::TerminalNode* const &x) {
212
- if (!x) return Nil;
213
- return Data_Object<tree::TerminalNode>(x, rb_cTerminalNode, nullptr, nullptr);
214
- }
215
-
216
- #{context_conversions}
217
- END
218
- end
245
+ @conversions ||= contexts.map(&:conversions).join("\n")
219
246
  end
220
247
 
221
248
  def proxy_class_methods
@@ -243,14 +270,21 @@ module Antlr4Native
243
270
  return parser;
244
271
  }
245
272
 
246
- VALUE visit(VisitorProxy* visitor) {
247
- visitor -> visit(this -> parser -> #{parser_root_method}());
273
+ Object #{parser_root_method}() {
274
+ auto ctx = this -> parser -> #{parser_root_method}();
275
+
276
+ #{capitalize(parser_root_method)}ContextProxy proxy((#{parser_ns}::#{capitalize(parser_root_method)}Context*) ctx);
277
+ return detail::To_Ruby<#{capitalize(parser_root_method)}ContextProxy>().convert(proxy);
278
+ }
279
+
280
+ Object visit(VisitorProxy* visitor) {
281
+ auto result = visitor -> visit(this -> parser -> #{parser_root_method}());
248
282
 
249
283
  // reset for the next visit call
250
284
  this -> lexer -> reset();
251
285
  this -> parser -> reset();
252
286
 
253
- return Qnil;
287
+ return result;
254
288
  }
255
289
 
256
290
  ~ParserProxy() {
@@ -280,10 +314,15 @@ module Antlr4Native
280
314
  #{parser_ns}* parser;
281
315
  };
282
316
 
283
- template <>
284
- Object to_ruby<ParserProxy*>(ParserProxy* const &x) {
285
- if (!x) return Nil;
286
- return Data_Object<ParserProxy>(x, rb_cParser, nullptr, nullptr);
317
+ namespace Rice::detail {
318
+ template <>
319
+ class To_Ruby<ParserProxy*> {
320
+ public:
321
+ VALUE convert(ParserProxy* const &x) {
322
+ if (!x) return Nil;
323
+ return Data_Object<ParserProxy>(x, false, rb_cParser);
324
+ }
325
+ };
287
326
  }
288
327
  END
289
328
  end
@@ -294,38 +333,37 @@ module Antlr4Native
294
333
  void Init_#{ext_name}() {
295
334
  Module rb_m#{parser_ns} = define_module("#{parser_ns}");
296
335
 
297
- rb_cToken = rb_m#{parser_ns}
298
- .define_class<Token>("Token")
299
- .define_method("text", &Token::getText);
300
-
301
- rb_cParser = rb_m#{parser_ns}
302
- .define_class<ParserProxy>("Parser")
303
- .define_singleton_method("parse", &ParserProxy::parse)
304
- .define_singleton_method("parse_file", &ParserProxy::parseFile)
305
- .define_method("visit", &ParserProxy::visit);
336
+ rb_cToken = define_class_under<Token>(rb_m#{parser_ns}, "Token")
337
+ .define_method("text", &Token::getText)
338
+ .define_method("channel", &Token::getChannel)
339
+ .define_method("token_index", &Token::getTokenIndex);
306
340
 
307
- rb_cParseTree = rb_m#{parser_ns}
308
- .define_class<tree::ParseTree>("ParseTree");
341
+ rb_cParseTree = define_class_under<tree::ParseTree>(rb_m#{parser_ns}, "ParseTree");
309
342
 
310
- rb_cContextProxy = rb_m#{parser_ns}
311
- .define_class<ContextProxy>("Context")
343
+ rb_cContextProxy = define_class_under<ContextProxy>(rb_m#{parser_ns}, "Context")
312
344
  .define_method("children", &ContextProxy::getChildren)
313
345
  .define_method("child_count", &ContextProxy::childCount)
314
346
  .define_method("text", &ContextProxy::getText)
347
+ .define_method("start", &ContextProxy::getStart)
348
+ .define_method("stop", &ContextProxy::getStop)
315
349
  .define_method("parent", &ContextProxy::getParent)
316
350
  .define_method("==", &ContextProxy::doubleEquals);
317
351
 
318
- rb_cTerminalNode = rb_mPython3Parser
319
- .define_class<TerminalNodeProxy, ContextProxy>("TerminalNodeImpl");
352
+ rb_cTerminalNode = define_class_under<TerminalNodeProxy, ContextProxy>(rb_m#{parser_ns}, "TerminalNodeImpl");
320
353
 
321
- rb_m#{parser_ns}
322
- .define_class<#{visitor_generator.cpp_class_name}>("#{visitor_generator.class_name}")
354
+ define_class_under<#{antlr_ns}BaseVisitor>(rb_m#{parser_ns}, "#{visitor_generator.class_name}")
323
355
  .define_director<#{visitor_generator.cpp_class_name}>()
324
356
  .define_constructor(Constructor<#{visitor_generator.cpp_class_name}, Object>())
325
357
  .define_method("visit", &#{visitor_generator.cpp_class_name}::ruby_visit)
326
358
  .define_method("visit_children", &#{visitor_generator.cpp_class_name}::ruby_visitChildren)
327
359
  #{visitor_generator.visitor_proxy_methods(' ').join("\n")};
328
360
 
361
+ rb_cParser = define_class_under<ParserProxy>(rb_m#{parser_ns}, "Parser")
362
+ .define_singleton_function("parse", &ParserProxy::parse)
363
+ .define_singleton_function("parse_file", &ParserProxy::parseFile)
364
+ .define_method("#{parser_root_method}", &ParserProxy::#{parser_root_method})
365
+ .define_method("visit", &ParserProxy::visit);
366
+
329
367
  #{class_wrappers_str(' ')}
330
368
  }
331
369
  END
@@ -337,7 +375,7 @@ module Antlr4Native
337
375
  [
338
376
  " #{idx == 0 ? 'if' : 'else if'} (antlrcpp::is<#{parser_ns}::#{context.name}*>(node)) {",
339
377
  " #{context.name}Proxy proxy((#{parser_ns}::#{context.name}*)node);",
340
- " return to_ruby(proxy);",
378
+ " return detail::To_Ruby<#{context.name}Proxy>().convert(proxy);",
341
379
  " }"
342
380
  ]
343
381
  end
@@ -347,7 +385,7 @@ module Antlr4Native
347
385
  #{wrapper_branches.join("\n")}
348
386
  else if (antlrcpp::is<tree::TerminalNodeImpl*>(node)) {
349
387
  TerminalNodeProxy proxy(node);
350
- return to_ruby(proxy);
388
+ return detail::To_Ruby<TerminalNodeProxy>().convert(proxy);
351
389
  } else {
352
390
  return Nil;
353
391
  }
@@ -1,3 +1,3 @@
1
1
  module Antlr4Native
2
- VERSION = '1.0.0'
2
+ VERSION = '2.0.0'
3
3
  end
@@ -46,13 +46,21 @@ module Antlr4Native
46
46
  #{cpp_class_name}(Object self) : Director(self) { }
47
47
 
48
48
  Object ruby_visit(ContextProxy* proxy) {
49
- visit(proxy -> getOriginal());
50
- return Nil;
49
+ auto result = visit(proxy -> getOriginal());
50
+ try {
51
+ return result.as<Object>();
52
+ } catch(std::bad_cast) {
53
+ return Qnil;
54
+ }
51
55
  }
52
56
 
53
57
  Object ruby_visitChildren(ContextProxy* proxy) {
54
- visitChildren(proxy -> getOriginal());
55
- return Nil;
58
+ auto result = visitChildren(proxy -> getOriginal());
59
+ try {
60
+ return result.as<Object>();
61
+ } catch(std::bad_cast) {
62
+ return Qnil;
63
+ }
56
64
  }
57
65
 
58
66
  #{vms.join("\n")}
Binary file
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: antlr4-native
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Dutro
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-01 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rice
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
13
27
  description: Create a Ruby native extension from any ANTLR4 grammar.
14
28
  email:
15
29
  - camertron@gmail.com
@@ -18,6 +32,7 @@ extensions: []
18
32
  extra_rdoc_files: []
19
33
  files:
20
34
  - Gemfile
35
+ - README.md
21
36
  - Rakefile
22
37
  - antlr4-native.gemspec
23
38
  - lib/antlr4-native.rb
@@ -28,10 +43,11 @@ files:
28
43
  - lib/antlr4-native/string_helpers.rb
29
44
  - lib/antlr4-native/version.rb
30
45
  - lib/antlr4-native/visitor_generator.rb
46
+ - vendor/antlr4-4.8-1-complete.jar
31
47
  homepage: http://github.com/camertron/antlr4-native-rb
32
48
  licenses: []
33
49
  metadata: {}
34
- post_install_message:
50
+ post_install_message:
35
51
  rdoc_options: []
36
52
  require_paths:
37
53
  - lib
@@ -46,9 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
62
  - !ruby/object:Gem::Version
47
63
  version: '0'
48
64
  requirements: []
49
- rubyforge_project:
50
- rubygems_version: 2.7.6.2
51
- signing_key:
65
+ rubygems_version: 3.2.22
66
+ signing_key:
52
67
  specification_version: 4
53
68
  summary: Create a Ruby native extension from any ANTLR4 grammar.
54
69
  test_files: []