如何使用 Kotlin 检测 Java 文件中方法体的结束?

huangapple go评论71阅读模式
英文:

How to detect the end of a method body of a java file using kotlin?

问题

假设我们有一个类似这样的 Java 文件:

class Something {

   public static void main(String[] args){
      
      System.out.println("Hello World!");
   
   }

}

我想编写一些 Kotlin 代码,可以遍历这个 Java 文件并检测方法体(这里只有 main 方法)中有多少行代码。空行也要计算在内!

我的方法是简单地使用 FileforEachLine 方法逐行读取 Java 文件。我可以编写代码来检测方法的签名。现在我想要确定方法在哪里结束。我不知道如何做到这一点。

如果我简单地查找 },我的代码可能会错误地认为我们已经到达了方法体的末尾,但实际上我们只是在方法内的某个 if 语句体的末尾。

我该如何避免这个陷阱?

英文:

Let's say we have a java file that looks like this :

class Something {

   public static void main(String[] args){
      
      System.out.println("Hello World!");
   
   }

}

I would like to write some Kotlin code that would go through this java file and detect how many lines there is in the method body (Here is the main method only). Empty lines are counted!

My approach is to simply use the File forEachline method to read the java file line by line. I can write code to detect the method signature. Now I want to be able to determine where the method ends. I don't know how to do that.

If I simply look for "}" my code could make mistakes assuming that we are at the end of the body of the method while in reality we are at the end of an if statement body within the method.

How can I avoid this pitfall?

答案1

得分: 2

一种处理方法是跟踪已看到的开括号('{')和闭括号('}')的数量。在方法开始时,计数将增加到1。假设方法结构是有效的,在方法结束时,未闭合的括号数应为0。类似这样的伪代码应该可以工作:

int numLines = 1  #(假设方法开始行计入)
int numBrackets = 1  #(在找到方法的开括号后)
while(numBrackets > 0):
    if char == '{': numBrackets += 1
    if char == '}': numBrackets -= 1
    if char == newline: numLines += 1
if numBrackets != 0: FAIL
return numLines

编辑

正如 Gidds 在下面指出的,这个伪代码是不够的。一个更完整的答案需要考虑到并非所有括号都影响方法结构。一种方法是在解析当前字符时跟踪其所处的上下文。只有在有效的上下文中(非字符串文字、注释等)才增加/减少 numBrackets。尽管如 Gidds 所指出的,这会增加复杂性。更新后的伪代码:

int numLines = 1
int numValidBrackets = 1
Context context = Context(MethodStructure)
while(numValidBrackets > 0):
    context.acceptNextChar(char)
    if char == newline: numLines += 1
    if context.state() != MethodStructure: continue
    if char == '{': numValidBrackets += 1
    if char == '}': numValidBrackets -= 1
if numBrackets != 0: FAIL
return numLines
英文:

One way to approach this is keeping track of the number of open brackets('{') and close brackets ('}') seen. At the start of the method, the count will increment to 1. Assuming the method is validly structured, at the end of the method the number of unclosed brackets should be 0. Pseudocode like this should work:

int numLines = 1 (assuming method start line counts)
int numBrackets = 1 (after finding method open bracket for method)
while(numBrackets > 0)
    if char = '{' -> numBrackets++
    if char = '}' -> numBrackets--
    if char = newline -> numLines++
if numBrackets not 0 -> FAIL
return numLines

Edit

As noted by Gidds below, this pseudo-code is insufficient. A more complete answer will need to include the fact that not all brackets impact method structure. One way to approach this is by keeping track of the context of the current character being parsed. Only increment/decrement numBrackets when in a valid context (non-string literal, comment, etc..). Though as noted by Gidds, this will increase complexity. Updated Pseudocode:

int numLines = 1
int numValidBrackets = 1
Context context = Context(MethodStructure)
while(numValidBrackets > 0)
    context.acceptNextChar(char)
    if char = newline -> numLines++
    if(context.state() != MethodStructure) continue;
    if char = '{' -> numValidBrackets++
    if char = '}' -> numValidBrackets--
if numBrackets not 0 -> FAIL
return numLines

huangapple
  • 本文由 发表于 2020年9月22日 00:07:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63996051.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定