optional user-specified end-delimiters Per Bothner (16 Apr 2013 19:32 UTC)
|
Re: optional user-specified end-delimiters
John Cowan
(16 Apr 2013 21:46 UTC)
|
Re: optional user-specified end-delimiters
Per Bothner
(16 Apr 2013 23:25 UTC)
|
Re: optional user-specified end-delimiters
John Cowan
(17 Apr 2013 06:41 UTC)
|
Re: optional user-specified end-delimiters
Per Bothner
(17 Apr 2013 18:03 UTC)
|
Re: optional user-specified end-delimiters
John Cowan
(17 Apr 2013 18:08 UTC)
|
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 xxxxxx@bothner.com http://per.bothner.com/