ebnf 1.1.2 → 1.1.3

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
- 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.