kaiseki 0.0.3 → 1.0.1
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.
- data/README +0 -0
- data/lib/action.rb +8 -0
- data/lib/grammar.rb +88 -0
- data/lib/kaiseki.rb +54 -48
- data/lib/mod_file.rb +5 -0
- data/lib/mod_kernel.rb +11 -0
- data/lib/mod_object.rb +11 -0
- data/lib/mod_proc.rb +7 -0
- data/lib/mod_regexp.rb +7 -0
- data/lib/mod_string.rb +11 -0
- data/lib/mod_symbol.rb +27 -0
- data/lib/node.rb +78 -0
- data/lib/parse_error.rb +16 -0
- data/lib/parse_result.rb +21 -0
- data/lib/parseable.rb +67 -0
- data/lib/{grammar/parslet.rb → parser_basic.rb} +7 -12
- data/lib/parser_choice.rb +24 -0
- data/lib/parser_eof.rb +27 -0
- data/lib/parser_multi.rb +27 -0
- data/lib/parser_package.rb +11 -0
- data/lib/parser_regexp.rb +19 -0
- data/lib/parser_repeat.rb +68 -0
- data/lib/parser_sequence.rb +41 -0
- data/lib/parser_string.rb +18 -0
- data/lib/parser_symbol.rb +16 -0
- data/lib/predicate_and.rb +19 -0
- data/lib/predicate_not.rb +19 -0
- data/lib/predicate_skip.rb +19 -0
- data/lib/result_cast.rb +33 -0
- data/lib/result_filter.rb +36 -0
- data/lib/result_merge.rb +20 -0
- data/lib/result_override.rb +20 -0
- data/lib/rule.rb +88 -0
- data/lib/stream.rb +98 -0
- data/lib/var_get.rb +40 -0
- data/lib/var_insert.rb +19 -0
- data/lib/var_set.rb +24 -0
- metadata +45 -40
- data/lib/additions/proc.rb +0 -7
- data/lib/additions/regexp.rb +0 -7
- data/lib/additions/string.rb +0 -7
- data/lib/additions/symbol.rb +0 -19
- data/lib/grammar/and_predicate.rb +0 -22
- data/lib/grammar/array_result.rb +0 -16
- data/lib/grammar/eof_parslet.rb +0 -32
- data/lib/grammar/grammar.rb +0 -113
- data/lib/grammar/grammar_node.rb +0 -31
- data/lib/grammar/location_tracking.rb +0 -57
- data/lib/grammar/log_node.rb +0 -21
- data/lib/grammar/node.rb +0 -59
- data/lib/grammar/not_predicate.rb +0 -22
- data/lib/grammar/parse_error.rb +0 -21
- data/lib/grammar/parse_logger.rb +0 -27
- data/lib/grammar/parse_result.rb +0 -33
- data/lib/grammar/parslet_choice.rb +0 -25
- data/lib/grammar/parslet_combination.rb +0 -35
- data/lib/grammar/parslet_combining.rb +0 -57
- data/lib/grammar/parslet_logging.rb +0 -22
- data/lib/grammar/parslet_merger.rb +0 -50
- data/lib/grammar/parslet_omission.rb +0 -20
- data/lib/grammar/parslet_repetition.rb +0 -65
- data/lib/grammar/parslet_sequence.rb +0 -45
- data/lib/grammar/predicate.rb +0 -30
- data/lib/grammar/proc_parslet.rb +0 -18
- data/lib/grammar/regexp_parslet.rb +0 -25
- data/lib/grammar/stream.rb +0 -90
- data/lib/grammar/string_parslet.rb +0 -29
- data/lib/grammar/string_result.rb +0 -16
- data/lib/grammar/symbol_parslet.rb +0 -22
@@ -1,57 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
module ParsletCombining
|
3
|
-
def sequence other
|
4
|
-
ParsletSequence.new self.to_parseable, other.to_parseable
|
5
|
-
end
|
6
|
-
|
7
|
-
alias :& :sequence
|
8
|
-
|
9
|
-
def merge other
|
10
|
-
ParsletMerger.new self.to_parseable, other.to_parseable
|
11
|
-
end
|
12
|
-
|
13
|
-
alias :>> :merge
|
14
|
-
|
15
|
-
def choose other
|
16
|
-
ParsletChoice.new self.to_parseable, other.to_parseable
|
17
|
-
end
|
18
|
-
|
19
|
-
alias :| :choose
|
20
|
-
|
21
|
-
def repeat min, max = nil
|
22
|
-
ParsletRepetition.new self.to_parseable, min, max
|
23
|
-
end
|
24
|
-
|
25
|
-
def optional
|
26
|
-
repeat 0, 1
|
27
|
-
end
|
28
|
-
|
29
|
-
alias :zero_or_one :optional
|
30
|
-
|
31
|
-
def zero_or_more
|
32
|
-
repeat 0
|
33
|
-
end
|
34
|
-
|
35
|
-
def one_or_more
|
36
|
-
repeat 1
|
37
|
-
end
|
38
|
-
|
39
|
-
def and_predicate
|
40
|
-
AndPredicate.new self.to_parseable
|
41
|
-
end
|
42
|
-
|
43
|
-
alias :and? :and_predicate
|
44
|
-
|
45
|
-
def not_predicate
|
46
|
-
NotPredicate.new self.to_parseable
|
47
|
-
end
|
48
|
-
|
49
|
-
alias :not! :not_predicate
|
50
|
-
|
51
|
-
def omission
|
52
|
-
ParsletOmission.new self.to_parseable
|
53
|
-
end
|
54
|
-
|
55
|
-
alias :skip :omission
|
56
|
-
end
|
57
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
module ParsletLogging
|
3
|
-
def log parse_logger = nil, &block
|
4
|
-
if parse_logger
|
5
|
-
node = LogNode.new self
|
6
|
-
parse_logger.root ? parse_logger.add(node) : parse_logger.root = node
|
7
|
-
parse_logger.push node
|
8
|
-
begin
|
9
|
-
node.result = block.call
|
10
|
-
parse_logger.pop
|
11
|
-
node.result
|
12
|
-
rescue ParseError => e
|
13
|
-
node.result = e
|
14
|
-
parse_logger.pop
|
15
|
-
raise e
|
16
|
-
end
|
17
|
-
else
|
18
|
-
block.call
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class ParsletMerger < ParsletCombination
|
3
|
-
def initialize *components
|
4
|
-
super *components
|
5
|
-
@delimiter = '&'
|
6
|
-
end
|
7
|
-
|
8
|
-
alias :>> :append
|
9
|
-
|
10
|
-
def parse stream, options = {}
|
11
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
12
|
-
parsed = ArrayResult.new
|
13
|
-
pos = stream.pos
|
14
|
-
@components.each do |parseable|
|
15
|
-
catch :PredicateSuccess do
|
16
|
-
begin
|
17
|
-
result = parseable.parse stream, options
|
18
|
-
if result.respond_to? :each
|
19
|
-
result.each {|n| parsed << n }
|
20
|
-
else
|
21
|
-
parsed << result
|
22
|
-
end
|
23
|
-
rescue ParseError => e
|
24
|
-
if options[:skipping]
|
25
|
-
begin
|
26
|
-
options[:skipping].parse stream, options.merge(:skipping => nil, :logger => nil)
|
27
|
-
redo
|
28
|
-
rescue ParseError
|
29
|
-
stream.rewind pos
|
30
|
-
raise e
|
31
|
-
end
|
32
|
-
else
|
33
|
-
stream.rewind pos
|
34
|
-
raise e
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
if options[:simplify]
|
40
|
-
if parsed.length == 1
|
41
|
-
parsed.first
|
42
|
-
else
|
43
|
-
parsed
|
44
|
-
end
|
45
|
-
else
|
46
|
-
parsed
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class ParsletOmission < Predicate
|
3
|
-
def initialize parseable
|
4
|
-
super parseable
|
5
|
-
@prefix = 'skip'
|
6
|
-
end
|
7
|
-
|
8
|
-
def parse stream, options = {}
|
9
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
10
|
-
pos = stream.pos
|
11
|
-
begin
|
12
|
-
@parseable.parse stream, options
|
13
|
-
rescue ParseError => e
|
14
|
-
stream.rewind pos
|
15
|
-
raise e
|
16
|
-
end
|
17
|
-
throw :PredicateSuccess
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class ParsletRepetition
|
3
|
-
include ParsletCombining
|
4
|
-
|
5
|
-
attr_reader :parseable, :min, :max
|
6
|
-
|
7
|
-
def initialize parseable, min, max = nil
|
8
|
-
@parseable = parseable
|
9
|
-
@min = min
|
10
|
-
@max = max
|
11
|
-
end
|
12
|
-
|
13
|
-
def parse stream, options = {}
|
14
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
15
|
-
parsed = ArrayResult.new
|
16
|
-
pos = stream.pos
|
17
|
-
while @max.nil? or parsed.length < @max
|
18
|
-
begin
|
19
|
-
parsed << @parseable.parse(stream, options)
|
20
|
-
rescue ParseError
|
21
|
-
if options[:skipping]
|
22
|
-
begin
|
23
|
-
options[:skipping].parse stream, options.merge(:skipping => nil, :logger => nil)
|
24
|
-
redo
|
25
|
-
rescue ParseError
|
26
|
-
break
|
27
|
-
end
|
28
|
-
else
|
29
|
-
break
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
if parsed.length < @min
|
35
|
-
stream.rewind pos
|
36
|
-
raise ParseError.new "required #{@min} match#{'es' unless @min == 1} but obtained #{parsed.length} (expected `#{@parseable}')",
|
37
|
-
options.merge(:line_end => stream.line, :column_end => stream.column)
|
38
|
-
else
|
39
|
-
if options[:simplify]
|
40
|
-
if @min == 0 and @max == 1
|
41
|
-
parsed.length == 0 ? nil : parsed.first
|
42
|
-
else
|
43
|
-
parsed
|
44
|
-
end
|
45
|
-
else
|
46
|
-
parsed
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_s
|
52
|
-
"repeat(#{@min}, #{@max}): #{@parseable}"
|
53
|
-
end
|
54
|
-
|
55
|
-
def to_parseable
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
|
-
def eql? other
|
60
|
-
other.is_a?(ParsletRepetition) and other.parseable == @parseable and other.min == @min and other.max == @max
|
61
|
-
end
|
62
|
-
|
63
|
-
alias :== :eql?
|
64
|
-
end
|
65
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class ParsletSequence < ParsletCombination
|
3
|
-
def initialize *components
|
4
|
-
super *components
|
5
|
-
@delimiter = '&'
|
6
|
-
end
|
7
|
-
|
8
|
-
alias :& :append
|
9
|
-
|
10
|
-
def parse stream, options = {}
|
11
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
12
|
-
parsed = ArrayResult.new
|
13
|
-
pos = stream.pos
|
14
|
-
@components.each do |parseable|
|
15
|
-
catch :PredicateSuccess do
|
16
|
-
begin
|
17
|
-
parsed << parseable.parse(stream, options)
|
18
|
-
rescue ParseError => e
|
19
|
-
if options[:skipping]
|
20
|
-
begin
|
21
|
-
options[:skipping].parse stream, options.merge(:skipping => nil, :logger => nil)
|
22
|
-
redo
|
23
|
-
rescue ParseError
|
24
|
-
stream.rewind pos
|
25
|
-
raise e
|
26
|
-
end
|
27
|
-
else
|
28
|
-
stream.rewind pos
|
29
|
-
raise e
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
if options[:simplify]
|
35
|
-
if parsed.length == 1
|
36
|
-
parsed.first
|
37
|
-
else
|
38
|
-
parsed
|
39
|
-
end
|
40
|
-
else
|
41
|
-
parsed
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/lib/grammar/predicate.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class Predicate
|
3
|
-
include ParsletCombining
|
4
|
-
|
5
|
-
attr_reader :parseable
|
6
|
-
|
7
|
-
def initialize parseable
|
8
|
-
@parseable = parseable
|
9
|
-
@prefix = 'predicate'
|
10
|
-
end
|
11
|
-
|
12
|
-
def parse *args
|
13
|
-
raise NotImplementedError
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_s
|
17
|
-
"<#{@prefix}:#{@parseable}>"
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_parseable
|
21
|
-
self
|
22
|
-
end
|
23
|
-
|
24
|
-
def eql? other
|
25
|
-
other.is_a?(self.class) and other.parseable == @parseable
|
26
|
-
end
|
27
|
-
|
28
|
-
alias :== :eql?
|
29
|
-
end
|
30
|
-
end
|
data/lib/grammar/proc_parslet.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class ProcParslet < Parslet
|
3
|
-
def initialize procedure = nil, &block
|
4
|
-
raise ArgumentError, "can't have both an argument and a block" if block_given? and procedure
|
5
|
-
if block_given?
|
6
|
-
super block
|
7
|
-
else
|
8
|
-
raise TypeError, "can't convert #{procedure.class} into Proc" unless procedure.is_a? Proc
|
9
|
-
super procedure
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def parse stream, options = {}
|
14
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
15
|
-
@expected.call stream, options
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class RegexpParslet < Parslet
|
3
|
-
def initialize regexp
|
4
|
-
raise TypeError, "can't convert #{regexp.class} into Regexp" unless regexp.is_a? Regexp
|
5
|
-
super regexp
|
6
|
-
end
|
7
|
-
|
8
|
-
def parse stream, options = {}
|
9
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
10
|
-
parsed = StringResult.new
|
11
|
-
pos = stream.pos
|
12
|
-
match = stream.getc(-1).match /\A#{@expected}/
|
13
|
-
if match
|
14
|
-
stream.rewind pos + match.to_s.length
|
15
|
-
parsed << match.to_s
|
16
|
-
parsed.info[:captures] = match.captures
|
17
|
-
parsed
|
18
|
-
else
|
19
|
-
stream.rewind pos
|
20
|
-
raise ParseError.new "non-matching characters while parsing `#{@expected}'",
|
21
|
-
options.merge(:line_end => stream.line, :column_end => stream.column)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/grammar/stream.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class Stream
|
3
|
-
attr_reader :file
|
4
|
-
|
5
|
-
def initialize source
|
6
|
-
if source.is_a? String
|
7
|
-
@file = nil
|
8
|
-
@string = source.dup
|
9
|
-
elsif source.is_a? File
|
10
|
-
@file = source.path
|
11
|
-
@string = ''
|
12
|
-
source.each_char {|c| @string << c }
|
13
|
-
else
|
14
|
-
raise TypeError, "can't convert #{source.class} into Stream"
|
15
|
-
end
|
16
|
-
@pos = 0
|
17
|
-
@newlines = []
|
18
|
-
start = 0
|
19
|
-
@string.length.times do |i|
|
20
|
-
if @string[i] == "\n"
|
21
|
-
@newlines << [start, i]
|
22
|
-
start = i + 1
|
23
|
-
end
|
24
|
-
end
|
25
|
-
@newlines << [start, @string.length]
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_s
|
29
|
-
@string.dup
|
30
|
-
end
|
31
|
-
|
32
|
-
def length
|
33
|
-
@string.length
|
34
|
-
end
|
35
|
-
|
36
|
-
def pos
|
37
|
-
@pos
|
38
|
-
end
|
39
|
-
|
40
|
-
def line
|
41
|
-
bsearch @pos, 0, @newlines.length
|
42
|
-
end
|
43
|
-
|
44
|
-
def column
|
45
|
-
@pos - @newlines[self.line].first
|
46
|
-
end
|
47
|
-
|
48
|
-
def getc num = 0
|
49
|
-
if num == 0
|
50
|
-
char = @string[@pos]
|
51
|
-
if char
|
52
|
-
@pos += 1
|
53
|
-
char
|
54
|
-
end
|
55
|
-
elsif num > 0
|
56
|
-
string = @string[@pos..(@pos + num - 1)]
|
57
|
-
@pos += string.length
|
58
|
-
string
|
59
|
-
else
|
60
|
-
string = @string[@pos..num]
|
61
|
-
@pos += string.length
|
62
|
-
string
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def rewind pos = 0
|
67
|
-
if pos < 0
|
68
|
-
pos = @string.length + pos + 1
|
69
|
-
@pos = pos < 0 ? 0 : pos
|
70
|
-
elsif pos > @string.length
|
71
|
-
@pos = @string.length
|
72
|
-
else
|
73
|
-
@pos = pos
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
def bsearch value, low, high
|
79
|
-
return nil if high < low
|
80
|
-
mid = low + (high - low) / 2
|
81
|
-
if value < @newlines[mid].first
|
82
|
-
bsearch value, low, mid - 1
|
83
|
-
elsif value > @newlines[mid].last
|
84
|
-
bsearch value, mid + 1, high
|
85
|
-
else
|
86
|
-
mid
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class StringParslet < Parslet
|
3
|
-
def initialize string
|
4
|
-
raise TypeError, "can't convert #{string.class} into String" unless string.is_a? String
|
5
|
-
super string
|
6
|
-
end
|
7
|
-
|
8
|
-
def parse stream, options = {}
|
9
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
10
|
-
parsed = StringResult.new
|
11
|
-
pos = stream.pos
|
12
|
-
@expected.each_char do |char|
|
13
|
-
actual = stream.getc
|
14
|
-
if actual.nil?
|
15
|
-
stream.rewind pos
|
16
|
-
raise ParseError.new "unexpected end-of-string (expected `#{char}') while parsing `#{@expected}'",
|
17
|
-
options.merge(:line_end => stream.line, :column_end => stream.column)
|
18
|
-
elsif actual != char
|
19
|
-
stream.rewind pos
|
20
|
-
raise ParseError.new "unexpected character `#{actual}' (expected `#{char}') while parsing `#{@expected}'",
|
21
|
-
options.merge(:line_end => stream.line, :column_end => stream.column)
|
22
|
-
else
|
23
|
-
parsed << actual
|
24
|
-
end
|
25
|
-
end
|
26
|
-
parsed
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class StringResult < String
|
3
|
-
include LocationTracking
|
4
|
-
|
5
|
-
attr_reader :info
|
6
|
-
|
7
|
-
def initialize string = '', info = {}
|
8
|
-
super string
|
9
|
-
self.line_start = info[:line_start] if info.key? :line_start
|
10
|
-
self.column_start = info[:column_start] if info.key? :column_start
|
11
|
-
self.line_end = info[:line_end] if info.key? :line_end
|
12
|
-
self.column_end = info[:column_end] if info.key? :column_end
|
13
|
-
@info = info
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Kaiseki
|
2
|
-
class SymbolParslet < Parslet
|
3
|
-
include ParsletLogging
|
4
|
-
|
5
|
-
def initialize symbol
|
6
|
-
raise TypeError, "can't convert #{symbol.class} into Symbol" unless symbol.is_a? Symbol
|
7
|
-
super symbol
|
8
|
-
end
|
9
|
-
|
10
|
-
def parse stream, options = {}
|
11
|
-
raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
|
12
|
-
raise ArgumentError, "parsing requires a grammar" unless options.key? :grammar
|
13
|
-
log options[:logger] do
|
14
|
-
options[:grammar].wrap stream, options.merge(:rule => @expected)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_s
|
19
|
-
":#{@expected}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|