ebnf 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/VERSION +1 -1
- data/lib/ebnf/ll1/lexer.rb +1 -4
- data/lib/ebnf/ll1/parser.rb +73 -41
- data/lib/ebnf/ll1/scanner.rb +10 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDg4MzMwZTA0Yzg3MzY5Y2UyZDMwMWI2ZWRiODNjZWZjZmU5NGRlZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzA2ODg3ZTI1NzIwNjVjNmE1YWJjMDYzNTEyNjI1NGIzZWI5OTg1ZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
N2FjYTRhNzI5NDFkZWI3OTNiOWFkNTNmYWY5NjUwMjA4YTM0ZmNiZTQ5NDYy
|
10
|
+
MjFjODYxODc1MzRjMTZjNGM0N2U4NDk2NTM2ZjM0MmY0ZGI3ZDE3OTg3OWFi
|
11
|
+
NjQwYTdjNzcxYTc3ZWJmYzcyMzlmOWJiZDlmZjc3YTJiOWVkODA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODVmZDZlMjVkMjY0ZDkwYWFiZGY4OGE3ZTRhNDQzZWRiZDlkZTQzODQ4ZWMw
|
14
|
+
MTZkZGMzNWYzZTMxNDc0MDc3YWFkNmU2NjExNWM2ZTkzOTJlZWE0MDQ1Yzdm
|
15
|
+
N2RmOTU5NGFhZTVlZDEwYzhlMjJjMDNhYmIwNDkyOTc3ZGVkNDQ=
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
data/lib/ebnf/ll1/lexer.rb
CHANGED
@@ -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)
|
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
|
##
|
data/lib/ebnf/ll1/parser.rb
CHANGED
@@ -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
|
-
|
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
|
-
#
|
548
|
-
#
|
549
|
-
#
|
550
|
-
#
|
551
|
-
#
|
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(
|
554
|
-
|
555
|
-
debug_level = options.fetch(:level,
|
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
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
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
|
|
data/lib/ebnf/ll1/scanner.rb
CHANGED
@@ -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 = {}
|
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.
|
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-
|
11
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sxp
|