grammar BruhlGrammar

rule root
  (ws* object_elem* ws*) {
    Bruhl::Object.new(
      captures(:object_elem).map(&:value)
    )
  }
end

rule object
  (ws* string? '{' ws* (object_elem ws*)* '}' ws*) {
    tag = capture(:string) ? capture(:string).to_s : nil
    Bruhl::Object.new(
      captures(:object_elem).map(&:value),
      tag
    )
  }
end

rule object_elem
  relation | rvalue
end

rule relation
  (ws* key:(string | integer) ws* operator ws* rvalue ws*) {
    Bruhl::Relation.new(
      capture(:key  ).value,
      capture(:operator).value,
      capture(:rvalue  ).value
    )
  }
end

rule number
  float | integer
end

rule integer
  (ws* num:('-'? [\d]+) ws*) {
    capture(:num).to_s.to_i
  }
end

rule string
  (ws* inside:(quoted_string | raw_string) ws*) {
    capture(:inside).value
  }
end

rule escaped_quote
  ('\"') {
    '"'
  }
end

rule quote_string_part_raw
  (!('\"' | '"')  .) {
    to_s
  }
end

rule quote_string_part
  escaped_quote | quote_string_part_raw
end

rule quoted_string
  ('"' quote_string_part* '"') {
    Bruhl::QuotedString.new(captures(:quote_string_part).map(&:value).join)
  }
end

rule raw_string
  ([-_'’@:\./%\p{alpha}][-\d_'’@:\./%\p{alpha}]*) {
    Bruhl::RawString.new(to_s)
  }
end

rule float
  (ws* num:('-'? ([\d]+ '.' [\d]+)) ws*) {
    capture(:num).to_s.to_f
  }
end

rule rvalue
  (ws* inside:(object | number | string) ws*) {
    capture(:inside).value
  }
end

rule operator
  ('<=' | '>=' | '=' | '<' | '>') {
    to_s
  }
end

rule ws
  [ \t\n§;~] | "\r\n" | comment
end

rule comment
  '#' (!"\n" .)*
end

end