aboutsummaryrefslogtreecommitdiffstats
path: root/test/ruby/sentgen.rb
blob: 29388e91d591527f1e646470a498c0e80a7b4dcf (plain)
1
2
3
4
5
6
7
8
9
10
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
43
44
45
46
47
48
49
50
51
52
53
54
# sentence generator

class SentGen
  def initialize(syntax)
    @syntax = syntax
  end

  def each_tree(sym, limit)
    generate_from_sym(sym, limit) {|_, tree|
      yield tree
    }
    nil
  end

  def each_string(sym, limit)
    generate_from_sym(sym, limit) {|_, tree|
      yield [tree].join('')
    }
    nil
  end

  def generate_from_sym(sym, limit, &b)
    return if limit < 0
    if String === sym
      yield limit, sym
    else
      rules = @syntax[sym]
      rules.each {|rhs|
        if rhs.length == 1 || rules.length == 1
          limit1 = limit
        else
          limit1 = limit-1
        end
        generate_from_rhs(rhs, limit1, &b)
      }
    end
    nil
  end

  def generate_from_rhs(rhs, limit)
    return if limit < 0
    if rhs.empty?
      yield limit, []
    else
      generate_from_sym(rhs[0], limit) {|limit1, child|
        generate_from_rhs(rhs[1..-1], limit1) {|limit2, arr|
          yield limit2, [child, *arr]
        }
      }
    end
    nil
  end
end