Add 'format-missing-comma' extension (closes #484) - #526
Add 'format-missing-comma' extension (closes #484)#526DisciplinedSoftware wants to merge 1 commit into
Conversation
Many compilers (gfortran, ifort, ifx) accept a missing comma between
a character-string edit descriptor and a neighbouring format item,
e.g. FORMAT('a' 1x,'b'), FORMAT(15x'a') or FORMAT('a' 'b').
Following the extension convention, 'format-missing-comma' is added
to the EXTENSIONS list in utils.py and the relaxation is implemented
in Format_Item_C1002, whose match logic is split into the standard
C1002 pass and an extension fallback. Found while parsing MODFLOW-2005
(gwf2swr7.f, gwf2swi27.fpp, gwf2lak7.f, gwf2sfr7.f); also covers the
example in issue stfc#484.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8ae7dad to
8baa74b
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new default-enabled parser extension, format-missing-comma, to accept missing commas between character-string edit descriptors and adjacent format items in FORMAT specifications (as supported by common compilers), addressing issue #484 and updating tests/docs accordingly.
Changes:
- Add
format-missing-commato the defaultEXTENSIONSlist. - Extend
Format_Item_C1002matching with an extension-aware fallback path to parse missing-comma constructs involving character literals. - Update/expand tests and user documentation (plus changelog) to reflect the new extension and its behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/fparser/two/utils.py | Registers the new format-missing-comma extension as enabled by default. |
| src/fparser/two/Fortran2003.py | Implements the extension logic in Format_Item_C1002 and adds helper for splitting character literals. |
| src/fparser/two/tests/fortran2003/test_format_specification_r1002.py | Updates negative/positive expectations for C1002-related missing-comma cases with the extension enabled/disabled. |
| src/fparser/two/tests/fortran2003/test_format_item_c1002.py | Adds direct tests covering the new missing-comma parsing behavior and disabled-extension behavior. |
| doc/source/fparser2.rst | Documents the new extension and notes re-generation behavior (commas reintroduced). |
| CHANGELOG.md | Records the new extension addition. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if not string or string[0] not in "'\"": | ||
| return None | ||
| quote = string[0] | ||
| index = 1 |
There was a problem hiding this comment.
This is intentional: a char-string-edit-desc may not have a kind parameter — F2008 (J3/10-007r1) 10.3.2, C1013 (R1021): "A kind parameter shall not be specified for the char-literal-constant"; likewise F2003 (WG5/N1601) 10.2.1, C1012 (R1019). Compilers enforce this (e.g. gfortran rejects FORMAT(4_'a')), so since this extension exists to mirror what compilers accept for missing commas, recognising kind-prefixed literals here would accept code that is invalid both per the standard and per the compilers. Happy to add kind-param handling if the maintainers prefer consistency with fparser's (lax) Char_Literal_Constant instead.
Closes #484.
Many compilers (gfortran, ifort, ifx) accept a missing comma between a character-string edit descriptor and a neighbouring format item:
Following the convention described in the developer guide, this adds a
format-missing-commaentry to theEXTENSIONSlist inutils.py(enabled by default, like the other extensions) and implements the relaxation inFormat_Item_C1002:matchbody becomes_standard_match(unchanged logic);matchnow runs the standard pass first and only falls back to_extension_matchwhen the standard pass finds no match and the extension is enabled — so standard-conforming code produces exactly the same tree as before (the standard pass can raiseNoMatchErrorfrom an eagerly-taken branch, which previously aborted matching entirely; it is now treated as no-match so the fallback can run);_extension_matchsplits the item at the boundary of the first character literal and matches both sides asFormat_Items.The full example from #484 parses with this change (verified verbatim). Also found independently while parsing MODFLOW-2005 (
gwf2swr7.f,gwf2swi27.fpp,gwf2lak7.f,gwf2sfr7.f).Two pre-existing negative tests in
test_syntaxerror_c1002assertedNoMatchErrorfor exactly the constructs this extension legalizes (('hello' 2/),('hello' 'hello')); they now assert the new behavior with the extension enabled and the old rejection with it disabled.Note: re-generating a format specification from the parse tree re-introduces the omitted commas (consistent with how
Format_Item_C1002renders its item pairs); this is documented in the extension section of the docs.pytest src/fparserpasses (2950 passed, 24 xfailed, 1 pre-existing xpassed)blackcleandoc/source/fparser2.rstand theFormat_Item_C1002docstring🤖 Generated with Claude Code