mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-09-12 06:28:31 +02:00
10 KiB
10 KiB
Nuclei
Type
open Common
type t = (Element.t * Coordinate.t) array
xyz file lexer/parser
Lexer
nuclei_lexer.mll
contains the description of the lexemes used in
an xyz file.
{
open Xyz_parser
}
let eol = ['\n']
let white = [' ' '\t']+
let word = [^' ' '\t' '\n']+
let letter = ['A'-'Z' 'a'-'z']
let integer = ['0'-'9']+
let real = '-'? (integer '.' integer | integer '.' | '.' integer) (['e' 'E'] ('+'|'-')? integer)?
rule read_all = parse
| eof { EOF }
| eol { EOL }
| white as w { SPACE w }
| integer as i { INTEGER (int_of_string i) }
| real as f { FLOAT (float_of_string f) }
| word as w { WORD w }
{
(* DEBUG
let () =
let ic = open_in "h2o.xyz" in
let lexbuf = Lexing.from_channel ic in
while true do
let s =
match read_all lexbuf with
| EOL -> "EOL"
| SPACE w -> "SPACE("^w^")"
| INTEGER i -> "INTEGER("^(string_of_int i)^")"
| FLOAT f -> "FLOAT("^(string_of_float f)^")"
| WORD w -> "WORD("^w^")"
| EOF -> "EOF"
in
print_endline s
done;
*)
}
Parser
xyz_parser.mly
parses nuclear coordinates in xyz format.
%{
open Common
let make_angstrom x y z =
Coordinate.(make_angstrom {
x ; y ; z
})
let output_of f x y z =
let a = make_angstrom x y z in
fun e ->
{
Xyz_ast.
element = f e;
coord = a ;
}
let output_of_string = output_of Element.of_string
let output_of_int = output_of Element.of_int
%}
%token EOL
%token <string> SPACE
%token <string> WORD
%token <int> INTEGER
%token <float> FLOAT
%token EOF
%start input
%type <Xyz_ast.xyz_file> input
%% /* Grammar rules and actions follow */
input:
| integer title atoms_xyz {
{
number_of_atoms = $1;
file_title = $2;
nuclei = $3;
}
}
;
integer:
| INTEGER EOL { $1 }
| INTEGER SPACE EOL { $1 }
| SPACE INTEGER EOL { $2 }
| SPACE INTEGER SPACE EOL { $2 }
;
title:
| title_list EOL { $1 }
;
text:
| WORD { $1 }
| SPACE { $1 }
| FLOAT { (string_of_float $1)}
| INTEGER { (string_of_int $1)}
;
title_list:
| { "" }
| title_list text { ($1 ^ $2) }
;
atoms_xyz:
| atoms_list EOL { List.rev $1 }
| atoms_list EOF { List.rev $1 }
;
atoms_list:
| { [] }
| atoms_list WORD SPACE FLOAT SPACE FLOAT SPACE FLOAT EOL { output_of_string $4 $6 $8 $2 :: $1 }
| atoms_list WORD SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_string $4 $6 $8 $2 :: $1 }
| atoms_list INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT EOL { output_of_int $4 $6 $8 $2 :: $1 }
| atoms_list INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_int $4 $6 $8 $2 :: $1 }
| atoms_list SPACE WORD SPACE FLOAT SPACE FLOAT SPACE FLOAT EOL { output_of_string $5 $7 $9 $3 :: $1 }
| atoms_list SPACE WORD SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_string $5 $7 $9 $3 :: $1 }
| atoms_list SPACE INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT EOL { output_of_int $5 $7 $9 $3 :: $1 }
| atoms_list SPACE INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_int $5 $7 $9 $3 :: $1 }
;
When an xyz file is read by xyz_parser.mly
, it is converted into
an xyz_file
data structure.
open Common
type nucleus =
{
element: Element.t ;
coord : Coordinate.angstrom Coordinate.point;
}
type xyz_file =
{
number_of_atoms : int ;
file_title : string ;
nuclei : nucleus list ;
}
Conversion
val of_xyz_string : string -> t
val to_xyz_string : t -> string
val of_xyz_file : string -> t
val of_zmt_string : string -> t
val of_zmt_file : string -> t
val to_string : t -> string
val of_filename : string -> t
of_xyz_string |
Create from a string, in xyz format |
of_xyz_file |
Create from a file, in xyz format |
of_zmt_string |
Create from a string, in z-matrix format |
of_zmt_file |
Create from a file, in z-matrix format |
to_string |
Transform to a string, for printing |
of_filename |
Detects the type of file (xyz, z-matrix) and reads the file |
TODO Query
val formula : t -> string
val repulsion : t -> float
val charge : t -> Charge.t
val small_core : t -> int
val large_core : t -> int
formula |
Returns the chemical formula |
repulsion |
Nuclear repulsion energy, in atomic units |
charge |
Sum of the charges of the nuclei |
small_core |
Number of core electrons in the small core model |
large_core |
Number of core electrons in the large core model |
Printers
val pp : Format.formatter -> t -> unit