ebnf 0.2.2 → 0.2.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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmVlMjA5ODQ5YTk5OWUxZDgwYzc2Y2RjYjEyOTU2NTAzN2U0MjQ5Yw==
4
+ NDg4MzMwZTA0Yzg3MzY5Y2UyZDMwMWI2ZWRiODNjZWZjZmU5NGRlZQ==
5
5
  data.tar.gz: !binary |-
6
- MWE3ZGJmYTYwNzdlYmQxZGEzZDdkY2U4NDc4NjhhYTI2MGYxZDhlNg==
6
+ NzA2ODg3ZTI1NzIwNjVjNmE1YWJjMDYzNTEyNjI1NGIzZWI5OTg1ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MGMyZGRlM2I5Zjc4NzQ1YTRlMDJjYmY3M2NjNDc3Y2VmOTRjYmUyMGIzMGM3
10
- ZjUzMzVkMmM2ODBmNGE3OGQ3ZDcxNjM4ODk0MmQ3YWZhYTllOTI4N2JkMmU0
11
- MDI4MjIxM2FiMDE1MjhjMzdlNmVmNWZjN2ExOWY2ZDVhMDAyMzQ=
9
+ N2FjYTRhNzI5NDFkZWI3OTNiOWFkNTNmYWY5NjUwMjA4YTM0ZmNiZTQ5NDYy
10
+ MjFjODYxODc1MzRjMTZjNGM0N2U4NDk2NTM2ZjM0MmY0ZGI3ZDE3OTg3OWFi
11
+ NjQwYTdjNzcxYTc3ZWJmYzcyMzlmOWJiZDlmZjc3YTJiOWVkODA=
12
12
  data.tar.gz: !binary |-
13
- YWQwMDk1Y2U2MzdlMTYzNGVjY2VlOGQ1ZGIyYTNmYzI4YzkwYjUzNTczMWYy
14
- YzExNTE4NDkyNjk5NzQ1N2Y1MmY5NTkwZjI3NjE4Zjk0NmViZmU0NjM2NzYx
15
- Mzk1MTMzZDQyN2Y2YWI5ODMyYjE1YTdmM2I1OThjOTQ1OTUwMDI=
13
+ ODVmZDZlMjVkMjY0ZDkwYWFiZGY4OGE3ZTRhNDQzZWRiZDlkZTQzODQ4ZWMw
14
+ MTZkZGMzNWYzZTMxNDc0MDc3YWFkNmU2NjExNWM2ZTkzOTJlZWE0MDQ1Yzdm
15
+ N2RmOTU5NGFhZTVlZDEwYzhlMjJjMDNhYmIwNDkyOTc3ZGVkNDQ=
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
@@ -135,10 +135,7 @@ module EBNF::LL1
135
135
  raise Error, "Terminal patterns not defined" unless @terminals && @terminals.length > 0
136
136
 
137
137
  @lineno = 1
138
- @scanner = Scanner.new(input) do |string|
139
- string.force_encoding(Encoding::UTF_8) if string.respond_to?(:force_encoding)
140
- string
141
- end
138
+ @scanner = Scanner.new(input)
142
139
  end
143
140
 
144
141
  ##
@@ -193,6 +193,8 @@ module EBNF::LL1
193
193
  # Show progress of parser productions
194
194
  # @option options [Boolean] :debug
195
195
  # Detailed debug output
196
+ # @option options [Boolean] :reset_on_start
197
+ # Reset the parser state if the start token set with `prod` is found in a production. This reduces the production stack depth growth, which is appropriate for some grammars.
196
198
  # @yield [context, *data]
197
199
  # Yields for to return data to parser
198
200
  # @yieldparam [:statement, :trace] context
@@ -227,6 +229,15 @@ module EBNF::LL1
227
229
  todo_stack.last[:terms] = []
228
230
  cur_prod = todo_stack.last[:prod]
229
231
 
232
+ # If cur_prod is the starting production, we can reset the stack
233
+ # to the beginning to avoid excessive growth in the production
234
+ # stack
235
+ if options[:reset_on_start] && cur_prod == prod
236
+ todo_stack = [{:prod => prod, :terms => []}]
237
+ @productions = []
238
+ @prod_data = [{}]
239
+ end
240
+
230
241
  # Get this first valid token appropriate for the stacked productions,
