rley 0.0.04 → 0.0.05

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.
@@ -10,90 +10,90 @@ require_relative '../../../lib/rley/parser/parse_state'
10
10
 
11
11
  module Rley # Open this namespace to avoid module qualifier prefixes
12
12
  module Parser # Open this namespace to avoid module qualifier prefixes
13
+ describe ParseState do
13
14
 
14
- describe ParseState do
15
+ let(:t_a) { Syntax::Terminal.new('A') }
16
+ let(:t_b) { Syntax::Terminal.new('B') }
17
+ let(:t_c) { Syntax::Terminal.new('C') }
18
+ let(:nt_sentence) { Syntax::NonTerminal.new('sentence') }
15
19
 
16
- let(:t_a) { Syntax::Terminal.new('A') }
17
- let(:t_b) { Syntax::Terminal.new('B') }
18
- let(:t_c) { Syntax::Terminal.new('C') }
19
- let(:nt_sentence) { Syntax::NonTerminal.new('sentence') }
20
+ let(:sample_prod) do
21
+ Syntax::Production.new(nt_sentence, [t_a, t_b, t_c])
22
+ end
20
23
 
21
- let(:sample_prod) do
22
- Syntax::Production.new(nt_sentence, [t_a, t_b, t_c])
23
- end
24
+ let(:other_prod) do
25
+ Syntax::Production.new(nt_sentence, [t_a])
26
+ end
24
27
 
25
- let(:other_prod) do
26
- Syntax::Production.new(nt_sentence, [t_a])
27
- end
28
-
29
- let(:empty_prod) do
30
- Syntax::Production.new(nt_sentence,[])
31
- end
32
-
33
- let(:origin_val) { 3 }
34
- let(:dotted_rule) { DottedItem.new(sample_prod, 2) }
35
- let(:other_dotted_rule) { double('mock-dotted-item') }
28
+ let(:empty_prod) do
29
+ Syntax::Production.new(nt_sentence, [])
30
+ end
36
31
 
37
- # Default instantiation rule
38
- subject { ParseState.new(dotted_rule, origin_val) }
32
+ let(:origin_val) { 3 }
33
+ let(:dotted_rule) { DottedItem.new(sample_prod, 2) }
34
+ let(:other_dotted_rule) { double('mock-dotted-item') }
39
35
 
40
- context 'Initialization:' do
36
+ # Default instantiation rule
37
+ subject { ParseState.new(dotted_rule, origin_val) }
41
38
 
42
- it 'should be created with a dotted item and a origin position' do
43
- expect { ParseState.new(dotted_rule, origin_val) }.not_to raise_error
44
- end
45
-
46
- it 'should complain when the dotted rule is nil' do
47
- err = StandardError
48
- msg = 'Dotted item cannot be nil'
49
- expect { ParseState.new(nil, 2) }.to raise_error(err, msg)
50
- end
39
+ context 'Initialization:' do
51
40
 
52
- it 'should know the related dotted rule' do
53
- expect(subject.dotted_rule).to eq(dotted_rule)
54
- end
41
+ it 'should be created with a dotted item and a origin position' do
42
+ args = [dotted_rule, origin_val]
43
+ expect { ParseState.new(*args) }.not_to raise_error
44
+ end
55
45
 
56
- it 'should know the origin value' do
57
- expect(subject.origin).to eq(origin_val)
58
- end
46
+ it 'should complain when the dotted rule is nil' do
47
+ err = StandardError
48
+ msg = 'Dotted item cannot be nil'
49
+ expect { ParseState.new(nil, 2) }.to raise_error(err, msg)
50
+ end
59
51
 
52
+ it 'should know the related dotted rule' do
53
+ expect(subject.dotted_rule).to eq(dotted_rule)
54
+ end
60
55
 
61
- end # context
56
+ it 'should know the origin value' do
57
+ expect(subject.origin).to eq(origin_val)
58
+ end
62
59
 
