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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3bce4d1c681a0426e00d2aab724b58570e0406c7
4
- data.tar.gz: 330e8371e50c0cb9ec7f51c7e69c0cc8d93220c7
2
+ SHA256:
3
+ metadata.gz: 658c0da6f1ba2b472e94badcedabc0dabfab7b3cbce02e58fe6bfb286416e247
4
+ data.tar.gz: 9cc79c8f8c0ce5d4e24eb8e1dfbac9d52b1bfe26951c97fd435a547fdb80cf84
5
5
  SHA512:
6
- metadata.gz: fe8809f249c2c4f048e542a57af6f7b765f8991220aa3dee4e61964c8f1ededec0f6247997ac266c9d7e790785b526bedf536bae3409e1cf740482304579e547
7
- data.tar.gz: 8ebc6be59401e64c06646acdd5855c7c99feed3abed90bb24442df3a910df37b3057b3795efe76a7b17062502e97d126cd77e87c077719b45e5ada0088b2f6af
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
  [![Gem Version](https://badge.fury.io/rb/ebnf.png)](http://badge.fury.io/rb/ebnf)
6
- [![Build Status](https://secure.travis-ci.org/gkellogg/ebnf.png?branch=master)](http://travis-ci.org/gkellogg/ebnf)
7
- [![Coverage Status](https://coveralls.io/repos/gkellogg/ebnf/badge.svg)](https://coveralls.io/r/gkellogg/ebnf)
8
- [![Dependency Status](https://gemnasium.com/gkellogg/ebnf.png)](https://gemnasium.com/gkellogg/ebnf)
6
+ [![Build Status](https://secure.travis-ci.org/dryruby/ebnf.png?branch=master)](http://travis-ci.org/dryruby/ebnf)
7
+ [![Coverage Status](https://coveralls.io/repos/dryruby/ebnf/badge.svg)](https://coveralls.io/r/dryruby/ebnf)
8
+ [![Dependency Status](https://gemnasium.com/dryruby/ebnf.png)](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.bnf'))
31
+ ebnf = EBNF.parse(File.open('./etc/ebnf.ebnf'))
32
32
 
33
- Output rules and terminals as S-Expressions, Turtle or EBNF
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.to_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(start_tokens)
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/gkellogg/ebnf/master/frames
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.2
1
+ 1.1.3
@@ -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://gkellogg.github.com/ebnf> ;
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/gkellogg/ebnf/issues> ;
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> ;
@@ -117,19 +117,19 @@ module EBNF
117
117
  #
118
118
  # @param [#read, #to_s] input
119
119
  # @param [Hash{Symbol => Object}] options
120
- # @option options [Boolean, Array] :debug
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
- def initialize(input, options = {})
125
- @options = {format: :ebnf}.merge(options)
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 @options[:format]
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 #{options[:format].inspect}"
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 [Hash{Symbol => Object}] options
198
- # @option options [String] :grammarFile
199
- def to_ruby(output = STDOUT, options = {})
200
- unless output == STDOUT
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 #{options[:grammarFile]}" if options[:grammarFile]
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 #{options.fetch(:mod_name, 'Branch')}"
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 == STDOUT
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(': ')}"
@@ -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
- else
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"
@@ -60,23 +60,19 @@ module EBNF
60
60
  # @param [Integer] id
61
61
  # @param [Symbol] sym
62
62
  # @param [Array] expr
63
- # @param [Hash{Symbol => Object}] options
64
- # @option options [Symbol] :kind
65
- # @option options [String] :ebnf
66
- # @option options [Array] :first
67
- # @option options [Array] :follow
68
- # option options [Boolean] :start
69
- def initialize(sym, id, expr, options = {})
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 = options[:ebnf]
73
- @top_rule = options.fetch(:top_rule, self)
74
- @first = options[:first]
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
- # @option options [Symbol] :kind
118
- # @option options [String] :ebnf EBNF instance (used for messages)
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
- kind: options[:kind],
123
- ebnf: @ebnf,
124
- top_rule: @top_rule || self,
125
- cleanup: options[:cleanup],
126
- }.merge(options))
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.shift if expr.is_a?(Array)
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
 
@@ -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
- # @option options [#write] :out ($stdout)
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 @options[:html]
73
+ if html
78
74
  # Output as formatted HTML
79
75
  begin
80
76
  require 'haml'
81
- html = Haml::Engine.new(HAML_DESC).render(self, rules: rules) do |rule|
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 html
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.2
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: 2017-12-13 00:00:00.000000000 Z
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: '4.0'
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: '2.2'
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: '4.0'
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: '0.9'
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: '0.9'
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/gkellogg/ebnf
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.14
186
+ rubygems_version: 2.7.6
179
187
  signing_key:
180
188
  specification_version: 4
181
189
  summary: EBNF parser and parser generator.