summaryrefslogtreecommitdiff
path: root/algorithms/parse_bracketed.rb
blob: cc90212c4fbb7c27c5a0ae3f2a9427b202866e5e (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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env ruby


def _c s
  s.strip.lstrip.gsub("'", '').gsub(/\s+/, "_")
end

class Item
  attr_accessor :predicate, :arguments

  def initialize predicate='', arguments=[]
    @predicate = predicate
    @arguments = []
  end

  def to_s
    args = @arguments.each{|i| i.to_s}.to_s.gsub('[','(').gsub(']',')')
    "#{@predicate}#{args}"
  end
end

def parse_funql s
  s = "(#{s})"
  structure = Item.new
  prev_p = nil
  p = structure
  collect = ''
  just_closed = false
  s.each_char { |c|
    if c == '('
      p.arguments << Item.new(_c(collect))
      collect = ''
      prev_p = p
      p = p.arguments.last
      just_closed = false
    elsif c == ')'
      if collect != ''
        p.arguments << _c(collect)
        collect = ''
      end
      p = prev_p
      just_closed = true
    elsif c == ','
       if collect != ''
         p.arguments << _c(collect)
         collect = ''
       end
       if just_closed
         p = prev_p
       end
       just_closed = false
    else
      collect += c
    end
  }
  return structure
end

def flatten_funql a
  return "#{a} " if a.class == String
  s = "#{a.predicate}$#{a.arguments.size} "
  a.arguments.each { |i|
    s += flatten_funql(i)
  }
  return s
end

def _fix_output s
  s[5..s.size-1].lstrip.strip.gsub("'", '')
end

def reverse s
  s.strip!
  open = 0
  r = ''
  s.split.each { |i|
    term, n = i.split '$'
    n = n.to_i
    out = term
    if n == 0
      out = "'#{out}'"
    elsif n > 0
      out += '('
      open += 1
    else
      puts "ERROR"
      exit
    end
    r += out
  }
  open.times { r += ')' }
  return r.gsub("''", "','")
end

def test
  a = []
  a << "answer(exclude(state(all), next_to_2(stateid('texas'))))"
  a << "answer(most(state(traverse_1(river(all)))))"
  a << "answer(state(loc_1(river(riverid('red')))))"
  a << "answer(smallest_one(area_1(state(next_to_2(stateid('texas'))))))"
  a << "answer(smallest_one(density_1(state(all))))"
  a << "answer(smallest_one(density_1(state(all))))"
  a << "answer(smallest_one(density_1(state(all))))"
  a << "answer(state(loc_1(cityid('kalamazoo', _))))"
  a.each { |i|
    puts i
    r = parse_funql(i)
    puts r.to_s
    puts _fix_output(flatten_funql(r))
    puts
  }
end

def main
  #test
  while line = STDIN.gets
    x = _fix_output(flatten_funql(parse_funql(line.strip)))
    puts line
    puts x
    puts reverse(x)
    puts
  end
end


main