Как разобрать символы из кода Python с помощью Antlr? - PullRequest
0 голосов
/ 10 октября 2019

Я использую грамматику Python3 из нижеуказанного местоположения,

https://github.com/antlr/grammars-v4/blob/master/python3/Python3.g4

У меня есть следующий код для разбора,

ANTLRInputStream input = new ANTLRInputStream(new FileInputStream("Functions.py"));
Python3Lexer lexer = new Python3Lexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
Python3Parser parser = new Python3Parser(tokens);

ParseTree tree = parser.funcdef(); //Not sure what to do here
ParseTreeWalker walker = new ParseTreeWalker();

walker.walk(new Listener(), tree);

Слушатель.java

public class Listener extends Python3BaseListener{
    @Override
    public void enterImport_name(Python3Parser.Import_nameContext ctx) { 
        System.out.println(ctx.getText());
    }

    @Override 
    public void enterFuncdef(Python3Parser.FuncdefContext ctx) { 
    System.out.println(ctx.getText()); //returns the whole code as string
    }   
}

Я пытаюсь прочитать все импорты, переменные и имена методов вместе с аргументами из файла python.

Как я могу это сделать?

1 Ответ

1 голос
/ 12 октября 2019

Это не тривиальная проблема. В качестве общего способа написания слушателей я бы порекомендовал вам получить код для распечатки дерева разбора, добавить его в свою программу и попробовать несколько разных исходных файлов. Затем вы можете решить, как писать слушатели и для каких узлов.

Например, https://github.com/antlr/grammars-v4/blob/master/python3/examples/base_events.py, первое поддерево импорта выглядит так:

  ( stmt
    ( simple_stmt
      ( small_stmt
        ( import_stmt
          ( import_name
            ( TOKEN i=2 t=import
            ) 
            ( dotted_as_names
              ( dotted_as_name
                ( dotted_name
                  ( HIDDEN text=\ 
                  ) 
                  ( TOKEN i=4 t=collections
      ) ) ) ) ) ) ) 
      ( TOKEN i=5 t=\r\n
  ) ) ) 

Вынужно будет взглянуть на грамматику и убедиться, что ваши примеры действительно охватывают грамматику. Для base_events.py import_from не выполняется (https://www.geeksforgeeks.org/import-module-python/),, поэтому вам придется написать несколько примеров, использующих этот синтаксис. Учитывая то, что вы сказали, и то, что я вижу, я бы создал слушатель для контекста dotted_as_name, проверяя, что его родитель - import_stmt, затем просто получите текст первого дочернего элемента. enterImport_name () - хороший выбор, если вас не волнует «import», «as», и запятые также появляются в строке, возвращаемой из getText ().

Но, думаю, у вас есть картинка.

...