stfc / fparser

This project maintains and develops a Fortran parser called fparser2 written purely in Python which supports Fortran 2003 and some Fortran 2008. A legacy parser fparser1 is also available but is not supported. The parsers were originally part of the f2py project by Pearu Peterson.
https://fparser.readthedocs.io
Other
61 stars 28 forks source link

Issues with matching of Hollerith constants #266

Open reuterbal opened 4 years ago

reuterbal commented 4 years ago

Sorry, another archaic one... Matching of Hollerith constants seems to have a few issues. I noticed the following:

  1. In a Format string, if the last item before the closing parenthesis is a Hollerith constant that ends in a white space, parsing fails (which might be a strip() or rstrip() issue?). The actual NoMatchError might be connected to 2. below.
    
    >>> from fparser.two.parser import ParserFactory
    >>> parser = ParserFactory().create()
    >>> from fparser.api import get_reader
    >>> fcode = 'PROGRAM HOLLERITH\n901 FORMAT (2HA ,1X)\nEND PROGRAM HOLLERITH'
    >>> parser(get_reader(fcode))
    Program(Main_Program(Program_Stmt('PROGRAM', Name('HOLLERITH')), Specification_Part(Implicit_Part(Format_Stmt('FORMAT', Format_Specification('(', Format_Item_List(',', (Hollerith_Item('A '), Position_Edit_Desc(Digit_String('1', None), 'X'))), ')')))), End_Program_Stmt('PROGRAM', Name('HOLLERITH'))))
    >>> fcode = 'PROGRAM HOLLERITH\n901 FORMAT (2HA )\nEND PROGRAM HOLLERITH'
    >>> parser(get_reader(fcode))
    Traceback (most recent call last):
    File "/.../src/fparser/two/Fortran2003.py", line 237, in __new__
    return Base.__new__(cls, string)
    File "/.../src/fparser/two/utils.py", line 407, in __new__
    raise NoMatchError(errmsg)
    fparser.two.utils.NoMatchError: at line 2
    >>>901 FORMAT (2HA )

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "", line 1, in File "/.../src/fparser/two/Fortran2003.py", line 241, in new raise FortranSyntaxError(string, "") fparser.two.utils.FortranSyntaxError: at line 2

901 FORMAT (2HA )

2. If the character count does not match the number of following characters, it fails to match. The webpage [linked to](https://gcc.gnu.org/onlinedocs/gfortran/Hollerith-constants-support.html) from the documentation however states that in such cases the constant is truncated or padded:
```python
>>> fcode = 'PROGRAM HOLLERITH\n901 FORMAT (2HAAA ,1X)\nEND PROGRAM HOLLERITH'
>>> parser(get_reader(fcode))
Traceback (most recent call last):
  File "/.../src/fparser/two/Fortran2003.py", line 237, in __new__
    return Base.__new__(cls, string)
  File "/.../src/fparser/two/utils.py", line 407, in __new__
    raise NoMatchError(errmsg)
fparser.two.utils.NoMatchError: at line 2
>>>901 FORMAT (2HAAA ,1X)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../src/fparser/two/Fortran2003.py", line 241, in __new__
    raise FortranSyntaxError(string, "")
fparser.two.utils.FortranSyntaxError: at line 2
>>>901 FORMAT (2HAAA ,1X)
reuterbal commented 4 months ago

Digging out a very old issue, just to point out that case 1 above works now correctly:

 python3 -c "
from fparser.two.parser import ParserFactory; from fparser.api import get_reader; parser = ParserFactory().create(); fcode = 'PROGRAM HOLLERITH\n901 FORMAT (2HA )\nEND PROGRAM HOLLERITH'; print(parser(get_reader(fcode)))"
PROGRAM HOLLERITH
901 FORMAT(2HA )
END PROGRAM HOLLERITH

However, case 2 is not handled in the expected way, yet:

 python3 -c "
from fparser.two.parser import ParserFactory; from fparser.api import get_reader; parser = ParserFactory().create(); fcode = 'PROGRAM HOLLERITH\n901 FORMAT (2HAAA ,1X)\nEND PROGRAM HOLLERITH'; print(parser(get_reader(fcode)))"
Traceback (most recent call last):
  File "/etc/ecmwf/nfs/dh1_home_a/nabr/loki/main/loki_env/lib/python3.8/site-packages/fparser/two/Fortran2003.py", line 267, in __new__
    return Base.__new__(cls, string)
  File "/etc/ecmwf/nfs/dh1_home_a/nabr/loki/main/loki_env/lib/python3.8/site-packages/fparser/two/utils.py", line 501, in __new__
    raise NoMatchError(errmsg)
fparser.two.utils.NoMatchError: at line 2
>>>901 FORMAT (2HAAA ,1X)