Repository: sphinx-doc/sphinx

Issue:
[C++] Problem parsing prototypes containing floating-point default values
Hello,

I am using sphinx + breathe to document a C++ software project. I have some function declarations which contain default floating-point parameters, which sometimes are expressed as literals in scientific notation, e.g., ``1e-6``. It seems like sphinx does not like them:

```
/home/yardbird/repos/pagmo2/doc/sphinx/docs/cpp/algorithms/de1220.rst:4: WARNING: Error when parsing function declaration.
If the function has no return type:
  Error in declarator or parameters and qualifiers
  Invalid definition: Expecting "," or ")" in parameters_and_qualifiers, got "e". [error at 183]
    pagmo::de1220::de1220(unsigned int gen = 1u, std::vector< unsigned int > allowed_variants = de1220_statics < void >::allowed_variants, unsigned int variant_adptv = 1u, double ftol = 1e-6, double xtol = 1e-6, bool memory = false, unsigned int seed = pagmo::random_device::next ())
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------^
```

I can provide a more detailed example, if needed.

Discussion:

Patch:
diff --git a/CHANGES b/CHANGES
index 6482e7f86..867b1dad9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -22,6 +22,7 @@ Bugs fixed
 * #5627: qthelp: index.html missing in QtHelp
 * #5659: linkcheck: crashes for a hyperlink containing multibyte character
 * #5754: DOC: Fix some mistakes in :doc:`/latex`
+* #5636: C++, fix parsing of floating point literals.
 
 Testing
 --------
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 5dfd8f5c3..7a84c3ba6 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -294,7 +294,18 @@
 _hex_literal_re = re.compile(r'0[xX][0-7a-fA-F][0-7a-fA-F]*')
 _binary_literal_re = re.compile(r'0[bB][01][01]*')
 _integer_suffix_re = re.compile(r'')
-_float_literal_re = re.compile(r'[+-]?[0-9]*\.[0-9]+')
+_float_literal_re = re.compile(r'''(?x)
+    [+-]?(
+    # decimal
+      ([0-9]+[eE][+-]?[0-9]+)
+    | ([0-9]*\.[0-9]+([eE][+-]?[0-9]+)?)
+    | ([0-9]+\.([eE][+-]?[0-9]+)?)
+    # hex
+    | (0[xX][0-9a-fA-F]+[pP][+-]?[0-9a-fA-F]+)
+    | (0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+([pP][+-]?[0-9a-fA-F]+)?)
+    | (0[xX][0-9a-fA-F]+\.([pP][+-]?[0-9a-fA-F]+)?)
+    )
+''')
 _char_literal_re = re.compile(r'''(?x)
     ((?:u8)|u|U|L)?
     '(


Test patch:
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index b8856824b..2602f73e6 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -124,8 +124,20 @@ def exprCheck(expr, id):
                 expr = i + l + u
                 exprCheck(expr, 'L' + expr + 'E')
     for suffix in ['', 'f', 'F', 'l', 'L']:
-        expr = '5.0' + suffix
-        exprCheck(expr, 'L' + expr + 'E')
+        for e in [
+                '5e42', '5e+42', '5e-42',
+                '5.', '5.e42', '5.e+42', '5.e-42',
+                '.5', '.5e42', '.5e+42', '.5e-42',
+                '5.0', '5.0e42','5.0e+42', '5.0e-42']:
+            expr = e + suffix
+            exprCheck(expr, 'L' + expr + 'E')
+        for e in [
+                'ApF', 'Ap+F', 'Ap-F',
+                'A.', 'A.pF', 'A.p+F', 'A.p-F',
+                '.A', '.ApF', '.Ap+F', '.Ap-F',
+                'A.B', 'A.BpF','A.Bp+F', 'A.Bp-F']:
+            expr = "0x" + e + suffix
+            exprCheck(expr, 'L' + expr + 'E')
     exprCheck('"abc\\"cba"', 'LA8_KcE')  # string
     exprCheck('this', 'fpT')
     # character literals