zenlish 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.yardopts +6 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +95 -0
- data/Rakefile +6 -0
- data/lib/zenlish.rb +9 -0
- data/lib/zenlish/lex/empty_lexicon.rb +7 -0
- data/lib/zenlish/lex/empty_lexicon_factory.rb +32 -0
- data/lib/zenlish/lex/lexeme.rb +19 -0
- data/lib/zenlish/lex/lexical_entry.rb +19 -0
- data/lib/zenlish/lex/lexicon.rb +55 -0
- data/lib/zenlish/lex/literal.rb +16 -0
- data/lib/zenlish/parser/zenlish_grammar.rb +29 -0
- data/lib/zenlish/parser/zparser.rb +30 -0
- data/lib/zenlish/version.rb +3 -0
- data/lib/zenlish/wclasses/adjective.rb +9 -0
- data/lib/zenlish/wclasses/all_word_classes.rb +11 -0
- data/lib/zenlish/wclasses/article.rb +9 -0
- data/lib/zenlish/wclasses/common_noun.rb +9 -0
- data/lib/zenlish/wclasses/definite_article.rb +9 -0
- data/lib/zenlish/wclasses/demonstrative_determiner.rb +9 -0
- data/lib/zenlish/wclasses/determiner.rb +9 -0
- data/lib/zenlish/wclasses/indefinite_pronoun.rb +9 -0
- data/lib/zenlish/wclasses/irregular_verb.rb +9 -0
- data/lib/zenlish/wclasses/lexical_verb.rb +9 -0
- data/lib/zenlish/wclasses/noun.rb +11 -0
- data/lib/zenlish/wclasses/pronoun.rb +9 -0
- data/lib/zenlish/wclasses/proper_noun.rb +10 -0
- data/lib/zenlish/wclasses/test_hierarchy.rb +3 -0
- data/lib/zenlish/wclasses/verb.rb +9 -0
- data/lib/zenlish/wclasses/word_class.rb +20 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/zenlish/lex/empty_lexicon_factory_spec.rb +35 -0
- data/spec/zenlish/lex/lexeme_spec.rb +39 -0
- data/spec/zenlish/lex/lexical_entry_spec.rb +46 -0
- data/spec/zenlish/lex/lexicon_spec.rb +104 -0
- data/spec/zenlish/lex/literal_spec.rb +41 -0
- data/spec/zenlish/parser/zenlish_grammar_spec.rb +21 -0
- data/spec/zenlish/parser/zparser_spec.rb +86 -0
- data/spec/zenlish/support/minimal_lexicon.rb +30 -0
- data/spec/zenlish/wclasses/common_noun_spec.rb +22 -0
- data/spec/zenlish/wclasses/irregular_verb_spec.rb +21 -0
- data/spec/zenlish/wclasses/proper_noun_spec.rb +21 -0
- data/spec/zenlish_spec.rb +5 -0
- data/zenlish.gemspec +61 -0
- metadata +158 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'word_class'
|
2
|
+
|
3
|
+
module Zenlish
|
4
|
+
module WClasses
|
5
|
+
# A noun denotes classes and categories of things in the unverse of discourse.
|
6
|
+
# Nouns denote people, animals, inanimate things, places, events, qualities
|
7
|
+
# and states.
|
8
|
+
class Noun < WordClass
|
9
|
+
end # class
|
10
|
+
end # module
|
11
|
+
end # module
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rley'
|
2
|
+
|
3
|
+
module Zenlish
|
4
|
+
module WClasses
|
5
|
+
# Also known as: part of speech, syntactic category or word category.
|
6
|
+
# A word class represents a group of word which have similar functions.
|
7
|
+
# Word classes are divided into:
|
8
|
+
# - Lexical words (?? same as content words??) such as nouns, verbs, adjectives, adverbs
|
9
|
+
# Content words carry the meaning of a sentence
|
10
|
+
# - Function words (?? same as structure words??) such as pronouns, determiners, modal verbs,
|
11
|
+
# auxiliary verbs,
|
12
|
+
# Structure words structure a sentence
|
13
|
+
# conjunctions and prepositions
|
14
|
+
class WordClass < Rley::Syntax::Terminal
|
15
|
+
def initialize
|
16
|
+
super(self.class.name.split('::').last)
|
17
|
+
end
|
18
|
+
end # class
|
19
|
+
end # module
|
20
|
+
end # module
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'rspec' # Use the RSpec framework
|
3
|
+
# require_relative '../lib/zenlish'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# Enable flags like --only-failures and --next-failure
|
7
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
8
|
+
|
9
|
+
config.expect_with :rspec do |c|
|
10
|
+
c.syntax = :expect
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load module under test
|
6
|
+
require_relative '../../../lib/zenlish/lex/empty_lexicon_factory'
|
7
|
+
|
8
|
+
module Zenlish
|
9
|
+
module Lex
|
10
|
+
describe EmptyLexiconFactory do
|
11
|
+
subject do
|
12
|
+
obj = Object.new
|
13
|
+
obj.extend(EmptyLexiconFactory)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'Mix-in integration:' do
|
17
|
+
it 'should acquire the methods of the mix-in module' do
|
18
|
+
expect(subject.respond_to?(:create_empty_lexicon)).to be_truthy
|
19
|
+
end
|
20
|
+
end # context
|
21
|
+
|
22
|
+
context 'Created lexicon:' do
|
23
|
+
it 'should allow the creation of empty lexicon' do
|
24
|
+
expect(subject.create_empty_lexicon).to be_kind_of(Lexicon)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should initialize lexicon with terminal symbols of the language' do
|
28
|
+
lexicon = subject.create_empty_lexicon
|
29
|
+
found = lexicon.terminals.find { |symb| symb.kind_of?(WClasses::CommonNoun) }
|
30
|
+
expect(found).to be_truthy
|
31
|
+
end
|
32
|
+
end # context
|
33
|
+
end # describe
|
34
|
+
end # module
|
35
|
+
end # module
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../../lib/zenlish/wclasses/all_word_classes'
|
5
|
+
require_relative '../../../lib/zenlish/lex/lexical_entry'
|
6
|
+
require_relative '../../../lib/zenlish/lex/lexeme' # Load the class under test
|
7
|
+
|
8
|
+
module Zenlish
|
9
|
+
module Lex
|
10
|
+
describe Lexeme do
|
11
|
+
let(:sample_wclass) { WClasses::CommonNoun.new }
|
12
|
+
let(:sample_lemma) { 'thing' }
|
13
|
+
let(:sample_entry) { LexicalEntry.new(sample_lemma) }
|
14
|
+
|
15
|
+
subject { Lexeme.new(sample_wclass, sample_entry) }
|
16
|
+
|
17
|
+
context 'Initialization:' do
|
18
|
+
it 'should be initialized with a word class and a lexical entry' do
|
19
|
+
expect { Lexeme.new(sample_wclass, sample_entry) }.not_to raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should know its word class' do
|
23
|
+
expect(subject.wclass).to eq(sample_wclass)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should know its lexical entry' do
|
27
|
+
expect(subject.entry).to eq(sample_entry)
|
28
|
+
end
|
29
|
+
end # context
|
30
|
+
|
31
|
+
context 'Provided services:' do
|
32
|
+
it 'should know its lemma' do
|
33
|
+
expect(subject.lemma).to eq(sample_lemma)
|
34
|
+
end
|
35
|
+
end # context
|
36
|
+
end # describe
|
37
|
+
end # module
|
38
|
+
end # module
|
39
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework'
|
4
|
+
require_relative '../../../lib/zenlish/lex/lexical_entry' # Load the class under test
|
5
|
+
|
6
|
+
module Zenlish
|
7
|
+
module Lex
|
8
|
+
describe LexicalEntry do
|
9
|
+
let(:sample_lemma) { 'other' }
|
10
|
+
let(:sample_lexeme1) { double('other-as-adjective') }
|
11
|
+
let(:sample_lexeme2) { double('other-as-pronoun') }
|
12
|
+
subject { LexicalEntry.new(sample_lemma) }
|
13
|
+
|
14
|
+
context 'Initialization:' do
|
15
|
+
it 'can be initialized with a lemma only' do
|
16
|
+
expect { LexicalEntry.new(sample_lemma) }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can be initialized with a lemma and a word class' do
|
20
|
+
expect { LexicalEntry.new(sample_lemma, sample_lexeme1) }.not_to raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should know its lemma' do
|
24
|
+
expect(subject.lemma).to eq(sample_lemma)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should know its lexeme (if any)' do
|
28
|
+
expect(subject.lexemes).to be_empty
|
29
|
+
instance = LexicalEntry.new(sample_lemma, sample_lexeme1)
|
30
|
+
expect(instance.lexemes).to eq([sample_lexeme1])
|
31
|
+
end
|
32
|
+
end # context
|
33
|
+
|
34
|
+
context 'Provided services:' do
|
35
|
+
|
36
|
+
it 'should accept links with lexeme(s)' do
|
37
|
+
subject.add_lexeme(sample_lexeme1)
|
38
|
+
expect(subject.lexemes).to eq([sample_lexeme1])
|
39
|
+
|
40
|
+
subject.add_lexeme(sample_lexeme2)
|
41
|
+
expect(subject.lexemes).to eq([sample_lexeme1, sample_lexeme2])
|
42
|
+
end
|
43
|
+
end # context
|
44
|
+
end # describe
|
45
|
+
end # module
|
46
|
+
end # module
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework'
|
4
|
+
require_relative '../../../lib/zenlish/wclasses/all_word_classes'
|
5
|
+
require_relative '../../../lib/zenlish/lex/lexical_entry'
|
6
|
+
require_relative '../../../lib/zenlish/lex/lexeme'
|
7
|
+
require_relative '../../../lib/zenlish/lex/lexicon' # Load the class under test
|
8
|
+
|
9
|
+
=begin
|
10
|
+
|
11
|
+
minimal_lexicon = Zenlish::Lex::Lexicon.new
|
12
|
+
ent = Zenlish::Lex::LexicalEntry.new('Lisa')
|
13
|
+
lexeme = Zenlish::Lex::Lexeme.new(o_proper_noun, ent)
|
14
|
+
minimal_lexicon.add_entry(ent)
|
15
|
+
|
16
|
+
ent = Zenlish::Lex::LexicalEntry.new('see')
|
17
|
+
lexeme = Zenlish::Lex::Lexeme.new(o_irregular_verb, ent)
|
18
|
+
minimal_lexicon.add_entry(ent)
|
19
|
+
|
20
|
+
ent = Zenlish::Lex::LexicalEntry.new('Tony')
|
21
|
+
lexeme = Zenlish::Lex::Lexeme.new(o_proper_noun, ent)
|
22
|
+
minimal_lexicon.add_entry(ent)
|
23
|
+
=end
|
24
|
+
|
25
|
+
|
26
|
+
module Zenlish
|
27
|
+
module Lex
|
28
|
+
describe Lexicon do
|
29
|
+
def create_entry(aLemma, aWordClass)
|
30
|
+
entry = Zenlish::Lex::LexicalEntry.new(aLemma)
|
31
|
+
lexeme = Zenlish::Lex::Lexeme.new(aWordClass, entry)
|
32
|
+
entry
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:adjective) { Zenlish::WClasses::Adjective.new }
|
36
|
+
let(:proper_noun) { Zenlish::WClasses::ProperNoun.new }
|
37
|
+
let(:pronoun) { Zenlish::WClasses::Pronoun.new }
|
38
|
+
let(:irregular_verb) { Zenlish::WClasses::IrregularVerb.new }
|
39
|
+
|
40
|
+
let(:sample_lexeme) { double('other-as-adjective') }
|
41
|
+
let(:sample_entry) { LexicalEntry.new('other', sample_lexeme) }
|
42
|
+
let(:other_lexeme) { double('other-as-pronoun') }
|
43
|
+
let(:similar_entry) { LexicalEntry.new('other', other_lexeme) }
|
44
|
+
let(:verb_lexeme) { double('hope-as-verb') }
|
45
|
+
let(:distinct_entry) {LexicalEntry.new('hope', verb_lexeme) }
|
46
|
+
subject { Lexicon.new }
|
47
|
+
|
48
|
+
context 'Initialization:' do
|
49
|
+
it 'should be initialized without parameter' do
|
50
|
+
expect { Lexicon.new }.not_to raise_error
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should have no registered terminals at initialization' do
|
54
|
+
expect(subject.terminals).to be_empty
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should have no entry at initialization' do
|
58
|
+
expect(subject.entries).to be_empty
|
59
|
+
expect(subject.lemma2entry).to be_empty
|
60
|
+
end
|
61
|
+
end # context
|
62
|
+
|
63
|
+
context 'Provided services:' do
|
64
|
+
it 'should accept the addition of terminals' do
|
65
|
+
terminal1 = proper_noun
|
66
|
+
terminal2 = irregular_verb
|
67
|
+
terminal3 = adjective
|
68
|
+
|
69
|
+
subject.add_terminal(terminal1)
|
70
|
+
expect(subject.terminals).to eq([terminal1])
|
71
|
+
subject.add_terminal(terminal2)
|
72
|
+
expect(subject.terminals).to eq([terminal1, terminal2])
|
73
|
+
subject.add_terminal(terminal3)
|
74
|
+
expect(subject.terminals).to eq([terminal1, terminal2, terminal3])
|
75
|
+
expect(subject.name2terminal['ProperNoun']).to eq(terminal1)
|
76
|
+
expect(subject.name2terminal['IrregularVerb']).to eq(terminal2)
|
77
|
+
expect(subject.name2terminal['Adjective']).to eq(terminal3)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should accept the addition of entries' do
|
81
|
+
subject.add_entry(sample_entry)
|
82
|
+
expect(subject.entries).to eq([sample_entry])
|
83
|
+
expect(subject.lemma2entry['other']).to eq(sample_entry)
|
84
|
+
|
85
|
+
# Add dissimilar entry
|
86
|
+
subject.add_entry(distinct_entry)
|
87
|
+
expect(subject.entries).to eq([sample_entry, distinct_entry])
|
88
|
+
expect(subject.lemma2entry['hope']).to eq(distinct_entry)
|
89
|
+
|
90
|
+
# Add "homonym" entry
|
91
|
+
subject.add_entry(similar_entry)
|
92
|
+
expect(subject.entries).to eq([sample_entry, distinct_entry, similar_entry])
|
93
|
+
expect(subject.lemma2entry['other']).to eq([sample_entry, similar_entry])
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should complain when retrieving an non-existing entry' do
|
97
|
+
subject.add_entry(sample_entry)
|
98
|
+
err_msg = 'key not found: "hapax"'
|
99
|
+
expect { subject.get_lexeme('hapax') }.to raise_error(KeyError, err_msg)
|
100
|
+
end
|
101
|
+
end # context
|
102
|
+
end # describe
|
103
|
+
end # module
|
104
|
+
end # module
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../../lib/zenlish/wclasses/all_word_classes'
|
5
|
+
require_relative '../../../lib/zenlish/lex/lexical_entry'
|
6
|
+
require_relative '../../../lib/zenlish/lex/lexeme'
|
7
|
+
require_relative '../../../lib/zenlish/lex/literal' # Load the class under test
|
8
|
+
|
9
|
+
module Zenlish
|
10
|
+
module Lex
|
11
|
+
describe Lexeme do
|
12
|
+
let(:sample_wclass) { WClasses::CommonNoun.new }
|
13
|
+
let(:sample_lemma) { 'thing' }
|
14
|
+
let(:sample_entry) { LexicalEntry.new(sample_lemma) }
|
15
|
+
let(:sample_position) { double('position') }
|
16
|
+
let(:sample_lexeme) { Lexeme.new(sample_wclass, sample_entry) }
|
17
|
+
|
18
|
+
subject { Literal.new('things', sample_lexeme, sample_position) }
|
19
|
+
|
20
|
+
context 'Initialization:' do
|
21
|
+
it 'should be initialized with a string, a lexeme and a position' do
|
22
|
+
expect { Literal.new('things', sample_lexeme, sample_position) }.not_to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
# it 'should know its word class' do
|
26
|
+
# expect(subject.wclass).to eq(sample_wclass)
|
27
|
+
# end
|
28
|
+
|
29
|
+
# it 'should know its lexical entry' do
|
30
|
+
# expect(subject.entry).to eq(sample_entry)
|
31
|
+
# end
|
32
|
+
end # context
|
33
|
+
|
34
|
+
context 'Provided services:' do
|
35
|
+
# it 'should know its lemma' do
|
36
|
+
# expect(subject.lemma).to eq(sample_lemma)
|
37
|
+
# end
|
38
|
+
end # context
|
39
|
+
end # describe
|
40
|
+
end # module
|
41
|
+
end # module
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../../../lib/zenlish/parser/zenlish_grammar' # Load the class under test
|
5
|
+
|
6
|
+
module Zenlish
|
7
|
+
module Parser
|
8
|
+
describe ZenlishGrammar do
|
9
|
+
subject { ZenlishGrammar }
|
10
|
+
|
11
|
+
context 'Initialization:' do
|
12
|
+
it 'should know its terminal symbols' do
|
13
|
+
expect { subject.name2symbol['CommonNoun'] }.not_to raise_error
|
14
|
+
end
|
15
|
+
end # context
|
16
|
+
|
17
|
+
context 'Provided services:' do
|
18
|
+
end # context
|
19
|
+
end # describe
|
20
|
+
end # module
|
21
|
+
end # module
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../spec_helper' # Use the RSpec framework
|
4
|
+
require_relative '../support/minimal_lexicon'
|
5
|
+
require_relative '../../../lib/zenlish/lex/literal'
|
6
|
+
require_relative '../../../lib/zenlish/parser/zparser' # Load the class under test
|
7
|
+
|
8
|
+
module Zenlish
|
9
|
+
module Parser
|
10
|
+
describe ZParser do
|
11
|
+
subject { ZParser.new }
|
12
|
+
|
13
|
+
context 'Initialization:' do
|
14
|
+
it 'should be initialized without argument' do
|
15
|
+
expect { ZParser.new }.not_to raise_error
|
16
|
+
end
|
17
|
+
end # context
|
18
|
+
|
19
|
+
context 'Provided services:' do
|
20
|
+
def get_lexeme(aLemma)
|
21
|
+
$ZenlishLexicon.get_lexeme(aLemma)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:tony) do
|
25
|
+
Lex::Literal.new('Tony', $ZenlishLexicon.get_lexeme('Tony'), 0)
|
26
|
+
end
|
27
|
+
let(:lisa) do
|
28
|
+
Lex::Literal.new('Lisa', $ZenlishLexicon.get_lexeme('Lisa'), 0)
|
29
|
+
end
|
30
|
+
let(:the) do
|
31
|
+
Lex::Literal.new('the', $ZenlishLexicon.get_lexeme('the'), 0)
|
32
|
+
end
|
33
|
+
let(:other) do
|
34
|
+
Lex::Literal.new('other', $ZenlishLexicon.get_lexeme('other'), 0)
|
35
|
+
end
|
36
|
+
let(:sees) do
|
37
|
+
Lex::Literal.new('sees', $ZenlishLexicon.get_lexeme('see'), 0)
|
38
|
+
end
|
39
|
+
let(:dot) do
|
40
|
+
Lex::Literal.new('.', $ZenlishLexicon.get_lexeme('.'), 0)
|
41
|
+
end
|
42
|
+
let(:something) do
|
43
|
+
Lex::Literal.new('something', $ZenlishLexicon.get_lexeme('something'), 0)
|
44
|
+
end
|
45
|
+
let(:thing) do
|
46
|
+
Lex::Literal.new('thing', $ZenlishLexicon.get_lexeme('thing'), 0)
|
47
|
+
end
|
48
|
+
let(:this) do
|
49
|
+
Lex::Literal.new('this', $ZenlishLexicon.get_lexeme('this'), 0)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should parse sample sentence 1-01' do
|
53
|
+
# Sentence is: "Tony sees Lisa."
|
54
|
+
# in absence of a tokenizer, we create a sequence of literals by hand...
|
55
|
+
literals = [tony, sees, lisa, dot]
|
56
|
+
expect { subject.parse(literals) }.not_to raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should parse sample sentence 1-02a' do
|
60
|
+
# Sentence is: "Tony sees something."
|
61
|
+
sentence_literals = [tony, sees, something, dot]
|
62
|
+
expect { subject.parse(sentence_literals) }.not_to raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should parse sample sentence 1-02b' do
|
66
|
+
# Sentence is: "Lisa sees something"
|
67
|
+
sentence_literals = [lisa, sees, something, dot]
|
68
|
+
expect { subject.parse(sentence_literals) }.not_to raise_error
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should parse sample sentence 1-03' do
|
72
|
+
# Sentence is: "Tony sees this thing."
|
73
|
+
sentence_literals = [tony, sees, this, thing, dot]
|
74
|
+
expect { subject.parse(sentence_literals) }.not_to raise_error
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should parse sample sentence 1-04' do
|
78
|
+
# Sentence is: "Lisa sees the other thing."
|
79
|
+
sentence_literals = [lisa, sees, the, other, thing, dot]
|
80
|
+
expect { subject.parse(sentence_literals) }.not_to raise_error
|
81
|
+
end
|
82
|
+
end # context
|
83
|
+
end # describe
|
84
|
+
end # module
|
85
|
+
end # module
|
86
|
+
|