antlr4-native 1.0.2 → 2.0.1

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: '08bed362c4b5695e0e900adb1b9837f284d92e70b7bc2006467bc1888d39f12c'
4
- data.tar.gz: 881aac540b1395c0f3e974f4c3d8a3f747ab695deeba95bd5d40c2c7924c5015
3
+ metadata.gz: ba388dfab9f2c91aec93eb1ae6ce3da83bff2777a921c14dca055e7c5ef06f82
4
+ data.tar.gz: 635a32e158d29328fdb181a636462ec5f73af777ab6c1bff24da13191d735f3b
5
5
  SHA512:
6
- metadata.gz: d02e7aa15bced54e120e5bef5ff5d2be69919a83a0473e025feca86b7e2ee446e4b808a7d56959f3a6e13a2e55eb0666b805f189ad668fe66b68c49fcf2dcd30
7
- data.tar.gz: bfa38b403307ffe88aff984d1713af1e7716629c0794512a4fcee432f60199510c588345d1f1005cc1be6ce0f4f68d4a97555024b11436739e2347c1d4877fab
6
+ metadata.gz: c019c9f3549d0b0d4f1aae071592a160d3e2fdd2c8a0bab89c24d34d2f81d0925c1a4f2b4d59f227988ce94b042011c2e910f63b20df14366d2956483f1eb11a
7
+ data.tar.gz: 658ec185e823312c7acd8f45d33ef249fed4f0f9125606b11e0d683ab2dc7150bac18a7e4fded01e8dfb40faa04f12c8ce3a42d647a872c43de6c76810d7d3d0
data/README.md CHANGED
@@ -28,7 +28,7 @@ generator = Antlr4Native::Generator.new(
28
28
  generator.generate
29
29
  ```
30
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:
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
32
 
33
33
  ```antlr
34
34
  parser grammar Python3Parser;
@@ -85,12 +85,13 @@ Finally, if you override `#initialize` in your visitor subclasses, don't forget
85
85
 
86
86
  ## System Requirements
87
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.
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
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.
90
91
 
91
92
  ## License
92
93
 
93
- Licensed under the MIT license. See LICENSE for details.
94
+ Licensed under the MIT license. See LICENSE.txt for details.
94
95
 
95
96
  ## Authors
96
97
 
@@ -14,4 +14,6 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.require_path = 'lib'
16
16
  s.files = Dir['{lib,spec,vendor}/**/*', 'Gemfile', 'README.md', 'Rakefile', 'antlr4-native.gemspec']
17
+
18
+ s.add_runtime_dependency "rice", "~> 4.0"
17
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,45 +134,43 @@ module Antlr4Native
96
134
  return orig -> getText();
97
135
  }
98
136
 
