class WordGenerator

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

Public Class Methods

new(file) click to toggle source

Constructor

# 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

Public Instance Methods

apply_replacements(word) click to toggle source

Apply replacements to words

# File lib/conlang/wordgenerator.rb, line 125
def apply_replacements(word)
  @replacements.each do |pattern, target|
    word.gsub!(pattern, target)
  end
  
  word
end
eval_expression() click to toggle source

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

# File lib/conlang/wordgenerator.rb, line 106
def eval_expression
  @evaluated_expression =
     ConlangWordGenerator::run_expression(@full_expression, @bindings)
end
get_words(qty = 30) click to toggle source

This method generates words

# 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_file() click to toggle source

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

# 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