63
- context 'Provided services:' do
64
- it 'should compare with itself' do
65
- expect(subject == subject).to eq(true)
66
- end
67
60
 
68
- it 'should compare with another' do
69
- equal = ParseState.new(dotted_rule, origin_val)
70
- expect(subject == equal).to eq(true)
61
+ end # context
71
62
 
72
- # Same dotted_rule, different origin
73
- diff_origin = ParseState.new(dotted_rule, 2)
74
- expect(subject == diff_origin).to eq(false)
63
+ context 'Provided services:' do
64
+ it 'should compare with itself' do
65
+ synonym = subject # Fool Rubocop
66
+ expect(subject == synonym).to eq(true)
67
+ end
75
68
 
76
- # Different dotted item, same origin
77
- diff_rule = ParseState.new(other_dotted_rule, 3)
78
- expect(subject == diff_rule).to eq(false)
79
- end
80
-
81
- it 'should know if the parsing reached the end of the production' do
82
- expect(subject).not_to be_complete
83
- at_end = DottedItem.new(sample_prod, 3)
69
+ it 'should compare with another' do
70
+ equal = ParseState.new(dotted_rule, origin_val)
71
+ expect(subject == equal).to eq(true)
84
72
 
85
- instance = ParseState.new(at_end, 2)
86
- expect(instance).to be_complete
87
- end
88
-
89
- it 'should know the next expected symbol' do
90
- expect(subject.next_symbol).to eq(t_c)
91
- end
92
- end # context
73
+ # Same dotted_rule, different origin
74
+ diff_origin = ParseState.new(dotted_rule, 2)
75
+ expect(subject == diff_origin).to eq(false)
76
+
77
+ # Different dotted item, same origin
78
+ diff_rule = ParseState.new(other_dotted_rule, 3)
79
+ expect(subject == diff_rule).to eq(false)
80
+ end
81
+
82
+ it 'should know if the parsing reached the end of the production' do
83
+ expect(subject).not_to be_complete
84
+ at_end = DottedItem.new(sample_prod, 3)
85
+
86
+ instance = ParseState.new(at_end, 2)
87
+ expect(instance).to be_complete
88
+ end
93
89
 
94
- end # describe
90
+ it 'should know the next expected symbol' do
91
+ expect(subject.next_symbol).to eq(t_c)
92
+ end
93
+ end # context
95
94
 
95
+ end # describe
96
96
  end # module
97
97
  end # module
98
98
 
99
- # End of file
99
+ # End of file
@@ -10,109 +10,108 @@ require_relative '../../../lib/rley/parser/parsing'
10
10
 
11
11
  module Rley # Open this namespace to avoid module qualifier prefixes
12
12
  module Parser # Open this namespace to avoid module qualifier prefixes
13
+ describe Parsing do
13
14
 
14
- describe Parsing do
15
+ # Grammar 1: A very simple language
16
+ # S ::= A.
17
+ # A ::= "a" A "c".
18
+ # A ::= "b".
19
+ let(:nt_S) { Syntax::NonTerminal.new('S') }
20
+ let(:nt_A) { Syntax::NonTerminal.new('A') }
21
+ let(:a_) { Syntax::VerbatimSymbol.new('a') }
22
+ let(:b_) { Syntax::VerbatimSymbol.new('b') }
23
+ let(:c_) { Syntax::VerbatimSymbol.new('c') }
24
+ let(:prod_S) { Syntax::Production.new(nt_S, [nt_A]) }
25
+ let(:prod_A1) { Syntax::Production.new(nt_A, [a_, nt_A, c_]) }
26
+ let(:prod_A2) { Syntax::Production.new(nt_A, [b_]) }
27
+ let(:start_dotted_rule) { DottedItem.new(prod_S, 0) }
15
28
 
