ebnf 1.1.3 → 1.2.0

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
2
  SHA256:
3
- metadata.gz: 658c0da6f1ba2b472e94badcedabc0dabfab7b3cbce02e58fe6bfb286416e247
4
- data.tar.gz: 9cc79c8f8c0ce5d4e24eb8e1dfbac9d52b1bfe26951c97fd435a547fdb80cf84
3
+ metadata.gz: aae4c0b2a8f6d03654bc5436b36c90e577669c41ea4df25d881be3aef86e5ace
4
+ data.tar.gz: 7f1b7fe448ae87f3755e6da4fc0faf47dbb3d3b573a3e4a8be9b3066f0fac6fa
5
5
  SHA512:
6
- metadata.gz: b0cce6804a7d9afa85fe0559148110e2e3443242ff44fac31f77c5939a22158b5bd1fe7bdb5474a98e2221b474c0010bf1e93612e9bd01320212406557892469
7
- data.tar.gz: 41f3a9b7b7bbaa650afa269f54a56724b029e6b14ac31a62632b8d09ce62578624221b15836f4fe52a549408b79d7bd8a20b841d9d6141bb18546efe211b0c59
6
+ metadata.gz: 6d0f441731842af8ac38f98352b96a47cf6810bfe81ce620f8ef57af87ce6d65c679d88903c35dbce99617b24bdea8fbb70a23d4873d941ae151275a11561627
7
+ data.tar.gz: f19f527e041a8f1c48da918497660466c5df71a02077e2183472b157a8611cbf87903fe2b6858e889c119211a7fedb279ad4889d811bec5d6132dd9287d74314
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.3
1
+ 1.2.0
data/bin/ebnf CHANGED
@@ -75,19 +75,19 @@ end
75
75
 
76
76
  input = File.open(ARGV[0]) if ARGV[0]
77
77
 
78
- ebnf = EBNF.parse(input || STDIN, options)
78
+ ebnf = EBNF.parse(input || STDIN, **options)
79
79
  ebnf.make_bnf if options[:bnf] || options[:ll1]
80
80
  if options[:ll1]
81
81
  ebnf.first_follow(*options[:ll1])
82
82
  ebnf.build_tables
83
-
83
+ end
84
84
 
85
85
  res = case options[:output_format]
86
86
  when :ebnf then ebnf.to_s
87
87
  when :html then ebnf.to_html
88
88
  when :sxp then ebnf.to_sxp
89
89
  when :ttl then ebnf.to_ttl(options[:prefix], options[:namespace])
90
- when :rb then ebnf.to_ruby(out, options.merge(grammarFile: ARGV[0]))
90
+ when :rb then ebnf.to_ruby(out, grammarFile: ARGV[0], **options)
91
91
  else ebnf.ast.inspect
92
92
  end
93
93
 
@@ -17,7 +17,7 @@ module EBNF
17
17
  # @param [Hash{Symbol => Object}] options
18
18
  # @return [EBNF::Base]
19
19
  # @raise [Exception] on invalid input
20
- def self.parse(input, options = {})
21
- query = ::EBNF::Base.new(input, options)
20
+ def self.parse(input, **options)
21
+ query = ::EBNF::Base.new(input, **options)
22
22
  end
23
23
  end
@@ -168,6 +168,10 @@ module EBNF
168
168
  progress("first_follow") {"(#{ittr}) firsts #{firsts}, follows #{follows}"}
169
169
  ittr += 1
170
170
  end while (firsts + follows) > 0
171
+
172
+ debug("Fi.2-post: non-terminals without first") do
173
+ ast.reject(&:terminal?).reject(&:first).map(&:sym)
174
+ end if ast.reject(&:terminal?).any? {|r| r.first.nil?}
171
175
  end
172
176
  end
173
177
 
@@ -287,16 +291,16 @@ module EBNF
287
291
 
288
292
  if rule.expr.first == :matches
289
293
  debug("prod") {"Rule is regexp: #{rule}"}
290
-
291
- error("No record of what token #{lhs} can start with") unless rule.first
292
294
  return
293
295
  end
294
296
 
297
+ error("No record of what token #{lhs.inspect} can start with") unless rule.first
298
+
295
299
  if rule.alt?
