如何从Java中的ANTLR监听器上下文获取行号

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

How to get line number from ANTLR listener context in Java

问题

我正在使用ANTLR监听器上下文(listener context)来获取任何方法的起始行号,使用以下Java代码:

@Override
public void enterFunctionDeclaration(KotlinParser.FunctionDeclarationContext ctx) {
  Token t = ctx.getStart();
  int lineno = t.getLine();
}

上述代码在代码中没有前导的\n\r时能够正常工作,但在有这些字符时会失败。

示例:

      Line 1 
      Line 2
      Line 3   func test(){
      Line 4  }

上述代码对于这种情况返回1,但我期望得到值3,因为这是函数“test”的起始行号。
我应该如何实现这一点?

英文:

I am using ANTLR listener context to get the starting line number of any method using the below Java code:

@Override
public void enterFunctionDeclaration(KotlinParser.FunctionDeclarationContext ctx) {
  Token t = ctx.getStart();
  int lineno = t.getLine();
}

The above code works fine if there is no leading \n or \r in the code, but fails otherwise.

Example:

  Line 1 
  Line 2
  Line 3   func test(){
  Line 4  }

The above code returns 1 for this case, but I am expecting value 3, as this is the starting line number of the function "test".
How can I achieve this?

答案1

得分: 1

我无法复现那个。顺便说一下,不是 getLineNo(),而是 getLine()

测试语法:

grammar T;

functionDeclaration
 : 'func' ID '(' ')' '{' '}'
 ;

ID     : [a-zA-Z]+;
SPACES : [ \t\r\n] -> skip;

以及 Java 测试类:

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

public class Main {

    private static void test(String source) {
        TLexer lexer = new TLexer(CharStreams.fromString(source));
        TParser parser = new TParser(new CommonTokenStream(lexer));
        ParseTreeWalker.DEFAULT.walk(new TestListener(), parser.functionDeclaration());
    }

    public static void main(String[] args) throws Exception {

        test("func test() {\n" +
             "}");

        test("\n" +
             "\n" +
             "func test() {\n" +
             "}");
    }
}

class TestListener extends TBaseListener {

    @Override
    public void enterFunctionDeclaration(TParser.FunctionDeclarationContext ctx) {
        Token t = ctx.getStart();
        int lineno = t.getLine();
        System.out.println("lineno=" + lineno);
    }
}

将会打印:

lineno=1
lineno=3
英文:

I could not reproduce that. Btw, it's not getLineNo() but getLine().

Test grammar:

grammar T;

functionDeclaration
 : 'func' ID '(' ')' '{' '}'
 ;

ID     : [a-zA-Z]+;
SPACES : [ \t\r\n] -> skip;

and the Java test class:

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

public class Main {

    private static void test(String source) {
        TLexer lexer = new TLexer(CharStreams.fromString(source));
        TParser parser = new TParser(new CommonTokenStream(lexer));
        ParseTreeWalker.DEFAULT.walk(new TestListener(), parser.functionDeclaration());
    }

    public static void main(String[] args) throws Exception {

        test("func test() {\n" +
             "}");

        test("\n" +
             "\n" +
             "func test() {\n" +
             "}");
    }
}

class TestListener extends TBaseListener {

    @Override
    public void enterFunctionDeclaration(TParser.FunctionDeclarationContext ctx) {
        Token t = ctx.getStart();
        int lineno = t.getLine();
        System.out.println("lineno=" + lineno);
    }
}

will print:

lineno=1
lineno=3

huangapple
  • 本文由 发表于 2020年10月22日 16:43:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/64478492.html
匿名

发表评论

匿名网友

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

确定