ebnf 1.1.3 → 1.2.0

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