fparser icon indicating copy to clipboard operation
fparser copied to clipboard

Error on concatenation of two strings with a backslash

Open mbraakhekke opened this issue 1 year ago • 4 comments

The following minimal program results in a NoMatchError for line 2:

program simple
    character(len=10) :: foo = '\' // 'b'
end program simple

I believe this is correct Fortran--at least it compiles fine on Intel.

I'm still investigating myself. It's doesn't seem to be a problem with the regex pattern for the concat-op. I think it has something to do with the fact that backslashes in strings get automatically escaped to \\ in Python.

Interestingly, if I take out the line from the program block, i.e. just:

character(len=10) :: foo = '\' // 'b'

it works fine.

mbraakhekke avatar Dec 18 '24 16:12 mbraakhekke

Thanks for reporting this @mbraakhekke. Do you get the expected parse tree for the line in isolation? (I ask because you have to be careful as, unless you tell the reader you have free-format code, it will see the first c and match a fixed-format comment.)

arporter avatar Dec 19 '24 10:12 arporter

Thanks for reporting this @mbraakhekke. Do you get the expected parse tree for the line in isolation? (I ask because you have to be careful as, unless you tell the reader you have free-format code, it will see the first c and match a fixed-format comment.)

You're right: the line gets interpreted as a comment. How do I tell the reader the file is free-format?

mbraakhekke avatar Dec 19 '24 13:12 mbraakhekke

It's slightly non-intuitive. You need to call set_format() on the reader object (https://fparser.readthedocs.io/en/latest/_static/html/classfparser_1_1common_1_1readfortran_1_1FortranReaderBase.html#ad9e18ea6d859fd5459381d4f1437311d) and pass it an appropriate sourceinfo.FortranFormat object:

from fparser.common.sourceinfo import FortranFormat

reader = ...
reader.set_format(FortranFormat(is_free=True, is_strict=False))
...

arporter avatar Dec 20 '24 08:12 arporter

OK thanks. Now the parsing also fails with a FortranSyntaxError. I'll keep digging. Possibly, I can submit a PR.

mbraakhekke avatar Dec 20 '24 12:12 mbraakhekke

I think I've hit a very similar bug - certainly I have a string with a backslash and fparser fails:

program a_test
  use some_mod
  ! Single met folder.
  L = Len_Trim(MetFolder)
  If (MetFolder(L:L) == '\' .and. L <= MaxFileNameLength) Then
     NWPMet%MetFolder = MetFolder
  end if
end program

gives:

File: 'a_test.f90'
ERROR:fparser.common.readfortran:While processing 'a_test.f90' (mode='free')..
    2:  use some_mod
    3:  ! Single met folder.
    4:  L = Len_Trim(MetFolder)
    5:  If (MetFolder(L:L) == '\' .and. L <= MaxFileNameLength) Then <== following character continuation: "'", expected None.
Syntax error: at line 5
>>>  If (MetFolder(L:L) == '\' .and. L <= MaxFileNameLength) Then

If I remove the .and. L <= ... part of the logical expression then fparser no longer fails.

arporter avatar May 29 '25 12:05 arporter

The following character continuation: "'", expected None warning came from the code that attempted to check for an inline comment. That seemed unnecessarily complicated but I do now have some test failures. However, having fixed that (possibly), we are still left with the syntax error.

arporter avatar Jun 03 '25 21:06 arporter

Looking at splitquote in common/splitline.py I see: https://github.com/stfc/fparser/blob/3bc75feb8fe1c0f18ac352cea9c2ea173699ffb3/src/fparser/common/splitline.py#L281-L289 but this seems to be fundamentally wrong: in standard Fortran the backslash is just a standard character, it doesn't escape anything. (The way to do this for a single quotation character is to repeat it twice).

arporter avatar Jun 04 '25 09:06 arporter

Testing this from Python is slightly complicated as (as mentioned earlier) backslash is an escape character in a Python string.

arporter avatar Jun 04 '25 09:06 arporter