Использование ANTLR с Python с кодом, перенесенным с Java

У меня есть следующая грамматика, и я хочу проанализировать входные данные, чтобы получить связанные AST. С ANTLR для Java все просто. Начиная с ANTLR4, в файлах грамматики вам не нужно указывать параметры `output=AST; для получения информации AST.

Привет.g

grammar  Hello; //  Define  a  grammar  called  Hello
stat    :   expr NEWLINE       
    |   ID '=' expr NEWLINE 
    |   NEWLINE   
        | expr
    ;

expr:   atom (op atom)* ;

op  : '+'|'-' ;

atom    :   INT |   ID;

ID  :   [a-zA-Z]+ ;

INT :  [0-9]+ ;

NEWLINE :   '\r' ? '\n' ;

WS  :   [ \t\r\n]+ -> skip ;

Test.java

import  org.antlr.v4.runtime.*;
import  org.antlr.v4.runtime.tree.*;
import java.io.*;
import lib.HelloLexer;
import lib.HelloParser;
public class Test {
    public  static  void  main(String[]  args)  throws  Exception  {
        ANTLRInputStream  input  =  new  ANTLRInputStream("5 + 3");
        //  create  a  lexer  that  feeds  off  of  input  CharStream
        HelloLexer  lexer  =  new  HelloLexer(input);
        //  create  a  buffer  of  tokens  pulled  from  the  lexer
        CommonTokenStream  tokens  =  new  CommonTokenStream(lexer);
        //  create  a  parser  that  feeds  off  the  tokens  buffer
        HelloParser  parser  =  new  HelloParser(tokens);
        ParseTree  tree  =  parser.expr();  //  begin  parsing  at  init  rule
        //System.out(tree.toStringTree(parser));  //  print  LISP-style  tree
        System.out.println(tree.toStringTree(parser));
    }   
}

Вывод будет таким:

(expr (atom 5) (op +) (atom 3))

Но не могли бы вы рассказать мне, как получить тот же результат с реализацией Python? В настоящее время я использую среду выполнения ANTLR 3.1.3 для Python. Следующий код возвращает только "(+ 5 3)"

Test.py

import sys
import antlr3
import antlr3.tree
from antlr3.tree import Tree
from HelloLexer import *
from HelloParser import *

char_stream = antlr3.ANTLRStringStream('5 + 3')
lexer = ExprLexer(char_stream)
tokens = antlr3.CommonTokenStream(lexer)
parser = ExprParser(tokens)
r = parser.stat()

print r.tree.toStringTree()

person anhldbk    schedule 21.02.2014    source источник


Ответы (2)


Теперь для Python существует среда выполнения antlr4 (https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Python+Target), но toStringTree — это метод класса в средах выполнения Python. Вы можете вызвать его так, чтобы получить дерево синтаксического анализа в стиле lisp, включая строковые токены:

from antlr4 import *
from antlr4.tree.Trees import Trees
# import your parser & lexer here

# setup your lexer, stream, parser and tree like normal

print(Trees.toStringTree(tree, None, parser))

# the None is an optional rule names list
person Mark Aufflick    schedule 03.08.2015

В настоящее время нет цели Python для ANTLR 4, а ANTLR 3 не поддерживает автоматическое создание деревьев синтаксического анализа для получения результатов, на которые вы смотрите.

Возможно, вы сможете использовать функцию создания AST в ANTLR 3 для создания дерева, но оно не будет иметь такую ​​же форму (и, конечно, не ту простоту), как в ANTLR 4.

person Sam Harwell    schedule 21.02.2014