为什么这个Less表达式是一个语法错误,这取决于数学运算?

为什么这个Less表达式是一个语法错误,这取决于数学运算?,less,Less,我有以下一段简短的内容: @Foo: 50px; .someClass { width: calc(~'(100% - @{Foo}' - 5px); } 这个很好用。但是,如果我将此更改为: @Foo: 50px; .someClass { width: calc(~'(100% - @{Foo}' + 5px); } 我们现在有一个ParseError。我们使用的是稍旧一点的Less版本,但我在上试过,它仍然会坏 这是一个bug还是我在做一些愚蠢的事情?这是一个非常有

我有以下一段简短的内容:

@Foo: 50px;

.someClass {
    width: calc(~'(100% - @{Foo}' - 5px);
}
这个很好用。但是,如果我将此更改为:

@Foo: 50px;

.someClass {
    width: calc(~'(100% - @{Foo}' + 5px);
}
我们现在有一个
ParseError
。我们使用的是稍旧一点的Less版本,但我在上试过,它仍然会坏


这是一个bug还是我在做一些愚蠢的事情?

这是一个非常有趣的案例。下面的代码编译良好,并在打开时生成预期的输出(
--strict math=on

禁用“严格数学”(这是默认设置)时,两行都会导致编译器错误。下面给出了错误消息,这表明Less编译器正在尝试对
calc
函数内的值执行数学运算

OperationError:对无效类型的操作

正如max在其评论中所确认的那样,
e()
函数的行为(无论是在启用严格数学时还是在禁用严格数学时)都是正确的,错误消息也与预期的一样


理想情况下,对于
~”
语法,也应该看到与上述相同的行为,因为。但不幸的是,情况似乎并非如此。无论是否启用严格数学设置,代码都无法编译,显示的错误消息如下:

ParseError:无法分析调用参数或缺少“')”

错误消息表明它是解析错误,而不是操作错误。正如seven Phase max所指出的,解析器似乎不希望算术运算符跟随非数字的值,因此抛出了解析器错误。错误消息可能更友好:)

此问题仅在操作员为
+
*
时发生,而不是在操作员为
-
/
时发生。当使用
-
/
时,它们不能始终被视为数学运算符(因为
-
用于前缀,而
/
用于
行高的
字体
属性等)因此,编译器将它们作为标识符进行处理,但
+
*
始终是一个数学运算符,因此会引发问题。当使用
-
/
时,只会导致字符串连接


下面是修复此问题的推荐方法,因为它不会使编译器认为必须执行某种数学运算(并将其作为CSS的一部分留给用户代理处理):


注意:计算函数中缺少右大括号(
),但与本例无关。

错误是因为Less(使用
--strict math=off
)试图将数字(
5px
)添加到字符串(
~“…
)中,这当然是无效的操作。也就是说,两个代码段都会抛出一个错误(不知道为什么“旧版本”通过了第一个示例-但无论如何这是不正确的)。@seven Phase max:我认为为旧版本(带有
e()
)和strict math=off的代码段)显示的错误消息是正确的,因为它表示对无效类型的操作。不是吗?实际上,较新的版本(带有
~“
”的版本)给出了一条错误消息,这可能会被视为有点误导,因为它没有说对无效类型的操作,而是说解析错误。嗯,是的,
~“…”
版本的错误是意外的(应该与
e
版本相同)-因此看起来像是一种错误/伪造的(解析器对函数/混合参数值使用稍有不同的解析算法,在这种特殊情况下,似乎根本不希望在“不是数字”之后有任何算术运算(而将yes
-
作为n标识符传递)。也就是说,
@var:~“…”+5px
语句解析得很好(因为属性/变量值解析更宽松,更能容忍假定的无效值),但参数值解析更严格(没有
not-a-number arithm op…
模式),因此会出现错误(但它确实可能是更友好的错误消息).无论哪种方式,您建议的解决方法实际上都是正确的语法(尽管有令人困惑的错误消息,原始代码段在假设编译器是文本处理器的情况下是错误的,而它不是,并且在
严格数学
模式下,解析器试图理解代码,在这种特殊情况下,
字符串+…
值是故意无效的CSS,而解析器在本例中从未预料到这一点。)文本)。
@Foo: 50px;
.someClass {
  width: calc(e('(100% - @{Foo}') - 5px);
}
.someClass {
  width: calc(e('(100% - @{Foo}') + 5px);
}
@Foo: 50px;
.someClass {
  width: calc(~'(100% - @{Foo} - 5px');
}
.someClass {
  width: calc(~'(100% - @{Foo} + 5px');
}