编写编译模式正则表达式

Writing compilation mode regexps

考虑到行和列范围的最终工作解决方案:

(csharp
 "^ *\(?:[0-9]+>\)*\(\(?:[a-zA-Z]:\)?[^:(\t\n]+\)(\([0-9]+\),\([0-9]+\),\([0-9]+\),\([0-9]+\)) *\: \(error\|warning\) *CS[0-9]+:)"
 1 (2 . 4) (3 . 5) )

下面的两个答案都非常有帮助;我现在更了解这个系统了。


总结:我的正则表达式可以匹配输出字符串,但不能在 compilation-error-regexp-alist-alist 中匹配我的编译输出中的错误。

我发现编译模式正则表达式有点混乱。我写了一个正则表达式,我知道它可以使用重建器和 compile.el.

中的原始正则表达式处理我的错误字符串

40>f:\Projects\dev\source\Helper.cs(37,22,37,45): error CS1061: 'foo.bar' does not contain a definition for 'function' and no extension method 'method' accepting a first argument of type 'foo.bar' could be found (are you missing a using directive or an assembly reference?)

这是我的正则表达式:

(pushnew '(csharp
 "^ *\(?:[0-9]+>\)*\(\(?:[a-zA-Z]:\)?[^:(\t\n]+\)(\([0-9]+\),\([0-9]+\),[0-9]+,[0-9]+) *\: \(?:error *CS[0-9]+:\)"
 2 3)
     compilation-error-regexp-alist-alist)

显然,我只是想获取输出的第一个 line/column 对。 (令我惊讶的是编译器输出的是 4 个数字而不是两个,但无论如何。)

如果我们查看 compile.el 中的 edg-1 正则表达式:

    (edg-1
 "^\([^ \n]+\)(\([0-9]+\)): \(?:error\|warnin\(g\)\|remar\(k\)\)"
 1 2 nil (3 . 4))

所以我猜我对参数的传递方式感到困惑。在edg-1中,3和4来自哪里?我猜他们不对应于捕获组?如果我在格式正确的错误消息上通过 re-builder 运行 edg-1 regexp 并进入子表达式模式,则 0 匹配整个匹配字符串,1 匹配文件名和路径,2 匹配行号。通过查看文档(当我执行 M-x describe-variable 时),它似乎只关心子表达式在主表达式中的位置。不管怎样,我显然误解了什么。

我也试过修改官方 csharp.el 正则表达式来处理额外的两个数字,但没有成功。

(编辑,稍微修复了示例,更新了 csharp 正则表达式)

找到了一些这方面的信息。

此页面有一个简化的解释:
http://praveen.kumar.in/2011/03/09/making-gnu-emacs-detect-custom-error-messages-a-maven-example/

引自页面 -

"Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK
HIGHLIGHT...]).  If REGEXP matches, the FILE'th subexpression
gives the file name, and the LINE'th subexpression gives the line
number.  The COLUMN'th subexpression gives the column number on
that line"

所以看起来格式是这样的:

(REGEXP FILE [LINE COLUMN TYPE HYPERLINK HIGHLIGHT...])

再次查看正则表达式,它看起来像是修改后的 BRE。

 ^                   # BOS
 \( [^ \n]+ \)       # Group 1

 (                   # Literal '('
 \( [0-9]+ \)        # Group 2
 )                   # Literal ')'

 : [ ] 

 \(?:
      error
   \|
      warnin\(g\)    # Group 3
   \|
      remar\(k\)     # Group 4
 \)

这里是edg-1

(edg-1
 "^\([^ \n]+\)(\([0-9]+\)): \(?:error\|warnin\(g\)\|remar\(k\)\)"
 1 2 nil (3 . 4))

哪里

"^\([^ \n]+\)(\([0-9]+\)): \(?:error\|warnin\(g\)\|remar\(k\)\)"
REGEXP ^^^^^^^^

 1     2    nil    (3 . 4)
 ^     ^     ^      ^^^^^
FILE LINE  COLUMN   TYPE

"TYPE is 2 or nil for a real error or 1 for warning or 0 for info.
TYPE can also be of the form (WARNING . INFO).  In that case this
will be equivalent to 1 if the WARNING'th subexpression matched
or else equivalent to 0 if the INFO'th subexpression matched."

因此,TYPE 是这种形式(警告。信息)

In the regex,
if capture group 3 matched (ie. warnin\(g\) ) it is equivalent to a warning.
If capture group 4 matched (ie. remar\(k\) ) it is equivalent to info.  
One of these will match.  

csharp 元素信息

查看您的 csharp 元素

"^ *\(?:[0-9]+>\)?\(\(?:[a-zA-Z]:\)?[^:(\t\n]+\)(\([0-9]+\),\([0-9]+\),[0-9]+,[0-9]+) *\: \(?:error *CS[0-9]+:\)"
2 3 4

而您的正则表达式(下方)实际上没有捕获组 4。
所以,你的 FILE LINE COLUMN of 2 3 4
可能应该是 1 2 3

这是引擎看到的正则表达式 -

 ^ 
 [ ]* 
 \(?:
      [0-9]+ > 
 \)?
 \(                            # Group 1
      \(?:
            [a-zA-Z] : 
      \)?
      [^:(\t\n]+ 
 \)
 (                             # Literal '('
      \( [0-9]+ \)                # Group 2
      ,
      \( [0-9]+ \)                # Group 3
      ,
      [0-9]+
      ,
      [0-9]+ 
 )                             # Literal ')'
 [ ]* \: [ ] 
 \(?:
      error [ ]* CS [0-9]+ :
 \)

我的crystal球给出了一个奇怪的解释:compilation-error-regexp-alist-alist只是一个匹配规则的集合,但并没有说使用哪些规则。所以如果你想使用你的新规则,你需要添加 csharpcompilation-error-regexp-alist

(3 . 4)的含义见C-h v compilation-error-regexp-alist