99
- Array getChildren() {
100
- if (children == nullptr) {
101
- children = new Array();
137
+ Object getStart() {
138
+ auto token = ((ParserRuleContext*) orig) -> getStart();
102
139
 
103
- if (orig != nullptr) {
104
- for (auto it = orig -> children.begin(); it != orig -> children.end(); it ++) {
105
- Object parseTree = ContextProxy::wrapParseTree(*it);
140
+ return detail::To_Ruby<Token*>().convert(token);
141
+ }
106
142
 
107
- if (parseTree != Nil) {
108
- children -> push(parseTree);
109
- }
110
- }
111
- }
112
- }
143
+ Object getStop() {
144
+ auto token = ((ParserRuleContext*) orig) -> getStop();
113
145
 
114
- return *children;
146
+ return detail::To_Ruby<Token*>().convert(token);
115
147
  }
116
148
 
117
- Object getParent() {
118
- if (parent == Nil) {
119
- if (orig != nullptr) {
120
- parent = ContextProxy::wrapParseTree(orig -> parent);
149
+ Array getChildren() {
150
+ Array children;
151
+ if (orig != nullptr) {
152
+ for (auto it = orig -> children.begin(); it != orig -> children.end(); it ++) {
153
+ Object parseTree = ContextProxy::wrapParseTree(*it);
154
+
155
+ if (parseTree != Nil) {
156
+ children.push(parseTree);
157
+ }
121
158
  }
122
159
  }
160
+ return children;
161
+ }
123
162
 
124
- return parent;
163
+ Object getParent() {
164
+ return orig == nullptr ? Nil : ContextProxy::wrapParseTree(orig -> parent);
125
165
  }
126
166
 
127
167
  size_t childCount() {
128
- if (orig == nullptr) {
129
- return 0;
130
- }
131
-
132
- return getChildren().size();
168
+ return orig == nullptr ? 0 : orig -> children.size();
133
169
  }
134
170
 
135
171
  bool doubleEquals(Object other) {
136
172
  if (other.is_a(rb_cContextProxy)) {
137
- return from_ruby<ContextProxy*>(other) -> getOriginal() == getOriginal();
173
+ return detail::From_Ruby<ContextProxy*>().convert(other) -> getOriginal() == getOriginal();
138
174
  } else {
139
175
  return false;
140
176
  }
@@ -146,8 +182,6 @@ module Antlr4Native
146
182
 
147
183
  protected:
148
184
  tree::ParseTree* orig = nullptr;
149
- Array* children = nullptr;
150
- Object parent = Nil;
151
185
  };
152
186
 
153
187
  class TerminalNodeProxy : public ContextProxy {
@@ -155,6 +189,7 @@ module Antlr4Native
155
189
  TerminalNodeProxy(tree::ParseTree* tree) : ContextProxy(tree) { }
156
190
  };
157
191
 
192
+
158
193
  #{proxy_class_headers}
159
194
 
160
195
  #{conversions}
@@ -191,31 +226,7 @@ module Antlr4Native
191
226
  end
192
227
 
193
228
  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
229
+ @conversions ||= contexts.map(&:conversions).join("\n")
219
230
  end
220
231
 
221
232
  def proxy_class_methods
@@ -243,14 +254,21 @@ module Antlr4Native
243
254
  return parser;
244
255
  }
245
256
 
246
- VALUE visit(VisitorProxy* visitor) {
247
- visitor -> visit(this -> parser -> #{parser_root_method}());
257
+ Object #{parser_root_method}() {
258
+ auto ctx = this -> parser -> #{parser_root_method}();
259
+
260
+ #{capitalize(parser_root_method)}ContextProxy proxy((#{parser_ns}::#{capitalize(parser_root_method)}Context*) ctx);
261
+ return detail::To_Ruby<#{capitalize(parser_root_method)}ContextProxy>().convert(proxy);
262
+ }
263
+
264
+ Object visit(VisitorProxy* visitor) {
265
+ auto result = visitor -> visit(this -> parser -> #{parser_root_method}());
248
266
 
249
267
  // reset for the next visit call
250
268
  this -> lexer -> reset();
251
269
  this -> parser -> reset();
252
270
 
253
- return Qnil;
271
+ return result;
254
272
  }
255
273
 
256
274
  ~ParserProxy() {
@@ -280,10 +298,15 @@ module Antlr4Native
280
298
  #{parser_ns}* parser;
281
299
  };
282
300
 
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);
301
+ namespace Rice::detail {
302
+ template <>
303
+ class To_Ruby<ParserProxy*> {
304
+ public:
305
+ VALUE convert(ParserProxy* const &x) {
306
+ if (!x) return Nil;
307
+ return Data_Object<ParserProxy>(x, false, rb_cParser);
308
+ }
309
+ };
287
310
  }
288
311
  END
289
312
  end
@@ -294,38 +317,37 @@ module Antlr4Native
294
317
  void Init_#{ext_name}() {
295
318
  Module rb_m#{parser_ns} = define_module("#{parser_ns}");
296
319
 
297
- rb_cToken = rb_m#{parser_ns}
298
- .define_class<Token>("Token")
299
- .define_method("text", &Token::getText);
320
+ rb_cToken = define_class_under<Token>(rb_m#{parser_ns}, "Token")
321
+ .define_method("text", &Token::getText)
322
+ .define_method("channel", &Token::getChannel)
323
+ .define_method("token_index", &Token::getTokenIndex);
300
324
 
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);
325
+ rb_cParseTree = define_class_under<tree::ParseTree>(rb_m#{parser_ns}, "ParseTree");
306
326
 
307
- rb_cParseTree = rb_m#{parser_ns}
308
- .define_class<tree::ParseTree>("ParseTree");
309
-
310
- rb_cContextProxy = rb_m#{parser_ns}
311
- .define_class<ContextProxy>("Context")
327
+ rb_cContextProxy = define_class_under<ContextProxy>(rb_m#{parser_ns}, "Context")
312
328
  .define_method("children", &ContextProxy::getChildren)
313
329
  .define_method("child_count", &ContextProxy::childCount)
314
330
  .define_method("text", &ContextProxy::getText)
331
+ .define_method("start", &ContextProxy::getStart)
332
+ .define_method("stop", &ContextProxy::getStop)
315
333
  .define_method("parent", &ContextProxy::getParent)
316
334
  .define_method("==", &ContextProxy::doubleEquals);
317
335
 
318
- rb_cTerminalNode = rb_m#{parser_ns}
319
- .define_class<TerminalNodeProxy, ContextProxy>("TerminalNodeImpl");
336
+ rb_cTerminalNode = define_class_under<TerminalNodeProxy, ContextProxy>(rb_m#{parser_ns}, "TerminalNodeImpl");
320
337
 
321
- rb_m#{parser_ns}
322
- .define_class<#{visitor_generator.cpp_class_name}>("#{visitor_generator.class_name}")
338
+ define_class_under<#{antlr_ns}BaseVisitor>(rb_m#{parser_ns}, "#{visitor_generator.class_name}")
323
339
  .define_director<#{visitor_generator.cpp_class_name}>()
324
340
  .define_constructor(Constructor<#{visitor_generator.cpp_class_name}, Object>())
325
341
  .define_method("visit", &#{visitor_generator.cpp_class_name}::ruby_visit)
326
342
  .define_method("visit_children", &#{visitor_generator.cpp_class_name}::ruby_visitChildren)
327
343
  #{visitor_generator.visitor_proxy_methods(' ').join("\n")};
328
344
 
345
+ rb_cParser = define_class_under<ParserProxy>(rb_m#{parser_ns}, "Parser")
346
+ .define_singleton_function("parse", &ParserProxy::parse)
347
+ .define_singleton_function("parse_file", &ParserProxy::parseFile)
348
+ .define_method("#{parser_root_method}", &ParserProxy::#{parser_root_method}, Return().keepAlive())
349
+ .define_method("visit", &ParserProxy::visit, Return().keepAlive());
350
+
329
351
  #{class_wrappers_str(' ')}
330
352
  }
331
353
  END
@@ -337,7 +359,7 @@ module Antlr4Native
337
359
  [
338
360
  " #{idx == 0 ? 'if' : 'else if'} (antlrcpp::is<#{parser_ns}::#{context.name}*>(node)) {",
339
361
  " #{context.name}Proxy proxy((#{parser_ns}::#{context.name}*)node);",
340
- " return to_ruby(proxy);",
362
+ " return detail::To_Ruby<#{context.name}Proxy>().convert(proxy);",
341
363
  " }"
342
364
  ]
343
365
  end
@@ -347,7 +369,7 @@ module Antlr4Native
347
369
  #{wrapper_branches.join("\n")}
348
370
  else if (antlrcpp::is<tree::TerminalNodeImpl*>(node)) {
349
371
  TerminalNodeProxy proxy(node);
350
- return to_ruby(proxy);
372
+ return detail::To_Ruby<TerminalNodeProxy>().convert(proxy);
351
373
  } else {
352
374
  return Nil;
353
375
  }
@@ -1,3 +1,3 @@
1
1
  module Antlr4Native
2
- VERSION = '1.0.2'
2
+ VERSION = '2.0.1'
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")}
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.2
4
+ version: 2.0.1
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-02 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-05-09 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
@@ -33,7 +47,7 @@ files:
33
47
  homepage: http://github.com/camertron/antlr4-native-rb
34
48
  licenses: []
35
49
  metadata: {}
36
- post_install_message:
50
+ post_install_message:
37
51
  rdoc_options: []
38
52
  require_paths:
39
53
  - lib
@@ -48,8 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
62
  - !ruby/object:Gem::Version
49
63
  version: '0'
50
64
  requirements: []
51
- rubygems_version: 3.0.6
52
- signing_key:
65
+ rubygems_version: 3.2.22
66
+ signing_key:
53
67
  specification_version: 4
54
68
  summary: Create a Ruby native extension from any ANTLR4 grammar.
55
69
  test_files: []