比如 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 之间只能用不含换行的注释
问题是,我如何能知道哪些空白区域可以换行,哪些地方不能?
|      1qi1070445109      2022-07-08 13:09:14 +08:00 via Android . 表示什么? | 
|      2fumeboy OP @qi1070445109 好像没有特殊含义,就是表示一个句子的结尾 | 
|  |      3Mohanson      2022-07-08 13:29:22 +08:00 tokenizer 的第一步是消除注释, 第二步是处理空格, 普遍是两种做法, 一是无用空格消除, 二是空格展开. http://accu.cc/content/misc/minits/, 见词法分析一节. | 
|      4fumeboy OP 嗯,但后来我发觉这个问题其实和 comment 没有关系,其实是空白区域能不能换行的问题,因为我刚才在文档里看到了多行注释会被视为一个换行符、单行注释会被视为一个空白符 | 
|      6fumeboy OP 我现在不得不手动遍历一下看看那些地方能够插入换行符 。。 像 `fmt.\nPrintln` 这样的 ident 也是 OK 的 | 
|  |      7RubyJack      2022-07-08 16:20:13 +08:00 | 
|  |      9chai2010      2022-07-12 19:40:06 +08:00 这明显是一个 BUG ,先把 patch 准备好了再提 issue 。重写 parser 没必要严格遵循语法,简单点才好。 也开一个手写 uGo 的坑,欢迎关注: https://github.com/wa-lang/ugo-compiler-book |