Fortran 90

"Martin Stein" <[email protected]> Wed, 4 Mar 2015 10:21:58 +0100
Newsgroups gmane.emacs.cedet
Message-ID <trinity-0228a10a-abfd-41cb-8e7c-e50f158e22d9-1425460918565@3capp-gmx-bs46>
Hi,

took me a while and it is far from finished, but I guess I can publish my wisent fortran parser based on cedet. As the patches might be a bit too large and are not yet ready to be incorporated into cedet anyway, I setup a fork of cedet to easily access my patches. The repository can be obtained by

git clone git://git.code.sf.net/u/mafor90/fortran90-cedet fortran90-cedet

or even easier just add

git remote add fortran90 git://git.code.sf.net/u/mafor90/fortran90-cedet

in an existing cedet repository and fetch the new commits with git fetch fortran90.
I hope sourceforge.net permissions are correctly set. Please let me know, if this does not work.

This adds two branches to cedet:
Branch f90/semantic contains a few patches to the cedet/semantic core routines I am relying on.
Branch f90/main currently contains a single commit with the new files. It also removes the f90 bovine parser (as it conflicts with the new code) and extends/adjusts the f90-test files. The commit message of this single commit contains an (probably incomplete) list of things still to do to have a mature fortran support in semantic.

Remarks on wisent related commits in f90/semantic:
In order to get the lex-spp preprocessor running I had to extend the wisent parser in some way. The only parser using lex-spp is c/c++, which is based on bovine. A token injected macroexpanded by lex-spp and injected into the token stream has the form (symb str bnds), where str is the difference to tokens generated by the normal lexers. This is used in c.el to recognise spp-injected tokens in recursive expandfull based calls (there are no expand macro based recursive calls relying on lex-spp). With wisent this approach is not possible, as the parser transforms all tokens immediately into (symb str bnds) format. I considered and experimented with a number of possible ways to make spp-injected tokens recognisable. The easiest one I came up with was to change the internal token structure with
 in wisent to (symb (val . :flag-something) bnds), where flag-something might be flag-spp, flag-input or flag-action (for action generated values). In order to access flag, $flagI symbols have been added and can be used in actions or by the macros I have added to make the parser spp aware. I hope that this approach is acceptable as it is still quite an intrusion on the wisent parser.

Remarks on compilation:
The order of compilation first f90-grammar-macros, then f90.wy and finally f90.el is done correctly. However, if f90-grammar-macros is changed, then f90.wy needs to be recompiled, but this dependency is not yet coded into the Makefile, and I do not know how to do that with ede!

Remarks on f90.el (also see todo list in commit message):
* As I am new to lisp I probably got a number of things wrong or just not optimal. To begin with, so far I did not deal with defmacro and the crazy quoting, backquoting and commating it comes with. So I just used defun and defsubst, not always being sure which might be the proper thing to do. Also there are probably lots of lost optimisation (eval-when-compile and the like) opportunities. Any help and advice regarding any of these lisp matters is greatly appreciated. checkdoc should run (except for the footer, which I copied from c.el, and a complain about fortran-keyword contains, which it confuses with the verb contains). 

* CEDET_STYLE_GUIDE requires CL to be required via eval-when-compile (as in python.el); however, cl seems to be obsolete, so I have used cl-lib. But eval-when-compile in the cl-lib require statement does not work? Moreover, cl-lib seems to be a standard component of emacs, so is CEDET_STYLE_GUIDE still up-to-date with respect to cl?

* Regular expression: I have defined quite a number of constants and functions to have easy to read building blocks. I know about the package rx, but I could not get it working the way I wished. In particular, defining constants and then using them within rx expressions requires an rx-eval, which makes reading those rx expression rather painful. That's why I used my own building blocks. Any improvements or suggestions on how to use rx would be nice. I also suspect that I need to do something about evaluating those regular expression strings at compile time.

* semantic-calculate-scope: This is not an overloadable function, but fortran might need its own version. At the moment there is a hack in the code to overcome the problems. Scoping within fortran seems to be a bit different compared to c/c++. In particular, consider the following example:

function fun1()
  integer :: myvar1
  my_code
  contains
  function fun2()
     integer :: myvar2
     ! myvar1 is in scope, and it is part of a function tag
     myvar2 = myvar1
  end function
end function

I just could not convince semantic-calculate-scope and its helpers to find myvar1 at the context of the myvar2 assignment. Even more I came to the conclusion that this does not fit the current default routine.

* semantic-analyze-current-context: I have overloaded this central function to add a few new context classes (more are planned). Otherwise this is more or less just a refactored version of the original function.

* semantic-analyze-possible-completions: This was overloaded as well. It is a refactored version of the original with a few adjustments and extensions (there is still some C++ code left). In particular this version can handle predicate-functions returned by semantic-analyze-type-constraint (the original routine expects a string from semantic-analyze-type-constraint) for type matching. This allows a number things like checking generic interfaces of subroutines in call-subroutine contexts etc. I plan to further explore this (such as make type matching of real(4)=single precision and real(8)=double precision customisable).

* preprocessor: The lex-spp preprocessor is running, looks fine so far. However, I had to copy quite a bit of the code from c.el and a bit from lex-spp.el, because in some parts it did not match fortran, or I did not want to reuse variables from the C parser, or I could not untangle the code to decide which part could be reused and which needed to be copied.

Martin

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/