Fortran-F90Namelist
view release on metacpan or search on metacpan
lib/Fortran/F90Namelist.pm view on Meta::CPAN
=head1 SEE ALSO
L<Fortran::Namelist> by Victor Marcello Santillan.
That module has a more limited scope (reading a namelist group from file,
inserting namelists, and writing the resulting group to another file [my
interpretation]), but is way faster on large files.
=cut
use strict;
use Carp;
use vars qw($VERSION);
# Cannot use use Perl5.8's constant { x => 1, y=>2 , ..} because 5.6
# is very popular still
#
# Possible states of parser [used at all?]
use constant UNDEF => -1;
use constant START => 0; # initial state of parser
use constant VAR => 1; # at beginning of variable name
use constant VALUE => 2; # at beginning of value
use constant SQUOTE => 3; # in string after opening single quote
use constant DQUOTE => 4; # in string after opeing double quote
use constant BRACKET => 5; # after opening bracket (e.g. complex number)
use constant COMMENT => 6; # after exclamation mark (F90 comment)
use constant NL_END => 7; # after closing `/'
#
# F90 data types
use constant UNKNOWN => 0;
use constant SQ_STRING => 1;
use constant DQ_STRING => 2;
use constant LOGICAL => 3;
use constant INTEGER => 4;
use constant FLOAT => 5; # a float here can be single or double
use constant SINGLE => 6;
use constant DOUBLE => 7;
use constant COMPLEX => 8;
use constant DCOMPLEX => 9;
use constant MULTIPLE => 20;
#
use constant ID => 100; # variable name (_not_ a data type)
$VERSION = '0.5.1';
## Regexps for integer and floating-point numbers
# general float:
my $numeric = qr/(?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[EeDd](?:[+-]?\d+))?/;
# float:
my $numeric_e = qr/(?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee](?:[+-]?\d+))?/;
# double:
my $numeric_d = qr/(?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Dd](?:[+-]?\d+))?/;
# float with decimal point, but w/o exponential part:
my $float = qr/(?:[-+]?(?:\d+\.\d*|\d*\.\d+))/;
## Extend floating-point numeric tpes by one- or two-point
## compactification of real numbers (any mathematicians here?), aka IEEE
## denormalized numbers (for engineers):
my $NaN = qr/NaN/;
my $Inf = qr/(?:[-+]?)Inf/;
my $ieee_denorm = qr/(?:$NaN|$Inf)/;
#$numeric_e = qr/(?:$numeric_e|$ieee_denorm)/;
#$numeric_d = qr/(?:$numeric_d|$ieee_denorm)/;
$numeric = qr/(?:$numeric|$ieee_denorm)/;
$float = qr/(?:$float|$ieee_denorm)/;
## Regexps for the different data type values. Make sure all brackets are
## marked grouping-but-non-capturing (?:...), or else the parsing
## algorithm will fail.
my @regexp;
$regexp[SQ_STRING] = qr/'(?:[^']|'')*'/; # even covers 'toto''s quote'
$regexp[DQ_STRING] = qr/"(?:[^"]|"")*"/; # ditto for double quotes
$regexp[DCOMPLEX] = qr/\(\s*$numeric_d\s*,\s*$numeric_d\s*\)/;
$regexp[COMPLEX] = qr/\(\s*$numeric\s*,\s*$numeric\s*\)/;
$regexp[LOGICAL] = qr/(?:T|F|\.(?:true|TRUE|false|FALSE)\.)/;
$regexp[MULTIPLE] = qr/[0-9]+\*/; # also need special treatment...
$regexp[INTEGER] = qr/[+-]?[0-9]+/;
$regexp[DOUBLE] = qr/$numeric_d/;
$regexp[SINGLE] = qr/$numeric_e/;
$regexp[FLOAT] = qr/$float/;
$regexp[ID] = qr/[a-zA-Z](?:[a-zA-Z0-9_])*/; # allowed namelist/var. names
## Corresponding regexp for compatible type class (numeric, complex, ...)
my @regexp2 = @regexp; # same regexp by default
$regexp2[DCOMPLEX] = qr/\(\s*$numeric\s*,\s*$numeric\s*\)/;
$regexp2[COMPLEX] = qr/\(\s*$numeric\s*,\s*$numeric\s*\)/;
$regexp2[INTEGER] = qr/$numeric/;
$regexp2[DOUBLE] = qr/$numeric/;
$regexp2[SINGLE] = qr/$numeric/;
$regexp2[FLOAT] = qr/$numeric/;
# Hash for looking up symbolic names for type constants. The constants are
# only expanded as numbers if adding 0.
my %stypes = ( UNKNOWN + 0 => 'unknown',
SQ_STRING + 0 => 'single-quote string',
DQ_STRING + 0 => 'double-quote string',
LOGICAL + 0 => 'logical',
INTEGER + 0 => 'integer',
FLOAT + 0 => 'unspecified float',
SINGLE + 0 => 'single precision float',
DOUBLE + 0 => 'double precision float',
COMPLEX + 0 => 'complex number',
DCOMPLEX + 0 => 'double precision complex number',
MULTIPLE + 0 => 'multiple data (array)',
);
# Global variables related to output() method:
my ($cmplx_pref,$cmplx_suff) = ('', ''); # default delimiters for complex nums
# ---------------------------------------------------------------------- #
##
## Object constructor
##
## Internal structure of Namlist objects (update me):
## DATA -- variable names, values, and types (hashref, see below)
## SLOTS -- ordered list of variable names (array ref)
## NSLOTS -- number of slots
## NAME -- name of namelist
## PARSED_ -- flag indicating that argument has been parsed
## DEBUG_ -- debug flag
##
( run in 1.423 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )