kdl-org / kdl

the kdl document language specifications
https://kdl.dev
Other
1.12k stars 62 forks source link

[kdl v2] .1 is currently an ident string, should it be a number? #366

Closed tabatkins closed 9 months ago

tabatkins commented 9 months ago

Currently, the decimal grammar is sign? integer ('.' integer)? exponent?. In other words, you must have one integer digit, and all the other parts are optional. This means that .1 is not a decimal number; instead, it's a valid ident.

I don't think this is very good. I know JSON doesn't allow a number to start with a decimal point, but writing .1 is a syntax error in JSON and you'll catch it. KDL's flexibility works against it here, making it accidentally masquerade as a valid value of a different type. Meanwhile, YAML allows .1, as do JS and CSS (and every other programming language I've ever used, I think?)

I suggest we change the grammar of decimal to:

decimal := sign? ( integer ('.' integer)? | '.' integer ) exponent?

and then modify the "bare-identifier" grammar to be able to look three characters forward, so it can successfully exclude -.1x from being an ident.

bare-identifier := ((identifier-char - digit - sign - '.') identifier-char* | sign ((identifier-char - digit - '.') identifier-char*)? | sign '.' ((identifier-char - digit) identifier-char*)? | '.' ((identifier-char - digit) identifier-char*)?) - keyword
larsgw commented 9 months ago

We can also disallow .0 and -.0 (and the like) entirely, from both decimals and identifiers/strings.

tabatkins commented 9 months ago

Yes, that would be my second preference. I'd much prefer they be numbers, since that's widely accepted as a number in many contexts, but if we think that shouldn't be done I'd at least like to make it a syntax error, like JSON.

zkat commented 9 months ago

I prefer -.0 and .0 both be illegal tbh.

tabatkins commented 9 months ago

That's acceptable. Would you like me to integrate that into the v2 branch?

zkat commented 9 months ago

Yes, please.

tabatkins commented 9 months ago

Done!