296
300
  # A First/Follow conflict appears when _eps is in the first
297
301
  # of one rule and there is a token in the first and
298
302
  # follow of the same rule
299
- if rule.first.include?(:_eps) && !(overlap = ((rule.first & (rule.follow || [])) - [:eps])).empty?
303
+ if Array(rule.first).include?(:_eps) && !(overlap = ((Array(rule.first) & (rule.follow || [])) - [:eps])).empty?
300
304
  error("First/Follow Conflict: #{overlap.first.inspect} is both first and follow of #{rule.sym}")
301
305
  end
302
306
 
@@ -98,8 +98,8 @@ module EBNF::LL1
98
98
  # @yieldparam [Lexer] lexer
99
99
  # @return [Lexer]
100
100
  # @raise [Lexer::Error] on invalid input
101
- def self.tokenize(input, terminals, options = {}, &block)
102
- lexer = self.new(input, terminals, options)
101
+ def self.tokenize(input, terminals, **options, &block)
102
+ lexer = self.new(input, terminals, **options)
103
103
  block_given? ? block.call(lexer) : lexer
104
104
  end
105
105
 
@@ -115,17 +115,24 @@ module EBNF::LL1
115
115
  # Whitespace between tokens, including comments
116
116
  # @option options[Integer] :high_water passed to scanner
117
117
  # @option options[Integer] :low_water passed to scanner
118
- def initialize(input = nil, terminals = nil, options = {})
118
+ def initialize(input = nil, terminals = nil, **options)
119
119
  @options = options.dup
120
120
  @whitespace = @options[:whitespace]
121
121
  @terminals = terminals.map do |term|
122
- term.is_a?(Array) ? Terminal.new(*term) : term
122
+ if term.is_a?(Array) && term.length ==3
123
+ # Last element is options
124
+ Terminal.new(term[0], term[1], **term[2])
125
+ elsif term.is_a?(Array)
126
+ Terminal.new(*term)
127
+ else
128
+ term
129
+ end
123
130
  end
124
131
 
125
132
  raise Error, "Terminal patterns not defined" unless @terminals && @terminals.length > 0
126
133
 
127
134
  @lineno = 1
128
- @scanner = Scanner.new(input, options)
135
+ @scanner = Scanner.new(input, **options)
129
136
  end
130
137
 
131
138
  ##
@@ -300,7 +307,7 @@ module EBNF::LL1
300
307
  # Cause strings and codepoints to be unescaped.
301
308
  # @option options [Regexp] :partial_regexp
302
309
  # A regular expression matching the beginning of this terminal; useful for terminals that match things longer than the scanner low water mark.
303
- def initialize(type, regexp, options = {})
310
+ def initialize(type, regexp, **options)
304
311
  @type, @regexp, @options = type, regexp, options
305
312
  @partial_regexp = options[:partial_regexp]
306
313
  @map = options.fetch(:map, {})
@@ -353,8 +360,8 @@ module EBNF::LL1
353
360
  # Scanner instance with access to matched groups
354
361
  # @param [Hash{Symbol => Object}] options
355
362
  # @return [Token]
356
- def token(type, value, options = {})
357
- Token.new(type, value, options.merge(lineno: lineno))
363
+ def token(type, value, **options)
364
+ Token.new(type, value, lineno: lineno, **options)
358
365
  end
359
366
 
360
367
  ##
@@ -398,7 +405,7 @@ module EBNF::LL1
398
405
  # @param [String] value
399
406
  # @param [Hash{Symbol => Object}] options
400
407
  # @option options [Integer] :lineno (nil)
401
- def initialize(type, value, options = {})
408
+ def initialize(type, value, **options)
402
409
  @type = type.to_s.to_sym if type
403
410
  @value = value.to_s
404
411
  @options = options.dup
@@ -514,7 +521,7 @@ module EBNF::LL1
514
521
  # @option options [String] :input (nil)
515
522
  # @option options [String] :token (nil)
516
523
  # @option options [Integer] :lineno (nil)
517
- def initialize(message, options = {})
524
+ def initialize(message, **options)
518
525
  @input = options[:input]
