编写编译模式regexps

时间:2015-01-07 23:00:43

标签: c# regex emacs compilation compilationmode

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

(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) )

以下两个答案都非常有用;我现在对系统的了解要好得多。


摘要:我的regexp用于匹配输出字符串,但不能在compilation-error-regexp-alist-alist中工作以匹配编译输出中的错误。

我发现编译模式regexps有点令人困惑。我已经编写了一个正则表达式,我知道使用rebuilder和compile.el中的原始正则表达式来处理我的错误字符串。

  

40> f:\ Projects \ dev \ source \ Helper.cs(37,22,37,45):错误CS1061:' foo.bar'不包含' function'的定义没有扩展方法'方法'接受类型' foo.bar'的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)

这是我的正则表达式:

(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)

显然,我只想尝试输出的第一行/列对。 (我很惊讶编译器正在输出4个数字而不是2个,但无论如何。)

如果我们看一下compile.el中的edg-1 regexp:

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

所以我想我对于如何传递参数感到困惑。在edg-1中,3和4来自哪里?我猜他们不对应捕获组?如果我通过在格式错误的消息上重新构建运行edg-1 regexp并进入子表达式模式,则0匹配整个匹配字符串,1匹配文件名和路径,2匹配行号。从查看文档(当我做M-x describe-variable)时,看起来它只关心子表达式在主表达式中的位置。无论哪种方式,我都明显误解了一些事情。

我还尝试修改官方csharp.el regexp以处理额外的两个数字,但没有运气。

(编辑,稍微修复了示例,更新了csharp regexp)

2 个答案:

答案 0 :(得分:1)

找到一些关于此的信息。

此页面有一个简化的解释:
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 那么,您的文件行列数为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]+ :
 \)

答案 1 :(得分:1)

我的水晶球提出了一个奇怪的解释:compilation-error-regexp-alist-alist只是匹配规则的集合,但它并没有说明要使用哪些规则。因此,如果您要使用新规则,则需要将csharp添加到compilation-error-regexp-alist

关于(3 . 4)的含义,请参阅C-h v compilation-error-regexp-alist