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
metadata CHANGED
@@ -3,10 +3,10 @@ name: kaiseki
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
- - 0
8
- - 3
9
- version: 0.0.3
8
+ - 1
9
+ version: 1.0.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - William Hamilton-Levi
@@ -14,12 +14,13 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-23 00:00:00 -05:00
17
+ date: 2010-12-21 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
21
- description: A parsing expression grammar generator written in Ruby.
22
- email: whamilt1@swarthmore.edu
21
+ description: A parsing expression grammar generator coded entirely in ruby. Currently can not create memoizing grammars.
22
+ email:
23
+ - whamilt1@swarthmore.edu
23
24
  executables: []
24
25
 
25
26
  extensions: []
@@ -27,41 +28,45 @@ extensions: []
27
28
  extra_rdoc_files: []
28
29
 
29
30
  files:
31
+ - lib/result_merge.rb
32
+ - lib/var_get.rb
33
+ - lib/parser_package.rb
34
+ - lib/var_set.rb
35
+ - lib/mod_object.rb
36
+ - lib/parser_string.rb
37
+ - lib/node.rb
38
+ - lib/predicate_skip.rb
39
+ - lib/parser_choice.rb
40
+ - lib/predicate_not.rb
41
+ - lib/rule.rb
42
+ - lib/parser_repeat.rb
43
+ - lib/predicate_and.rb
44
+ - lib/result_cast.rb
45
+ - lib/parseable.rb
46
+ - lib/parser_regexp.rb
47
+ - lib/result_filter.rb
30
48
  - lib/kaiseki.rb
31
- - lib/additions/symbol.rb
32
- - lib/additions/string.rb
33
- - lib/additions/regexp.rb
34
- - lib/additions/proc.rb
35
- - lib/grammar/array_result.rb
36
- - lib/grammar/symbol_parslet.rb
37
- - lib/grammar/string_parslet.rb
38
- - lib/grammar/eof_parslet.rb
39
- - lib/grammar/string_result.rb
40
- - lib/grammar/grammar_node.rb
41
- - lib/grammar/node.rb
42
- - lib/grammar/parslet_omission.rb
43
- - lib/grammar/parslet.rb
44
- - lib/grammar/regexp_parslet.rb
45
- - lib/grammar/predicate.rb
46
- - lib/grammar/stream.rb
47
- - lib/grammar/parslet_sequence.rb
48
- - lib/grammar/parslet_merger.rb
49
- - lib/grammar/not_predicate.rb
50
- - lib/grammar/parslet_combination.rb
51
- - lib/grammar/parslet_repetition.rb
52
- - lib/grammar/parse_result.rb
53
- - lib/grammar/parslet_logging.rb
54
- - lib/grammar/parse_logger.rb
55
- - lib/grammar/grammar.rb
56
- - lib/grammar/log_node.rb
57
- - lib/grammar/and_predicate.rb
58
- - lib/grammar/parslet_choice.rb
59
- - lib/grammar/parslet_combining.rb
60
- - lib/grammar/location_tracking.rb
61
- - lib/grammar/proc_parslet.rb
62
- - lib/grammar/parse_error.rb
49
+ - lib/action.rb
50
+ - lib/stream.rb
51
+ - lib/var_insert.rb
52
+ - lib/parser_sequence.rb
53
+ - lib/mod_symbol.rb
54
+ - lib/parser_eof.rb
55
+ - lib/parse_result.rb
56
+ - lib/parser_symbol.rb
57
+ - lib/mod_proc.rb
58
+ - lib/grammar.rb
59
+ - lib/parser_basic.rb
60
+ - lib/result_override.rb
61
+ - lib/mod_regexp.rb
62
+ - lib/parser_multi.rb
63
+ - lib/parse_error.rb
64
+ - lib/mod_file.rb
65
+ - lib/mod_string.rb
66
+ - lib/mod_kernel.rb
67
+ - README
63
68
  has_rdoc: true