519
526
  @token = options[:token]
520
527
  @lineno = options[:lineno]
@@ -51,10 +51,10 @@ module EBNF::LL1
51
51
  # @yieldparam [Proc] block
52
52
  # Block passed to initialization for yielding to calling parser.
53
53
  # Should conform to the yield specs for #initialize
54
- def terminal(term, regexp, options = {}, &block)
54
+ def terminal(term, regexp, **options, &block)
55
55
  @patterns ||= []
56
56
  # Passed in order to define evaulation sequence
57
- @patterns << EBNF::LL1::Lexer::Terminal.new(term, regexp, options)
57
+ @patterns << EBNF::LL1::Lexer::Terminal.new(term, regexp, **options)
58
58
  @terminal_handlers ||= {}
59
59
  @terminal_handlers[term] = block if block_given?
60
60
  end
@@ -122,7 +122,14 @@ module EBNF::LL1
122
122
 
123
123
  def method_missing(method, *args, &block)
124
124
  if @delegate ||= nil
125
- @delegate.send method, *args, &block
125
+ # special handling when last arg is **options
126
+ params = @delegate.method(method).parameters
127
+ if params.any? {|t, _| t == :keyrest} && args.last.is_a?(Hash)
128
+ opts = args.pop
129
+ @delegate.send(method, *args, **opts, &block)
130
+ else
131
+ @delegate.send(method, *args, &block)
132
+ end
126
133
  else
127
134
  super
128
135
  end
@@ -219,7 +226,7 @@ module EBNF::LL1
219
226
  # or errors raised during processing callbacks. Internal
220
227
  # errors are raised using {Error}.
221
228
  # @see http://cs.adelaide.edu.au/~charles/lt/Lectures/07-ErrorRecovery.pdf
222
- def parse(input = nil, start = nil, options = {}, &block)
229
+ def parse(input = nil, start = nil, **options, &block)
223
230
  @options = options.dup
224
231
  @options[:debug] ||= case
225
232
  when @options[:progress] then 2
@@ -229,7 +236,7 @@ module EBNF::LL1
229
236
  @first = options[:first] ||= {}
230
237
  @follow = options[:follow] ||= {}
231
238
  @cleanup = options[:cleanup] ||= {}
232
- @lexer = input.is_a?(Lexer) ? input : Lexer.new(input, self.class.patterns, @options)
239
+ @lexer = input.is_a?(Lexer) ? input : Lexer.new(input, self.class.patterns, **@options)
233
240
  @productions = []
234
241
  @parse_callback = block
235
242
  @recovering = false
@@ -467,7 +474,7 @@ module EBNF::LL1
467
474
  # @option options [URI, #to_s] :production
468
475
  # @option options [Token] :token
469
476
  # @see {#debug}
470
- def error(node, message, options = {})
477
+ def error(node, message, **options)
471
478
  lineno = @lineno || (options[:token].lineno if options[:token].respond_to?(:lineno))
472
479
  m = "ERROR "
473
480
  m += "[line: #{lineno}] " if lineno
@@ -476,7 +483,7 @@ module EBNF::LL1
476
483
  m += ", production = #{options[:production].inspect}" if options[:production]
477
484
  @error_log << m unless @recovering
478
485
  @recovering = true
479
- debug(node, m, options.merge(level: 0))
486
+ debug(node, m, level: 0, **options)
480
487
  if options[:raise] || @options[:validate]
481
488
  raise Error.new(m, lineno: lineno, token: options[:token], production: options[:production])
482
489
  end
@@ -491,20 +498,20 @@ module EBNF::LL1
491
498
  # @option options [URI, #to_s] :production
492
499
  # @option options [Token] :token
493
500
  # @see {#debug}
494
- def warn(node, message, options = {})
501
+ def warn(node, message, **options)
495
502
  m = "WARNING "
496
503
  m += "[line: #{@lineno}] " if @lineno
497
504
  m += message
498
505
  m += " (found #{options[:token].inspect})" if options[:token]
499
506
  m += ", production = #{options[:production].inspect}" if options[:production]
500
507
  @error_log << m unless @recovering
501
- debug(node, m, options.merge(level: 1))
508
+ debug(node, m, level: 1, **options)
502
509
  end
