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.
Files changed (69) hide show
  1. data/README +0 -0
  2. data/lib/action.rb +8 -0
  3. data/lib/grammar.rb +88 -0
  4. data/lib/kaiseki.rb +54 -48
  5. data/lib/mod_file.rb +5 -0
  6. data/lib/mod_kernel.rb +11 -0
  7. data/lib/mod_object.rb +11 -0
  8. data/lib/mod_proc.rb +7 -0
  9. data/lib/mod_regexp.rb +7 -0
  10. data/lib/mod_string.rb +11 -0
  11. data/lib/mod_symbol.rb +27 -0
  12. data/lib/node.rb +78 -0
  13. data/lib/parse_error.rb +16 -0
  14. data/lib/parse_result.rb +21 -0
  15. data/lib/parseable.rb +67 -0
  16. data/lib/{grammar/parslet.rb → parser_basic.rb} +7 -12
  17. data/lib/parser_choice.rb +24 -0
  18. data/lib/parser_eof.rb +27 -0
  19. data/lib/parser_multi.rb +27 -0
  20. data/lib/parser_package.rb +11 -0
  21. data/lib/parser_regexp.rb +19 -0
  22. data/lib/parser_repeat.rb +68 -0
  23. data/lib/parser_sequence.rb +41 -0
  24. data/lib/parser_string.rb +18 -0
  25. data/lib/parser_symbol.rb +16 -0
  26. data/lib/predicate_and.rb +19 -0
  27. data/lib/predicate_not.rb +19 -0
  28. data/lib/predicate_skip.rb +19 -0
  29. data/lib/result_cast.rb +33 -0
  30. data/lib/result_filter.rb +36 -0
  31. data/lib/result_merge.rb +20 -0
  32. data/lib/result_override.rb +20 -0
  33. data/lib/rule.rb +88 -0
  34. data/lib/stream.rb +98 -0
  35. data/lib/var_get.rb +40 -0
  36. data/lib/var_insert.rb +19 -0
  37. data/lib/var_set.rb +24 -0
  38. metadata +45 -40
  39. data/lib/additions/proc.rb +0 -7
  40. data/lib/additions/regexp.rb +0 -7
  41. data/lib/additions/string.rb +0 -7
  42. data/lib/additions/symbol.rb +0 -19
  43. data/lib/grammar/and_predicate.rb +0 -22
  44. data/lib/grammar/array_result.rb +0 -16
  45. data/lib/grammar/eof_parslet.rb +0 -32
  46. data/lib/grammar/grammar.rb +0 -113
  47. data/lib/grammar/grammar_node.rb +0 -31
  48. data/lib/grammar/location_tracking.rb +0 -57
  49. data/lib/grammar/log_node.rb +0 -21
  50. data/lib/grammar/node.rb +0 -59
  51. data/lib/grammar/not_predicate.rb +0 -22
  52. data/lib/grammar/parse_error.rb +0 -21
  53. data/lib/grammar/parse_logger.rb +0 -27
  54. data/lib/grammar/parse_result.rb +0 -33
  55. data/lib/grammar/parslet_choice.rb +0 -25
  56. data/lib/grammar/parslet_combination.rb +0 -35
  57. data/lib/grammar/parslet_combining.rb +0 -57
  58. data/lib/grammar/parslet_logging.rb +0 -22
  59. data/lib/grammar/parslet_merger.rb +0 -50
  60. data/lib/grammar/parslet_omission.rb +0 -20
  61. data/lib/grammar/parslet_repetition.rb +0 -65
  62. data/lib/grammar/parslet_sequence.rb +0 -45
  63. data/lib/grammar/predicate.rb +0 -30
  64. data/lib/grammar/proc_parslet.rb +0 -18
  65. data/lib/grammar/regexp_parslet.rb +0 -25
  66. data/lib/grammar/stream.rb +0 -90
  67. data/lib/grammar/string_parslet.rb +0 -29
  68. data/lib/grammar/string_result.rb +0 -16
  69. data/lib/grammar/symbol_parslet.rb +0 -22
