zenlish 0.1.25 → 0.2.00
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -1
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/lib/zenlish/feature/boolean_domain.rb +29 -0
- data/lib/zenlish/feature/boolean_value.rb +9 -0
- data/lib/zenlish/feature/enumeration_domain.rb +32 -0
- data/lib/zenlish/feature/feature.rb +30 -0
- data/lib/zenlish/feature/feature_def.rb +48 -0
- data/lib/zenlish/feature/feature_domain.rb +9 -0
- data/lib/zenlish/feature/feature_struct.rb +24 -0
- data/lib/zenlish/feature/feature_struct_def.rb +44 -0
- data/lib/zenlish/feature/feature_struct_def_bearer.rb +65 -0
- data/lib/zenlish/feature/feature_value.rb +17 -0
- data/lib/zenlish/feature/identifier_domain.rb +29 -0
- data/lib/zenlish/feature/identifier_value.rb +9 -0
- data/lib/zenlish/feature/symbol_value.rb +8 -0
- data/lib/zenlish/inflect/atomic_o_expression.rb +9 -0
- data/lib/zenlish/inflect/composite_o_expression.rb +14 -0
- data/lib/zenlish/inflect/concatenation.rb +36 -0
- data/lib/zenlish/inflect/equals_literal.rb +25 -0
- data/lib/zenlish/inflect/feature_heading.rb +16 -0
- data/lib/zenlish/inflect/formal_argument.rb +11 -0
- data/lib/zenlish/inflect/heading.rb +11 -0
- data/lib/zenlish/inflect/inflection_rule.rb +28 -0
- data/lib/zenlish/inflect/inflection_table.rb +46 -0
- data/lib/zenlish/inflect/inflection_table_builder.rb +120 -0
- data/lib/zenlish/inflect/input_asis.rb +22 -0
- data/lib/zenlish/inflect/input_expression.rb +9 -0
- data/lib/zenlish/inflect/literal_asis.rb +17 -0
- data/lib/zenlish/inflect/matches_pattern.rb +26 -0
- data/lib/zenlish/inflect/method_heading.rb +16 -0
- data/lib/zenlish/inflect/nullary_input_expression.rb +8 -0
- data/lib/zenlish/inflect/output_expression.rb +6 -0
- data/lib/zenlish/inflect/substitution.rb +65 -0
- data/lib/zenlish/inflect/unary_input_expression.rb +13 -0
- data/lib/zenlish/inflect/unconditionally_true.rb +11 -0
- data/lib/zenlish/lang/dictionary.rb +19 -6
- data/lib/zenlish/lang/zenlish_grammar.rb +1 -0
- data/lib/zenlish/lex/empty_lexicon_factory.rb +3 -0
- data/lib/zenlish/lex/lexeme.rb +27 -4
- data/lib/zenlish/lex/lexicon.rb +3 -0
- data/lib/zenlish/lex/literal.rb +5 -1
- data/lib/zenlish/version.rb +1 -1
- data/lib/zenlish/wclasses/common_noun.rb +45 -0
- data/lib/zenlish/wclasses/noun.rb +21 -0
- data/lib/zenlish/wclasses/preposition.rb +5 -0
- data/lib/zenlish/wclasses/proper_noun.rb +11 -0
- data/lib/zenlish/wclasses/verb.rb +9 -1
- data/lib/zenlish/wclasses/word_class.rb +21 -6
- data/spec/spec_helper.rb +2 -3
- data/spec/zenlish/feature/boolean_domain_spec.rb +35 -0
- data/spec/zenlish/feature/boolean_value_spec.rb +26 -0
- data/spec/zenlish/feature/enumeration_domain_spec.rb +42 -0
- data/spec/zenlish/feature/feature_def_spec.rb +50 -0
- data/spec/zenlish/feature/feature_spec.rb +51 -0
- data/spec/zenlish/feature/feature_struct_def_bearer_spec.rb +54 -0
- data/spec/zenlish/feature/feature_struct_def_spec.rb +69 -0
- data/spec/zenlish/feature/identifier_domain_spec.rb +36 -0
- data/spec/zenlish/feature/identifier_value_spec.rb +26 -0
- data/spec/zenlish/feature/symbol_value_spec.rb +27 -0
- data/spec/zenlish/inflect/concatenation_spec.rb +40 -0
- data/spec/zenlish/inflect/equals_literal_spec.rb +58 -0
- data/spec/zenlish/inflect/feature_heading_spec.rb +30 -0
- data/spec/zenlish/inflect/formal_argument_spec.rb +25 -0
- data/spec/zenlish/inflect/inflection_rule_spec.rb +102 -0
- data/spec/zenlish/inflect/inflection_table_builder_spec.rb +127 -0
- data/spec/zenlish/inflect/inflection_table_spec.rb +129 -0
- data/spec/zenlish/inflect/input_asis_spec.rb +50 -0
- data/spec/zenlish/inflect/literal_asis_spec.rb +31 -0
- data/spec/zenlish/inflect/matches_pattern_spec.rb +61 -0
- data/spec/zenlish/inflect/method_heading_spec.rb +31 -0
- data/spec/zenlish/inflect/substitution_spec.rb +43 -0
- data/spec/zenlish/inflect/unconditionally_true_spec.rb +28 -0
- data/spec/zenlish/lang/dictionary_spec.rb +33 -0
- data/spec/zenlish/lex/lexeme_spec.rb +24 -9
- data/spec/zenlish/lex/literal_spec.rb +3 -11
- data/spec/zenlish/parser/lesson3_spec.rb +44 -0
- data/spec/zenlish/support/minimal_lexicon.rb +0 -2
- data/spec/zenlish/support/var2word.rb +5 -1
- data/spec/zenlish/wclasses/common_noun_spec.rb +25 -4
- data/spec/zenlish/wclasses/noun_spec.rb +31 -0
- data/spec/zenlish/wclasses/preposition_spec.rb +24 -0
- data/spec/zenlish/wclasses/verb_spec.rb +24 -0
- metadata +89 -2
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative 'feature_heading'
|
2
|
+
require_relative 'method_heading'
|
3
|
+
require_relative 'formal_argument'
|
4
|
+
require_relative 'equals_literal'
|
5
|
+
require_relative 'unconditionally_true'
|
6
|
+
require_relative 'matches_pattern'
|
7
|
+
require_relative 'input_asis'
|
8
|
+
require_relative 'concatenation'
|
9
|
+
require_relative 'substitution'
|
10
|
+
require_relative 'inflection_rule'
|
11
|
+
require_relative 'inflection_table'
|
12
|
+
|
13
|
+
# DecisionTable: Common_form
|
14
|
+
# | NUMBER | .base_form | Common_form |
|
15
|
+
# | singular | X | base_form |
|
16
|
+
# | plural | ~ /[^aeiouy]y$/ | sub(base_form, /y$/, "ies")|
|
17
|
+
# | plural | X | base_form + "s" |
|
18
|
+
# build('Common_form') do
|
19
|
+
# feature_heading 'NUMBER'
|
20
|
+
# method_heading 'base_form'
|
21
|
+
# | NUMBER | base_form | Common_form |
|
22
|
+
# rule [equals(:singular), dont_care ], col('base_form')
|
23
|
+
# rule [equals(:plural) , matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies')
|
24
|
+
# rule [equals(:plural) , dont_care ], concat(col('base_form'), 's')
|
25
|
+
# end
|
26
|
+
|
27
|
+
module Zenlish
|
28
|
+
module Inflect
|
29
|
+
class InflectionTableBuilder
|
30
|
+
# Name of decision table
|
31
|
+
attr_reader :table
|
32
|
+
attr_reader :headings
|
33
|
+
attr_reader :conds
|
34
|
+
attr_reader :rules
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
reset
|
38
|
+
end
|
39
|
+
|
40
|
+
def build(aTableName, &aBlock)
|
41
|
+
reset
|
42
|
+
@table = InflectionTable.new(aTableName)
|
43
|
+
instance_exec(&aBlock) if block_given?
|
44
|
+
@table
|
45
|
+
end
|
46
|
+
|
47
|
+
def feature_heading(aFeatureName)
|
48
|
+
hd = FeatureHeading.new(aFeatureName)
|
49
|
+
headings << hd
|
50
|
+
table.add_heading(hd) if table
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_heading(aMethodName)
|
54
|
+
hd = MethodHeading.new(aMethodName)
|
55
|
+
headings << hd
|
56
|
+
table.add_heading(hd) if table
|
57
|
+
end
|
58
|
+
|
59
|
+
def rule(conditions, consequent)
|
60
|
+
@conds = []
|
61
|
+
rl = InflectionRule.new(conditions.dup, consequent)
|
62
|
+
rules << rl
|
63
|
+
table.add_rule(rl) if table
|
64
|
+
|
65
|
+
rl
|
66
|
+
end
|
67
|
+
|
68
|
+
def equals(aValue)
|
69
|
+
arg = FormalArgument.new(conds.size)
|
70
|
+
equality_cond = EqualsLiteral.new(arg, aValue)
|
71
|
+
conds << equality_cond
|
72
|
+
|
73
|
+
equality_cond
|
74
|
+
end
|
75
|
+
|
76
|
+
def dont_care
|
77
|
+
item = UnconditionallyTrue.new
|
78
|
+
conds << item
|
79
|
+
|
80
|
+
item
|
81
|
+
end
|
82
|
+
|
83
|
+
def col(aColName)
|
84
|
+
col_index = headings.find_index { |hd| hd.label == aColName }
|
85
|
+
err_msg = "Cannot find heading named '#{aColName}'."
|
86
|
+
raise StandardError, err_msg if col_index.nil?
|
87
|
+
formal = FormalArgument.new(col_index)
|
88
|
+
InputAsIs.new(formal)
|
89
|
+
end
|
90
|
+
|
91
|
+
def matches(aPattern)
|
92
|
+
arg = FormalArgument.new(conds.size)
|
93
|
+
match_cond = MatchesPattern.new(arg, aPattern)
|
94
|
+
conds << match_cond
|
95
|
+
match_cond
|
96
|
+
end
|
97
|
+
|
98
|
+
def sub(original, pattern, replacement)
|
99
|
+
Substitution.new(original, pattern, replacement)
|
100
|
+
end
|
101
|
+
|
102
|
+
def concat(arg1, arg2)
|
103
|
+
Concatenation.new(arg1, arg2)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def reset()
|
109
|
+
@table = nil
|
110
|
+
@headings = []
|
111
|
+
@conds = []
|
112
|
+
@rules = []
|
113
|
+
end
|
114
|
+
|
115
|
+
# def do_it
|
116
|
+
# @headings
|
117
|
+
# end
|
118
|
+
end # class
|
119
|
+
end # module
|
120
|
+
end # module
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative 'atomic_o_expression'
|
2
|
+
|
3
|
+
module Zenlish
|
4
|
+
module Inflect
|
5
|
+
class InputAsIs < AtomicOExpression
|
6
|
+
attr_reader :formal
|
7
|
+
|
8
|
+
def initialize(anArgument)
|
9
|
+
@formal = anArgument
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate(headings, lexeme, actuals)
|
13
|
+
if actuals.empty?
|
14
|
+
hd = headings[formal.index]
|
15
|
+
hd.evaluate_for(lexeme)
|
16
|
+
else
|
17
|
+
actuals[formal.index]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end # class
|
21
|
+
end # module
|
22
|
+
end # module
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'atomic_o_expression'
|
2
|
+
|
3
|
+
module Zenlish
|
4
|
+
module Inflect
|
5
|
+
class LiteralAsIs < AtomicOExpression
|
6
|
+
attr_reader :text
|
7
|
+
|
8
|
+
def initialize(aLiteralValue)
|
9
|
+
@text = aLiteralValue
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate(_headings, _lexeme, _values)
|
13
|
+
text
|
14
|
+
end
|
15
|
+
end # class
|
16
|
+
end # module
|
17
|
+
end # module
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'unary_input_expression'
|
2
|
+
|
3
|
+
module Zenlish
|
4
|
+
module Inflect
|
5
|
+
class MatchesPattern < UnaryInputExpression
|
6
|
+
attr_reader :pattern
|
7
|
+
|
8
|
+
def initialize(anArgument, aPattern)
|
9
|
+
super(anArgument)
|
10
|
+
@pattern = aPattern
|
11
|
+
end
|
12
|
+
|
13
|
+
def success?(headings, lexeme, actuals)
|
14
|
+
val = nil
|
15
|
+
if actuals.empty?
|
16
|
+
# require 'debug'
|
17
|
+
hd = headings[argument.index]
|
18
|
+
val = hd.evaluate_for(lexeme)
|
19
|
+
else
|
20
|
+
val = actuals[argument.index]
|
21
|
+
end
|
22
|
+
val =~ pattern
|
23
|
+
end
|
24
|
+
end # class
|
25
|
+
end # module
|
26
|
+
end # module
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'heading'
|
2
|
+
|
3
|
+
module Zenlish
|
4
|
+
module Inflect
|
5
|
+
class MethodHeading < Heading
|
6
|
+
|
7
|
+
def initialize(aLabel)
|
8
|
+
super(aLabel)
|
9
|
+
end
|
10
|
+
|
11
|
+
def evaluate_for(aFeatureBearer)
|
12
|
+
aFeatureBearer.send(label)
|
13
|
+
end
|
14
|
+
end # class
|
15
|
+
end # module
|
16
|
+
end # module
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require_relative 'literal_asis'
|
2
|
+
require_relative 'composite_o_expression'
|
3
|
+
|
4
|
+
module Zenlish
|
5
|
+
module Inflect
|
6
|
+
class Substitution < CompositeOExpression
|
7
|
+
def initialize(theOriginal, aPattern, theReplacement)
|
8
|
+
valid_original = validated_argument(theOriginal)
|
9
|
+
valid_pattern = validated_pattern(aPattern)
|
10
|
+
valid_replac = validated_argument(theReplacement)
|
11
|
+
super([valid_original, valid_pattern, valid_replac])
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate(headings, lexeme, values)
|
15
|
+
original = children[0].generate(headings, lexeme, values)
|
16
|
+
replacement = children[-1].generate(headings, lexeme, values)
|
17
|
+
|
18
|
+
original.sub(pattern, replacement)
|
19
|
+
end
|
20
|
+
|
21
|
+
def pattern
|
22
|
+
children[1]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def validated_original(theOriginal)
|
28
|
+
arg = nil
|
29
|
+
if theOriginal.kind_of?(String)
|
30
|
+
arg = LiteralAsIs.new(theOriginal)
|
31
|
+
elsif theOriginal.kind_of?(OutputExpression)
|
32
|
+
arg = theOriginal
|
33
|
+
else
|
34
|
+
err_msg = "Expected an OutputExpression, found '#{theOriginal.inspect}' instead."
|
35
|
+
raise StandardError, err_msg
|
36
|
+
end
|
37
|
+
|
38
|
+
arg
|
39
|
+
end
|
40
|
+
|
41
|
+
def validated_pattern(aPattern)
|
42
|
+
unless aPattern.kind_of?(Regexp)
|
43
|
+
err_msg = "Expected a Regexp, found #{aPattern.inspect}."
|
44
|
+
raise StandardError, err_msg
|
45
|
+
end
|
46
|
+
|
47
|
+
aPattern
|
48
|
+
end
|
49
|
+
|
50
|
+
def validated_argument(anArgument)
|
51
|
+
arg = nil
|
52
|
+
if anArgument.kind_of?(String)
|
53
|
+
arg = LiteralAsIs.new(anArgument)
|
54
|
+
elsif anArgument.kind_of?(OutputExpression)
|
55
|
+
arg = anArgument
|
56
|
+
else
|
57
|
+
err_msg = "Expected an OutputExpression, found #{anArgument.inspect}."
|
58
|
+
raise StandardError, err_msg
|
59
|
+
end
|
60
|
+
|
61
|
+
arg
|
62
|
+
end
|
63
|
+
end # class
|
64
|
+
end # module
|
65
|
+
end # module
|
@@ -1,4 +1,5 @@
|
|
1
1
|
unless defined?(Zenlish::Lang::Dictionary)
|
2
|
+
require_relative '../feature/feature_struct_def_bearer'
|
2
3
|
module Zenlish
|
3
4
|
module Lang
|
4
5
|
require_relative '../lex/empty_lexicon_factory'
|
@@ -8,12 +9,16 @@ unless defined?(Zenlish::Lang::Dictionary)
|
|
8
9
|
sandbox = Object.new
|
9
10
|
sandbox.extend(Zenlish::Lex::EmptyLexiconFactory)
|
10
11
|
Dictionary = sandbox.create_empty_lexicon
|
12
|
+
self.extend(Feature::FeatureStructDefBearer)
|
11
13
|
|
12
|
-
|
14
|
+
# @param aLemma [String] is the canonical form, dictionary form,
|
15
|
+
# or citation form of a headword.
|
16
|
+
# @param aWClassName [String] the name of a word class.
|
17
|
+
def self.add_entry(aLemma, aWClassName, aFeatureHash = nil)
|
13
18
|
entry = Zenlish::Lex::LexicalEntry.new(aLemma)
|
14
19
|
wclass = Dictionary.name2terminal[aWClassName]
|
15
20
|
raise StandardError, "Undefined word class for '#{aLemma}'" unless wclass
|
16
|
-
lexeme = Zenlish::Lex::Lexeme.new(wclass, entry).freeze
|
21
|
+
lexeme = Zenlish::Lex::Lexeme.new(wclass, entry, aFeatureHash).freeze
|
17
22
|
Dictionary.add_entry(entry.freeze)
|
18
23
|
end
|
19
24
|
|
@@ -47,6 +52,7 @@ unless defined?(Zenlish::Lang::Dictionary)
|
|
47
52
|
add_entry('big', 'Adjective')
|
48
53
|
add_entry('body', 'CommonNoun')
|
49
54
|
add_entry('but', 'Coordinator')
|
55
|
+
add_entry('can', 'IrregularVerb')
|
50
56
|
add_entry('can', 'ModalVerbCan')
|
51
57
|
add_entry('cause', 'RegularVerb')
|
52
58
|
add_entry('change', 'RegularVerb')
|
@@ -54,7 +60,9 @@ unless defined?(Zenlish::Lang::Dictionary)
|
|
54
60
|
add_entry('contain', 'RegularVerb')
|
55
61
|
add_entry('container', 'CommonNoun')
|
56
62
|
add_entry('could', 'ModalVerbCould')
|
63
|
+
add_entry('damage', 'RegularVerb')
|
57
64
|
add_entry('die', 'RegularVerb')
|
65
|
+
add_entry('difficult', 'Adjective')
|
58
66
|
add_entry('different', 'Adjective')
|
59
67
|
add_entry('do', 'AuxiliaryDo')
|
60
68
|
add_entry('do', 'IrregularVerbDo')
|
@@ -72,7 +80,9 @@ unless defined?(Zenlish::Lang::Dictionary)
|
|
72
80
|
add_entry('happen', 'RegularVerb')
|
73
81
|
add_entry('hear', 'IrregularLinkingVerb')
|
74
82
|
add_entry('here', 'Adverb')
|
75
|
-
|
83
|
+
# example: ...from here (works as a pronoun of a place)
|
84
|
+
add_entry('here', 'CommonNoun', {'NUMBER' => enumeration(:singular),
|
85
|
+
'PARADIGM' => [identifier, 'Singular_only']})
|
76
86
|
add_entry('I', 'PersonalPronoun')
|
77
87
|
add_entry('if', 'SubordinatingConjunction')
|
78
88
|
add_entry('in', 'Preposition')
|
@@ -99,7 +109,8 @@ unless defined?(Zenlish::Lang::Dictionary)
|
|
99
109
|
add_entry('near', 'Preposition')
|
100
110
|
add_entry('near to', 'Preposition')
|
101
111
|
add_entry('now', 'Adverb')
|
102
|
-
add_entry('now', 'CommonNoun')
|
112
|
+
add_entry('now', 'CommonNoun', {'NUMBER' => enumeration(:singular),
|
113
|
+
'PARADIGM' => [identifier, 'Singular_only']})
|
103
114
|
add_entry('not', 'AdverbNot')
|
104
115
|
add_entry('of', 'PrepositionOf')
|
105
116
|
add_entry('on', 'Preposition')
|
@@ -109,8 +120,10 @@ unless defined?(Zenlish::Lang::Dictionary)
|
|
109
120
|
add_entry('or', 'Coordinator')
|
110
121
|
add_entry('other', 'Adjective')
|
111
122
|
add_entry('part', 'CommonNoun')
|
112
|
-
add_entry('people', 'CommonNoun')
|
113
|
-
|
123
|
+
add_entry('people', 'CommonNoun', {'NUMBER' => enumeration(:plural),
|
124
|
+
'PARADIGM' => [identifier, 'Plural_only']})
|
125
|
+
add_entry('person', 'CommonNoun', {'NUMBER' => enumeration(:singular),
|
126
|
+
'PARADIGM' => [identifier, 'Singular_only']})
|
114
127
|
add_entry('place', 'CommonNoun')
|
115
128
|
add_entry('same', 'Adjective')
|
116
129
|
add_entry('same', 'Pronoun')
|
@@ -4,6 +4,9 @@ require_relative 'lexicon'
|
|
4
4
|
module Zenlish
|
5
5
|
module Lex
|
6
6
|
module EmptyLexiconFactory
|
7
|
+
# Factory method. Helps in creating an "empty" lexicon.
|
8
|
+
# It just contains the word classes of Zenlish but no headwords.
|
9
|
+
# @return [Lexicon] the created lexicon object
|
7
10
|
def create_empty_lexicon()
|
8
11
|
lexicon = Lexicon.new
|
9
12
|
|
data/lib/zenlish/lex/lexeme.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative '../feature/feature_struct_def_bearer'
|
1
2
|
module Zenlish
|
2
3
|
module Lex
|
3
4
|
# A word in the abstract sense; an individual, distinct item of a lexicon
|
@@ -5,23 +6,45 @@ module Zenlish
|
|
5
6
|
# may exist. For instance, the word forms: 'hide', 'hides', 'hid', 'hidden'
|
6
7
|
# relate to the lexeme for verb 'hide'. Also called 'dictionary word'.
|
7
8
|
class Lexeme
|
8
|
-
|
9
|
+
include Feature::FeatureStructDefBearer
|
10
|
+
|
11
|
+
# @return [Zenlish::WClasses::WordClass]
|
9
12
|
attr_reader :wclass
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
# @param aWClass [WClasses::WordClass, Rley::Syntax::Terminal]
|
15
|
+
# @param anEntry [Zenlish::LexicalEntry]
|
16
|
+
# @param aFeatureHash [Hash, NilClass]
|
17
|
+
def initialize(aWClass, anEntry, aFeatureHash = nil)
|
18
|
+
@wclass = aWClass
|
13
19
|
@entry = anEntry.object_id
|
14
20
|
anEntry.add_lexeme(self)
|
21
|
+
|
22
|
+
p_struct = aWClass.kind_of?(WClasses::WordClass) ? aWClass.struct : nil
|
23
|
+
overriding_struct_defs = aFeatureHash.nil? ? {} : aFeatureHash
|
24
|
+
init_struct_def(p_struct, overriding_struct_defs)
|
15
25
|
end
|
16
26
|
|
17
|
-
# @return Zenlish::Lex::LexicalEntry
|
27
|
+
# @return [Zenlish::Lex::LexicalEntry]
|
18
28
|
def entry
|
19
29
|
ObjectSpace._id2ref(@entry)
|
20
30
|
end
|
31
|
+
|
32
|
+
def inflect(constraints)
|
33
|
+
table = paradigm
|
34
|
+
table.inflect(self, constraints)
|
35
|
+
end
|
21
36
|
|
37
|
+
# @return [String]
|
22
38
|
def lemma
|
23
39
|
entry.lemma
|
24
40
|
end
|
41
|
+
|
42
|
+
def paradigm
|
43
|
+
paradigm_feat_def = self['PARADIGM']
|
44
|
+
wclass.paradigms[paradigm_feat_def.default.val]
|
45
|
+
end
|
46
|
+
|
47
|
+
alias base_form lemma
|
25
48
|
end # class
|
26
49
|
end # module
|
27
50
|
end # module
|
data/lib/zenlish/lex/lexicon.rb
CHANGED
@@ -3,6 +3,7 @@ module Zenlish
|
|
3
3
|
# A lexicon is a collection of lexical entries.
|
4
4
|
# Every entry is associated with one one more lexemes.
|
5
5
|
class Lexicon
|
6
|
+
# @return [Array<Lex::LexicalEntry>] entries in the lexicon
|
6
7
|
attr_reader :entries
|
7
8
|
attr_reader :lemma2entry
|
8
9
|
|
@@ -20,6 +21,8 @@ module Zenlish
|
|
20
21
|
end
|
21
22
|
|
22
23
|
# @param aLemma[String] retrieve the lexeme form the given "head word".
|
24
|
+
# @param aWordClass [WordClasses::WordClass, NilClass] the word class of
|
25
|
+
# the lexeme.
|
23
26
|
def get_lexeme(aLemma, aWordClass = nil)
|
24
27
|
if aWordClass
|
25
28
|
lexeme = nil
|
data/lib/zenlish/lex/literal.rb
CHANGED
@@ -2,11 +2,15 @@ require 'rley'
|
|
2
2
|
|
3
3
|
module Zenlish
|
4
4
|
module Lex
|
5
|
-
#
|
5
|
+
# An occurrence of a grammar terminal symbol that occurs in the input text.
|
6
6
|
class Literal < Rley::Lexical::Token
|
7
7
|
attr_reader :zlexeme
|
8
8
|
|
9
9
|
# initialize(theLexeme, aTerminal, aPosition) ⇒ Token
|
10
|
+
# @param literalText [String] the portion of input text that represents
|
11
|
+
# an occurence of the lexeme.
|
12
|
+
# @param aLexeme [Lex::Lexeme] the lexeme matched by the literal text.
|
13
|
+
# @param aPosition [Integer] the position of the literal in the input.
|
10
14
|
def initialize(literalText, aLexeme, aPosition)
|
11
15
|
super(literalText, aLexeme.wclass.name, aPosition)
|
12
16
|
@zlexeme = aLexeme
|
data/lib/zenlish/version.rb
CHANGED
@@ -1,9 +1,54 @@
|
|
1
1
|
require_relative 'noun'
|
2
|
+
require_relative '../inflect/inflection_table_builder'
|
2
3
|
|
3
4
|
module Zenlish
|
4
5
|
module WClasses
|
5
6
|
# Common nouns refer to general entities. Most have a singular and plural form.
|
6
7
|
class CommonNoun < Noun
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@paradigms = {}
|
11
|
+
init_paradigms
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Inflection::InflectionTable] Return default paradigm
|
15
|
+
def paradigm
|
16
|
+
paradigm_feat_def = self['PARADIGM']
|
17
|
+
paradigms[paradigm_feat_def.default.val]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def init_paradigms
|
23
|
+
builder = Inflect::InflectionTableBuilder.new
|
24
|
+
|
25
|
+
table = builder.build('Common_form') do
|
26
|
+
feature_heading 'NUMBER'
|
27
|
+
method_heading 'base_form'
|
28
|
+
rule([equals(:singular), dont_care], col('base_form'))
|
29
|
+
rule([equals(:plural), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
|
30
|
+
rule([equals(:plural), dont_care], concat(col('base_form'), 's'))
|
31
|
+
end
|
32
|
+
add_paradigm(table)
|
33
|
+
|
34
|
+
table = builder.build('Plural_only') do
|
35
|
+
feature_heading 'NUMBER'
|
36
|
+
method_heading 'base_form'
|
37
|
+
rule([equals(:plural), dont_care], col('base_form'))
|
38
|
+
end
|
39
|
+
add_paradigm(table)
|
40
|
+
|
41
|
+
table = builder.build('Singular_only') do
|
42
|
+
feature_heading 'NUMBER'
|
43
|
+
method_heading 'base_form'
|
44
|
+
rule([equals(:singular), dont_care], col('base_form'))
|
45
|
+
end
|
46
|
+
add_paradigm(table)
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_paradigm(anInflectionTable)
|
50
|
+
@paradigms[anInflectionTable.name] = anInflectionTable
|
51
|
+
end
|
7
52
|
end # class
|
8
53
|
end # module
|
9
54
|
end # module
|
@@ -6,6 +6,27 @@ module Zenlish
|
|
6
6
|
# Nouns denote people, animals, inanimate things, places, events, qualities
|
7
7
|
# and states.
|
8
8
|
class Noun < WordClass
|
9
|
+
def initialize
|
10
|
+
super()
|
11
|
+
init_feature_defs
|
12
|
+
end
|
13
|
+
|
14
|
+
# Nouns inflect according to number, possessive. Therefore they are
|
15
|
+
# variable.
|
16
|
+
def invariable?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def init_feature_defs
|
23
|
+
# Create standard feature definitions for nouns.
|
24
|
+
feature_def_dsl {
|
25
|
+
feature_def 'NUMBER' => enumeration(:singular, :plural)
|
26
|
+
feature_def 'COUNTABILITY' => enumeration(:count, :non_count)
|
27
|
+
feature_def 'PARADIGM' => [identifier, 'Common_form'] # 2nd item is default value
|
28
|
+
}
|
29
|
+
end
|
9
30
|
end # class
|
10
31
|
end # module
|
11
32
|
end # module
|
@@ -5,6 +5,17 @@ module Zenlish
|
|
5
5
|
# Proper nouns refer to persons, places, geographical features, planets, or various
|
6
6
|
# period of time.
|
7
7
|
class ProperNoun < Noun
|
8
|
+
def initialize
|
9
|
+
super()
|
10
|
+
init_feature_defs
|
11
|
+
end
|
12
|
+
|
13
|
+
def init_feature_defs
|
14
|
+
# Override standard feature definitions for proper nouns.
|
15
|
+
feature_def_dsl {
|
16
|
+
feature_def 'NUMBER' => enumeration(:singular)
|
17
|
+
}
|
18
|
+
end
|
8
19
|
end # class
|
9
20
|
end # module
|
10
21
|
end # module
|
@@ -2,8 +2,16 @@ require_relative 'word_class'
|
|
2
2
|
|
3
3
|
module Zenlish
|
4
4
|
module WClasses
|
5
|
-
#
|
5
|
+
# Abstract class. In traditional grammar, the verb is often defined
|
6
|
+
# notionally as a 'doing' word (i.e. a word that describes the action
|
7
|
+
# in a clause).
|
6
8
|
class Verb < WordClass
|
9
|
+
|
10
|
+
# As all verbs inflect, or change form, to reflect changes in tense,
|
11
|
+
# person, number, and voice, they are, by definition, variable.
|
12
|
+
def invariable?
|
13
|
+
false
|
14
|
+
end
|
7
15
|
end # class
|
8
16
|
end # module
|
9
17
|
end # module
|