503
510
 
504
511
  ##
505
512
  # Progress output when parsing. Passed as level `2` debug messages.
506
513
  #
507
- # @overload progress(node, message, options)
514
+ # @overload progress(node, message, **options)
508
515
  # @param [String] node Relevant location associated with message
509
516
  # @param [String] message ("")
510
517
  # @param [Hash] options
@@ -526,7 +533,7 @@ module EBNF::LL1
526
533
  # if `@options[:debug]` is an Integer, the call is aborted if the
527
534
  # `:level` option is less than than `:level`.
528
535
  #
529
- # @overload debug(node, message, options)
536
+ # @overload debug(node, message, **options)
530
537
  # @param [Array<String>] args Relevant location associated with message
531
538
  # @param [Hash] options
532
539
  # @option options [Integer] :depth
@@ -751,7 +758,7 @@ module EBNF::LL1
751
758
  # @option options [Symbol] :production (nil)
752
759
  # @option options [String] :token (nil)
753
760
  # @option options [Integer] :lineno (nil)
754
- def initialize(message, options = {})
761
+ def initialize(message, **options)
755
762
  @production = options[:production]
756
763
  @token = options[:token]
757
764
  @lineno = options[:lineno] || (@token.lineno if @token.respond_to?(:lineno))
@@ -20,11 +20,11 @@ module EBNF::LL1
20
20
  ##
21
21
  # If we don't have an IO input, simply use StringScanner directly
22
22
  # @private
23
- def self.new(input, options = {})
23
+ def self.new(input, **options)
24
24
  input ||= ""
25
25
  if input.respond_to?(:read)
26
26
  scanner = self.allocate
27
- scanner.send(:initialize, input, options)
27
+ scanner.send(:initialize, input, **options)
28
28
  else
29
29
  if input.encoding != Encoding::UTF_8
30
30
  input = input.dup if input.frozen?
@@ -42,7 +42,7 @@ module EBNF::LL1
42
42
  # @option options[Integer] :high_water (HIGH_WATER)
43
43
  # @option options[Integer] :low_water (LOW_WATER)
44
44
  # @return [Scanner]
45
- def initialize(input, options = {})
45
+ def initialize(input, **options)
46
46
  @options = options.merge(high_water: HIGH_WATER, low_water: LOW_WATER)
47
47
 
48
48
  @input = input
@@ -137,6 +137,7 @@ module EBNF
137
137
  # Return SXP representation of this rule
138
138
  # @return [String]
139
139
  def to_sxp
140
+ require 'sxp' unless defined?(SXP)
140
141
  for_sxp.to_sxp
141
142
  end
142
143
 
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.3
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-09 00:00:00.000000000 Z
11
+ date: 2019-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sxp
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rdf
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.0'
33
+ version: '3.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '3.0'
40
+ version: '3.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rdf-spec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '3.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '3.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: haml
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,56 +72,56 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '3.7'
75
+ version: '3.9'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '3.7'
82
+ version: '3.9'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec-its
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.2'
89
+ version: '1.3'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '1.2'
96
+ version: '1.3'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: yard
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.9.12
103
+ version: '0.9'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.9.12
110
+ version: '0.9'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rake
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '12.0'
117
+ version: '13.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '12.0'
124
+ version: '13.0'
125
125
  description: EBNF is a Ruby parser for W3C EBNF and a parser generator for compliant
126
126
  LL(1) grammars.
127
127
  email: public-rdf-ruby@w3.org
@@ -175,15 +175,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
175
175
  requirements:
176
176
  - - ">="
177
177
  - !ruby/object:Gem::Version
178
- version: 2.2.2
178
+ version: '2.4'
179
179
  required_rubygems_version: !ruby/object:Gem::Requirement
180
180
  requirements:
181
181
  - - ">="
182
182
  - !ruby/object:Gem::Version
183
183
  version: '0'
184
184
  requirements: []
185
- rubyforge_project:
186
- rubygems_version: 2.7.6
185
+ rubygems_version: 3.0.6
187
186
  signing_key:
188
187
  specification_version: 4
189
188
  summary: EBNF parser and parser generator.