rley 0.1.08 → 0.1.09

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +8 -8
  2. data/.rubocop.yml +81 -74
  3. data/CHANGELOG.md +4 -0
  4. data/Rakefile +4 -6
  5. data/examples/grammars/grammar_L0.rb +31 -31
  6. data/examples/grammars/grammar_abc.rb +26 -26
  7. data/lib/rley/constants.rb +1 -1
  8. data/lib/rley/formatter/base_formatter.rb +1 -3
  9. data/lib/rley/formatter/debug.rb +1 -3
  10. data/lib/rley/formatter/json.rb +2 -5
  11. data/lib/rley/parse_tree_visitor.rb +0 -2
  12. data/lib/rley/parser/dotted_item.rb +3 -1
  13. data/lib/rley/parser/earley_parser.rb +4 -4
  14. data/lib/rley/parser/parsing.rb +10 -9
  15. data/lib/rley/parser/state_set.rb +1 -3
  16. data/lib/rley/ptree/non_terminal_node.rb +1 -1
  17. data/lib/rley/ptree/parse_tree.rb +32 -34
  18. data/lib/rley/ptree/parse_tree_node.rb +1 -3
  19. data/lib/rley/ptree/terminal_node.rb +1 -2
  20. data/lib/rley/ptree/token_range.rb +14 -14
  21. data/spec/rley/formatter/debug_spec.rb +65 -68
  22. data/spec/rley/formatter/json_spec.rb +69 -72
  23. data/spec/rley/parse_tree_visitor_spec.rb +5 -7
  24. data/spec/rley/parser/chart_spec.rb +0 -4
  25. data/spec/rley/parser/dotted_item_spec.rb +0 -3
  26. data/spec/rley/parser/earley_parser_spec.rb +0 -1
  27. data/spec/rley/parser/parse_state_spec.rb +0 -5
  28. data/spec/rley/parser/parsing_spec.rb +0 -3
  29. data/spec/rley/parser/state_set_spec.rb +0 -4
  30. data/spec/rley/parser/token_spec.rb +0 -4
  31. data/spec/rley/ptree/non_terminal_node_spec.rb +0 -1
  32. data/spec/rley/ptree/parse_tree_node_spec.rb +4 -4
  33. data/spec/rley/ptree/parse_tree_spec.rb +2 -3
  34. data/spec/rley/ptree/token_range_spec.rb +16 -17
  35. data/spec/rley/support/grammar_abc_helper.rb +0 -2
  36. data/spec/rley/syntax/grammar_builder_spec.rb +1 -4
  37. data/spec/rley/syntax/grammar_spec.rb +0 -9
  38. data/spec/rley/syntax/grm_symbol_spec.rb +0 -1
  39. data/spec/rley/syntax/literal_spec.rb +0 -1
  40. data/spec/rley/syntax/non_terminal_spec.rb +0 -1
  41. data/spec/rley/syntax/production_spec.rb +0 -2
  42. data/spec/rley/syntax/symbol_seq_spec.rb +0 -1
  43. data/spec/rley/syntax/terminal_spec.rb +0 -1
  44. data/spec/rley/syntax/verbatim_symbol_spec.rb +0 -1
  45. metadata +2 -2
@@ -45,7 +45,8 @@ module Rley # This module is used as a namespace
45
45
  if ptree.current_node.is_a?(PTree::TerminalNode)
46
46
  ptree.current_node.token = tokens[state_set_index]
47
47
  end
48
- parse_state = chart[state_set_index].predecessor_state(parse_state)
48
+ state_set = chart[state_set_index]
49
+ parse_state = state_set.predecessor_state(parse_state)
49
50
  curr_dotted_item = parse_state.dotted_rule
50
51
 
51
52
  when Syntax::NonTerminal
@@ -58,8 +59,8 @@ module Rley # This module is used as a namespace
58
59
  node_range = ptree.current_node.range
59
60
  ptree.add_children(curr_dotted_item.production, node_range)
