ebnf 1.1.2 → 1.1.3
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 +5 -5
- data/README.md +10 -8
- data/VERSION +1 -1
- data/etc/doap.ttl +2 -2
- data/lib/ebnf/base.rb +21 -24
- data/lib/ebnf/ll1.rb +2 -2
- data/lib/ebnf/rule.rb +24 -29
- data/lib/ebnf/writer.rb +5 -9
- metadata +23 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 658c0da6f1ba2b472e94badcedabc0dabfab7b3cbce02e58fe6bfb286416e247
|
4
|
+
data.tar.gz: 9cc79c8f8c0ce5d4e24eb8e1dfbac9d52b1bfe26951c97fd435a547fdb80cf84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0cce6804a7d9afa85fe0559148110e2e3443242ff44fac31f77c5939a22158b5bd1fe7bdb5474a98e2221b474c0010bf1e93612e9bd01320212406557892469
|
7
|
+
data.tar.gz: 41f3a9b7b7bbaa650afa269f54a56724b029e6b14ac31a62632b8d09ce62578624221b15836f4fe52a549408b79d7bd8a20b841d9d6141bb18546efe211b0c59
|
data/README.md
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
[EBNF][] parser and generic parser generator.
|
4
4
|
|
5
5
|
[](http://badge.fury.io/rb/ebnf)
|
6
|
-
[](http://travis-ci.org/dryruby/ebnf)
|
7
|
+
[](https://coveralls.io/r/dryruby/ebnf)
|
8
|
+
[](https://gemnasium.com/dryruby/ebnf)
|
9
9
|
|
10
10
|
## Description
|
11
11
|
This is a [Ruby][] implementation of an [EBNF][] and [BNF][] parser and parser generator. It parses [EBNF][] grammars to [BNF][], generates [First/Follow][] and Branch tables for [LL(1)][] grammars, which can be used with the stream [Tokenizer][] and [LL(1) Parser][].
|
@@ -28,13 +28,14 @@ Of note in this implementation is that the tokenizer and parser are streaming, s
|
|
28
28
|
|
29
29
|
require 'ebnf'
|
30
30
|
|
31
|
-
ebnf = EBNF.parse(File.open('./etc/ebnf.
|
31
|
+
ebnf = EBNF.parse(File.open('./etc/ebnf.ebnf'))
|
32
32
|
|
33
|
-
Output rules and terminals as S-Expressions, Turtle or
|
33
|
+
Output rules and terminals as S-Expressions, Turtle, HTML or BNF
|
34
34
|
|
35
35
|
puts ebnf.to_sxp
|
36
36
|
puts ebnf.to_ttl
|
37
|
-
puts ebnf.
|
37
|
+
puts ebnf.to_html
|
38
|
+
puts ebnf.to_s
|
38
39
|
|
39
40
|
Transform EBNF to BNF (generates sub-productions using `alt` or `seq` from `plus`, `star` or `opt`)
|
40
41
|
|
@@ -42,10 +43,11 @@ Transform EBNF to BNF (generates sub-productions using `alt` or `seq` from `plus
|
|
42
43
|
|
43
44
|
Generate [First/Follow][] rules for BNF grammars
|
44
45
|
|
45
|
-
ebnf.first_follow(
|
46
|
+
ebnf.first_follow(:ebnf)
|
46
47
|
|
47
48
|
Generate Terminal, [First/Follow][], Cleanup and Branch tables as Ruby for parsing grammars
|
48
49
|
|
50
|
+
ebnf.build_tables
|
49
51
|
ebnf.to_ruby
|
50
52
|
|
51
53
|
Generate formatted grammar using HTML (requires [Haml][Haml] gem)
|
@@ -255,7 +257,7 @@ A copy of the [Turtle EBNF][] and derived parser files are included in the repos
|
|
255
257
|
[YARD-GS]: http://rubydoc.info/docs/yard/file/docs/GettingStarted.md
|
256
258
|
[PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
|
257
259
|
[EBNF]: http://www.w3.org/TR/REC-xml/#sec-notation
|
258
|
-
[EBNF doc]: http://rubydoc.info/github/
|
260
|
+
[EBNF doc]: http://rubydoc.info/github/dryruby/ebnf/master/frames
|
259
261
|
[First/Follow]: http://en.wikipedia.org/wiki/LL_parser#Constructing_an_LL.281.29_parsing_table
|
260
262
|
[LL(1)]: http://www.csd.uwo.ca/~moreno//CS447/Lectures/Syntax.html/node14.html
|
261
263
|
[LL(1) Parser]: http://en.wikipedia.org/wiki/LL_parser
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.3
|
data/etc/doap.ttl
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
|
10
10
|
<http://rubygems.org/gems/ebnf> a doap:Project, earl:TestSubject, earl:Software ;
|
11
11
|
doap:name "ebnf" ;
|
12
|
-
doap:homepage <http://
|
12
|
+
doap:homepage <http://dryruby.github.com/ebnf> ;
|
13
13
|
doap:license <http://creativecommons.org/licenses/publicdomain/> ;
|
14
14
|
doap:shortdesc "EBNF parser and parser generator"@en ;
|
15
15
|
doap:description "EBNF is a Ruby parser for W3C EBNF and a parser generator for compliant LL(1) grammars."@en ;
|
@@ -20,7 +20,7 @@
|
|
20
20
|
<http://dbpedia.org/resource/Ruby_(programming_language)> ;
|
21
21
|
doap:download-page <http://rubygems.org/gems/ebnf> ;
|
22
22
|
doap:mailing-list <http://lists.w3.org/Archives/Public/public-rdf-ruby/> ;
|
23
|
-
doap:bug-database <http://github.com/
|
23
|
+
doap:bug-database <http://github.com/dryruby/ebnf/issues> ;
|
24
24
|
doap:blog <http://greggkellogg.net/> ;
|
25
25
|
doap:developer <http://greggkellogg.net/foaf#me> ;
|
26
26
|
doap:maintainer <http://greggkellogg.net/foaf#me> ;
|
data/lib/ebnf/base.rb
CHANGED
@@ -117,19 +117,19 @@ module EBNF
|
|
117
117
|
#
|
118
118
|
# @param [#read, #to_s] input
|
119
119
|
# @param [Hash{Symbol => Object}] options
|
120
|
-
# @
|
121
|
-
# Output debug information to an array or STDOUT.
|
122
|
-
# @option options [Symbol] :format (:ebnf)
|
120
|
+
# @param [Symbol] :format (:ebnf)
|
123
121
|
# Format of input, one of :ebnf, or :sxp
|
124
|
-
|
125
|
-
|
122
|
+
# @option options [Boolean, Array] :debug
|
123
|
+
# Output debug information to an array or $stdout.
|
124
|
+
def initialize(input, format: :ebnf, **options)
|
125
|
+
@options = options.dup
|
126
126
|
@lineno, @depth, @errors = 1, 0, []
|
127
127
|
terminal = false
|
128
128
|
@ast = []
|
129
129
|
|
130
130
|
input = input.respond_to?(:read) ? input.read : input.to_s
|
131
131
|
|
132
|
-
case
|
132
|
+
case format
|
133
133
|
when :sxp
|
134
134
|
require 'sxp' unless defined?(SXP)
|
135
135
|
@ast = SXP::Reader::Basic.read(input).map {|e| Rule.from_sxp(e)}
|
@@ -144,7 +144,7 @@ module EBNF
|
|
144
144
|
terminal = true
|
145
145
|
when /^@pass\s*(.*)$/m
|
146
146
|
expr = expression($1).first
|
147
|
-
rule = Rule.new(nil, nil, expr, kind: :pass)
|
147
|
+
rule = Rule.new(nil, nil, expr, kind: :pass, ebnf: self)
|
148
148
|
rule.orig = expr
|
149
149
|
@ast << rule
|
150
150
|
else
|
@@ -156,7 +156,7 @@ module EBNF
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
else
|
159
|
-
raise "unknown input format #{
|
159
|
+
raise "unknown input format #{format.inspect}"
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
@@ -194,17 +194,17 @@ module EBNF
|
|
194
194
|
# Output Ruby parser files
|
195
195
|
#
|
196
196
|
# @param [IO, StringIO] output
|
197
|
-
# @param [
|
198
|
-
# @
|
199
|
-
def to_ruby(output =
|
200
|
-
unless output ==
|
197
|
+
# @param [String] :grammarFile
|
198
|
+
# @param [String] :mod_name ('Branch')
|
199
|
+
def to_ruby(output = $stdout, grammarFile: nil, mod_name: 'Branch')
|
200
|
+
unless output == $stdout
|
201
201
|
output.puts "# This file is automatically generated by #{__FILE__}"
|
202
|
-
output.puts "# BRANCH derived from #{
|
202
|
+
output.puts "# BRANCH derived from #{grammarFile}" if grammarFile
|
203
203
|
unless self.errors.empty?
|
204
204
|
output.puts "# Note, tables completed with errors, may need to be resolved manually:"
|
205
205
|
#output.puts "# #{pp.conflicts.map{|c| c.join("\n# ")}.join("\n# ")}"
|
206
206
|
end
|
207
|
-
output.puts "module #{
|
207
|
+
output.puts "module #{mod_name}"
|
208
208
|
output.puts " START = #{self.start.inspect}"
|
209
209
|
output.puts
|
210
210
|
end
|
@@ -214,7 +214,7 @@ module EBNF
|
|
214
214
|
self.outputTable(output, 'FOLLOW', self.follow, 1)
|
215
215
|
self.outputTable(output, 'CLEANUP', self.cleanup, 1)
|
216
216
|
self.outputTable(output, 'PASS', [self.pass], 1) if self.pass
|
217
|
-
unless output ==
|
217
|
+
unless output == $stdout
|
218
218
|
output.puts "end"
|
219
219
|
end
|
220
220
|
end
|
@@ -238,19 +238,19 @@ module EBNF
|
|
238
238
|
# @param [String] prefix for language
|
239
239
|
# @param [String] ns URI for language
|
240
240
|
# @return [String]
|
241
|
-
def to_ttl(prefix, ns)
|
241
|
+
def to_ttl(prefix = nil, ns = "http://example.org/")
|
242
242
|
unless ast.empty?
|
243
243
|
[
|
244
244
|
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.",
|
245
245
|
"@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.",
|
246
|
-
"@prefix #{prefix}: <#{ns}>.",
|
246
|
+
("@prefix #{prefix}: <#{ns}>." if prefix),
|
247
247
|
"@prefix : <#{ns}>.",
|
248
248
|
"@prefix re: <http://www.w3.org/2000/10/swap/grammar/regex#>.",
|
249
249
|
"@prefix g: <http://www.w3.org/2000/10/swap/grammar/ebnf#>.",
|
250
250
|
"",
|
251
251
|
":language rdfs:isDefinedBy <>; g:start :#{ast.first.id}.",
|
252
252
|
"",
|
253
|
-
]
|
253
|
+
].compact
|
254
254
|
end.join("\n") +
|
255
255
|
|
256
256
|
ast.sort.map(&:to_ttl).join("\n")
|
@@ -264,9 +264,8 @@ module EBNF
|
|
264
264
|
end
|
265
265
|
|
266
266
|
# Progress output, less than debugging
|
267
|
-
def progress(*args)
|
267
|
+
def progress(*args, **options)
|
268
268
|
return unless @options[:progress] || @options[:debug]
|
269
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
270
269
|
depth = options[:depth] || @depth
|
271
270
|
args << yield if block_given?
|
272
271
|
message = "#{args.join(': ')}"
|
@@ -276,8 +275,7 @@ module EBNF
|
|
276
275
|
end
|
277
276
|
|
278
277
|
# Error output
|
279
|
-
def error(*args)
|
280
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
278
|
+
def error(*args, **options)
|
281
279
|
depth = options[:depth] || @depth
|
282
280
|
args << yield if block_given?
|
283
281
|
message = "#{args.join(': ')}"
|
@@ -298,9 +296,8 @@ module EBNF
|
|
298
296
|
# @param [String] message ("")
|
299
297
|
#
|
300
298
|
# @yieldreturn [String] added to message
|
301
|
-
def debug(*args)
|
299
|
+
def debug(*args, **options)
|
302
300
|
return unless @options[:debug]
|
303
|
-
options = args.last.is_a?(Hash) ? args.pop : {}
|
304
301
|
depth = options[:depth] || @depth
|
305
302
|
args << yield if block_given?
|
306
303
|
message = "#{args.join(': ')}"
|
data/lib/ebnf/ll1.rb
CHANGED
@@ -216,7 +216,7 @@ module EBNF
|
|
216
216
|
@branch = {}
|
217
217
|
@already = []
|
218
218
|
@agenda = []
|
219
|
-
@starts.each do |start|
|
219
|
+
Array(@starts).each do |start|
|
220
220
|
do_production(start)
|
221
221
|
while !@agenda.empty?
|
222
222
|
x = @agenda.shift
|
@@ -265,7 +265,7 @@ module EBNF
|
|
265
265
|
end
|
266
266
|
end
|
267
267
|
io.puts "#{ind0}}.freeze\n"
|
268
|
-
|
268
|
+
elsif table
|
269
269
|
io.puts "#{ind0}#{name} = [\n#{ind1}" +
|
270
270
|
table.sort_by{|t| t.to_s.sub(/^_/, '')}.map(&:inspect).join(",\n#{ind1}") +
|
271
271
|
"\n#{ind0}].freeze\n"
|
data/lib/ebnf/rule.rb
CHANGED
@@ -60,23 +60,19 @@ module EBNF
|
|
60
60
|
# @param [Integer] id
|
61
61
|
# @param [Symbol] sym
|
62
62
|
# @param [Array] expr
|
63
|
-
# @param [
|
64
|
-
# @
|
65
|
-
# @
|
66
|
-
# @
|
67
|
-
# @
|
68
|
-
#
|
69
|
-
|
63
|
+
# @param [Symbol] :kind
|
64
|
+
# @param [String] :ebnf
|
65
|
+
# @param [Array] :first
|
66
|
+
# @param [Array] :follow
|
67
|
+
# @param [Boolean] :start
|
68
|
+
# @param [Rule] :top_rule
|
69
|
+
# @param [Boolean] :cleanup
|
70
|
+
def initialize(sym, id, expr, kind: nil, ebnf: nil, first: nil, follow: nil, start: nil, top_rule: nil, cleanup: nil)
|
70
71
|
@sym, @id = sym, id
|
71
72
|
@expr = expr.is_a?(Array) ? expr : [:seq, expr]
|
72
|
-
@ebnf =
|
73
|
-
@top_rule
|
74
|
-
@
|
75
|
-
@follow = options[:follow]
|
76
|
-
@start = options[:start]
|
77
|
-
@cleanup = options[:cleanup]
|
78
|
-
@kind = case
|
79
|
-
when options[:kind] then options[:kind]
|
73
|
+
@ebnf, @kind, @first, @follow, @start, @cleanup, @top_rule = ebnf, kind, first, follow, start, cleanup, top_rule
|
74
|
+
@top_rule ||= self
|
75
|
+
@kind ||= case
|
80
76
|
when sym.to_s == sym.to_s.upcase then :terminal
|
81
77
|
when !BNF_OPS.include?(@expr.first) then :terminal
|
82
78
|
else :rule
|
@@ -114,16 +110,15 @@ module EBNF
|
|
114
110
|
#
|
115
111
|
# @param [Array] expr
|
116
112
|
# @param [Hash{Symbol => Object}] options
|
117
|
-
# @
|
118
|
-
|
119
|
-
def build(expr, options = {})
|
113
|
+
# @param [Symbol] :kind
|
114
|
+
def build(expr, kind: nil, cleanup: nil, **options)
|
120
115
|
new_sym, new_id = (@top_rule ||self).send(:make_sym_id)
|
121
|
-
Rule.new(new_sym, new_id, expr,
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
116
|
+
Rule.new(new_sym, new_id, expr,
|
117
|
+
kind: kind,
|
118
|
+
ebnf: @ebnf,
|
119
|
+
top_rule: (@top_rule || self),
|
120
|
+
cleanup: cleanup,
|
121
|
+
**options)
|
127
122
|
end
|
128
123
|
|
129
124
|
# Return representation for building S-Expressions
|
@@ -151,7 +146,7 @@ module EBNF
|
|
151
146
|
# @return [String]
|
152
147
|
def to_ttl
|
153
148
|
@ebnf.debug("to_ttl") {inspect} if @ebnf
|
154
|
-
comment = orig.strip.
|
149
|
+
comment = orig.to_s.strip.
|
155
150
|
gsub(/"""/, '\"\"\"').
|
156
151
|
gsub("\\", "\\\\").
|
157
152
|
sub(/^\"/, '\"').
|
@@ -389,7 +384,7 @@ module EBNF
|
|
389
384
|
# Rules compare using their ids
|
390
385
|
def <=>(other)
|
391
386
|
if id.to_i == other.id.to_i
|
392
|
-
id <=> other.id
|
387
|
+
id.to_s <=> other.id.to_s
|
393
388
|
else
|
394
389
|
id.to_i <=> other.id.to_i
|
395
390
|
end
|
@@ -398,8 +393,8 @@ module EBNF
|
|
398
393
|
private
|
399
394
|
def ttl_expr(expr, pfx, depth, is_obj = true)
|
400
395
|
indent = ' ' * depth
|
401
|
-
@ebnf.debug("ttl_expr", depth: depth) {expr.inspect}
|
402
|
-
op = expr
|
396
|
+
@ebnf.debug("ttl_expr", depth: depth) {expr.inspect} if @ebnf
|
397
|
+
op, *expr = expr if expr.is_a?(Array)
|
403
398
|
statements = []
|
404
399
|
|
405
400
|
if is_obj
|
@@ -435,7 +430,7 @@ module EBNF
|
|
435
430
|
end
|
436
431
|
|
437
432
|
statements.last << " ." unless is_obj
|
438
|
-
@ebnf.debug("statements", depth: depth) {statements.join("\n")}
|
433
|
+
@ebnf.debug("statements", depth: depth) {statements.join("\n")} if @ebnf
|
439
434
|
statements
|
440
435
|
end
|
441
436
|
|
data/lib/ebnf/writer.rb
CHANGED
@@ -54,14 +54,10 @@ module EBNF
|
|
54
54
|
##
|
55
55
|
# @param [Array<Rule>] rules
|
56
56
|
# @param [Hash{Symbol => Object}] options
|
57
|
+
# @param [#write] :out ($stdout)
|
57
58
|
# @option options [Symbol] :format
|
58
|
-
|
59
|
-
# @option options [Boolean] :html (false)
|
60
|
-
# Format as HTML
|
61
|
-
def initialize(rules, options = {})
|
59
|
+
def initialize(rules, out: $stdout, html: false, **options)
|
62
60
|
@options = options.dup
|
63
|
-
out = options.fetch(:out, $stdio)
|
64
|
-
#fmt = options.fetch(:format, :ebnf)
|
65
61
|
|
66
62
|
# Determine max LHS length
|
67
63
|
max_id = rules.max_by {|r| r.id.to_s.length}.id.to_s.length
|
@@ -74,15 +70,15 @@ module EBNF
|
|
74
70
|
end
|
75
71
|
rhs_length = LINE_LENGTH - lhs_length
|
76
72
|
|
77
|
-
if
|
73
|
+
if html
|
78
74
|
# Output as formatted HTML
|
79
75
|
begin
|
80
76
|
require 'haml'
|
81
|
-
|
77
|
+
hout = Haml::Engine.new(HAML_DESC).render(self, rules: rules) do |rule|
|
82
78
|
formatted_expr = format(rule.expr)
|
83
79
|
formatted_expr.length > rhs_length ? format(rule.expr, "\n") : formatted_expr
|
84
80
|
end
|
85
|
-
out.write
|
81
|
+
out.write hout
|
86
82
|
return
|
87
83
|
rescue LoadError
|
88
84
|
$stderr.puts "Generating HTML requires haml gem to be loaded"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ebnf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregg Kellogg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sxp
|
@@ -28,22 +28,30 @@ dependencies:
|
|
28
28
|
name: rdf
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.2'
|
34
|
-
- - "<"
|
31
|
+
- - "~>"
|
35
32
|
- !ruby/object:Gem::Version
|
36
|
-
version: '
|
33
|
+
version: '3.0'
|
37
34
|
type: :runtime
|
38
35
|
prerelease: false
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
40
37
|
requirements:
|
41
|
-
- - "
|
38
|
+
- - "~>"
|
42
39
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
44
|
-
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdf-spec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
45
53
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
54
|
+
version: '3.0'
|
47
55
|
- !ruby/object:Gem::Dependency
|
48
56
|
name: haml
|
49
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,14 +100,14 @@ dependencies:
|
|
92
100
|
requirements:
|
93
101
|
- - "~>"
|
94
102
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
103
|
+
version: 0.9.12
|
96
104
|
type: :development
|
97
105
|
prerelease: false
|
98
106
|
version_requirements: !ruby/object:Gem::Requirement
|
99
107
|
requirements:
|
100
108
|
- - "~>"
|
101
109
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
110
|
+
version: 0.9.12
|
103
111
|
- !ruby/object:Gem::Dependency
|
104
112
|
name: rake
|
105
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -155,7 +163,7 @@ files:
|
|
155
163
|
- lib/ebnf/rule.rb
|
156
164
|
- lib/ebnf/version.rb
|
157
165
|
- lib/ebnf/writer.rb
|
158
|
-
homepage: http://github.com/
|
166
|
+
homepage: http://github.com/dryruby/ebnf
|
159
167
|
licenses:
|
160
168
|
- Unlicense
|
161
169
|
metadata: {}
|
@@ -175,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
183
|
version: '0'
|
176
184
|
requirements: []
|
177
185
|
rubyforge_project:
|
178
|
-
rubygems_version: 2.6
|
186
|
+
rubygems_version: 2.7.6
|
179
187
|
signing_key:
|
180
188
|
specification_version: 4
|
181
189
|
summary: EBNF parser and parser generator.
|