@@ -0,0 +1,68 @@
1
+ module Kaiseki
2
+ class RepeatParser
3
+ include Parseable
4
+ attr_reader :expected, :min, :max
5
+
6
+ def initialize expected, min, max = nil
7
+ @expected = expected.to_parseable
8
+ @min = min
9
+ @max = max
10
+ end
11
+
12
+ def parse! stream, options = {}
13
+ stream.must_be Stream
14
+ stream.lock do
15
+ result = []
16
+ count = 0
17
+ while max.nil? or count < max
18
+ begin
19
+ catch :SkipSuccess do
20
+ result << @expected.parse(stream, options)
21
+ end
22
+ count += 1
23
+ rescue ParseError
24
+ if options[:skipping]
25
+ begin
26
+ catch :SkipSuccess do
27
+ options[:skipping].parse stream, options.merge(:skipping => nil)
28
+ end
29
+ redo
30
+ rescue ParseError
31
+ break
32
+ end
33
+ else
34
+ break
35
+ end
36
+ end
37
+ end
38
+ if result.length < @min
39
+ raise ParseError.new "expected #{@min} match#{'es' unless @min == 1} but obtained #{result.length} when parsing #{self}", options
40
+ else
41
+ if options[:simplify]
42
+ if @min == 0 and @max == 1
43
+ result.length == 0 ? nil : result[0]
44
+ else
45
+ result
46
+ end
47
+ else
48
+ result
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def eql? other
55
+ other.is_a?(self.class) and other.expected == @expected and other.min == @min and other.max == @max
56
+ end
57
+
58
+ alias :== :eql?
59
+
60
+ def to_s
61
+ if @max
62
+ @expected.to_s + " [#{@min}..#{@max}]"
63
+ else
64
+ @expected.to_s + " [#{@min}+]"
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,41 @@
1
+ module Kaiseki
2
+ class SequenceParser < MultiParser
3
+ def parse! stream, options = {}
4
+ stream.must_be Stream
5
+ stream.lock do
6
+ result = []
7
+ @expected.each do |n|
8
+ begin
9
+ catch :SkipSuccess do
10
+ result << n.parse(stream, options)
11
+ end
12
+ rescue ParseError => e
13
+ if options[:skipping]
14
+ begin
15
+ catch :SkipSuccess do
16
+ options[:skipping].parse stream, options.merge(:skipping => nil)
17
+ end
18
+ redo
19
+ rescue ParseError
20
+ raise e
21
+ end
22
+ else
23
+ raise e
24
+ end
25
+ end
26
+ end
27
+ if options[:simplify]
28
+ result.length == 1 ? result[0] : result
29
+ else
30
+ result
31
+ end
32
+ end
33
+ end
34
+
35
+ alias :& :append
36
+
37
+ def delimiter
38
+ '&'
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ module Kaiseki
2
+ class StringParser < BasicParser
3
+ def parse! stream, options = {}
4
+ stream.must_be Stream
5
+ stream.lock do
6
+ @expected.each_char do |char|
7
+ actual = stream.getc
8
+ if actual.nil?
9
+ raise ParseError.new "unexpected end-of-string (expected \"#{char}\") when parsing #{self}", options
10
+ elsif actual != char
11
+ raise ParseError.new "unexpected character \"#{actual}\" (expected \"#{char}\") when parsing #{self}", options
12
+ end
13
+ end
14
+ @expected.dup
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module Kaiseki
2
+ class SymbolParser < BasicParser
3
+ def parse! stream, options = {}
4
+ if options[:grammar]
5
+ if options[:grammar].rules[@expected]
6
+ options[:grammar].rules[@expected].parse stream, options.merge(:rule => @expected)
7
+ else
8
+ STDERR.puts "skipping #{self}: not implemented"
9
+ throw :SkipSuccess
10
+ end
11
+ else
12
+ raise "can't use #{self} without a grammar"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module Kaiseki
2
+ class AndPredicate < PackageParser
3
+ def parse! stream, options = {}
4
+ stream.must_be Stream
5
+ stream.lock do
6
+ begin
7
+ @expected.parse stream, options
8
+ rescue ParseError => e
9
+ raise ParseError.new "predicate not satisfied when parsing #{self}: #{e.to_s}", options
10
+ end
11
+ throw :PredicateSuccess
12
+ end
13
+ end
14
+
15
+ def to_s
16
+ "#{@expected}.and?"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Kaiseki
2
+ class NotPredicate < PackageParser
3
+ def parse! stream, options = {}
4
+ stream.must_be Stream
5
+ stream.lock do
6
+ begin
7
+ result = @expected.parse stream, options
8
+ rescue ParseError
9
+ throw :PredicateSuccess
10
+ end
11
+ raise ParseError.new "predicate not satisfied when parsing #{self}: matched #{result}", options
12
+ end
13
+ end
14
+
15
+ def to_s
16
+ "#{@expected}.not!"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Kaiseki
2
+ class SkipPredicate < PackageParser
3
+ def parse! stream, options = {}
4
+ stream.must_be Stream
5
+ stream.lock do
6
+ begin
7
+ @expected.parse stream, options
8
+ rescue ParseError => e
9
+ raise ParseError.new "predicate not satisfied when parsing #{self}: #{e.to_s}", options
10
+ end
11
+ throw :SkipSuccess
12
+ end
13
+ end
14
+
15
+ def to_s
16
+ "#{@expected}.skip"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module Kaiseki
2
+ class CastResult < PackageParser
3
+ attr_reader :to_class
4
+
5
+ def initialize expected, to_class
6
+ super expected
7
+ @to_class = to_class
8
+ end
9
+
10
+ def parse! stream, options = {}
11
+ result = @expected.parse stream, options
12
+ if @to_class == Integer
13
+ result.is_a?(MatchData) ? result.to_s.to_i : result.to_i
14
+ elsif @to_class == Float
15
+ result.is_a?(MatchData) ? result.to_s.to_f : result.to_f
16
+ elsif @to_class == String
17
+ result.is_a?(Array) ? result.join : result.to_s
18
+ elsif @to_class == Symbol
19
+ result.is_a?(Array) ? result.join.to_sym : result.to_sym
20
+ elsif @to_class == Array
21
+ result.is_a?(String) ? result.split(options[:delimiter] || '') : result.to_a
22
+ else
23
+ raise "can't cast to #{@to_class}"
24
+ end
25
+ end
26
+
27
+ def eql? other
28
+ other.is_a?(self.class) and other.expected == @expected and other.to_class == @to_class
29
+ end
30
+
31
+ alias :== :eql?
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ module Kaiseki
2
+ class FilterResult < PackageParser
3
+ attr_reader :node, :block
4
+
5
+ def initialize expected, node = Node.subclass([:result], :arity => {:result => 0}), &block
6
+ super expected
7
+ @node = node
8
+ @block = block
9
+ end
10
+
11
+ def parse! stream, options = {}
12
+ if @node.is_a? Class
13
+ node_class = @node
14
+ else
15
+ if options[:grammar]
16
+ node_class = options[:grammar].nodes[@node]
17
+ else
18
+ raise "can't use named nodes without a grammar"
19
+ end
20
+ end
21
+ result = @expected.parse stream, options
22
+ if result.is_a? Array
23
+ node = node_class.new result, options[:global]
24
+ else
25
+ node = node_class.new [result]
26
+ end
27
+ node.eval options[:global], &@block
28
+ end
29
+
30
+ def eql? other
31
+ other.is_a?(self.class) and other.expected == @expected and other.block == @block
32
+ end
33
+
34
+ alias :== :eql?
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ module Kaiseki
2
+ class MergeResult < PackageParser
3
+ def parse! stream, options = {}
4
+ results = @expected.parse stream, options
5
+ new_results = []
6
+ if results.respond_to? :each
7
+ results.each do |result|
8
+ if result.respond_to? :each
9
+ result.each {|n| new_results << n }
10
+ else
11
+ new_results << result
12
+ end
13
+ end
14
+ else
15
+ new_results = results
16
+ end
17
+ new_results
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Kaiseki
2
+ class OverrideResult < PackageParser
3
+ attr_reader :options
4
+
5
+ def initialize expected, options
6
+ super expected
7
+ @options = options
8
+ end
9
+
10
+ def parse! stream, options = {}
11
+ @expected.parse stream, options.merge(@options)
12
+ end
13
+
14
+ def eql? other
15
+ other.is_a?(self.class) and other.expected == @expected and other.options == @options
16
+ end
17
+
18
+ alias :== :eql?
19
+ end
20
+ end
data/lib/rule.rb ADDED
@@ -0,0 +1,88 @@
1
+ module Kaiseki
2
+ class Rule
3
+ attr_reader :parseable
4
+
5
+ def initialize name, grammar, &block
6
+ @name = name
7
+ @grammar = grammar
8
+ @parseable = nil
9
+
10
+ instance_eval &block if block_given?
11
+ end
12
+
13
+ def parses parseable
14
+ if @parseable
15
+ raise "parseable for rule #{@name.inspect} already defined"
16
+ else
17
+ @parseable = parseable.to_parseable
18
+ end
19
+ end
20
+
21
+ def override options
22
+ if @parseable
23
+ @parseable = @parseable.override options
24
+ else
25
+ raise "parseable for rule #{@name.inspect} undefined"
26
+ end
27
+ end
28
+
29
+ def skipping parseable
30
+ if @parseable
31
+ @parseable = @parseable.override :skipping => parseable.to_parseable
32
+ else
33
+ raise "parseable for rule #{@name.inspect} undefined"
34
+ end
35
+ end
36
+
37
+ def simplify bool = true
38
+ if @parseable
39
+ @parseable = @parseable.override :simplify => bool
40
+ else
41
+ raise "parseable for rule #{@name.inspect} undefined"
42
+ end
43
+ end
44
+
45
+ def merge
46
+ if @parseable
47
+ @parseable = @parseable.merge
48
+ else
49
+ raise "parseable for rule #{@name.inspect} undefined"
50
+ end
51
+ end
52
+
53
+ def cast to_class
54
+ if @parseable
55
+ @parseable = @parseable.cast to_class
56
+ else
57
+ raise "parseable for rule #{@name.inspect} undefined"
58
+ end
59
+ end
60
+
61
+ def filter node = @name, &block
62
+ if @parseable
63
+ @grammar.nodes[@name] ||= Node.subclass([:result], :arity => {:result => 0})
64
+ @parseable = @parseable.filter node, &block
65
+ else
66
+ raise "parseable for rule #{@name.inspect} undefined"
67
+ end
68
+ end
69
+
70
+ def node args, options = {}
71
+ args.must_be Array
72
+ if @grammar.nodes.key? @name
73
+ raise "node #{@name.inspect} already defined"
74
+ else
75
+ parent = options[:class] || Node
76
+ @grammar.nodes[@name] = parent.subclass args, options
77
+ end
78
+ end
79
+
80
+ def set *vars
81
+ if @parseable
82
+ @parseable = @parseable.set *vars
83
+ else
84
+ raise "parseable for rule #{@name.inspect} undefined"
85
+ end
86
+ end
87
+ end
88
+ end
data/lib/stream.rb ADDED
@@ -0,0 +1,98 @@
1
+ module Kaiseki
2
+ class Stream
3
+ attr_reader :pos
4
+
5
+ def initialize string
6
+ if string.is_a? File
7
+ @string = ''
8
+ string.each_char {|n| @string << n }
9
+ else
10
+ @string = string.to_s
11
+ end
12
+ @pos = 0
13
+ #index_lines
14
+ end
15
+
16
+ def getc
17
+ if @pos < @string.length
18
+ @pos += 1
19
+ @string[@pos - 1]
20
+ else
21
+ nil
22
+ end
23
+ end
24
+
25
+ def match regexp
26
+ match = @string[@pos..-1].match /\A#{regexp}/
27
+ if match
28
+ @pos += match.to_s.length
29
+ match
30
+ else
31
+ nil
32
+ end
33
+ end
34
+
35
+ def look len = 10
36
+ if @string.length - @pos > len
37
+ "\"#{@string[@pos, len - 3] + '...'}\""
38
+ else
39
+ "\"#{@string[@pos..-1]}\""
40
+ end
41
+ end
42
+
43
+ def goto pos
44
+ if pos < 0
45
+ @pos = 0
46
+ elsif pos > @string.length
47
+ @pos = @string.length
48
+ end
49
+ end
50
+
51
+ def lock &block
52
+ safe_pos = @pos
53
+ begin
54
+ catch :PredicateSuccess do
55
+ return block.call
56
+ end
57
+ @pos = safe_pos
58
+ throw :SkipSuccess
59
+ rescue ParseError => e
60
+ @pos = safe_pos
61
+ #e.line ||= self.line
62
+ #e.column ||= self.column
63
+ raise e
64
+ end
65
+ end
66
+
67
+ def to_s
68
+ @string.dup
69
+ end
70
+
71
+ def to_stream
72
+ self
73
+ end
74
+
75
+ def length
76
+ @string.length
77
+ end
78
+
79
+ alias :size :length
80
+
81
+ def line
82
+
83
+ end
84
+
85
+ def column
86
+
87
+ end
88
+
89
+ private
90
+ def index_lines
91
+
92
+ end
93
+
94
+ def bsearch
95
+
96
+ end
97
+ end
98
+ end
data/lib/var_get.rb ADDED
@@ -0,0 +1,40 @@
1
+ module Kaiseki
2
+ class GetVar < BasicParser
3
+ attr_reader :parser
4
+
5
+ def initialize expected, parser
6
+ super expected
7
+ @parser = parser.to_parseable
8
+ end
9
+
10
+ def parse! stream, options = {}
11
+ if @expected.is_a? Symbol
12
+ if options[:global] and options[:global].key?(@expected)
13
+ source = options[:global][@expected]
14
+ else
15
+ raise "$#{@expected} undefined"
16
+ end
17
+ else
18
+ source = @expected
19
+ end
20
+ result = @parser.parse stream, options
21
+ if source.is_a?(MatchData) and result.is_a?(MatchData) and source.to_s == result.to_s and source.regexp == result.regexp
22
+ result
23
+ elsif source == result
24
+ result
25
+ else
26
+ raise ParseError.new "unexpected result #{result.inspect} (expected #{source.inspect}) when parsing #{@parser}", options
27
+ end
28
+ end
29
+
30
+ def eql? other
31
+ other.is_a?(self.class) and other.expected == @expected and other.parser == @parser
32
+ end
33
+
34
+ alias :== :eql?
35
+
36
+ def to_s
37
+ "#{@expected.is_a?(Symbol) ? "$#{@expected}" : @expected.inspect} (match)"
38
+ end
39
+ end
40
+ end
data/lib/var_insert.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Kaiseki
2
+ class InsertVar < BasicParser
3
+ def parse! stream, options = {}
4
+ if @expected.is_a? Symbol
5
+ if options[:global] and options[:global].key?(@expected)
6
+ options[:global][@expected]
7
+ else
8
+ raise "$#{@expected} undefined"
9
+ end
10
+ else
11
+ @expected
12
+ end
13
+ end
14
+
15
+ def to_s
16
+ "#{@expected.is_a?(Symbol) ? "$#{@expected}" : @expected.inspect} (ins)"
17
+ end
18
+ end
19
+ end
data/lib/var_set.rb ADDED
@@ -0,0 +1,24 @@
1
+ module Kaiseki
2
+ class SetVar < PackageParser
3
+ attr_reader :vars
4
+
5
+ def initialize expected, *vars
6
+ super expected
7
+ @vars = []
8
+ vars.each {|n| @vars << n }
9
+ end
10
+
11
+ def parse! stream, options = {}
12
+ result = @expected.parse stream, options
13
+ options[:global] ||= {}
14
+ @vars.each {|n| options[:global][n] = result }
15
+ result
16
+ end
17
+
18
+ def eql? other
19
+ other.is_a?(self.class) and other.expected == @expected and other.vars == @vars
20
+ end
21
+
22
+ alias :== :eql?
23
+ end
24
+ end