60
61
  if ptree.current_node.is_a?(PTree::TerminalNode)
61
- curr_node = ptree.current_node
62
- curr_node.token = tokens[state_set_index-1] unless curr_node.token
62
+ a_node = ptree.current_node
63
+ a_node.token = tokens[state_set_index - 1] unless a_node.token
63
64
  end
64
65
 
65
66
  when NilClass
@@ -102,12 +103,12 @@ module Rley # This module is used as a namespace
102
103
  # determine the "next" dotted rule for a given one.
103
104
  def scanning(aTerminal, aPosition, &nextMapping)
104
105
  curr_token = tokens[aPosition]
105
- if curr_token.terminal == aTerminal
106
- states = states_expecting(aTerminal, aPosition)
107
- states.each do |s|
108
- next_item = nextMapping.call(s.dotted_rule)
109
- push_state(next_item, s.origin, aPosition + 1)
110
- end
106
+ return unless curr_token.terminal == aTerminal
107
+
108
+ states = states_expecting(aTerminal, aPosition)
109
+ states.each do |s|
110
+ next_item = nextMapping.call(s.dotted_rule)
111
+ push_state(next_item, s.origin, aPosition + 1)
111
112
  end
112
113
  end
113
114
 
@@ -42,15 +42,13 @@ module Rley # This module is used as a namespace
42
42
  # Retrieve the parse state that is the predecessor of the given one.
43
43
  def predecessor_state(aParseState)
44
44
  if aParseState.dotted_rule.prev_position.nil?
45
- raise StandardError, "#{aParseState}"
45
+ fail StandardError, "#{aParseState}"
46
46
  else
47
- prod = aParseState.dotted_rule.production
48
47
  candidate = states.find { |s| s.precedes?(aParseState) }
49
48
  end
50
49
 
51
50
  return candidate
52
51
  end
53
-
54
52
 
55
53
  private
56
54
 
@@ -26,4 +26,4 @@ module Rley # This module is used as a namespace
26
26
  end # class
27
27
  end # module
28
28
  end # module
29
- # End of file
29
+ # End of file
@@ -38,9 +38,9 @@ module Rley # This module is used as a namespace
38
38
  aProduction.rhs.each do |symb|
39
39
  case symb
40
40
  when Syntax::Terminal
41
- new_node = TerminalNode.new(symb,{})
41
+ new_node = TerminalNode.new(symb, {})
42
42
  when Syntax::NonTerminal
43
- new_node = NonTerminalNode.new(symb,{})
43
+ new_node = NonTerminalNode.new(symb, {})
44
44
  end
45
45
 
46
46
  current_node.add_child(new_node)
@@ -49,57 +49,55 @@ module Rley # This module is used as a namespace
49
49
  children = current_node.children
50
50
  children.first.range = low_bound(aRange)
51
51
  children.last.range = high_bound(aRange)
52
- unless children.empty?
53
- path_increment = [children.size - 1, children.last]
54
- @current_path.concat(path_increment)
55
- end
52
+ return if children.empty?
53
+
54
+ path_increment = [children.size - 1, children.last]
55
+ @current_path.concat(path_increment)
56
56
  end
57
-
57
+
58
58
  # Move the current node to the parent node.
59
59
  # @param tokenPos [Fixnum] position of the matching input token
60
- def step_up(tokenPos)
61
- (pos, last_node) = current_path.pop(2)
60
+ def step_up(_tokenPos)
61
+ current_path.pop(2)
62
62
  end
63
-
63
+
64
64
 
65
65
 
66
66
  # Move the current node to the previous sibling node.
67
67
  # @param tokenPos [Fixnum] position of the matching input token
68
68
  def step_back(tokenPos)
69
69
  (pos, last_node) = current_path[-2, 2]
