Added xyz file parser/lexer

This commit is contained in:
Anthony Scemama 2017-12-31 18:27:58 +01:00
parent 9c51073bca
commit cfc59a256d
5 changed files with 97 additions and 2 deletions

View File

@ -12,7 +12,7 @@ let ang_mom = ['S' 'P' 'D' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O'
's' 'p' 'd' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' ]
white
let integer = ['0'-'9']+
let real = '-'? integer '.' integer (['e' 'E'] '-'? integer)?
let real = '-'? integer '.' integer (['e' 'E'] ('+'|'-')? integer)?
rule read_all_rule = parse

View File

@ -1,9 +1,10 @@
.NOPARALLEL:
INCLUDE_DIRS=Nuclei,Utils,Basis
LIBS=
PKGS=
OCAMLCFLAGS="-g"
OCAMLBUILD=ocamlbuild -j 0 -cflags $(OCAMLCFLAGS) -lflags $(OCAMLCFLAGS) -I Utils -I Basis
OCAMLBUILD=ocamlbuild -j 0 -cflags $(OCAMLCFLAGS) -lflags $(OCAMLCFLAGS) -Is $(INCLUDE_DIRS)
MLLFILES=$(wildcard */*.mll) $(wildcard *.mll)
MLYFILES=$(wildcard */*.mly) $(wildcard *.mly)
MLFILES= $(wildcard */*.ml) $(wildcard *.ml)

1
Nuclei/Nuclei.ml Normal file
View File

@ -0,0 +1 @@
type xyz_input = string * ( (string * (float array)) array)

38
Nuclei/Nuclei_lexer.mll Normal file
View File

@ -0,0 +1,38 @@
{
open Nuclei_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 (['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 }
{
let debug () =
let ic = open_in "caffeine.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;
}

55
Nuclei/Nuclei_parser.mly Normal file
View File

@ -0,0 +1,55 @@
/* Parses basis sets in GAMESS format */
%{
exception InputError of string
%}
%token EOL
%token <string> SPACE
%token <string> WORD
%token <int> INTEGER
%token <float> FLOAT
%token EOF
%start input
%type <Nuclei.xyz_input> input
%% /* Grammar rules and actions follow */
input:
| integer title atoms {
let len = List.length $3 in
if len <> $1 then
let error_msg = Printf.sprintf "%d atoms entered, expected %d" len $1 in
raise (InputError error_msg)
else
($2,Array.of_list $3)
}
integer:
| INTEGER EOL { $1 }
| INTEGER SPACE EOL { $1 }
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:
| atoms_list EOL { List.rev $1 }
| atoms_list EOF { List.rev $1 }
atoms_list:
| { [] }
| atoms_list WORD SPACE FLOAT SPACE FLOAT SPACE FLOAT EOL { ($2, [| $4;$6;$8 |]) :: $1 }
| atoms_list WORD SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { ($2, [| $4;$6;$8 |]) :: $1 }