在写 go 的 parser 时,对于语法有定义有一些疑惑

2022-07-08 12:57:51 +08:00
 fumeboy

比如 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 之间只能用不含换行的注释

问题是,我如何能知道哪些空白区域可以换行,哪些地方不能?

1921 次点击
所在节点    Go 编程语言
9 条回复
qi1070445109
2022-07-08 13:09:14 +08:00
. 表示什么?
fumeboy
2022-07-08 13:16:37 +08:00
@qi1070445109 好像没有特殊含义,就是表示一个句子的结尾
Mohanson
2022-07-08 13:29:22 +08:00
tokenizer 的第一步是消除注释, 第二步是处理空格, 普遍是两种做法, 一是无用空格消除, 二是空格展开.

http://accu.cc/content/misc/minits/, 见词法分析一节.
fumeboy
2022-07-08 14:42:42 +08:00
嗯,但后来我发觉这个问题其实和 comment 没有关系,其实是空白区域能不能换行的问题,因为我刚才在文档里看到了多行注释会被视为一个换行符、单行注释会被视为一个空白符
fumeboy
2022-07-08 14:43:15 +08:00
@fumeboy 只是消除注释不能解决问题
fumeboy
2022-07-08 14:59:28 +08:00
我现在不得不手动遍历一下看看那些地方能够插入换行符 。。 像 `fmt.\nPrintln` 这样的 ident 也是 OK 的
RubyJack
2022-07-08 16:20:13 +08:00
fumeboy
2022-07-08 16:31:57 +08:00
@RubyJack 抱歉,没懂你的意思
chai2010
2022-07-12 19:40:06 +08:00
这明显是一个 BUG ,先把 patch 准备好了再提 issue 。重写 parser 没必要严格遵循语法,简单点才好。
也开一个手写 uGo 的坑,欢迎关注: https://github.com/wa-lang/ugo-compiler-book

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/864910

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX