dendroid 0.0.4 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a28b9efefb235a669b37c24f587704cc94b7a10f411eafdeef418094013abfc2
4
- data.tar.gz: 1e316ac1c14b8b81ee2a3acf96a3f04d3e772e72f0a062976150ea5def7080f6
3
+ metadata.gz: e94a9721000d8e9a45184107ec3488a3dad0c92337507c6753d4cbfa973400fd
4
+ data.tar.gz: 03bbe70d73b5e12de42b5dca4f008f1850fb9efcc4272115e5123c7397984f4a
5
5
  SHA512:
6
- metadata.gz: 72b4df1de4b537b3bb5ae1d00f56a7cde86627c5b5b2205390a02c824809bfd81ee493ee70ca01d08ea3874e9dc04beb66f09366b186fb133a4250e426281553
7
- data.tar.gz: 5cb5126a0f116d86a91f2a2138dac2330bfaf3911548324947196d768e0ec4e45a897360ce2ab3d31e48497bd24e2fdefdbfc365c28dda5f953f20ea3a16a563
6
+ metadata.gz: 8dde1d9509f2d713db092e5730a1c37f1aaab2a1a58b45cb46c3e28011e672d6c27d9e630262d96a5e5597de35b9278aab8b6e2b87934bf4840e024eee0d6bea
7
+ data.tar.gz: d927b08bf68f6c2a128c92c4724a533991799acf207cd13c381d4abea4cbbf8b340de17771c0a41c351bed3a0d6ac2cd523990d1c0bb699824ce14b9ccd97fe6
data/CHANGELOG.md ADDED
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [0.0.5] - 2023-10-28
6
+ ### Added
7
+ - Class `Choice` and its spec file
8
+
9
+ ### Fixed
10
+ - File `dendroid.gemspec`: added missing `CHANGELOG.md` in the package
11
+
12
+ ## [0.0.4] - 2023-10-28
13
+ ### Added
14
+ - Class `Production` and its spec file
15
+
16
+ ## [0.0.3] - 2023-10-28
17
+ ### Added
18
+ - Class `Rule` and its spec file
19
+
20
+ ## [0.0.2] - 2023-10-28
21
+ ### Added
22
+ - Class `SymbolSeq` and its spec file
23
+ - File `CHANGELOG.md`; the file file you're reading now.
24
+
25
+ ### Changed
26
+ - Line separator set to lf (line feed)
27
+ - Code re-styling to please Rubocop 1.57.1
28
+
29
+ ## [0.0.1] - 2023-10-27
30
+ ### Added
31
+ - Class `NonTerminal` and its spec file
32
+
33
+ ## [0.0.0] - 2023-10-27
34
+ - Initial commit
35
+
36
+ ### Added
37
+ - Class `GrmSymbol` and its spec file
38
+ - Class `Terminal` and its spec file
data/dendroid.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
  'lib/**/*.rb',
17
17
  'spec/**/*.rb',
18
18
  '.rubocop.yml',
19
+ 'CHANGELOG.md',
19
20
  'dendroid.gemspec',
20
21
  'LICENSE',
21
22
  'Rakefile',
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'rule'
4
+
5
+ module Dendroid
6
+ module Syntax
7
+ # A specialization of the Rule class.
8
+ # A choice is a rule with multiple rhs
9
+ class Choice < Rule
10
+ # @return [Array<Dendroid::Syntax::SymbolSeq>]
11
+ attr_reader :alternatives
12
+
13
+ # Create a Choice instance.
14
+ # @param lhs [Dendroid::Syntax::NonTerminal] The left-hand side of the rule.
15
+ # @param alt [Array<Dendroid::Syntax::SymbolSeq>] the alternatives (each as a sequence of symbols).
16
+ def initialize(lhs, alt)
17
+ super(lhs)
18
+ @alternatives = valid_alternatives(alt)
19
+ end
20
+
21
+ # Predicate method to check whether the rule has alternatives
22
+ # @return [TrueClass]
23
+ def choice?
24
+ true
25
+ end
26
+
27
+ # Return the text representation of the choice
28
+ # @return [String]
29
+ def to_s
30
+ "#{head} => #{alternatives.join(' | ')}"
31
+ end
32
+
33
+ # Predicate method to check whether the choice rule body is productive.
34
+ # It is productive when at least of its alternative is productive.
35
+ # @return [Boolean]
36
+ def productive?
37
+ productive_alts = alternatives.select(&:productive?)
38
+ return false if productive_alts.empty?
39
+
40
+ @productive = Set.new(productive_alts)
41
+ head.productive = true
42
+ end
43
+
44
+ # Predicate method to check whether the rule has at least one empty alternative.
45
+ # @return [Boolean]
46
+ def empty?
47
+ alternatives.any?(&:empty?)
48
+ end
49
+
50
+ # Returns an array with the symbol sequence of its alternatives
51
+ # @return [Array<Dendroid::Syntax::SymbolSeq>]
52
+ def rhs
53
+ alternatives
54
+ end
55
+
56
+ # Equality operator
57
+ # Two production rules are equal when their head and alternatives are equal.
58
+ # @return [Boolean]
59
+ def ==(other)
60
+ return true if equal?(other)
61
+ return false if other.is_a?(Production)
62
+
63
+ (head == other.head) && (alternatives == other.alternatives)
64
+ end
65
+
66
+ private
67
+
68
+ def valid_alternatives(alt)
69
+ if alt.size < 2
70
+ # A choice must have at least two alternatives
71
+ raise StandardError.new, "The choice for #{lhs} must have at least two alternatives."
72
+ end
73
+
74
+ cyclic = alt.find { |a| a.size == 1 && lhs == a.first }
75
+ if cyclic
76
+ # Forbid cyclic rules (e.g. A => A)
77
+ raise StandardError.new, "Cyclic rule of the kind #{lhs} => #{lhs} is not allowed."
78
+ end
79
+
80
+ alt
81
+ end
82
+ end # class
83
+ end # module
84
+ end # module
@@ -5,8 +5,7 @@ require_relative 'rule'
5
5
  module Dendroid
