Class: WordGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/conlang/wordgenerator.rb

Overview

This Ruby class generates random words using prabability-weighted symbols, and grammar rules from a given *.lang file as input.

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ WordGenerator

Constructor



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/conlang/wordgenerator.rb', line 11

def initialize(file)
  # Check file extension.

  unless file.match(/.*\.lang/)
    raise LangFileIOError,
          "Given file, \"#{file}\", is not a .lang file." 
  end

  # Check if files exist

  unless File.exist?(file)
    raise LangFileIOError,
          "File \"#{file}\" was not found." 
  end

  #   #   #   #   #   #   #   #   #


  # Input filename

  @lang_file = file

  # Bindings for SymbolSets and a variable 

  # to save the grammatical expression string.

  @bindings = {}
  @full_expression = ""

  # Bindings for replacements

  @replacements = {}

  # Parse .lang file

  parse_lang_file

  # Parse and evaluate grammatical expression

  eval_expression
end

Instance Method Details

#apply_replacements(word) ⇒ Object

Apply replacements to words



125
126
127
128
129
130
131
# File 'lib/conlang/wordgenerator.rb', line 125

def apply_replacements(word)
  @replacements.each do |pattern, target|
    word.gsub!(pattern, target)
  end
  
  word
end

#eval_expressionObject

This method evaluates the grammatical expression and then generate random words.



106
107
108
109
# File 'lib/conlang/wordgenerator.rb', line 106

def eval_expression
  @evaluated_expression =
     ConlangWordGenerator::run_expression(@full_expression, @bindings)
end

#get_words(qty = 30) ⇒ Object

This method generates words



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/conlang/wordgenerator.rb', line 112

def get_words(qty = 30)
  raise "Error on quantity of words." if qty < 1

  words = []

  qty.times do
    words += [apply_replacements(@evaluated_expression.sample)]
  end 

  words
end

#parse_lang_fileObject

This method reads a .lang file to parse it. It parses the symbols and then copies the full grammatical expression to evaluate it later.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/conlang/wordgenerator.rb', line 47

def parse_lang_file
  # Open .lang file and parse it, then copy 

  # its full grammatical expression.

  File.open(@lang_file, "r:UTF-8") do |file|
    lines_count = 1
    current = :none

    # Evaluating lines

    while (line = file.gets)
      # Parsing .lang file

      case line
      when /(^\s*$)|(^\s*#.*$)/
        # Ignore blank lines or comments

        
      when /^\s*symbols\s*for\s*(\w*)?\s*(\w+)\s*:\s*(#.*)?$/
        # Create new symbol set

        captured = line.scan(/\s*(\w+)\s*:/)
        current_binding = captured[0][0]
        @bindings[current_binding] = ConlangWordGenerator::SymbolSet.new
        current = :symbols

      when /^\s*expression\s*:\s*(#.*)?$/
        # Start of grammatical expression

        current = :expression

      when /^\s*replacements\s*:\s*(#.*)?$/
        # Start of list of replacements

        current = :replacements

      when /^\s*(\S+)\s*[:=]\s*(\S+)\s*(#.*)?$/
        # Add bindings

        case current
        when :symbols
          #Add a symbol to the current SymbolSet's binding

          @bindings[current_binding].add_pair($1, $2.to_i)
        when :replacements
          @replacements[$1] = $2
        else
          raise LangSyntaxError, "Runtime error when evaluating " +
                                 "\"#{@lang_file}\" at binding line #{lines_count}."
        end
      else
        if current == :expression
          # Copying expression

          @full_expression += line.strip
        else
          raise LangSyntaxError, "Runtime error when evaluating " +
                                 "\"#{@lang_file}\" at line #{lines_count}."
        end
      end

      #Counting lines

      lines_count += 1
    end
  end
end