This page is part of the web mail archives of SRFI 108 from before July 7th, 2015. The new archives for SRFI 108 contain all messages, not just those from before July 7th, 2015.
This is a proposed syntax for optional user-specified end tokens for both SRFI-108 and SRFI-109. First the proposal, then a discussion comparing alternatives. PROPOSAL A string quasi-literal may have an optional end-label, specified by a '!' followed by an label. For example: &!END{ &|line1 &|line2 }!END Syntax: label ::= tagname-subsequent+ It seems reasonable to allow an integer label, so we allow starting with a digit. Thus for simplicity we also allow hyphen, underscore, or period. (In an unrelated change, I think tagname-subsequent should allow periods. XML compatibility is one reason.) extended-string-literal ::= "&" string-starttag? "{" initial-ignored? string-literal-part* "}!" string-endtag? string-starttag ::= "!" label string-endtag ::= "!" label The string-endtag is required if the string-starttag is specified, and of course the labels must much. Note this chance means that an extended-string-literal must be followed by a delimiter or end of input. For a named quasi-literal, we can use the constructor-name as an end-tag: &example{ &|line1 &|line2 }example DISCUSSION: Should we require a final "!" if there is no explicit label? Make it optional? I.e.: }example! You can add an explicit label: &example!23{ &|line1 &|line2 }example!23 or: &example!23{ &|line1 &|line2 }!23 (It's not clear all these options are all that useful.) extended-datum-body ::="&" cname datum-start-label? "{" initial-ignored? named-literal-part* "}" datum-end-label? | "&" cname datum-start-label? "[" expression* "]{" initial-ignored? named-literal-part* "}" datum-end-label?
datum-start-label ::= "!" label datum-end-label := cname "!"? | cname? "!" label If may occasionally be useful to make labels available for semantic information. One example is as implicit "id" attributes. To do that we modify the translation: &cname!label[init-args...]{content}cname!label ==>($construct$:cname init-args... $>>$ "content" ($construct-label$ "label"))
I.e. we add ($construct-label$ "label") as the final operand of the $construct$:foo. We also add a standard definition: (define ($construct-label$ label) "") This way the $construct-label$ by default becomes a no-op, including when using define-simple-constructor. ALTERNATIVES There are some plausible alternatives. For example we can put the end-tag just before the right brace. For named constructors we could use: &cname{ line1 line2 &cname} This works and parses unambiguously. However, it's difficult to come up with a "compatible" syntax for strings, as discussed below. Also, the start-of-literal and the end-of-literal both start with the same prefix "&cname", which makes visual scanning slower. We could add the "!" as also used for strings: &!cname} or: &cname!} The former appears incompatible with optional explicit labels (i.e. "cname!tag"), while the latter doesn't help much with the visual scanning problem. For strings we don't need the "&" since the end-delimiter is required if specified: &!END{ &|line1 &|line2 !END} This is a little tricky to parse, since you don't know that !END if an end-tag until you see the right-brace. (For the same reason it's not very human-readable.) However, it doesn't feel very consistent with the named-constructor case. We could avoid this by requiring a '&' before the end-tag, either: &END} or: &!END} The former feels inconsistent with named constructors (it seems to preclude explicit labels); the latter seems excessive. -- --Per Bothner per@xxxxxxxxxxx http://per.bothner.com/