【问题标题】:Is there used incorrect terminology in description of a compile error as to 'for' syntax in golang?在描述 golang 中的“for”语法的编译错误时,是否使用了不正确的术语?
【发布时间】:2017-12-07 00:28:11
【问题描述】:

我尝试使用类似的东西

for i := 0; i < len(bytes); ++i {
        ...
}

这是不正确的,我收到了错误

语法错误:意外 ++,需要 表达式

那是因为++i不是我想的表达方式。

然后我发现i++(它在for循环中工作)也不是根据the documentation的表达式。

我在some cases(现在我认为在所有情况下)中也遇到过不能用语句代替表达式。

现在如果我们回到错误,我们会看到for 循环需要一个表达式。我对此感到困惑。我检查了the documentation 的另一部分,结果发现for 需要声明。

带有for子句的语句

带有 ForClause 的“for”语句也受其控制 条件,但另外它可以指定一个 init 和一个 post 声明

我从问题开始(我比最后一个问题更喜欢这个问题,因为我认为它是关于语言不熟悉的)

语句被接受为表达式是循环语法的特殊情况还是golang中还有其他情况?

在写问题和检查文档的过程中,我遇到了一个问题

在描述错误时是否使用了不正确的术语,应该修复以免混淆?还是在某些情况下通常用语句和表达式等术语来代替?

【问题讨论】:

  • 我实际上写了 ++i 不是我的问题中的表达,所以我没有问它并在文档中指出了相同的位置。我看到 i++ 是语句,我也写了关于它我不明白为什么当我可以使用语句时错误说期望表达式并且它令人困惑。
  • 啊,我明白你现在在问什么了。很抱歉造成混乱。
  • @DanielGrankin 你是对的,错误信息“有点”误导,但它从来没有打扰过我。如果将 ++i 替换为 break(或任何其他非简单语句),则会收到相同的错误消息。如果您愿意,可以提出问题。
  • 我想说谢谢那些对这个问题感兴趣并试图找出“问题”的人。另外我想对所有阅读评论的人说,如果您真的不知道答案,请不要关闭,抹黑一个问题。

标签: go compiler-errors syntax-error


【解决方案1】:

The Go Programming Language Specification

Primary expressions

主表达式是一元和二元表达式的操作数。

PrimaryExpr =
  Operand |
  Conversion |
  PrimaryExpr Selector |
  PrimaryExpr Index |
  PrimaryExpr Slice |
  PrimaryExpr TypeAssertion |
  PrimaryExpr Arguments .

Selector       = "." identifier .
Index          = "[" Expression "]" .
Slice          = "[" [ Expression ] ":" [ Expression ] "]" |
                 "[" [ Expression ] ":" Expression ":" Expression "]" .
TypeAssertion  = "." "(" Type ")" .
Arguments      = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .

运算符和标点符号

以下字符序列表示运算符:

++    
--    

Operators

运算符将操作数组合成表达式。

Expression = UnaryExpr | Expression binary_op Expression .
UnaryExpr  = PrimaryExpr | unary_op UnaryExpr .

binary_op  = "||" | "&&" | rel_op | add_op | mul_op .
rel_op     = "==" | "!=" | "<" | "<=" | ">" | ">=" .
add_op     = "+" | "-" | "|" | "^" .
mul_op     = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .

unary_op   = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .

运算符优先级

++ 和 -- 运算符构成语句,而不是表达式。

IncDec statements

“++”和“--”语句将其操作数递增或递减 无类型常量 1. 与赋值一样,操作数必须是 可寻址或地图索引表达式。

IncDecStmt = Expression ( "++" | "--" ) .

++-- 是运算符。 ++-- 运算符构成语句,而不是表达式。

IncDecStmt = Expression ( "++" | "--" ) . 

当编译器遇到++ 运算符时,它希望它前面紧跟一个表达式。

例如,

package main

func main() {

    // syntax error: unexpected ++, expecting expression
    for i := 0; i < 1; ++i {}
}

游乐场:https://play.golang.org/p/y2d9ijeMdw

输出:

main.go:6:21: syntax error: unexpected ++, expecting expression

编译器抱怨语法。它发现了一个 ++ 运算符,前面没有紧接的表达式:syntax error: unexpected ++, expecting expression

【讨论】:

  • 但是即使我们写for i := 0; i &lt; 1; break {},我们也会得到同样的错误(unexpected break, expecting expression)。 break 之前没有预期的表达式。
  • 感谢您的解释!至少对我来说,这个错误的描述性不是很好,现在很明显,描述是合理的,而且它来自哪里。
【解决方案2】:

Go 规范说 for 子句的 post 语句接受(除其他外)IndDec 语句。

IncDec 语句定义为:IncDecStmt = Expression ( "++" | "--" ) .

解析器发现一个 IndDec 语句但一个空表达式,因此吐出错误“期望表达式”。

编辑:这可能会失败,因为要解析 SimplStmt 的后备节点是一个表达式。 IncDecStmt 失败,因此它继续使用默认值。该错误准确地反映了冒泡的最新错误。

虽然错误消息是正确的,但它有点误导。但是,修复它需要传递更多关于正在解析的当前树的上下文。例如:bad ForClause: bad PostStmt: bad SimpleStmt: expected expression

仍然存在expected expression 是最后遇到的错误的问题。在此之前,它无法解析 IncDecStmt 但该错误被吞下,因为它依赖于表达式。这同样适用于树的更高级别。

即使没有这个问题,它也会比当前的错误消息更加笨拙,甚至可能更令人困惑。不过,您可能想征求 Go 人员的意见。

【讨论】:

  • 所以如果有人试图使用语句而不是表达式stackoverflow.com/questions/23880663/… 他被否决了,如果错误消息说在语句可以使用时使用表达式也是正常的,是吗?
  • 我只是想知道这很好我没有假装它不是。目前我认为这不正常。
  • SimpleStmt parser 尝试匹配表达式,如果没有其他方法。这意味着如果它在解析其他人时没有失败(例如:SendStmtAssignment 等...),它将无法尝试解析表达式。
  • @Marc 生成的错误消息是给工具的用户,而不是给工具的编写者或维护者,因此错误消息应该是最对用户有用且相关,而不是反映如何何时解析器得出语法无效的结论。
  • 我仍然同意。我在之前的 cmets 中提到的问题与“你究竟返回什么错误信息”有关?这完全是为了向用户提供可操作的信息,而不是让他们淹没在大量不相关的数据中。我唯一的观点是,在解析方面可能没有一个完美的答案,当然也不是一个简单的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
相关资源
最近更新 更多