6
6
  module Syntax
7
7
  # A specialization of the Rule class.
8
- # A production is the unique rule for the non-terminal symbol
9
- # at its left-hand side (lhs).
8
+ # A production is a rule with a single rhs
10
9
  class Production < Rule
11
10
  # @return [Dendroid::Syntax::SymbolSeq]
12
11
  attr_reader :body
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '..\..\spec_helper'
4
+ require_relative '..\..\..\lib\dendroid\syntax\terminal'
5
+ require_relative '..\..\..\lib\dendroid\syntax\non_terminal'
6
+ require_relative '..\..\..\lib\dendroid\syntax\symbol_seq'
7
+ require_relative '..\..\..\lib\dendroid\syntax\choice'
8
+
9
+ describe Dendroid::Syntax::Choice do
10
+ let(:num_symb) { Dendroid::Syntax::Terminal.new('NUMBER') }
11
+ let(:plus_symb) { Dendroid::Syntax::Terminal.new('PLUS') }
12
+ let(:minus_symb) { Dendroid::Syntax::Terminal.new('MINUS') }
13
+ let(:expr_symb) { Dendroid::Syntax::NonTerminal.new('expression') }
14
+ let(:foo_symb) { Dendroid::Syntax::NonTerminal.new('foo') }
15
+ let(:alt1) { Dendroid::Syntax::SymbolSeq.new([num_symb, plus_symb, num_symb]) }
16
+ let(:alt2) { Dendroid::Syntax::SymbolSeq.new([num_symb, minus_symb, num_symb]) }
17
+ let(:empty_body) { Dendroid::Syntax::SymbolSeq.new([]) }
18
+
19
+ # Implements a choice rule:
20
+ # expression => NUMBER PLUS NUMBER
21
+ # | NUMBER MINUS NUMBER
22
+ # | epsilon
23
+ subject { described_class.new(expr_symb, [alt1, alt2, empty_body]) }
24
+
25
+ context 'Initialization:' do
26
+ it 'is initialized with a head and alternatives' do
27
+ expect { described_class.new(expr_symb, [alt1, alt2, empty_body]) }.not_to raise_error
28
+ end
29
+
30
+ it 'knows its alternatives' do
31
+ expect(subject.alternatives).to eq([alt1, alt2, empty_body])
32
+ end
33
+
34
+ it 'renders a String representation of itself' do
35
+ expectation = 'expression => NUMBER PLUS NUMBER | NUMBER MINUS NUMBER | '
36
+ expect(subject.to_s).to eq(expectation)
37
+ end
38
+ end # context
39
+
40
+ context 'Provided services:' do
41
+ it 'knows its terminal members' do
42
+ expect(subject.terminals).to eq([num_symb, plus_symb, minus_symb])
43
+ end
44
+
45
+ it 'knows its non-terminal members' do
46
+ expect(subject.nonterminals).to be_empty
47
+
48
+ my_alt1 = Dendroid::Syntax::SymbolSeq.new([expr_symb, plus_symb, expr_symb])
49
+ my_alt2 = Dendroid::Syntax::SymbolSeq.new([foo_symb, minus_symb, expr_symb])
50
+ instance = described_class.new(foo_symb, [my_alt1, my_alt2])
51
+ expect(instance.nonterminals).to eq([expr_symb, foo_symb])
52
+ end
53
+ end # context
54
+ end # describe
data/version.txt CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dendroid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
@@ -17,18 +17,21 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - ".rubocop.yml"
20
+ - CHANGELOG.md
20
21
  - LICENSE
21
22
  - README.md
22
23
  - Rakefile
23
24
  - bin/dendroid
24
25
  - dendroid.gemspec
25
26
  - lib/dendroid/dendroid.rb
27
+ - lib/dendroid/syntax/choice.rb
26
28
  - lib/dendroid/syntax/grm_symbol.rb
27
29
  - lib/dendroid/syntax/non_terminal.rb
28
30
  - lib/dendroid/syntax/production.rb
29
31
  - lib/dendroid/syntax/rule.rb
30
32
  - lib/dendroid/syntax/symbol_seq.rb
31
33
  - lib/dendroid/syntax/terminal.rb
34
+ - spec/dendroid/syntax/choice_spec.rb
32
35
  - spec/dendroid/syntax/grm_symbol_spec.rb
33
36
  - spec/dendroid/syntax/non_terminal_spec.rb
34
37
  - spec/dendroid/syntax/production_spec.rb