rley 0.0.10 → 0.0.11

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmIxMmNjMmEwZDYwMTUxMzFjY2ZhMjgzNzg4OWEwNTIzMDAxNWMxOQ==
4
+ MTE3MWVhNjUzOTkzNjM3N2E3MjdjYzE5MWE1MDEyMmNkZGM3NGJiYw==
5
5
  data.tar.gz: !binary |-
6
- YTU0MDBmMzliOWE4ZTgyZjMzMGJlNzQxNzE4MDY4MWM5NTc2MGI2ZQ==
6
+ NGM4ZGI2NTY2ZDU1NDU5YzQxMjFiNWVlZmU0YWU3MDhjMGMxYTQ5OA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NTkyOWUzZDIzYWU3OWM5YmYzN2MwNzkzZGMwNThjYTM4YWIzMzdkMjI0ZDc0
10
- ZjBhZDc5ZWFjYTAyYzNhOTIxZTU2YTM0Nzg2MjE0M2E1NWNjMzA0MjM4ZGJh
11
- NjIyNGE3MjVhMDY3MWEyZjhiZjZhOWEyYzA3MTBiMmRkM2E2ZmI=
9
+ NDA1NzYzZTU2NjY5MDdlMGJkYjZiZGEzZGY5YTkxMzYxZTk3NTNmNDlhZGRl
10
+ NTUwZjRkYTZlZGIyYTAxYWI2NGE2MWVmMWNiN2JjYTY4MDU2ZDgwYjIyNDY1
11
+ Y2E3ZjViZTkyM2Q5ZTY1ZjJiMmViNmNlZGFlODE3MzE5YjhiM2Y=
12
12
  data.tar.gz: !binary |-
13
- YzRkY2QzZjRiMDI1ODgwYmE1N2VmYWJjNzc0ZmM1MDM0NjgzZGRmYmFlNjYy
14
- ZTM5MDU3ZTIyMTE4NGY3OTUzNDEyMzg4NzQ1NzBkMDc4Yjc3YmM4M2EwMzQ4
15
- YzJlZGUyZDJjZjNjYjZmNDU3MTE4NmNjNWNhOTAzZjBhZjM1ZjY=
13
+ NzUxNmMzMjZkMWM2Y2NmMzJmY2U3ZTA3ZDYyYmVkZDI2MjAxYTc2MWIxYmRj
14
+ NzYyMzRjOGQxZWIxOTFlN2U4OGUzMTMzMzU5ZjNhMTU0OTkwMDk2MmMzMmU5
15
+ NTZiNTMwZjc4MjBlZWJjOWJmOWE4MWFmZDcyYWQyZWZlZTdmN2U=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ### 0.0.11 / 2014-11-16
2
+ * [CHANGE] Usage of `GrammarBuilder`simplified: the call to method `GrammarBuilder#add_non_terminal` isn't necessary. Method is removed
3
+ * [CHANGE] Updated the `examples` folder accordingly.
4
+
1
5
  ### 0.0.10 / 2014-11-15
2
6
  * [NEW] New folder `examples` added with two examples of grammar creation
3
7
 
@@ -12,14 +12,11 @@ builder.add_terminals('Noun', 'Verb', 'Adjective')
12
12
  builder.add_terminals('Pronoun', 'Proper-Noun', 'Determiner')
13
13
  builder.add_terminals('Preposition', 'Conjunction')
14
14
 
15
- # Enumerate the non-terminal symbols...
16
- builder.add_non_terminals('S', 'NP', 'Nominal', 'VP', 'PP')
17
-
18
15
  # Now the production rules...
19
16
  builder.add_production('S'=> ['NP', 'VP']) # e.g. I + want a morning flight
20
17
  builder.add_production('NP' => 'Pronoun') # e.g. I
21
18
  builder.add_production('NP' => 'Proper-Noun') # e.g. Los Angeles
22
- builder.add_production('NP' => ['Det', 'Nominal']) # e.g. a + flight
19
+ builder.add_production('NP' => ['Determiner', 'Nominal']) # e.g. a + flight
23
20
  builder.add_production('Nominal' => %w(Nominal Noun)) # morning + flight
24
21
  builder.add_production('Nominal' => 'Noun') # e.g. flights
25
22
  builder.add_production('VP' => 'Verb') # e.g. do
@@ -12,7 +12,6 @@ require 'rley' # Load the gem
12
12
  # Let's create the grammar step-by-step with the grammar builder:
13
13
  builder = Rley::Syntax::GrammarBuilder.new
14
14
  builder.add_terminals('a', 'b', 'c')
15
- builder.add_non_terminals('S', 'A')
16
15
  builder.add_production('S' => 'A')
17
16
  builder.add_production('A' => %w(a A c))
18
17
  builder.add_production('A' => 'b')
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Rley # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.0.10'
6
+ Version = '0.0.11'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = "Ruby implementation of the Earley's parsing algorithm"
@@ -4,7 +4,7 @@ require_relative 'parsing'
4
4
 
5
5
  module Rley # This module is used as a namespace
6
6
  module Parser # This module is used as a namespace
7
- # Implementation of a parser that uses the Earley parsing algorithm.
7
+ # Implementation of a parser that uses the Earley parsing algorithm.
8
8
  class EarleyParser
9
9
  # The grammar of the language.
10
10
  attr_reader(:grammar)
@@ -29,6 +29,7 @@ module Rley # This module is used as a namespace
29
29
  @next_mapping = build_next_mapping(dotted_items)
30
30
  end
31
31
 
32
+ # Parse a sequence of input tokens.
32
33
  # @param aTokenSequence [Array] Array of Tokens objects returned by a
33
34
  # tokenizer/scanner/lexer.
34
35
  # @return a Parsing object that embeds the parse result.
