lexy icon indicating copy to clipboard operation
lexy copied to clipboard

dsl for real numbers

Open facontidavide opened this issue 3 years ago • 11 comments
trafficstars

I am new to the library so I apologize if I am missing something.

Exploring the examples I can't find anything similar to dsl::integer for real numbers. O course I understand that parsing real numbers is complicated having a lot of different representations, but I would need something simple such as 5.67 to start with.

My application is an AST similar to the calculator example.

facontidavide avatar Sep 03 '22 15:09 facontidavide

I plan on adding that in the future.

What I'm doing right now as a workaround is to manually parse digits + period + digits, capture that and call std::stod/std::from_chars on the lexeme.

foonathan avatar Sep 03 '22 16:09 foonathan

Would you mind adding a code snippet ? (I am trying to do the same)

facontidavide avatar Sep 03 '22 16:09 facontidavide

https://godbolt.org/z/1WExWsod9

If you want to use a different decimal separator, you need to capture each dsl::digits part individually and then manually build a string in the format expected by std::stod.

foonathan avatar Sep 03 '22 17:09 foonathan

Thanks. You saved me a ton of time :smile: .

I am still learning, and I would have needed a lot of time to figure this out.

facontidavide avatar Sep 03 '22 17:09 facontidavide

I'm reopening this as I do want to add it properly.

foonathan avatar Sep 03 '22 17:09 foonathan

I am using type erased numbers (for the sake of simplicity, let's assume it is std::variant<int,double>).

The matching doesn't seem to work as expected if I do this: https://godbolt.org/z/jWG4zoKTP

test string would be:

  • -7 -> expects int: -7
  • 3.14 -> expects double: 3.14
  • 1e2 -> expects double: 100
  • 0x7 -> expects int: 7
  • 0x7e8 -> expects error

My point is that if you are implementing dsl::real, it would be interesting to use it alongside dsl::integer.

facontidavide avatar Sep 04 '22 11:09 facontidavide

I am realizing that what I should probably do is similar to ast::json_number in the json.cpp example

facontidavide avatar Sep 04 '22 12:09 facontidavide

The matching doesn't seem to work as expected if I do this: https://godbolt.org/z/jWG4zoKTP

Choice is ordered and takes the first branch that matches. When it sees 5.3 dsl::integer matches so that is parsed; it then leaves .3 unconsumed. I recommend attempting to match the real number first and ensuring that it does not match integers only: https://godbolt.org/z/dn83sxqdG

Please ask more questions in the discussions in the future.

foonathan avatar Sep 04 '22 13:09 foonathan

Relevant resources for float parsing:

  • https://github.com/lemire/fast_double_parser
  • https://arxiv.org/abs/2101.11408
  • https://www.exploringbinary.com/how-strtod-works-and-sometimes-doesnt/

foonathan avatar Nov 24 '22 21:11 foonathan

Are you planning to parse those as valid? .3 0. 43.

I think I managed to parse those at one point, but it was 2 additional rules, so it was not very efficient.

I don't know what ISO or other standard say about this, but to me it seems that something like .003 should not be standard, but as soon as it's valid code somewhere, people are going to ask for it.

jokoon avatar Sep 27 '23 07:09 jokoon

The interface I'm imagining is similar to the split between dsl::digits and dsl::integer.

I'm envisioning a dsl::number rule that takes token rules. One for matching the integer part, one for matching a fractional part, and one for matching the exponent.

So you can completely define what's considered to be valid.

foonathan avatar Sep 27 '23 10:09 foonathan