zenlish 0.1.25 → 0.2.00

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.md +3 -3
  5. data/lib/zenlish/feature/boolean_domain.rb +29 -0
  6. data/lib/zenlish/feature/boolean_value.rb +9 -0
  7. data/lib/zenlish/feature/enumeration_domain.rb +32 -0
  8. data/lib/zenlish/feature/feature.rb +30 -0
  9. data/lib/zenlish/feature/feature_def.rb +48 -0
  10. data/lib/zenlish/feature/feature_domain.rb +9 -0
  11. data/lib/zenlish/feature/feature_struct.rb +24 -0
  12. data/lib/zenlish/feature/feature_struct_def.rb +44 -0
  13. data/lib/zenlish/feature/feature_struct_def_bearer.rb +65 -0
  14. data/lib/zenlish/feature/feature_value.rb +17 -0
  15. data/lib/zenlish/feature/identifier_domain.rb +29 -0
  16. data/lib/zenlish/feature/identifier_value.rb +9 -0
  17. data/lib/zenlish/feature/symbol_value.rb +8 -0
  18. data/lib/zenlish/inflect/atomic_o_expression.rb +9 -0
  19. data/lib/zenlish/inflect/composite_o_expression.rb +14 -0
  20. data/lib/zenlish/inflect/concatenation.rb +36 -0
  21. data/lib/zenlish/inflect/equals_literal.rb +25 -0
  22. data/lib/zenlish/inflect/feature_heading.rb +16 -0
  23. data/lib/zenlish/inflect/formal_argument.rb +11 -0
  24. data/lib/zenlish/inflect/heading.rb +11 -0
  25. data/lib/zenlish/inflect/inflection_rule.rb +28 -0
  26. data/lib/zenlish/inflect/inflection_table.rb +46 -0
  27. data/lib/zenlish/inflect/inflection_table_builder.rb +120 -0
  28. data/lib/zenlish/inflect/input_asis.rb +22 -0
  29. data/lib/zenlish/inflect/input_expression.rb +9 -0
  30. data/lib/zenlish/inflect/literal_asis.rb +17 -0
  31. data/lib/zenlish/inflect/matches_pattern.rb +26 -0
  32. data/lib/zenlish/inflect/method_heading.rb +16 -0
  33. data/lib/zenlish/inflect/nullary_input_expression.rb +8 -0
  34. data/lib/zenlish/inflect/output_expression.rb +6 -0
  35. data/lib/zenlish/inflect/substitution.rb +65 -0
  36. data/lib/zenlish/inflect/unary_input_expression.rb +13 -0
  37. data/lib/zenlish/inflect/unconditionally_true.rb +11 -0
  38. data/lib/zenlish/lang/dictionary.rb +19 -6
  39. data/lib/zenlish/lang/zenlish_grammar.rb +1 -0
  40. data/lib/zenlish/lex/empty_lexicon_factory.rb +3 -0
  41. data/lib/zenlish/lex/lexeme.rb +27 -4
  42. data/lib/zenlish/lex/lexicon.rb +3 -0
  43. data/lib/zenlish/lex/literal.rb +5 -1
  44. data/lib/zenlish/version.rb +1 -1
  45. data/lib/zenlish/wclasses/common_noun.rb +45 -0
  46. data/lib/zenlish/wclasses/noun.rb +21 -0
  47. data/lib/zenlish/wclasses/preposition.rb +5 -0
  48. data/lib/zenlish/wclasses/proper_noun.rb +11 -0
  49. data/lib/zenlish/wclasses/verb.rb +9 -1
  50. data/lib/zenlish/wclasses/word_class.rb +21 -6
  51. data/spec/spec_helper.rb +2 -3
  52. data/spec/zenlish/feature/boolean_domain_spec.rb +35 -0
  53. data/spec/zenlish/feature/boolean_value_spec.rb +26 -0
  54. data/spec/zenlish/feature/enumeration_domain_spec.rb +42 -0
  55. data/spec/zenlish/feature/feature_def_spec.rb +50 -0
  56. data/spec/zenlish/feature/feature_spec.rb +51 -0
  57. data/spec/zenlish/feature/feature_struct_def_bearer_spec.rb +54 -0
  58. data/spec/zenlish/feature/feature_struct_def_spec.rb +69 -0
  59. data/spec/zenlish/feature/identifier_domain_spec.rb +36 -0
  60. data/spec/zenlish/feature/identifier_value_spec.rb +26 -0
  61. data/spec/zenlish/feature/symbol_value_spec.rb +27 -0
  62. data/spec/zenlish/inflect/concatenation_spec.rb +40 -0
  63. data/spec/zenlish/inflect/equals_literal_spec.rb +58 -0
  64. data/spec/zenlish/inflect/feature_heading_spec.rb +30 -0
  65. data/spec/zenlish/inflect/formal_argument_spec.rb +25 -0
  66. data/spec/zenlish/inflect/inflection_rule_spec.rb +102 -0
  67. data/spec/zenlish/inflect/inflection_table_builder_spec.rb +127 -0
  68. data/spec/zenlish/inflect/inflection_table_spec.rb +129 -0
  69. data/spec/zenlish/inflect/input_asis_spec.rb +50 -0
  70. data/spec/zenlish/inflect/literal_asis_spec.rb +31 -0
  71. data/spec/zenlish/inflect/matches_pattern_spec.rb +61 -0
  72. data/spec/zenlish/inflect/method_heading_spec.rb +31 -0
  73. data/spec/zenlish/inflect/substitution_spec.rb +43 -0
  74. data/spec/zenlish/inflect/unconditionally_true_spec.rb +28 -0
  75. data/spec/zenlish/lang/dictionary_spec.rb +33 -0
  76. data/spec/zenlish/lex/lexeme_spec.rb +24 -9
  77. data/spec/zenlish/lex/literal_spec.rb +3 -11
  78. data/spec/zenlish/parser/lesson3_spec.rb +44 -0
  79. data/spec/zenlish/support/minimal_lexicon.rb +0 -2
  80. data/spec/zenlish/support/var2word.rb +5 -1
  81. data/spec/zenlish/wclasses/common_noun_spec.rb +25 -4
  82. data/spec/zenlish/wclasses/noun_spec.rb +31 -0
  83. data/spec/zenlish/wclasses/preposition_spec.rb +24 -0
  84. data/spec/zenlish/wclasses/verb_spec.rb +24 -0
  85. 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,9 @@
