比如 import 语句的定义如下,可知 import 语句由 “import” + 可选的 ImportSpec + ImportPath 组成 ( https://go.dev/ref/spec#ImportSpec )
ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = string_lit .
但问题是,连接这三者的“空白区域”的定义并不明确,比如,我认为 空白区域可以填充任意形式的注释,但并非如此:
import /*
*/f "fmt"
上面这个注释的使用是正确的
import /*
*/f /*
*/ "fmt"
但这个注释的使用就是错误的,ImportSpec 和 ImportPath 之间只能用不含换行的注释
问题是,我如何能知道哪些空白区域可以换行,哪些地方不能?
1
qi1070445109 2022-07-08 13:09:14 +08:00 via Android
. 表示什么?
|
2
fumeboy OP @qi1070445109 好像没有特殊含义,就是表示一个句子的结尾
|
3
Mohanson 2022-07-08 13:29:22 +08:00
tokenizer 的第一步是消除注释, 第二步是处理空格, 普遍是两种做法, 一是无用空格消除, 二是空格展开.
http://accu.cc/content/misc/minits/, 见词法分析一节. |
4
fumeboy OP 嗯,但后来我发觉这个问题其实和 comment 没有关系,其实是空白区域能不能换行的问题,因为我刚才在文档里看到了多行注释会被视为一个换行符、单行注释会被视为一个空白符
|
6
fumeboy OP 我现在不得不手动遍历一下看看那些地方能够插入换行符 。。 像 `fmt.\nPrintln` 这样的 ident 也是 OK 的
|
7
RubyJack 2022-07-08 16:20:13 +08:00
|
9
chai2010 2022-07-12 19:40:06 +08:00
这明显是一个 BUG ,先把 patch 准备好了再提 issue 。重写 parser 没必要严格遵循语法,简单点才好。
也开一个手写 uGo 的坑,欢迎关注: https://github.com/wa-lang/ugo-compiler-book |