231
242
  # skipping invalid tokens until either a valid token is found (from @first),
232
243
  # or a token appearing in @follow appears.
@@ -239,11 +250,11 @@ module EBNF::LL1
239
250
  "prod #{cur_prod.inspect}, " +
240
251
  "depth #{depth}"
241
252
  end
242
-
253
+
243
254
  # Got an opened production
244
255
  onStart(cur_prod)
245
256
  break if token.nil?
246
-
257
+
247
258
  if prod_branch = @branch[cur_prod]
248
259
  @recovering = false
249
260
  sequence = prod_branch[token.representation]
@@ -304,7 +315,6 @@ module EBNF::LL1
304
315
  (@recovering && @follow.fetch(terms.last, []).none? {|t| (token || :_eps) == t}))
305
316
  debug("parse(pop)", :level => 2) {"todo #{todo_stack.last.inspect}, depth #{depth}"}
306
317
  if terms.empty?
307
- prod = todo_stack.last[:prod]
308
318
  todo_stack.pop
309
319
  onFinish
310
320
  else
@@ -483,21 +493,6 @@ module EBNF::LL1
483
493
  token
484
494
  end
485
495
 
486
- ##
487
- # @param [String] node Relevant location associated with message
488
- # @param [String] message Error string
489
- # @param [Hash] options
490
- # @option options [URI, #to_s] :production
491
- # @option options [Token] :token
492
- def error(node, message, options = {})
493
- message += ", found #{options[:token].representation.inspect}" if options[:token]
494
- message += " at line #{@lineno}" if @lineno
495
- message += ", production = #{options[:production].inspect}" if options[:production]
496
- @error_log << message unless @recovering
497
- @recovering = true
498
- debug(node, message, options.merge(:level => 0))
499
- end
500
-
501
496
  ##
502
497
  # Return the next token, entering error recovery if the token is invalid
503
498
  #
@@ -521,6 +516,21 @@ module EBNF::LL1
521
516
  token
522
517
  end
523
518
 
519
+ ##
520
+ # @param [String] node Relevant location associated with message
521
+ # @param [String] message Error string
522
+ # @param [Hash] options
523
+ # @option options [URI, #to_s] :production
524
+ # @option options [Token] :token
525
+ def error(node, message, options = {})
526
+ message += ", found #{options[:token].representation.inspect}" if options[:token]
527
+ message += " at line #{@lineno}" if @lineno
528
+ message += ", production = #{options[:production].inspect}" if options[:production]
529
+ @error_log << message unless @recovering
530
+ @recovering = true
531
+ debug(node, message, options.merge(:level => 0))
532
+ end
533
+
524
534
  ##
525
535
  # Progress output when parsing
526
536
  # param [String] node Relevant location associated with message
@@ -535,35 +545,57 @@ module EBNF::LL1
535
545
  message = args.join(",")
536
546
  depth = options[:depth] || self.depth
537
547
  message += yield.to_s if block_given?
538
- if @options[:debug]
539
- return debug(node, message, {:level => 0}.merge(options))
540
- else
541
- $stderr.puts("[#{@lineno}]#{' ' * depth}#{node}: #{message}")
542
- end
548
+ debug(node, message, options.merge(:level => 1))
543
549
  end
544
550
 
545
551
  ##
546
- # Progress output when debugging
547
- # @param [String] node Relevant location associated with message
548
- # @param [String] message ("")
549
- # @param [Hash] options
550
- # @option options [Integer] :depth
551
- # Recursion depth for indenting output
552
+ # Progress output when debugging.
553
+ # Captures output to `@options[:debug]` if it is an array.
554
+ # Otherwise, if `@options[:debug]` is set, or
555
+ # `@options[:progress]` is set and `:level` <= 1, or
556
+ # `@options[:validate]` is set and `:level` == 0 output
557
+ # to standard error.
558
+ #
559
+ # @overload debug(node, message)
560
+ # @param [String] node Relevant location associated with message
561
+ # @param [String] message ("")
562
+ # @param [Hash] options
563
+ # @option options [Integer] :depth
564
+ # Recursion depth for indenting output
565
+ # @option options [Integer] :level
566
+ # Debug level, `0` for errors, `1` for progress, anything else
567
+ # for debug output.
568
+ #
569
+ # @overload debug(message)
570
+ # @param [String] node Relevant location associated with message
571
+ # @param [Hash] options
572
+ # @option options [Integer] :depth
573
+ # Recursion depth for indenting output
574
+ # @option options [Integer] :level
575
+ # Debug level, `0` for errors, `1` for progress, anything else
576
+ # for debug output.
552
577
  # @yieldreturn [String] added to message
553
- def debug(node, message = "", options = {})
554
- return unless @options[:debug]
555
- debug_level = options.fetch(:level, 1)
556
- return unless debug_level <= DEBUG_LEVEL
578
+ def debug(*args)
579
+ options = args.last.is_a?(Hash) ? args.pop : {}
580
+ debug_level = options.fetch(:level, 2)
581
+ return unless @options[:debug] && debug_level <= DEBUG_LEVEL ||
582
+ @options[:progress] && debug_level <= 1 ||
583
+ @options[:validate] && debug_level == 0
557
584
  depth = options[:depth] || self.depth
558
- message += yield if block_given?
559
- str = "[#{@lineno}](#{debug_level})#{' ' * depth}#{node}: #{message}"
560
- case @options[:debug]
561
- when Array
562
- @options[:debug] << str
563
- when TrueClass
564
- $stderr.puts str
565
- when :yield
585
+ d_str = depth > 20 ? ' ' * 20 + '+' : ' ' * depth
586
+ args << yield if block_given?
587
+ message = "#{args.join(': ')}"
588
+ str = "[#{@lineno}](#{debug_level})#{d_str}#{message}"
589
+ @options[:debug] << str if @options[:debug].is_a?(Array)
590
+ case
591
+ when @options[:yield]
566
592
  @parse_callback.call(:trace, node, message, options)
593
+ when @options[:debug] == true
594
+ $stderr.puts str
595
+ when @options[:progress] && debug_level <= 1
596
+ $stderr.puts str
597
+ when @options[:validate] && debug_level == 0
598
+ $stderr.puts str
567
599
  end
568
600
  end
569
601
 
@@ -24,12 +24,8 @@ module EBNF::LL1
24
24
  # @param [Hash{Symbol => Object}] options
25
25
  # @option options[Integer] :high_water (HIGH_WATER)
26
26
  # @option options[Integer] :low_water (LOW_WATER)
27
- # @yield [string]
28
- # @yieldparam [String] string data read from input file
29
- # @yieldreturn [String] replacement read data, useful for decoding escapes.
30
27
  # @return [Scanner]
31
- def initialize(input, options = {}, &block)
32
- @block = block
28
+ def initialize(input, options = {})
33
29
  @options = options.merge(:high_water => HIGH_WATER, :low_water => LOW_WATER)
34
30
 
35
31
  if input.respond_to?(:read)
@@ -48,7 +44,7 @@ module EBNF::LL1
48
44
  # @return [String]
49
45
  def rest
50
46
  feed_me
51
- super
47
+ encode_utf8 super
52
48
  end
53
49
 
54
50
  ##
@@ -82,7 +78,7 @@ module EBNF::LL1
82
78
  # @return [String]
83
79
  def scan(pattern)
84
80
  feed_me
85
- super
81
+ encode_utf8 super
86
82
  end
87
83
 
88
84
  private
@@ -91,11 +87,15 @@ module EBNF::LL1
91
87
  if rest_size < @options[:low_water] && @input && !@input.eof?
92
88
  # Read up to high-water mark ensuring we're at an end of line
93
89
  diff = @options[:high_water] - rest_size
94
- string = @input.read(diff)
95
- string << @input.gets unless @input.eof?
96
- string = @block.call(string) if @block
90
+ string = encode_utf8(@input.read(diff))
91
+ string << encode_utf8(@input.gets) unless @input.eof?
97
92
  self << string if string
98
93
  end
99
94
  end
95
+
96
+ # Perform UTF-8 encoding of input
97
+ def encode_utf8(string)
98
+ string.respond_to?(:force_encoding) ? string.force_encoding(Encoding::UTF_8) : string
99
+ end
100
100
  end
101
101
  end
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: 0.2.2
4
+ version: 0.2.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: 2013-03-22 00:00:00.000000000 Z
11
+ date: 2013-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sxp