16
- # Grammar 1: A very simple language
17
- # S ::= A.
18
- # A ::= "a" A "c".
19
- # A ::= "b".
20
- let(:nt_S) { Syntax::NonTerminal.new('S') }
21
- let(:nt_A) { Syntax::NonTerminal.new('A') }
22
- let(:a_) { Syntax::VerbatimSymbol.new('a') }
23
- let(:b_) { Syntax::VerbatimSymbol.new('b') }
24
- let(:c_) { Syntax::VerbatimSymbol.new('c') }
25
- let(:prod_S) { Syntax::Production.new(nt_S, [nt_A]) }
26
- let(:prod_A1) { Syntax::Production.new(nt_A, [a_, nt_A, c_]) }
27
- let(:prod_A2) { Syntax::Production.new(nt_A, [b_]) }
28
- let(:start_dotted_rule) { DottedItem.new(prod_S, 0) }
29
-
30
- # Helper method that mimicks the output of a tokenizer
31
- # for the language specified by gramma_abc
32
- let(:grm1_tokens) do
33
- [
34
- Token.new('a', a_),
35
- Token.new('a', a_),
36
- Token.new('b', b_),
37
- Token.new('c', c_),
38
- Token.new('c', c_)
39
- ]
40
- end
29
+ # Helper method that mimicks the output of a tokenizer
30
+ # for the language specified by gramma_abc
31
+ let(:grm1_tokens) do
32
+ [
33
+ Token.new('a', a_),
34
+ Token.new('a', a_),
35
+ Token.new('b', b_),
36
+ Token.new('c', c_),
37
+ Token.new('c', c_)
38
+ ]
39
+ end
41
40
 
42
- # Default instantiation rule
43
- subject { Parsing.new(start_dotted_rule, grm1_tokens) }
41
+ # Default instantiation rule
42
+ subject { Parsing.new(start_dotted_rule, grm1_tokens) }
44
43
 
45
- context 'Initialization:' do
44
+ context 'Initialization:' do
46
45
 
47
- it 'should be created with a list of tokens and a start dotted rule' do
48
- expect { Parsing.new(start_dotted_rule, grm1_tokens) }.not_to raise_error
49
- end
50
-
51
- it 'should know the input tokens' do
52
- expect(subject.tokens).to eq(grm1_tokens)
53
- end
46
+ it 'should be created with list of tokens and start dotted rule' do
47
+ start_rule = start_dotted_rule
48
+ tokens = grm1_tokens
49
+ expect { Parsing.new(start_rule, tokens) }.not_to raise_error
50
+ end
51
+
52
+ it 'should know the input tokens' do
53
+ expect(subject.tokens).to eq(grm1_tokens)
54
+ end
54
55
 
55
- it 'should know its chart object' do
56
- expect(subject.chart).to be_kind_of(Chart)
57
- end
56
+ it 'should know its chart object' do
57
+ expect(subject.chart).to be_kind_of(Chart)
58
+ end
58
59
 
59
- end # context
60
-
61
- context 'Parsing:' do
62
- it 'should push a state to a given chart entry' do
63
- expect(subject.chart[1]).to be_empty
64
- item = DottedItem.new(prod_A1, 1)
60
+ end # context
61
+
62
+ context 'Parsing:' do
63
+ it 'should push a state to a given chart entry' do
64
+ expect(subject.chart[1]).to be_empty
65
+ item = DottedItem.new(prod_A1, 1)
66
+
67
+ subject.push_state(item, 1, 1)
68
+ expect(subject.chart[1]).not_to be_empty
69
+ expect(subject.chart[1].first.dotted_rule).to eq(item)
70
+
71
+ # Pushing twice the same state must be no-op
72
+ subject.push_state(item, 1, 1)
73
+ expect(subject.chart[1].size).to eq(1)
74
+ end
65
75
 
66
- subject.push_state(item, 1, 1)
67
- expect(subject.chart[1]).not_to be_empty
68
- expect(subject.chart[1].first.dotted_rule).to eq(item)
76
+ it 'should complain when trying to push a nil dotted item' do
77
+ err = StandardError
78
+ msg = 'Dotted item may not be nil'
79
+ expect { subject.push_state(nil, 1, 1) }.to raise_error(err, msg)
80
+ end
69
81
 
