antlr4-native 1.0.0 → 2.0.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.
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: []