rley 0.0.04 → 0.0.05

Sign up to get free protection for your applications and to get access to all the features.
@@ -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