Class: Alumina::HIN::Parser

Inherits:
Object show all
Defined in:
lib/alumina/hin/parser.rb

Overview

Class that parses HIN files to produce Molecule instances. This class is not thread-safe! You must instantiate a new parser for each thread of your program.

Constant Summary collapse

BOND_TYPES =

Mapping of HIN file bond types to their symbol values for the Atom class.

{
  's' => :single,
  'd' => :double,
  't' => :triple,
  'a' => :aromatic
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#lenientObject

If @true@, does not raise ParseError when

  • unknown commands are encountered,

  • the bond count is incorrect, or

  • an @endmol@‘s ID does not correspond to its @mol@’s ID.



23
24
25
# File 'lib/alumina/hin/parser.rb', line 23

def lenient
  @lenient
end

Instance Method Details

#parse(input) ⇒ Array<Alumina::Molecule>

Parses HIN data and returns an array of Molecules.

Parameters:

  • input (IO, String)

    The HIN data to parse.

Returns:

Raises:

  • (ParseError)

    If the HIN data is improperly formatted.



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
# File 'lib/alumina/hin/parser.rb', line 31

def parse(input)
  @molecules = Array.new
  @current_molecule = nil
  @line_counter = 0
  @bonds = Hash.autonew

  input.each_line do |line|
    @line_counter += 1
    next if line =~ /^\s*$/
    next if line[0] == ';' # comment
    parts = line.split(/\s+/)

    command = parts.shift
    method = :"parse_#{command}"
    if respond_to?(method) then
      send(method, *parts)
    else
      if lenient then
        next
      else
        raise ParseError.new(@line_counter, "Unknown command #{command}")
      end
    end
  end
  
  @bonds.each do |molecule, firsts|
    firsts.each do |atom1, lasts|
      lasts.each do |atom2, bond_type|
        Atom.bind molecule[atom1], molecule[atom2], BOND_TYPES[bond_type]
      end
    end
  end

  return @molecules
end