spec/rley/parser/parsing_spec.rb in rley-0.0.18 vs spec/rley/parser/parsing_spec.rb in rley-0.1.00
- old
+ new
@@ -1,12 +1,14 @@
require_relative '../../spec_helper'
require_relative '../../../lib/rley/syntax/non_terminal'
require_relative '../../../lib/rley/syntax/verbatim_symbol'
require_relative '../../../lib/rley/syntax/production'
+require_relative '../../../lib/rley/syntax/grammar_builder'
require_relative '../../../lib/rley/parser/dotted_item'
require_relative '../../../lib/rley/parser/token'
+require_relative '../../../lib/rley/parser/earley_parser'
# Load the class under test
require_relative '../../../lib/rley/parser/parsing'
module Rley # Open this namespace to avoid module qualifier prefixes
module Parser # Open this namespace to avoid module qualifier prefixes
@@ -46,71 +48,95 @@
it 'should be created with list of tokens and start dotted rule' do
start_rule = start_dotted_rule
tokens = grm1_tokens
expect { Parsing.new(start_rule, tokens) }.not_to raise_error
end
-
+
it 'should know the input tokens' do
expect(subject.tokens).to eq(grm1_tokens)
end
it 'should know its chart object' do
expect(subject.chart).to be_kind_of(Chart)
end
end # context
-
+
context 'Parsing:' do
it 'should push a state to a given chart entry' do
expect(subject.chart[1]).to be_empty
item = DottedItem.new(prod_A1, 1)
-
+
subject.push_state(item, 1, 1)
expect(subject.chart[1]).not_to be_empty
expect(subject.chart[1].first.dotted_rule).to eq(item)
-
+
# Pushing twice the same state must be no-op
subject.push_state(item, 1, 1)
expect(subject.chart[1].size).to eq(1)
end
-
+
it 'should complain when trying to push a nil dotted item' do
err = StandardError
msg = 'Dotted item may not be nil'
expect { subject.push_state(nil, 1, 1) }.to raise_error(err, msg)
end
-
-
+
+
it 'should retrieve the parse states that expect a given terminal' do
item1 = DottedItem.new(prod_A1, 2)
item2 = DottedItem.new(prod_A1, 1)
subject.push_state(item1, 2, 2)
subject.push_state(item2, 2, 2)
states = subject.states_expecting(c_, 2)
expect(states.size).to eq(1)
expect(states[0].dotted_rule).to eq(item1)
end
-
+
it 'should update the states upon token match' do
# When a input token matches an expected terminal symbol
# then new parse states must be pushed to the following chart slot
expect(subject.chart[1]).to be_empty
-
+
item1 = DottedItem.new(prod_A1, 0)
item2 = DottedItem.new(prod_A2, 0)
subject.push_state(item1, 0, 0)
subject.push_state(item2, 0, 0)
subject.scanning(a_, 0) { |i| i } # Code block is mock
-
+
# Expected side effect: a new state at chart[1]
expect(subject.chart[1].size).to eq(1)
new_state = subject.chart[1].states[0]
expect(new_state.dotted_rule).to eq(item1)
expect(new_state.origin).to eq(0)
end
-
- end
-
+
+ end # context
+
+ context 'Parse tree building:' do
+ let(:sample_grammar1) do
+ builder = Syntax::GrammarBuilder.new
+ builder.add_terminals('a', 'b', 'c')
+ builder.add_production('S' => ['A'])
+ builder.add_production('A' => %w(a A c))
+ builder.add_production('A' => ['b'])
+ builder.grammar
+ end
+
+ let(:token_seq1) do
+ %w(a a b c c).map do |letter|
+ Token.new(letter, sample_grammar1.name2symbol[letter])
+ end
+ end
+
+
+ it 'should build the parse tree for a non-ambiguous grammar' do
+ parser = EarleyParser.new(sample_grammar1)
+ instance = parser.parse(token_seq1)
+ ptree = instance.parse_tree
+ expect(ptree).to be_kind_of(PTree::ParseTree)
+ end
+ end # context
end # describe
end # module
end # module
# End of file