为什么Vims errorformat不采用正则表达式?

时间:2009-05-28 09:00:35

标签: vim

Vims errorformat(用于解析编译/构建错误)使用c中的一种神秘格式来解析错误。

尝试为nant设置errorformat似乎几乎不可能,我已经尝试了很多个小时而且无法得到它。我也从我的搜索中看到,很多人似乎都遇到了同样的问题。解决这个问题的正则表达式需要写一些。

那为什么vim仍然使用这种格式?很可能C解析器速度更快,但对于最多每隔几分钟发生一次的事情几乎不相关。有充分的理由还是只是一件历史文物?

5 个答案:

答案 0 :(得分:7)

并不是说Vim使用来自C的神秘格式。它使用来自scanf想法,这是一个C函数。这意味着匹配错误消息的字符串由3部分组成:

  • 空白
  • 字符
  • 转换规范

空格是你的标签和空格。字符是字母,数字和其他正常的东西。转换规范是以'%'(百分号)字符开头的序列。在scanf中,您通常会将输入字符串与%d或%f匹配,以转换为整数或浮点数。使用Vim的错误格式,您将在输入字符串(错误消息)中搜索文件,行和其他编译器特定信息。

如果您使用scanf从字符串“99瓶啤酒”中提取整数,那么您将使用:

int i;
scanf("%d bottles of beer", &i); // i would be 99, string read from stdin

现在有了Vim的错误格式,它会变得有点棘手,但它确实试图轻松匹配更复杂的模式。比如多行错误消息,文件名,更改目录等等。错误格式帮助中的一个示例很有用:

1  Error 275
2  line 42
3  column 3
4  ' ' expected after '--'

The appropriate error format string has to look like this:

  :set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m

这里%E告诉Vim它是多行错误消息的开头。 %n是错误号。 %C是多行消息的延续,%l是行号,%c是列号。 %Z标记多行消息的结尾,%m匹配将在状态行中显示的错误消息。你需要用反斜杠来逃避空间,这会增加一些额外的怪异。

虽然使用正则表达式最初看起来似乎更容易,但这种迷你语言专门用于帮助匹配编译器错误。它有很多快捷方式。我的意思是你不必考虑匹配多行,多个数字,匹配路径名称(只需使用%f)。

另一个想法:如果你只使用普通的正则表达式,你会如何将数字映射到平均行数,或者将字符串映射到平均文件或错误消息?按组位置?这可能有用,但不会很灵活。另一种方式是命名捕获组,但是这个语法看起来很像是一个简短的手。您实际上可以使用.*等正则表达式通配符 - 使用此语言编写%.%#

好的,所以它并不完美。但这也不是不可能的,并且以自己的方式有意义。陷入困境,阅读帮助并停止抱怨! : - )

答案 1 :(得分:0)

我建议为编译器编写一个后处理过滤器,它使用正则表达式或其他任何东西,并以简单的格式输出消息,很容易为它编写errorformat。为什么要学习一些新的,巴洛克式的单用途语言,除非你必须这样做?

答案 2 :(得分:0)

根据:help quickfix

  

也可以指定(几乎)任何支持Vim的常规   格式化字符串中的表达式。

然而,文档令人困惑,我没有花太多时间来验证它的工作原理和实用性。您仍然需要使用类似scanf的代码来提取文件名等。

答案 3 :(得分:0)

使用它们很痛苦,但要明确:可以使用正则表达式(主要是)。

来自文档:

Pattern matching

The scanf()-like "%*[]" notation is supported for backward-compatibility
with previous versions of Vim.  However, it is also possible to specify
(nearly) any Vim supported regular expression in format strings.
Since meta characters of the regular expression language can be part of
ordinary matching strings or file names (and therefore internally have to
be escaped), meta symbols have to be written with leading '%':
    %\      The single '\' character.  Note that this has to be
            escaped ("%\\") in ":set errorformat=" definitions.
    %.      The single '.' character.
    %#      The single '*'(!) character.
    %^      The single '^' character.  Note that this is not
            useful, the pattern already matches start of line.
    %$      The single '$' character.  Note that this is not
            useful, the pattern already matches end of line.
    %[      The single '[' character for a [] character range.
    %~      The single '~' character.
When using character classes in expressions (see |/\i| for an overview),
terms containing the "\+" quantifier can be written in the scanf() "%*"
notation.  Example: "%\\d%\\+" ("\d\+", "any number") is equivalent to "%*\\d".
Important note: The \(...\) grouping of sub-matches can not be used in format
specifications because it is reserved for internal conversions.

答案 4 :(得分:-3)

lol尝试查看实际的vim源代码。它是一个C代码的巢,如此古老而模糊,你会认为你正在进行考古挖掘。

至于为什么vim使用C语法分析器,有很多好的理由从它开始就非常普遍。但真正的原因是,在过去20年的某个时候,有人写它来使用C解析器并且它可以工作。没有人改变它的作用。

如果它不起作用 ,vim社区会告诉您自己编写。愚蠢的开源混蛋。