antlr4-native 1.0.2 → 2.0.1

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: '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: []