70
- # Pushing twice the same state must be no-op
71
- subject.push_state(item, 1, 1)
72
- expect(subject.chart[1].size).to eq(1)
73
- end
74
-
75
- it 'should complain when trying to push a nil dotted item' do
76
- err = StandardError
77
- msg = 'Dotted item may not be nil'
78
- expect { subject.push_state(nil, 1, 1) }.to raise_error(err, msg)
79
- end
80
-
81
-
82
- it 'should retrieve the parse states that expect a given terminal' do
83
- item1 = DottedItem.new(prod_A1, 2)
84
- item2 = DottedItem.new(prod_A1, 1)
85
- subject.push_state(item1, 2, 2)
86
- subject.push_state(item2, 2, 2)
87
- states = subject.states_expecting(c_, 2)
88
- expect(states.size).to eq(1)
89
- expect(states[0].dotted_rule).to eq(item1)
90
- end
91
-
92
- it 'should update the states upon token match' do
93
- # When a input token matches an expected terminal symbol
94
- # then new parse states must be pushed to the following chart slot
95
- expect(subject.chart[1]).to be_empty
96
82
 
97
- item1 = DottedItem.new(prod_A1, 0)
98
- item2 = DottedItem.new(prod_A2, 0)
99
- subject.push_state(item1, 0, 0)
100
- subject.push_state(item2, 0, 0)
101
- subject.scanning(a_, 0) { |i| i } # Code block is mock
83
+ it 'should retrieve the parse states that expect a given terminal' do
84
+ item1 = DottedItem.new(prod_A1, 2)
85
+ item2 = DottedItem.new(prod_A1, 1)
86
+ subject.push_state(item1, 2, 2)
87
+ subject.push_state(item2, 2, 2)
88
+ states = subject.states_expecting(c_, 2)
89
+ expect(states.size).to eq(1)
90
+ expect(states[0].dotted_rule).to eq(item1)
91
+ end
102
92
 
103
- # Expected side effect: a new state at chart[1]
104
- expect(subject.chart[1].size).to eq(1)
105
- new_state = subject.chart[1].states[0]
106
- expect(new_state.dotted_rule).to eq(item1)
107
- expect(new_state.origin).to eq(0)
108
- end
109
-
110
- # completion(aState, aPosition, &nextMapping)
111
- end
93
+ it 'should update the states upon token match' do
94
+ # When a input token matches an expected terminal symbol
95
+ # then new parse states must be pushed to the following chart slot
96
+ expect(subject.chart[1]).to be_empty
97
+
98
+ item1 = DottedItem.new(prod_A1, 0)
99
+ item2 = DottedItem.new(prod_A2, 0)
100
+ subject.push_state(item1, 0, 0)
101
+ subject.push_state(item2, 0, 0)
102
+ subject.scanning(a_, 0) { |i| i } # Code block is mock
103
+
104
+ # Expected side effect: a new state at chart[1]
105
+ expect(subject.chart[1].size).to eq(1)
106
+ new_state = subject.chart[1].states[0]
107
+ expect(new_state.dotted_rule).to eq(item1)
108
+ expect(new_state.origin).to eq(0)
109
+ end
112
110
 
113
- end # describe
111
+ end
114
112
 
113
+ end # describe
115
114
  end # module
116
115
  end # module
117
116
 
118
- # End of file
117
+ # End of file
@@ -7,62 +7,60 @@ require_relative '../../../lib/rley/parser/state_set'
7
7
 
8
8
  module Rley # Open this namespace to avoid module qualifier prefixes
9
9
  module Parser # Open this namespace to avoid module qualifier prefixes
