FLEMON:
-------

Adaptation of the lemon parser by D. Richard Hipp for Fortran.
Generates a Fortran-encoded parser for LALR(1) grammars, much
like Yacc and Bison.

Current limitations and remarks:
- You can not convenient use the extra argument
  (Macros involved are not expanded)
  You can use %include instead to make a "global" variable
  to hold the state.
- You need to use %include to _use_ a module with the type definitions
  for the token data (type(parsetokentype)) or put the definition
  in the %include statement. Do not forget to make it public!

Documentation of the lemon parser can be found at
http://www.hwaci.com/sw/lemon.

Below is information on "flemon":

1. The parser must be of type "yyparser" and is initialised via the
   subroutine parsealloc:

   type(yyparser) :: parser   ! Not a pointer!

   call parsealloc( parser )

   Note:
   I have not tried the %name option yet, so I do not know if the
   infixed string "parse" will be replaced by the argument to %name
   or not. I will probably rename the type at some point, to get
   rid of the "yy" prefix.

2. You need to define a type "parsetokentype" to hold all information
   on the token. This is most convenient via the %include statement.

3. When all tokens are passed to the parser, finish it with a call
   like:

   call parse( parser, 0, token, state )

   The token with major index 0 is special: it completes the input and
   thus makes the parser complete all rules.

4. When you are done, free the parser with a call to parsefree:

   call parsefree( parser )

5. Some care must be taken if the type "parsetokentype" contains
   pointers. As the data are simply _assigned_, you will need to define
   a custom assignment operation, so that the _contents_ of the memory
   that the pointers point to is copied, and not just the reference.

   Failing to do so may give surprising results, as the tokens are not
   all treated when they are fed to the parser.

Here is an extremely simple example:

--- fexpr.y (gets translated into fexpr.f90 with the module parse_mod ---

// Simple parser:
// expr = value + value + value + ...

%include {
type ParseTOKENTYPE
    character(len=10) :: token
end type
type StateTYPE
    integer :: sum
end type
public :: ParseTOKENTYPE
public :: StateTYPE
}

%extra_argument {type(statetype) state}
%token_type {type(parsetokentype)}
%type term {integer}

expr ::= firstterm plusterms . {
    write(*,*) "Result: ", state%sum
}

firstterm ::= term(T) . {
    state%sum = T
    write(*,*) "First term: ", T ;
}

term(V) ::= NUMBER(N) . {
    read( N%token, *, V )
    write(*,*) "Term: ", V, "-- ",  N->token
}

plusterms ::= .
plusterms ::= plusterms plusterm .

plusterm ::= PLUS term(T) . {
    state%sum = state%sum + T
    write(*,*) "Result so far: ", state%sum
}

--- fexprmain.f90 - fexpr.h contains the values of the parameters
P_NUMBER and P_WORD, this file is generated by flemon ---
program fexprmain
    use Parse_mod

    include "fexpr.h"

    type(yyparser)       :: pparser
    type(statetype)      :: state
    type(Parsetokentype) :: token

    call ParseAlloc( pparser )

    call ParseTrace( 6, ">>" )

    token%token = "1"; call Parse( pParser, P_NUMBER, token, state )
    token%token = "+"; call Parse( pParser, P_PLUS,   token, state )
    token%token = "2"; call Parse( pParser, P_NUMBER, token, state )
    token%token = "+"; call Parse( pParser, P_PLUS,   token, state )
    token%token = "3"; call Parse( pParser, P_NUMBER, token, state )

    call Parse( pParser, 0, token, state )

    call ParseFree( pParser )

end program
