Rand Stats

Fortran::Grammar

zef:raku-community-modules

Actions Status Actions Status

NAME

Fortran::Grammar - Grammar to parse FORTRAN source code

SYNOPSIS

use Fortran::Grammar;

DESCRIPTION

Note: This module is still in very early development.

MOTIVATION

Working on large Fortran projects with lots of code that you haven't written yourself and try to understand/debug, I found it to be very handy to have a text filter that scans the source code and automatically wraps write(*,*) ... statements around specific codelines, e.g. specific MPI subroutine calls. To get information on this code and fill the write (*,*) ... statements with useful information, it has to be parsed.

I initially wrote a Perl script to do this by parsing the source code line-by-line. Parsing became more and more ugly the stranger the code became ( a lot of nested arguments, Fortran-style line continuation with & \n &, the code of interest enclosed in IF-oneliners, etc...).

When I discovered Raku Grammars, I immediately wanted to implement this :-)

The main goal of this module is not to provide a Fortran syntax-checker (although with a lot of work it could become one...) but to give painless access to the structural components of Fortran statements - e.g. the subroutine name of a subroutine call, its arguments (which may contain function calls or calculations), etc...

Usage

Use it like any grammar in Raku

use Fortran::Grammar; # use the module

# some simple Fortran code
my Str $fortran = q:to/EOT/;
call sub( array(1:2), sin(1.234_prec), & ! Fortran-style linebreak / comment
    & (/ 1.23, 3.45, 6.78 /), "Hello World!" )
EOT

# parse the Fortran code
my $parsed = Fortran::Grammar::FortranBasic.parse: $fortran.chomp,
                rule => "subroutine-call";

say "### input ###";
say $fortran;
say "### parsed ###";
say $parsed;

Output:

### input ###
call sub( array(1:2), sin(1.234_prec), & ! Fortran-style linebreak / comment
    & (/ 1.23, 3.45, 6.78 /), "Hello World!" )

### parsed ###
「call sub( array(1:2), sin(1.234_prec), & ! Fortran-style linebreak / comment
    & (/ 1.23, 3.45, 6.78 /), "Hello World!" )」
 name => 「sub」
 arguments => 「array(1:2), sin(1.234_prec), & ! Fortran-style linebreak / comment
    & (/ 1.23, 3.45, 6.78 /), "Hello World!" 」
  argument => 「array(1:2)」
   value-returning-code => 「array(1:2)」
    accessed-variable => 「array(1:2)」
     indexed-array => 「array(1:2)」
      name => 「array」
      array-indices => 「1:2」
       array-index => 「1:2」
        array-index-region => 「1:2」
         value-returning-code => 「1」
          in-place => 「1」
           atomic => 「1」
            number => 「1」
             integer => 「1」
              digits => 「1」
         value-returning-code => 「2」
          in-place => 「2」
           atomic => 「2」
            number => 「2」
             integer => 「2」
              digits => 「2」
  argument => 「sin(1.234_prec)」
   value-returning-code => 「sin(1.234_prec)」
    function-call => 「sin(1.234_prec)」
     name => 「sin」
     arguments => 「1.234_prec」
      argument => 「1.234_prec」
       value-returning-code => 「1.234_prec」
        in-place => 「1.234_prec」
         atomic => 「1.234_prec」
          number => 「1.234_prec」
           float => 「1.234_prec」
            digits => 「1」
            digits => 「234」
            precision-spec => 「_prec」
             name => 「prec」
  argument => 「(/ 1.23, 3.45, 6.78 /)」
   value-returning-code => 「(/ 1.23, 3.45, 6.78 /)」
    in-place => 「(/ 1.23, 3.45, 6.78 /)」
     in-place-array => 「(/ 1.23, 3.45, 6.78 /)」
      numbers => 「1.23, 3.45, 6.78 」
       number => 「1.23」
        float => 「1.23」
         digits => 「1」
         digits => 「23」
       number => 「3.45」
        float => 「3.45」
         digits => 「3」
         digits => 「45」
       number => 「6.78」
        float => 「6.78」
         digits => 「6」
         digits => 「78」
  argument => 「"Hello World!" 」
   value-returning-code => 「"Hello World!" 」
    in-place => 「"Hello World!" 」
     atomic => 「"Hello World!" 」
      string => 「"Hello World!" 」

Special thanks

smls on StackOverflow.com for an Action object FALLBACK method that converts a Match object to a JSON-serializable Hash.

AUTHORS

COPYRIGHT AND LICENSE

Copyright 2017 Yann Büchau

Copyright 2024 Raku Community

This library is free software; you can redistribute it and/or modify it under the GNU GENERAL PUBLIC LICENSE, Version 3