@@ -22,7 +22,7 @@ module Rley # This module is used as a namespace
22
22
  @symbols = {}
23
23
  @productions = []
24
24
  end
25
-
25
+
26
26
  # Retrieve a grammar symbol from its name.
27
27
  # Raise an exception if not found.
28
28
  # @param [aSymbolName] the name of a symbol grammar.
@@ -39,23 +39,15 @@ module Rley # This module is used as a namespace
39
39
  symbols.merge!(new_symbs)
40
40
  end
41
41
 
42
- # Add the non-terminal symbols of the language
43
- # nonTerminalSymbols [String or NonTerminal] one or more non-terminal
44
- # symbols to add to the grammar.
45
- def add_non_terminals(*nonTerminalSymbols)
46
- new_symbs = build_symbols(NonTerminal, nonTerminalSymbols)
47
- symbols.merge!(new_symbs)
48
- end
49
-
50
42
  # builder.add_production('A' => ['a', 'A', 'c'])
51
43
  def add_production(aProductionRepr)
52
44
  aProductionRepr.each_pair do |(lhs_name, rhs_repr)|
53
- lhs = self[lhs_name]
45
+ lhs = get_nonterminal(lhs_name)
54
46
  case rhs_repr
55
47
  when Array
56
- rhs_constituents = rhs_repr.map { |name| self[name] }
48
+ rhs_constituents = rhs_repr.map { |name| get_nonterminal(name) }
57
49
  when String
58
- rhs_constituents = [ self[rhs_repr] ]
50
+ rhs_constituents = [ get_nonterminal(rhs_repr) ]
59
51
  end
60
52
  new_prod = Production.new(lhs, rhs_constituents)
61
53
  productions << new_prod
@@ -69,6 +61,13 @@ module Rley # This module is used as a namespace
69
61
  if productions.empty?
70
62
  fail StandardError, 'No production found for grammar'
71
63
  end
64
+
65
+ # Check that each non-terminal appears at least once in lhs.
66
+ all_non_terminals = symbols.values.select { |s| s.is_a?(NonTerminal) }
67
+ all_non_terminals.each do |n_term|
68
+ next if productions.any? { |prod| n_term == prod.lhs }
69
+ fail StandardError, "Nonterminal #{n_term.name} not rewritten"
70
+ end
72
71
 
73
72
  return Grammar.new(productions.dup)
74
73
  end
@@ -107,6 +106,18 @@ module Rley # This module is used as a namespace
107
106
 
108
107
  return a_symbol
109
108
  end
109
+
110
+ # Retrieve the non-terminal symbol with given name.
111
+ # If it doesn't exist yet, then it is created on the fly.
112
+ # @param aSymbolName [String] the name of the grammar symbol to retrieve
113
+ # @return [NonTerminal]
114
+ def get_nonterminal(aSymbolName)
115
+ unless symbols.include? aSymbolName
116
+ symbols[aSymbolName] = NonTerminal.new(aSymbolName)
117
+ end
118
+ return symbols[aSymbolName]
119
+ end
120
+
110
121
  end # class
111
122
  end # module
112
123
  end # module
@@ -45,17 +45,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes
45
45
  expect(subject.symbols['b']).to eq(b)
46
46
  expect(subject.symbols['c']).to eq(c)
47
47
  end
48
-
49
- it 'should build non-terminals from their names' do
50
- subject.add_non_terminals('PP', 'VP', 'DT')
51
- expect(subject.symbols.size).to eq(3)
52
- expect(subject.symbols['PP']).to be_kind_of(NonTerminal)
53
- expect(subject.symbols['PP'].name).to eq('PP')
54
- expect(subject.symbols['VP']).to be_kind_of(NonTerminal)
55
- expect(subject.symbols['VP'].name).to eq('VP')
56
- expect(subject.symbols['DT']).to be_kind_of(NonTerminal)
57
- expect(subject.symbols['DT'].name).to eq('DT')
58
- end
59
48
 
60
49
  it 'should accept already built terminals' do
61
50
  a = Terminal.new('a')
@@ -74,7 +63,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes
74
63
  subject do
75
64
  instance = GrammarBuilder.new
76
65
  instance.add_terminals('a', 'b', 'c')
77
- instance.add_non_terminals('S', 'A')
78
66
  instance
79
67
  end
80
68
 
@@ -105,7 +93,6 @@ module Rley # Open this namespace to avoid module qualifier prefixes
105
93
  subject do
106
94
  instance = GrammarBuilder.new
107
95
  instance.add_terminals('a', 'b', 'c')
108
- instance.add_non_terminals('S', 'A')
109
96
  instance.add_production('S' => ['A'])
110
97
  instance.add_production('A' => %w(a A c))
111
98
  instance.add_production('A' => ['b'])
@@ -128,11 +115,19 @@ module Rley # Open this namespace to avoid module qualifier prefixes
128
115
  it 'should complain in absence of productions' do
129
116
  instance = GrammarBuilder.new
130
117
  instance.add_terminals('a', 'b', 'c')
131
- instance.add_non_terminals('S', 'A')
132
118
  err = StandardError
133
119
  msg = 'No production found for grammar'
134
120
  expect { instance.grammar }.to raise_error(err, msg)
135
121
  end
122
+
123
+ it 'should complain when non-terminal has no production' do
124
+ instance = GrammarBuilder.new
125
+ instance.add_terminals('a', 'b', 'c')
126
+ instance.add_production('S' => ['A'])
127
+ err = StandardError
128
+ msg = 'Nonterminal A not rewritten'
129
+ expect { instance.grammar }.to raise_error(err, msg)
130
+ end
136
131
  end
137
132
 
138
133
  end # describe
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-15 00:00:00.000000000 Z
11
+ date: 2014-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake