java - 如何匹配 Clojure 中的多行正则表达式来解析 Groovy 源文件?

标签 java regex groovy clojure

我试图在 Groovy 源文件上运行 Clojure 正则表达式来解析各个函数。

// gremlin.groovy

def warm_cache() {
  for (vertex in g.getVertices()) {
    vertex.getOutEdges()
  }
}

def clear() {
  g.clear()
}

这是我在 Clojure 中使用的模式:

(def source (read-file "gremlin.groovy"))

(def pattern #"(?m)^def.*[^}]")   

(re-seq pattern source)

但是,它只是抓取第一行,而不是多行函数。

最佳答案

为了演示如何从 GroovyRecognizer 获取 AST,并避免尝试使用正则表达式解析语言,您可以在 Groovy 中执行此操作:

import org.codehaus.groovy.antlr.*
import org.codehaus.groovy.antlr.parser.*

def code = '''
// gremlin.groovy

def warm_cache() {
  for (vertex in g.getVertices()) {
    vertex.getOutEdges()
  }
}

def clear() {
  g.clear()
}
'''


def ast = new GroovyRecognizer( new GroovyLexer( new StringReader( code ) ).plumb() ).with { p ->
  p.compilationUnit()
  p.AST
}


while( ast ) {
  println ast.toStringTree()
  ast = ast.nextSibling
}

打印出每个 GroovySourceAST 的 AST AST 中的节点,给你(对于这个例子):

 ( METHOD_DEF MODIFIERS TYPE warm_cache PARAMETERS ( { ( for ( in vertex ( ( ( . g getVertices ) ELIST ) ) ( { ( EXPR ( ( ( . vertex getOutEdges ) ELIST ) ) ) ) ) )
 ( METHOD_DEF MODIFIERS TYPE clear PARAMETERS ( { ( EXPR ( ( ( . g clear ) ELIST ) ) ) )

您应该能够使用 Clojure 的 java 互操作和 groovy-all jar 文件做同样的事情


编辑

要获得更多信息,您只需深入研究 AST 并稍微操作一下输入脚本。将上述代码中的 while 循环更改为:

while( ast ) {
  if( ast.type == GroovyTokenTypes.METHOD_DEF ) {
    println """Lines $ast.line to $ast.lineLast
              |  Name:  $ast.firstChild.nextSibling.nextSibling.text
              |  Code:  ${code.split('\n')[ (ast.line-1)..<ast.lineLast ]*.trim().join( ' ' )}
              |   AST:  ${ast.toStringTree()}""".stripMargin()
  }
  ast = ast.nextSibling
}

打印出来:

Lines 4 to 8
  Name:  warm_cache
  Code:  def warm_cache() { for (vertex in g.getVertices()) { vertex.getOutEdges() } }
   AST:   ( METHOD_DEF MODIFIERS TYPE warm_cache PARAMETERS ( { ( for ( in vertex ( ( ( . g getVertices ) ELIST ) ) ( { ( EXPR ( ( ( . vertex getOutEdges ) ELIST ) ) ) ) ) )
Lines 10 to 12
  Name:  clear
  Code:  def clear() { g.clear() }
   AST:   ( METHOD_DEF MODIFIERS TYPE clear PARAMETERS ( { ( EXPR ( ( ( . g clear ) ELIST ) ) ) )

显然,Code: 部分只是将行重新连接在一起,因此如果粘贴回 groovy 可能无法正常工作,但它们可以让您了解原始代码...

关于java - 如何匹配 Clojure 中的多行正则表达式来解析 Groovy 源文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10514215/

相关文章:

Java 扫描器反斜杠分隔符

regex - 电子邮件验证 - @ 之前和点之前的字符长度

interface - 如何使 Groovy 类看起来像 Map 到 Java 代码而不显式实现 Map 接口(interface)

java - 将自定义环境变量传递给 maven cargo

java - 正则表达式从日志条目中获取请求参数的特定部分?

java - 带引擎的 Sql 解析器

grails - 没有命名空间的Groovy XMLSlurper命名空间错误

curl - Jenkins Pipeline - 使用 sh 和curl 获取 java.io.NotSerializedException

java - 是否有用于创建具有指定大小和内容的列表的实用方法?

java - MalformedURLException 虽然我已经用 %20 替换了空格