64
- homepage: http://github.com/phi2dao/Kaiseki
69
+ homepage: https://github.com/phi2dao/Kaiseki
65
70
  licenses: []
66
71
 
67
72
  post_install_message:
@@ -91,6 +96,6 @@ rubyforge_project:
91
96
  rubygems_version: 1.3.7
92
97
  signing_key:
93
98
  specification_version: 3
94
- summary: A parsing expression grammar generator written in Ruby.
99
+ summary: A parsing expression grammar generator
95
100
  test_files: []
96
101
 
@@ -1,7 +0,0 @@
1
- class Proc
2
- include Kaiseki::ParsletCombining
3
-
4
- def to_parseable
5
- Kaiseki::ProcParslet.new self
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- class Regexp
2
- include Kaiseki::ParsletCombining
3
-
4
- def to_parseable
5
- Kaiseki::RegexpParslet.new self
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- class String
2
- include Kaiseki::ParsletCombining
3
-
4
- def to_parseable
5
- Kaiseki::StringParslet.new self
6
- end
7
- end
@@ -1,19 +0,0 @@
1
- class Symbol
2
- include Kaiseki::ParsletCombining
3
-
4
- def to_parseable
5
- self == :EOF ? Kaiseki::EOFParslet.new : Kaiseki::SymbolParslet.new(self)
6
- end
7
-
8
- def to_instance_variable_name
9
- self[0] == '@' ? self : :"@#{self}"
10
- end
11
-
12
- def to_class_variable_name
13
- self[0..1] == '@@' ? self : :"@@#{self}"
14
- end
15
-
16
- def to_class_name
17
- self.to_s.split('_').collect {|n| n.capitalize }.join.to_sym
18
- end
19
- end
@@ -1,22 +0,0 @@
1
- module Kaiseki
2
- class AndPredicate < Predicate
3
- def initialize parseable
4
- super parseable
5
- @prefix = 'and'
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
14
- stream.rewind pos
15
- raise ParseError.new "Predicate not satisfied (expecting `#{@parseable}')",
16
- options.merge(:line_end => stream.line, :column_end => stream.column)
17
- end
18
- stream.rewind pos
19
- throw :PredicateSuccess
20
- end
21
- end
22
- end
@@ -1,16 +0,0 @@
1
- module Kaiseki
2
- class ArrayResult < Array
3
- include LocationTracking
4
-
5
- attr_reader :info
6
-
7
- def initialize arg1 = 0, arg2 = nil, info = {}
8
- super arg1, arg2
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,32 +0,0 @@
1
- module Kaiseki
2
- class EOFParslet
3
- include ParsletCombining
4
-
5
- def parse stream, options = {}
6
- raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
7
- pos = stream.pos
8
- char = stream.getc
9
- if char
10
- stream.rewind pos
11
- raise ParseError.new "unexpected character `#{char}' (expected EOF)",
12
- options.merge(:line_end => stream.line, :column_end => stream.column)
13
- else
14
- throw :PredicateSuccess
15
- end
16
- end
17
-
18
- def to_s
19
- 'EOF'
20
- end
21
-
22
- def to_parseable
23
- self
24
- end
25
-
26
- def eql? other
27
- other.is_a? EOFParslet
28
- end
29
-
30
- alias :== :eql?
31
- end
32
- end
@@ -1,113 +0,0 @@
1
- module Kaiseki
2
- class Grammar
3
- attr_reader :starting_rule, :skipping_rule, :rules, :overrides, :nodes, :actions
4
-
5
- def initialize &block
6
- @starting_rule = nil
7
- @skipping_rule = nil
8
-
9
- @rules = Hash.new {|hash, key| raise NameError, "rule `#{key}' is not defined" }
10
- @overrides = Hash.new {|hash, key| raise NameError, "override `#{key}' is not defined" }
11
- @nodes = Hash.new {|hash, key| raise NameError, "node `#{key}' is not defined" }
12
- @actions = Hash.new {|hash, key| raise NameError, "action `#{key}' is not defined" }
13
-
14
- @simplify = false
15
-
16
- instance_eval &block if block_given?
17
- end
18
-
19
- def starting parseable
20
- raise StandardError, "starting rule already defined" if @starting_rule
21
- @starting_rule = parseable.to_parseable
22
- end
23
-
24
- def skipping parseable
25
- raise StandardError, "skipping rule already defined" if @skipping_rule
26
- @skipping_rule = parseable.to_parseable
27
- end
28
-
29
- def rule symbol, &block
30
- raise TypeError, "can't convert #{symbol.class} into Symbol" unless symbol.is_a? Symbol
31
- raise StandardError, "rule `#{symbol}' already defined" if @rules.key? symbol
32
- GrammarNode.new(symbol, self).instance_eval(&block) if block_given?
33
- @rules[symbol] = ProcParslet.new { raise NotImplementedError, "rule `#{symbol}' not yet implemented" } unless @rules.key? symbol
34
- end
35
-
36
- def simplify
37
- @simplify = true
38
- end
39
-
40
- def parse! source, options = {}
41
- raise StandardError, "starting rule not defined" unless @starting_rule
42
- stream = source.is_a?(Stream) ? source : Stream.new(source)
43
- options[:grammar] = self
44
- options[:file] = stream.file
45
- options[:rule] = @starting_rule.is_a?(SymbolParslet) ? @starting_rule.expected : :root
46
- options[:skipping] = @skipping_rule
47
- options[:simplify] = @simplify
48
- @starting_rule.parse stream, options
49
- end
50
-
51
- def parse source, options = {}
52
- stream = source.is_a?(Stream) ? source : Stream.new(source)
53
- result = ParseResult.new self, stream, options
54
- begin
55
- result.result = parse! stream, options.merge(:logger => result.logger)
56
- rescue ParseError => e
57
- result.error = e
58
- end
59
- result
60
- end
61
-
62
- def wrap stream, options = {}
63
- raise TypeError, "can't convert #{stream.class} into Stream" unless stream.is_a? Stream
64
- raise ArgumentError, "wrapping requires a rule" unless options.key? :rule
65
- rule = options[:rule]
66
- options.merge! @overrides[rule] if @overrides.key? rule
67
- result = @rules[rule].parse stream, options
68
- if @nodes.key?(rule) and @actions.key?(rule)
69
- node_class = @nodes[rule]
70
- if node_class.arity == 1
71
- node = node_class.new result
72
- else
73
- node = node_class.new *result
74
- end
75
- node.instance_eval &@actions[rule]
76
- else
77
- result
78
- end
79
- end
80
- end
81
-
82
- class << Grammar
83
- def subclass &block
84
- if block_given?
85
- subclass = Class.new self
86
- subclass.bind &block
87
- subclass
88
- else
89
- Class.new self
90
- end
91
- end
92
-
93
- def bind &block
94
- if self == Grammar
95
- raise StandardError, "Grammar rootclass can't be bound"
96
- elsif bound?
97
- raise StandardError, "Grammar can't be bound multiple times"
98
- else
99
- self.send :define_method, :initialize do
100
- super &block
101
- end
102
- self.define_singleton_method :bound? do
103
- true
104
- end
105
- end
106
- true
107
- end
108
-
109
- def bound?
110
- false
111
- end
112
- end
113
- end
@@ -1,31 +0,0 @@
1
- module Kaiseki
2
- class GrammarNode < Node
3
- def parse parseable
4
- raise StandardError, "rule `#{@name}' already defined" if @grammar.rules.key? @name
5
- @grammar.rules[@name] = parseable.to_parseable
6
- end
7
-
8
- def override options
9
- raise StandardError, "rule `#{@name}' not defined" unless @grammar.rules.key? @name
10
- raise StandardError, "override already deinfed for rule `#{@name}'" if @grammar.overrides.key? @name
11
- @grammar.overrides[@name] = options
12
- end
13
-
14
- def node options = {:params => [:results]}
15
- superclass = options.key?(:superclass) ? options[:superclass] : Node
16
- raise TypeError, "can't convert #{superclass.class} into Class" unless superclass.is_a? Class
17
- raise StandardError, "rule `#{@name}' not defined" unless @grammar.rules.key? @name
18
- raise StandardError, "node already defined for rule `#{@name}'" if @grammar.nodes.key? @name
19
- node = @grammar.nodes[@name] = superclass.subclass(*options[:params])
20
- end
21
-
22
- def action &block
23
- raise StandardError, "rule `#{@name}' not defined" unless @grammar.rules.key? @name
24
- raise StandardError, "action already defined for rule `#{@name}'" if @grammar.actions.key? @name
25
- @grammar.nodes[@name] = node unless @grammar.nodes.key? @name
26
- @grammar.actions[@name] = block
27
- end
28
- end
29
-
30
- GrammarNode.bind :name, :grammar
31
- end
@@ -1,57 +0,0 @@
1
- module Kaiseki
2
- module LocationTracking
3
- def line_start
4
- @line_start || 0
5
- end
6
-
7
- def line_start= number
8
- @line_start = number.to_i
9
- end
10
-
11
- def column_start
12
- @column_start || 0
13
- end
14
-
15
- def column_start= number
16
- @column_start = number.to_i
17
- end
18
-
19
- def start
20
- [line_start, column_start]
21
- end
22
-
23
- def start= array
24
- raise TypeError, "can't convert #{array.class} into Array" unless array.is_a? Array
25
- raise ArgumentError, "array must have length 2" unless array.length == 2
26
- @line_start = array[0]
27
- @column_start = array[1]
28
- end
29
-
30
- def line_end
31
- @line_end || 0
32
- end
33
-
34
- def line_end= number
35
- @line_end = number.to_i
36
- end
37
-
38
- def column_end
39
- @column_end || 0
40
- end
41
-
42
- def column_end= number
43
- @column_end = number.to_i
44
- end
45
-
46
- def end
47
- [line_end, column_end]
48
- end
49
-
50
- def end= array
51
- raise TypeError, "can't convert #{array.class} into Array" unless array.is_a? Array
52
- raise ArgumentError, "array must have length 2" unless array.length == 2
53
- @line_end = array[0]
54
- @column_end = array[1]
55
- end
56
- end
57
- end
@@ -1,21 +0,0 @@
1
- module Kaiseki
2
- class LogNode
3
- attr_accessor :result
4
- attr_reader :parslet, :children
5
-
6
- def initialize parslet
7
- @parslet = parslet
8
- @children = []
9
- @result = nil
10
- end
11
-
12
- def add node
13
- @children << node
14
- end
15
-
16
- def print indent = 0
17
- puts " " * indent + "in #{@parslet} got #{@result}"
18
- @children.each {|n| n.print indent + 2 }
19
- end
20
- end
21
- end
data/lib/grammar/node.rb DELETED
@@ -1,59 +0,0 @@
1
- module Kaiseki
2
- class Node
3
-
4
- end
5
-
6
- class << Node
7
- def subclass *parameters
8
- if parameters.empty?
9
- Class.new self
10
- else
11
- subclass = Class.new self
12
- subclass.bind *parameters
13
- subclass
14
- end
15
- end
16
-
17
- def bind *parameters
18
- if self == Node
19
- raise StandardError, "Node rootclass can't be bound"
20
- elsif bound?
21
- raise StandardError, "Node can't be bound multiple times"
22
- else
23
- self.send :define_method, :initialize do |*arguments|
24
- raise ArgumentError, "wrong number of arguments (#{arguments.length} for #{parameters.length})" unless arguments.length == parameters.length
25
- arguments.length.times do |i|
26
- instance_variable_set parameters[i].to_instance_variable_name, arguments[i]
27
- end
28
- end
29
- parameters.each do |parameter|
30
- self.send :define_method, parameter do
31
- instance_variable_get parameter.to_instance_variable_name
32
- end
33
- end
34
- self.define_singleton_method :arity do
35
- parameters.length
36
- end
37
- self.define_singleton_method :parameters do
38
- parameters.dup
39
- end
40
- self.define_singleton_method :bound? do
41
- true
42
- end
43
- end
44
- true
45
- end
46
-
47
- def arity
48
- 0
49
- end
50
-
51
- def parameters
52
- []
53
- end
54
-
55
- def bound?
56
- false
57
- end
58
- end
59
- end
@@ -1,22 +0,0 @@
1
- module Kaiseki
2
- class NotPredicate < Predicate
3
- def initialize parseable
4
- super parseable
5
- @prefix = 'not'
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
14
- stream.rewind pos
15
- throw :PredicateSuccess
16
- end
17
- stream.rewind pos
18
- raise ParseError.new "predicate not satisfied (`#{@parseable}' not allowed)",
19
- options.merge(:line_end => stream.line, :column_end => stream.column)
20
- end
21
- end
22
- end
@@ -1,21 +0,0 @@
1
- module Kaiseki
2
- class ParseError < Exception
3
- include LocationTracking
4
-
5
- attr_reader :file, :rule
6
-
7
- def initialize message, info = {}
8
- super message
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
- @file = info[:file]
14
- @rule = info[:rule]
15
- end
16
-
17
- def location
18
- "from #{@file || 'unknown'}:#{line_end + 1}:#{column_end + 1} in #{@rule || 'unknown'}"
19
- end
20
- end
21
- end
@@ -1,27 +0,0 @@
1
- module Kaiseki
2
- class ParseLogger
3
- attr_accessor :root
4
- attr_reader :stack
5
-
6
- def initialize
7
- @root = nil
8
- @stack = []
9
- end
10
-
11
- def push item
12
- @stack.push item
13
- end
14
-
15
- def pop
16
- @stack.pop
17
- end
18
-
19
- def add item
20
- @stack.last.add item
21
- end
22
-
23
- def backtrace
24
- @root.print
25
- end
26
- end
27
- end
@@ -1,33 +0,0 @@
1
- module Kaiseki
2
- class ParseResult
3
- attr_accessor :grammar, :stream, :options, :result, :error, :logger
4
-
5
- def initialize grammar, stream, options
6
- @grammar = grammar
7
- @stream = stream
8
- @options = options
9
- @result = nil
10
- @error = nil
11
- @logger = ParseLogger.new
12
- end
13
-
14
- def parsed?
15
- !@error
16
- end
17
-
18
- def error_message
19
- "#{@error}\n\t#{@error.location}"
20
- end
21
-
22
- alias :msg :error_message
23
-
24
- def reparse options = {}
25
- @stream.rewind
26
- @grammar.parse @stream, @options.merge(options)
27
- end
28
-
29
- def backtrace
30
- @logger.backtrace
31
- end
32
- end
33
- end
@@ -1,25 +0,0 @@
1
- module Kaiseki
2
- class ParsletChoice < 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
- error = nil
14
- @components.each do |parseable|
15
- begin
16
- return parseable.parse stream, options
17
- rescue ParseError => e
18
- error = e
19
- end
20
- end
21
- raise ParseError.new "no valid alternatives (#{error})",
22
- options.merge(:line_end => stream.line, :column_end => stream.column)
23
- end
24
- end
25
- end
@@ -1,35 +0,0 @@
1
- module Kaiseki
2
- class ParsletCombination
3
- include ParsletCombining
4
-
5
- attr_reader :components
6
-
7
- def initialize *components
8
- @components = components
9
- @delimiter = '--'
10
- end
11
-
12
- def append object
13
- @components << object.to_parseable
14
- self
15
- end
16
-
17
- def parse *args
18
- raise NotImplementedError
19
- end
20
-
21
- def to_s
22
- "<#{@components.join " #{@delimiter} "}>"
23
- end
24
-
25
- def to_parseable
26
- self
27
- end
28
-
29
- def eql? other
30
- other.is_a?(self.class) and other.components == @components
31
- end
32
-
33
- alias :== :eql?
34
- end
35
- end