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 +8 -8
- data/CHANGELOG.md +4 -0
- data/examples/grammars/grammar_L0.rb +1 -4
- data/examples/grammars/grammar_abc.rb +0 -1
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/parser/earley_parser.rb +2 -1
- data/lib/rley/syntax/grammar_builder.rb +23 -12
- data/spec/rley/syntax/grammar_builder_spec.rb +9 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTE3MWVhNjUzOTkzNjM3N2E3MjdjYzE5MWE1MDEyMmNkZGM3NGJiYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NGM4ZGI2NTY2ZDU1NDU5YzQxMjFiNWVlZmU0YWU3MDhjMGMxYTQ5OA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDA1NzYzZTU2NjY5MDdlMGJkYjZiZGEzZGY5YTkxMzYxZTk3NTNmNDlhZGRl
|
10
|
+
NTUwZjRkYTZlZGIyYTAxYWI2NGE2MWVmMWNiN2JjYTY4MDU2ZDgwYjIyNDY1
|
11
|
+
Y2E3ZjViZTkyM2Q5ZTY1ZjJiMmViNmNlZGFlODE3MzE5YjhiM2Y=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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' => ['
|
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')
|
data/lib/rley/constants.rb
CHANGED
@@ -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 =
|
45
|
+
lhs = get_nonterminal(lhs_name)
|
54
46
|
case rhs_repr
|
55
47
|
when Array
|
56
|
-
rhs_constituents = rhs_repr.map { |name|
|
48
|
+
rhs_constituents = rhs_repr.map { |name| get_nonterminal(name) }
|
57
49
|
when String
|
58
|
-
rhs_constituents = [
|
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.
|
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-
|
11
|
+
date: 2014-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|