This document describes the various considerations that have gone into the decision as how to implement RFC #3101.
In particular, there are two main implementation strategies under consideration:
foo"bar"
, foo#bar
, and foo#99
.
match"foo"
foo
and "bar"
token, and determines there is no whitespace between them, and we are in Rust 2021, it would error.Proposed result: On balance, we should make an edition-dependent lexer. In particular, the ergonomic hit of requiring independent lexing outweighs the pro of allowing more procedural macros, particularly given that LEX is more forwards compatible. There doesn't seem to be a killer argument against LEX.
The following points were raised to help in deciding between those two approaches.
Today the lexer lexes things different depending on prefix:
"foo"
is a standard string and cannot, for example, contain invalid UTF-8 or illegal escape sequences like \xXX
r"foo"
is a raw string and can (with #
) embed "
or other escape sequencesb"foo"
is a byte string and can only contain ASCIIThere are many future extensions that might want their own lexing rules:
f"foo{bar("")}"
might want to permit ""
recursively inside of code blocks.c"foo"
, for C strings, might want to support escape sequences.Using JOINTNESS information would however force those "foo"
strings to be lexed according to the traditional rules. We could use #
escaping to get raw string behavior and then re-implement the various rules in the parser, but that's not terribly ergonomic (c#"foo"#
etc).
Using LEX will require the lexer to have knowledge of editions. Existing APIs that tokenize do somewhat depend on this, but they can be deprecated.
For example, match”foo”
. Unless the lexer knows about keywords, this code will become an error under LEX (though it could be readily accommodated under JOINTNESS). It seems ok for this to be an error though: match
does indeed resemble a prefix here, and perhaps we would ultimately want to give some semantics to that.
If you have a macro-rules like
macro_rules! m {
($x:expr) => {
}
($($y:tt)) => {
}
}
then under JOINTNESS the behavior of m!(f#"foo")
could change when f#"foo"
becomes a legal expression. Fixing that requires making $x:expr
parse successfully with macro-rules but error later.
Under LEX this is a non-issue as we don't get there.
For example, one could write a macro to handle f""
strings by examining jointness (people do this today with span hacks). Even if we add different f
strings, your macro keeps working, because it operates before the parser comes along.
If we give lexer errors, we can eventually fix the rules and adopt a jointness based approach if we want.
How well is jointness preserved under macro rules? For example, if I do this, what happens?
macro_rules! m {
($a:tt $b:tt $c:Tt) => {
$a $b $c
}
}
Is m!(foo#bar)
still considered a series of three joint tokens? What about when they are not adjacent, or one inserts a #
:
macro_rules! m {
($a:tt # $c:Tt) => {
$a # $c
}
}
Lex error prevents us from getting here
Jointness means we always produce same set of tokens
But if can change the meaning of $t:expr
Jointness cannot be expressed in macro-rules, cannot take multiple tokens and preserve jointness
What happen with +=
today?
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing