rley 0.0.10 → 0.0.11

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