70
- last_node.range = low_bound({low: tokenPos})
71
-
72
- if pos > 0
73
- current_path.pop(2)
74
- new_pos = pos - 1
75
- new_curr_node = current_path.last.children[new_pos]
76
- current_path << new_pos
77
- current_path << new_curr_node
78
- new_curr_node.range = high_bound({high: tokenPos})
79
- end
70
+ last_node.range = low_bound(low: tokenPos)
71
+
72
+ return if pos <= 0
73
+ current_path.pop(2)
74
+ new_pos = pos - 1
75
+ new_curr_node = current_path.last.children[new_pos]
76
+ current_path << new_pos
77
+ current_path << new_curr_node
78
+ new_curr_node.range = high_bound(high: tokenPos)
80
79
  end
81
80
 
82
81
  private
83
82
 
84
- def low_bound(aRange)
85
- result = case aRange
86
- when Hash then aRange[:low]
87
- when TokenRange then aRange.low
88
- end
89
-
90
- return { low: result }
83
+ def low_bound(aRange)
84
+ result = case aRange
85
+ when Hash then aRange[:low]
86
+ when TokenRange then aRange.low
91
87
  end
92
88
 
93
- def high_bound(aRange)
94
- result = case aRange
95
- when Hash then aRange[:high]
96
- when TokenRange then aRange.high
97
- end
89
+ return { low: result }
90
+ end
98
91
 
99
- return { high: result }
92
+ def high_bound(aRange)
93
+ result = case aRange
94
+ when Hash then aRange[:high]
95
+ when TokenRange then aRange.high
100
96
  end
101
97
 
98
+ return { high: result }
99
+ end
102
100
  end # class
103
101
  end # module
104
102
  end # module
105
- # End of file
103
+ # End of file
@@ -9,7 +9,6 @@ module Rley # This module is used as a namespace
9
9
  # A range of indices for tokens corresponding to the node.
10
10
  attr_reader(:range)
11
11
 
12
-
13
12
  def initialize(aSymbol, aRange)
14
13
  @symbol = aSymbol
15
14
  @range = TokenRange.new(aRange)
@@ -18,8 +17,7 @@ module Rley # This module is used as a namespace
18
17
  def range=(aRange)
19
18
  range.assign(aRange)
20
19
  end
21
-
22
20
  end # class
23
21
  end # module
24
22
  end # module
25
- # End of file
23
+ # End of file
@@ -15,8 +15,7 @@ module Rley # This module is used as a namespace
15
15
  def accept(aVisitor)
16
16
  aVisitor.visit_terminal(self)
17
17
  end
18
-
19
18
  end # class
20
19
  end # module
21
20
  end # module
22
- # End of file
21
+ # End of file
@@ -12,18 +12,18 @@ module Rley # This module is used as a namespace
12
12
  assign_low(aRangeRep)
13
13
  assign_high(aRangeRep)
14
14
  end
15
-
16
-
15
+
16
+
17
17
  def ==(other)
18
18
  return true if object_id == other.object_id
19
-
19
+
20
20
  case other
21
21
  when Hash
22
22
  result = low == other[:low] && high == other[:high]
23
23
  when TokenRange
24
24
  result = low == other.low && high == other.high
25
25
  end
26
-
26
+
27
27
  return result
28
28
  end
29
29
 
@@ -31,31 +31,31 @@ module Rley # This module is used as a namespace
31
31
  def bounded?()
32
32
  return !(low.nil? || high.nil?)
33
33
  end
34
-
34
+
35
35
  # Conditional assign
36
36
  def assign(aRange)
37
37
  return if bounded?
38
-
38
+
39
39
  assign_low(aRange) if low.nil?
40
40
  assign_high(aRange) if high.nil?
41
41
  end
42
-
42
+
43
43
  private
44
+
44
45
  def assign_low(aRange)
45
46
  case aRange
46
- when Hash then @low = aRange.fetch(:low, nil)
47
- when TokenRange then @low = aRange.low
47
+ when Hash then @low = aRange.fetch(:low, nil)
48
+ when TokenRange then @low = aRange.low
48
49
  end
49
50
  end
50
-
51
+
51
52
  def assign_high(aRange)
52
53
  case aRange