1
+ module Zenlish
2
+ module Inflect
3
+ class InputExpression
4
+ def success?(_lexeme, _heading_values)
5
+ raise NotImplementedError, 'Method must be implemented in subclass(es).'
6
+ end
7
+ end # class
8
+ end # module
9
+ 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,8 @@
1
+ require_relative 'input_expression'
2
+
3
+ module Zenlish
4
+ module Inflect
5
+ class NullaryInputExpression < InputExpression
6
+ end # class
7
+ end # module
8
+ end # module
@@ -0,0 +1,6 @@
1
+ module Zenlish
2
+ module Inflect
3
+ class OutputExpression
4
+ end # class
5
+ end # module
6
+ 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
@@ -0,0 +1,13 @@
1
+ require_relative 'input_expression'
2
+
3
+ module Zenlish
4
+ module Inflect
5
+ class UnaryInputExpression < InputExpression
6
+ attr_reader :argument
7
+
8
+ def initialize(anArgument)
9
+ @argument = anArgument
10
+ end
11
+ end # class
12
+ end # module
13
+ end # module
@@ -0,0 +1,11 @@
1
+ require_relative 'nullary_input_expression'
2
+
3
+ module Zenlish
4
+ module Inflect
5
+ class UnconditionallyTrue < NullaryInputExpression
6
+ def success?(_headings, _lexeme, _heading_values)
7
+ true
8
+ end
9
+ end # class
10
+ end # module
11
+ 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
- def self.add_entry(aLemma, aWClassName)
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
- add_entry('here', 'CommonNoun') # from here (works as a pronoun of a place)
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
- add_entry('person', 'CommonNoun')
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')
@@ -237,6 +237,7 @@ builder = Rley::Syntax::GrammarBuilder.new do
237
237
  rule 'lexical_verb' => 'IrregularVerbKnow'
238
238
  rule 'lexical_verb' => 'IrregularVerbSay'
239
239
  rule 'lexical_verb' => 'IrregularVerbThink'
240
+
240
241
 
241
242
  rule 'linking_verb' => 'IrregularLinkingVerb'
242
243
 
@@ -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
 
@@ -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
- # @return Zenlish::WClasses::WordClass
9
+ include Feature::FeatureStructDefBearer
10
+
11
+ # @return [Zenlish::WClasses::WordClass]
9
12
  attr_reader :wclass
10
13
 
11
- def initialize(aWordClass, anEntry)
12
- @wclass = aWordClass
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
@@ -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
@@ -2,11 +2,15 @@ require 'rley'
2
2
 
3
3
  module Zenlish
4
4
  module Lex
5
- # TODO: document
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
@@ -1,3 +1,3 @@
1
1
  module Zenlish
2
- VERSION = '0.1.25'.freeze
2
+ VERSION = '0.2.00'.freeze
3
3
  end
@@ -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
@@ -4,6 +4,11 @@ module Zenlish
4
4
  module WClasses
5
5
  # TODO: document
6
6
  class Preposition < WordClass
7
+
8
+ # Prepositions do not inflect, so they're invariable.
9
+ def invariable?
10
+ true
11
+ end
7
12
  end # class
8
13
  end # module
9
14
  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
- # TODO: document
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