Repository navigation
Conversation
|
@tabatkins honestly the most heartbreaking thing about all this to me is that I can't have |
|
@bgotink does this align with your understanding/experience/what you did in your lib? |
|
alright, tests added. This is ready for final review. |
| annotation as a "suffix", instead of prepending it between `(` and `)`. This | ||
| makes it possible to, for example, write `10px`, `10.5%`, `512GiB`, etc., which | ||
| are equivalent to `(px)10`, `(%)5`, and `(GiB)512`, respectively. | ||
|
|
There was a problem hiding this comment.
Just for readability purposes, I think it's worth mentioning the # escape hatch here with a reference to the "Explicit Suffix Type Annotation" section, at least when it comes to types like u32. For example, maybe:
To remove ambiguity, some suffixes must be prefixed with
#: for example,10.0u8is invalid, but10.0#u8is. The full list of rules for invalid suffixes is clarified in the "Explicit Suffix Type Annotation" section.
There was a problem hiding this comment.
I dropped a suggestion for this.
There was a problem hiding this comment.
Ah, GitHub collapsed it as "outdated" because they're bad
tabatkins
left a comment
There was a problem hiding this comment.
r+ after review of suggested changes
| annotation as a "suffix", instead of prepending it between `(` and `)`. This | ||
| makes it possible to, for example, write `10px`, `10.5%`, `512GiB`, etc., which | ||
| are equivalent to `(px)10`, `(%)5`, and `(GiB)512`, respectively. | ||
|
|
There was a problem hiding this comment.
I dropped a suggestion for this.
bgotink
left a comment
There was a problem hiding this comment.
This matches what I implemented apart from one test that appears to be wrong and one mistake on my end where the parser skips certain validations on # suffixes which makes 123#123 equivalent to ("123")123 which is wrong.
There was a problem hiding this comment.
integer can end on an underscore so this is actually valid and equivalent to (abc)123_
There was a problem hiding this comment.
correct. this is why we can't start a bare suffix with _, becuase the syntax would parse differently than intended.
|
The following tests that previously failed now run successfully:
|
|
Uggghhhhh. That makes sense. Looks like we’re gonna need to be more specific what order things run in. I have an idea for the grammar. |
Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
Looking at this... These should be dropped because they're ok now:
These tests should stay and continue to fail. Once you've hit a
|
|
uggghhhh I understand why those last 3 tests pass now. I want to do something about it, though. I don't like that. I wonder if there's a good way around it. |
|
@bgotink @tabatkins I've... kind of changed the rules a bit. They're simpler now. And most importantly: we have I checked #510 and I didn't see any discussion about us tackling these rules, because we were focusing so much on what the rules for the suffix should be that we didn't take a step back and think of these numbers as a whole, and how the number syntax in general could be addressed. Please lmk what you think. I think with these changes, we'll get the results I expected in #513 (comment) |
|
Some key changes:
|
|
I'm also wondering: could we just drop the exponent restriction (but keep the |
|
I don't think the specification prose as currently written does require or even allow a trailing I think either the description of the grammatical language needs tightening, or the grammar may now allow some undesirable constructions with underscores and suffixes. Specifically, I'm not sure whether Consider I'm not sure whether I am misreading the description of the grammar language. If there is an issue, either banning Something shaped like If nothing else, test cases including both underscores within the number and invalid suffixes will be good to ensure that the incorrect readings are detected. I also wonder in a similar way about |
| significand-initial = digit | ||
| - '0b' | ||
| - '0o' | ||
| - '0x' |
There was a problem hiding this comment.
This use of - isn't quite right - it's not subtracting from the LHS (the digit), it's imposing a wider restriction on the digit and its following character (which in this grammar would come from the start of bare-type-suffix).
I think this should instead be handled as a cut point on the hex/octal/binary productions, so that if you see their prefix you're committed. (We'll also have to specify that the ordering of | alternates is significant when cuts are involved, so normal-value is parsed first and gets to claim that syntax space with a cut before suffixed-decimal can run and claim it.)
Yup, the |
This isn't correct, there's still an unexpected parsing success in some cases. See If the part following the |
Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
|
This seems like a very useful feature but appears stuck at the moment. Would something like the following work?
These would then just work:
These would need an Explicit Suffix with
In the test cases mentioned above,
|
|
honestly it's less that it's stuck on specification, and more that it's stuck on at least one implementation. I started it in kdl-rs but dropped that work for now. If anyone ends up picking that up, it would help us figure out a lot of issues. |
|
My js implementation has support for one of the many versions discussed in this thread (honestly don't remember the exact details, it's been a while, the tests reference 07788d1 so probably the version as described in that commit) in the console on https://github.bram.dev/kdl/ If there's interest to toy with this I could update the implementation to the latest version in this PR, and we could then easily set this up under a flag on the playground so people can get a feel for what's being proposed. |
Co-authored-by: Bram Gotink <bram@gotink.me>
|
getting this on the playground would be awesome tbh |
|
I also have an implementation of this in https://github.com/mwh/kdly. It's gated behind a hard-coded boolean switch in the lexer (line 7, I believe it implements the latest version as discussed here. It accepts and rejects the examples from the specification. Of the new examples above, it does not permit |
i don't see it in the official list of implementations. is there a reason why you haven't submitted it? |
|
i don't think my implementation in go will be helpful here, because two projects in js and python are available, but i still can give some input from an implementer perspective. my project is aimed to be fully format-preserving. entries and annotations are represented like this: // Annotation = "(" Leading? Name Trailing? ")" Following?
type Annotation struct {
Leading Whitespace
Name String
Trailing Whitespace
Following Whitespace
}
// Entry = Slashdash? Key? Annotation? Value Trailing?
type Entry struct {
Slashdash *Slashdash
Key *Key
Annotation *Annotation
Value Value
Trailing Whitespace
}
the issue here is that however, it's a pretty funny thing that my number type is a string: type Number string // implements Valuei did that to store the original number format as in the source. and that also helps to resolve this situation, because the suffix annotation can just be stored as a part of this string. while that works, it blends the separation between values and annotations. previously it was only in the element tree, and now it lives with the number. it can be convenient to, for example, represent |
|
kdl-rs was mentioned previously, and it is also a format-preserving library. based on the code here: pub struct KdlEntry {
pub(crate) ty: Option<KdlIdentifier>,
pub(crate) value: KdlValue,
pub(crate) name: Option<KdlIdentifier>,
pub(crate) format: Option<KdlEntryFormat>,
#[cfg(feature = "span")]
pub(crate) span: SourceSpan,
}the same layout is used in kdl-rs: annotations are represented by an optional string. if it is available, then it is referred to as the whole block with the parentheses. however, values are represented as primitives (i don't know whether pub enum KdlValue {
String(String),
Integer(i128),
Float(f64),
Bool(bool),
Null,
}that leads to this, because the library cannot store numbers as strings for arbitrary large numbers. also, probably library is unable to store the source format of numbers in the first place. if suffix type annotations for numbers will be added, then there are two solutions:
the first solution is backwards compatible, but is pretty messy. just a flag like
the second solution is not backwards compatible and is a bit of a stretch for the end user (the number is a string and needs to be converted to the needed data type before use), but removes the limit on parseable numbers, stores the format and is able to store the annotation. i am not a kdl-rs contributor or even a rust developer at all, so i don't know about the policy of breaking changes in kdl-rs or in rust projects. but the library is already a v6.x.x, so i suppose there already were quite a bit. i saw that someone wants to rewrite parser internals, so i thought it's better to mention this now. |
|
also some comments for things i was involved in: in compressed format these annotations should probably always be stored in the prefix format anyway. while suffix format is able to be more compact, parsing the annotation once again to figure out whether it can be used as a suffix or not probably is not worth it. also probably many implementations won't support suffix format for a while, so storing all annotations as prefixes is better for compatibility. for kdl-in-json, all annotations should be considered as prefixed for serialization (from json to kdl). for deserialization, it is parsed and stored in the same field, because semantically prefix and suffix are identical. |
|
I fuzzed bgotink/kdl's vs kdly's implementation of number suffixes to see if there are differences. I found these:
I think bgotink/kdl is spec-compliant on 3, 8, and 9. kdly is compliant on 1 and 7. Neither is right on 2. And I'm not sure about 4, 5 and 6. |
i think, according to the current spec description and grammar:
i don't know how i feel about 6. i am going to say that it looks confusing enough to disallow it, so the regex above should include an underscore with the plus and minus |
|
I've fixed the four kdly cases there (2, 3, 8, 9). 4 & 5 should be errors because |
|
wanted to give it a try and implement it, but bumped into an interesting case: what we should do about keyword numbers? right now, according to the specification, bare suffix type annotations cannot be used with keyword numbers, because they are not decimals. but explicit suffixes say "any number". and spec says that numbers have 5 valid syntax variations, including keywords. e.g. this should be valid: node #inf#byteswhich is not the case for both is this an oversight or is this intended? personally, i don't see an issue here (looks okay and doesn't break anything), but thought i should mention it anyway |
|
as a follow-up, i checked the grammar and right now it doesn't even permit hex/octal/binary numbers with explicit suffixes: only decimals. however, the text says that |
6 is a conscious decision on my part, see #513 (comment): |
Fixes: #510