53
- when Hash then @high = aRange.fetch(:high, nil)
54
- when TokenRange then @high = aRange.high
54
+ when Hash then @high = aRange.fetch(:high, nil)
55
+ when TokenRange then @high = aRange.high
55
56
  end
56
57
  end
57
-
58
58
  end # class
59
59
  end # module
60
60
  end # module
61
- # End of file
61
+ # End of file
@@ -10,75 +10,73 @@ require_relative '../../../lib/rley/parse_tree_visitor'
10
10
  require_relative '../../../lib/rley/formatter/debug'
11
11
 
12
12
  module Rley # Re-open the module to get rid of qualified names
13
- module Formatter
13
+ module Formatter
14
+ describe Debug do
15
+ include GrammarABCHelper # Mix-in module for grammar abc
14
16
 
15
- describe Debug do
16
- include GrammarABCHelper # Mix-in module with builder for grammar abc
17
+ # Factory method. Build a production with the given sequence
18
+ # of symbols as its rhs.
19
+ let(:grammar_abc) do
20
+ builder = grammar_abc_builder
21
+ builder.grammar
22
+ end
23
+
24
+ # Variables for the terminal symbols
25
+ let(:a_) { grammar_abc.name2symbol['a'] }
26
+ let(:b_) { grammar_abc.name2symbol['b'] }
27
+ let(:c_) { grammar_abc.name2symbol['c'] }
28
+
29
+ # Helper method that mimicks the output of a tokenizer
30
+ # for the language specified by gramma_abc
31
+ let(:grm_abc_tokens1) do
32
+ [
33
+ Parser::Token.new('a', a_),
34
+ Parser::Token.new('a', a_),
35
+ Parser::Token.new('b', b_),
36
+ Parser::Token.new('c', c_),
37
+ Parser::Token.new('c', c_)
38
+ ]
39
+ end
17
40
 
18
- # Factory method. Build a production with the given sequence
19
- # of symbols as its rhs.
20
- let(:grammar_abc) do
21
- builder = grammar_abc_builder
22
- builder.grammar
23
- end
24
-
25
- # Variables for the terminal symbols
26
- let(:a_) { grammar_abc.name2symbol['a'] }
27
- let(:b_) { grammar_abc.name2symbol['b'] }
28
- let(:c_) { grammar_abc.name2symbol['c'] }
29
-
30
- # Helper method that mimicks the output of a tokenizer
31
- # for the language specified by gramma_abc
32
- let(:grm_abc_tokens1) do
33
- [
34
- Parser::Token.new('a', a_),
35
- Parser::Token.new('a', a_),
36
- Parser::Token.new('b', b_),
37
- Parser::Token.new('c', c_),
38
- Parser::Token.new('c', c_)
39
- ]
40
- end
41
-
42
- # Factory method that builds a sample parse tree.
43
- # Generated tree has the following structure:
44
- # S[0,5]
45
- # +- A[0,5]
46
- # +- a[0,0]
47
- # +- A[1,4]
48
- # | +- a[1,1]
49
- # | +- A[2,3]
50
- # | | +- b[2,3]
51
- # | +- c[3,4]
52
- # +- c[4,5]
53
- # Capital letters represent non-terminal nodes
54
- let(:grm_abc_ptree1) do
55
- parser = Parser::EarleyParser.new(grammar_abc)
56
- parse_result = parser.parse(grm_abc_tokens1)
57
- parse_result.parse_tree
58
- end
41
+ # Factory method that builds a sample parse tree.
42
+ # Generated tree has the following structure:
43
+ # S[0,5]
44
+ # +- A[0,5]
45
+ # +- a[0,0]
46
+ # +- A[1,4]
47
+ # | +- a[1,1]
48
+ # | +- A[2,3]
49
+ # | | +- b[2,3]
50
+ # | +- c[3,4]
51
+ # +- c[4,5]
52
+ # Capital letters represent non-terminal nodes
53
+ let(:grm_abc_ptree1) do
54
+ parser = Parser::EarleyParser.new(grammar_abc)
55
+ parse_result = parser.parse(grm_abc_tokens1)
56
+ parse_result.parse_tree
57
+ end
59
58
 
60
- let(:destination) { StringIO.new('', 'w') }
61
-
62
- context 'Standard creation & initialization:' do
59
+ let(:destination) { StringIO.new('', 'w') }
63
60
 
64
- it 'should be initialized with an IO argument' do
65
- expect { Debug.new(StringIO.new('', 'w')) }.not_to raise_error
66
- end
67
-
68
- it 'should know its output destination' do
69
- instance = Debug.new(destination)
70
- expect(instance.output).to eq(destination)
71
- end
72
- end # context
61
+ context 'Standard creation & initialization:' do
62
+ it 'should be initialized with an IO argument' do
63
+ expect { Debug.new(StringIO.new('', 'w')) }.not_to raise_error
64
+ end
65
+
66
+ it 'should know its output destination' do
67
+ instance = Debug.new(destination)
68
+ expect(instance.output).to eq(destination)
69
+ end
70
+ end # context
73
71
 
74
72
 
75
73
 
76
- context 'Formatting events:' do
77
- it 'should support visit events of a parse tree' do
78
- instance = Debug.new(destination)
79
- visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
80
- instance.render(visitor)
81
- expectations = <<-SNIPPET
74
+ context 'Formatting events:' do
75
+ it 'should support visit events of a parse tree' do
76
+ instance = Debug.new(destination)
77
+ visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
78
+ instance.render(visitor)
79
+ expectations = <<-SNIPPET
82
80
  before_ptree
83
81
  before_non_terminal
84
82
  before_children
@@ -108,12 +106,11 @@ before_ptree
108
106
  after_non_terminal
109
107
  after_ptree
110
108
  SNIPPET
111
- expect(destination.string).to eq(expectations)
112
- end
113
- end # context
114
- end # describe
115
-
116
- end # module
109
+ expect(destination.string).to eq(expectations)
110
+ end
111
+ end # context
112
+ end # describe
113
+ end # module
117
114
  end # module
118
115
 
119
116
  # End of file
@@ -11,75 +11,73 @@ require_relative '../../../lib/rley/parse_tree_visitor'
11
11
  require_relative '../../../lib/rley/formatter/json'
12
12
 
13
13
  module Rley # Re-open the module to get rid of qualified names
14
- module Formatter
14
+ module Formatter
15
+ describe Json do
16
+ include GrammarABCHelper # Mix-in module with builder for grammar abc
15
17
 
16
- describe Json do
17
- include GrammarABCHelper # Mix-in module with builder for grammar abc
18
-
19
- # Factory method. Build a production with the given sequence
20
- # of symbols as its rhs.
21
- let(:grammar_abc) do
22
- builder = grammar_abc_builder
23
- builder.grammar
24
- end
25
-
26
- # Variables for the terminal symbols
27
- let(:a_) { grammar_abc.name2symbol['a'] }
28
- let(:b_) { grammar_abc.name2symbol['b'] }
29
- let(:c_) { grammar_abc.name2symbol['c'] }
30
-
31
- # Helper method that mimicks the output of a tokenizer
32
- # for the language specified by gramma_abc
33
- let(:grm_abc_tokens1) do
34
- [
35
- Parser::Token.new('a', a_),
36
- Parser::Token.new('a', a_),
37
- Parser::Token.new('b', b_),
38
- Parser::Token.new('c', c_),
39
- Parser::Token.new('c', c_)
40
- ]
41
- end
42
-
43
- # Factory method that builds a sample parse tree.
44
- # Generated tree has the following structure:
45
- # S[0,5]
46
- # +- A[0,5]
47
- # +- a[0,0]
48
- # +- A[1,4]
49
- # | +- a[1,1]
50
- # | +- A[2,3]
51
- # | | +- b[2,3]
52
- # | +- c[3,4]
53
- # +- c[4,5]
54
- # Capital letters represent non-terminal nodes
55
- let(:grm_abc_ptree1) do
56
- parser = Parser::EarleyParser.new(grammar_abc)
57
- parse_result = parser.parse(grm_abc_tokens1)
58
- parse_result.parse_tree
59
- end
60
-
61
- let(:destination) { StringIO.new('', 'w') }
18
+ # Factory method. Build a production with the given sequence
19
+ # of symbols as its rhs.
20
+ let(:grammar_abc) do
21
+ builder = grammar_abc_builder
22
+ builder.grammar
23
+ end
24
+
25
+ # Variables for the terminal symbols
26
+ let(:a_) { grammar_abc.name2symbol['a'] }
27
+ let(:b_) { grammar_abc.name2symbol['b'] }
28
+ let(:c_) { grammar_abc.name2symbol['c'] }
29
+
30
+ # Helper method that mimicks the output of a tokenizer
31
+ # for the language specified by gramma_abc
32
+ let(:grm_abc_tokens1) do
33
+ [
34
+ Parser::Token.new('a', a_),
35
+ Parser::Token.new('a', a_),
36
+ Parser::Token.new('b', b_),
37
+ Parser::Token.new('c', c_),
38
+ Parser::Token.new('c', c_)
39
+ ]
40
+ end
62
41
 
