antlr4-native 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +97 -0
- data/antlr4-native.gemspec +1 -1
- data/lib/antlr4-native/version.rb +1 -1
- data/vendor/antlr4-4.8-1-complete.jar +0 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21633b380c20483273937e10a72b1b415e2b24b93e3b5fb3ed92b54cb31a9bf9
|
4
|
+
data.tar.gz: 0ce8f5470722e38fcbd90997b5bcbc914f39bb58976ac528d5a7a9a0a99cc41c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e92035c90ca04a7ad191446234226237100209d69b1261e7f2944a4b7c54f5bda1e08e10861d967dd455afda3e2b6c3485ae6fe3829857783678eb2043859f3
|
7
|
+
data.tar.gz: b5456c0caf77ff17f5581c4ac3f39060f38f558c5f4fe009fd7f90db2448a15e9ff37f2a4e9419522dae5418684586bf7ded5240ed8c8e886e94b20ed920a9bf
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
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.
|
89
|
+
* Ruby >= 2.3.
|
90
|
+
|
91
|
+
## License
|
92
|
+
|
93
|
+
Licensed under the MIT license. See LICENSE for details.
|
94
|
+
|
95
|
+
## Authors
|
96
|
+
|
97
|
+
* Cameron C. Dutro: http://github.com/camertron
|
data/antlr4-native.gemspec
CHANGED
@@ -14,5 +14,5 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.has_rdoc = true
|
15
15
|
|
16
16
|
s.require_path = 'lib'
|
17
|
-
s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'README.md', 'Rakefile', 'antlr4-native.gemspec']
|
17
|
+
s.files = Dir['{lib,spec,vendor}/**/*', 'Gemfile', 'README.md', 'Rakefile', 'antlr4-native.gemspec']
|
18
18
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: antlr4-native
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Dutro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Create a Ruby native extension from any ANTLR4 grammar.
|
14
14
|
email:
|
@@ -18,6 +18,7 @@ extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- Gemfile
|
21
|
+
- README.md
|
21
22
|
- Rakefile
|
22
23
|
- antlr4-native.gemspec
|
23
24
|
- lib/antlr4-native.rb
|
@@ -28,6 +29,7 @@ files:
|
|
28
29
|
- lib/antlr4-native/string_helpers.rb
|
29
30
|
- lib/antlr4-native/version.rb
|
30
31
|
- lib/antlr4-native/visitor_generator.rb
|
32
|
+
- vendor/antlr4-4.8-1-complete.jar
|
31
33
|
homepage: http://github.com/camertron/antlr4-native-rb
|
32
34
|
licenses: []
|
33
35
|
metadata: {}
|
@@ -46,8 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
48
|
- !ruby/object:Gem::Version
|
47
49
|
version: '0'
|
48
50
|
requirements: []
|
49
|
-
|
50
|
-
rubygems_version: 2.7.6.2
|
51
|
+
rubygems_version: 3.0.6
|
51
52
|
signing_key:
|
52
53
|
specification_version: 4
|
53
54
|
summary: Create a Ruby native extension from any ANTLR4 grammar.
|