10
-
11
- describe StateSet do
12
- let(:dotted_rule1) { double('fake_dotted_rule1') }
13
- let(:state1) { ParseState.new(dotted_rule1, 2) }
14
- let(:dotted_rule2) { double('fake_dotted_rule2') }
15
- let(:state2) { ParseState.new(dotted_rule2, 5) }
16
-
17
- context 'Initialization:' do
18
-
19
- it 'should be created without argument' do
20
- expect { StateSet.new }.not_to raise_error
21
- end
22
- end # context
23
-
24
- context 'Provided services:' do
25
-
26
- it 'should push a state' do
27
- expect(subject.states).to be_empty
28
- expect { subject.push_state(state1) }.not_to raise_error
29
- expect(subject).not_to be_empty
30
- subject.push_state(state2)
31
- expect(subject.states).to eq([state1, state2])
32
- end
33
-
34
- it 'should list the states expecting a given terminal' do
35
- # Case of no state
36
- expect(subject.states_expecting(:a)).to be_empty
37
-
38
- # Adding states
39
- subject.push_state(state1)
40
- subject.push_state(state2)
41
- allow(dotted_rule1).to receive(:next_symbol).and_return(:b)
42
- allow(dotted_rule2).to receive(:next_symbol).and_return(:a)
43
- expect(subject.states_expecting(:a)).to eq([state2])
44
- expect(subject.states_expecting(:b)).to eq([state1])
45
- end
46
-
47
- it 'should list the states related to a production' do
48
- a_prod = double('fake-production')
49
-
50
- # Case of no state
51
- expect(subject.states_for(a_prod)).to be_empty
52
-
53
- # Adding states
54
- subject.push_state(state1)
55
- subject.push_state(state2)
56
- allow(dotted_rule1).to receive(:production).and_return(:dummy)
57
- allow(dotted_rule2).to receive(:production).and_return(a_prod)
58
- expect(subject.states_for(a_prod)).to eq([state2])
59
- end
60
-
61
- end # context
62
-
63
- end # describe
64
-
10
+ describe StateSet do
11
+ let(:dotted_rule1) { double('fake_dotted_rule1') }
12
+ let(:state1) { ParseState.new(dotted_rule1, 2) }
13
+ let(:dotted_rule2) { double('fake_dotted_rule2') }
14
+ let(:state2) { ParseState.new(dotted_rule2, 5) }
15
+
16
+ context 'Initialization:' do
17
+
18
+ it 'should be created without argument' do
19
+ expect { StateSet.new }.not_to raise_error
20
+ end
21
+ end # context
22
+
23
+ context 'Provided services:' do
24
+
25
+ it 'should push a state' do
26
+ expect(subject.states).to be_empty
27
+ expect { subject.push_state(state1) }.not_to raise_error
28
+ expect(subject).not_to be_empty
29
+ subject.push_state(state2)
30
+ expect(subject.states).to eq([state1, state2])
31
+ end
32
+
33
+ it 'should list the states expecting a given terminal' do
34
+ # Case of no state
35
+ expect(subject.states_expecting(:a)).to be_empty
36
+
37
+ # Adding states
38
+ subject.push_state(state1)
39
+ subject.push_state(state2)
40
+ allow(dotted_rule1).to receive(:next_symbol).and_return(:b)
41
+ allow(dotted_rule2).to receive(:next_symbol).and_return(:a)
42
+ expect(subject.states_expecting(:a)).to eq([state2])
43
+ expect(subject.states_expecting(:b)).to eq([state1])
44
+ end
45
+
46
+ it 'should list the states related to a production' do
47
+ a_prod = double('fake-production')
48
+
49
+ # Case of no state
50
+ expect(subject.states_for(a_prod)).to be_empty
51
+
52
+ # Adding states
53
+ subject.push_state(state1)
54
+ subject.push_state(state2)
55
+ allow(dotted_rule1).to receive(:production).and_return(:dummy)
56
+ allow(dotted_rule2).to receive(:production).and_return(a_prod)
57
+ expect(subject.states_for(a_prod)).to eq([state2])
58
+ end
59
+
60
+ end # context
61
+
62
+ end # describe
65
63
  end # module
66
64
  end # module
67
65
 
68
- # End of file
66
+ # End of file