63
- context 'Standard creation & initialization:' do
42
+ # Factory method that builds a sample parse tree.
43
+ # Generated tree has the following structure:
44
+ # S[0,5]
45
+ # +- A[0,5]
46
+ # +- a[0,0]
47
+ # +- A[1,4]
48
+ # | +- a[1,1]
49
+ # | +- A[2,3]
50
+ # | | +- b[2,3]
51
+ # | +- c[3,4]
52
+ # +- c[4,5]
53
+ # Capital letters represent non-terminal nodes
54
+ let(:grm_abc_ptree1) do
55
+ parser = Parser::EarleyParser.new(grammar_abc)
56
+ parse_result = parser.parse(grm_abc_tokens1)
57
+ parse_result.parse_tree
58
+ end
59
+
60
+ let(:destination) { StringIO.new('', 'w') }
64
61
 
65
- it 'should be initialized with an IO argument' do
66
- expect { Json.new(StringIO.new('', 'w')) }.not_to raise_error
67
- end
68
-
69
- it 'should know its output destination' do
70
- instance = Json.new(destination)
71
- expect(instance.output).to eq(destination)
72
- end
73
- end # context
74
-
62
+ context 'Standard creation & initialization:' do
63
+ it 'should be initialized with an IO argument' do
64
+ expect { Json.new(StringIO.new('', 'w')) }.not_to raise_error
65
+ end
66
+
67
+ it 'should know its output destination' do
68
+ instance = Json.new(destination)
69
+ expect(instance.output).to eq(destination)
70
+ end
71
+ end # context
72
+
75
73
 
76
-
77
- context 'Formatting events:' do
78
- it 'should render a parse tree in JSON' do
79
- instance = Json.new(destination)
80
- visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
81
- instance.render(visitor)
82
- expectations = <<-SNIPPET
74
+
75
+ context 'Formatting events:' do
76
+ it 'should render a parse tree in JSON' do
77
+ instance = Json.new(destination)
78
+ visitor = Rley::ParseTreeVisitor.new(grm_abc_ptree1)
79
+ instance.render(visitor)
80
+ expectations = <<-SNIPPET
83
81
  {
84
82
  "root":
85
83
  { "S": [
@@ -100,13 +98,12 @@ describe Json do
100
98
  ]
101
99
  }
102
100
  }
103
- SNIPPET
104
- expect(destination.string).to eq(expectations.chomp)
105
- end
106
- end # context
107
- end # describe
108
-
109
- end # module
101
+ SNIPPET
102
+ expect(destination.string).to eq(expectations.chomp)
103
+ end
104
+ end # context
105
+ end # describe
106
+ end # module
110
107
  end # module
111
108
 
112
109
  # End of file