解析C++;用Python

解析C++;用Python,python,antlr,antlr4,Python,Antlr,Antlr4,我试图用python解析cpp。我使用ANTLR for python生成了解析器,现在我想访问该树并收集一些信息 是否仍然可以将ANTLR树转储为JSON格式的AST 我试图跟踪函数调用,但在生成的解析器文件中找不到任何东西 这是我正在使用的语法文件 我尝试了以下命令来获取CPP解析器, java-jar-antlr-4.8-complete.jar-Dlanguage=Python3./CPP14.g4-visitor 这是我掌握的最基本的代码 import sys import os

我试图用python解析cpp。我使用ANTLR for python生成了解析器,现在我想访问该树并收集一些信息

  • 是否仍然可以将ANTLR树转储为JSON格式的AST
  • 我试图跟踪函数调用,但在生成的解析器文件中找不到任何东西
这是我正在使用的语法文件

我尝试了以下命令来获取CPP解析器, java-jar-antlr-4.8-complete.jar-Dlanguage=Python3./CPP14.g4-visitor

这是我掌握的最基本的代码

import sys
import os
from antlr4 import *
from CPP14Lexer import *
from CPP14Parser import *
from CPP14Visitor import *



class TREEVisitor(CPP14Visitor):
    def __init__(self):
        pass


    def visitExpressionstatement(self, ctx):
        print(ctx.getText())
        return self.visitChildren(ctx)



if __name__ == '__main__':
    dtype = ""
    input_stream = FileStream(sys.argv[1])
    cpplex = CPP14Lexer(input_stream)
    commtokstream = CommonTokenStream(cpplex)
    cpparser = CPP14Parser(commtokstream)
    print("parse errors: {}".format(cpparser._syntaxErrors))

    tree = cpparser.translationunit()

    tv = TREEVisitor()
    tv.visit(tree)

以及我试图解析的输入文件

#include <iostream>

using namespace std;


int foo(int i, int i2)
{
    return i * i2;
}

int main(int argc, char *argv[])
{
    cout << "test" << endl;
    foo(1, 3);
    return 0;
}
#包括
使用名称空间std;
intfoo(inti,inti2)
{
返回i*i2;
}
int main(int argc,char*argv[])
{

cout函数调用由
postfix表达式
规则识别:

postfixexpression
   : primaryexpression
   | postfixexpression '[' expression ']'
   | postfixexpression '[' bracedinitlist ']'
   | postfixexpression '(' expressionlist? ')'   // <---- this alternative!
   | simpletypespecifier '(' expressionlist? ')'
   | typenamespecifier '(' expressionlist? ')'
   | simpletypespecifier bracedinitlist
   | typenamespecifier bracedinitlist
   | postfixexpression '.' Template? idexpression
   | postfixexpression '->' Template? idexpression
   | postfixexpression '.' pseudodestructorname
   | postfixexpression '->' pseudodestructorname
   | postfixexpression '++'
   | postfixexpression '--'
   | Dynamic_cast '<' thetypeid '>' '(' expression ')'
   | Static_cast '<' thetypeid '>' '(' expression ')'
   | Reinterpret_cast '<' thetypeid '>' '(' expression ')'
   | Const_cast '<' thetypeid '>' '(' expression ')'
   | typeidofthetypeid '(' expression ')'
   | typeidofthetypeid '(' thetypeid ')'
   ;
它将被打印。请注意,它现在将打印比函数调用多得多的内容,因为它匹配的内容远不止这些。您可以:

然后只打印
foo(1,3)
(请注意,您可能希望在
postfixexpression
规则内将更多规则标记为
functionCallPostfixexpression

是否仍然可以将ANTLR树转储为JSON格式的AST

没有

当然,您可以轻松地自己创建一些东西:每个解析器规则返回的对象,如
translationunit
,包含整个树。一个快速而肮脏的示例:

导入antlr4
从antlr4.tree.tree导入TerminalNodeImpl
导入json
#导入CPP14Lexer、CPP14Parser。。。
定义到目录(根目录):
obj={}
_填充(对象、根)
返回obj
def_填充(obj,节点):
如果isinstance(节点,终端节点):
obj[“类型”]=node.symbol.type
obj[“text”]=node.getText()
返回
class\u name=类型(节点)。\u name\u.replace('Context','')
规则名称=“{}{}”。格式(类名称[0]。下限(),类名称[1:])
arr=[]
obj[规则名称]=arr
对于node.children中的child_节点:
child_obj={}
arr.append(子对象)
_填充(子对象、子节点)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
来源=”“
#包括
使用名称空间std;
intfoo(inti,inti2)
{
返回i*i2;
}
int main(int argc,char*argv[])
{

你能给你正在使用的语法添加一个链接吗?你能更新你的问题并发布你用来解析CPP源文件的代码吗?(以及这个源文件的内容)在语法中,我没有看到一个名为
CallExpr
的规则:你为什么期待它?你正在解析的输入是什么?问题是我如何访问像foo(1,2,3)这样的函数调用;我想这可能是在该语法文件中的另一个名称下定义的!删除
def\uu init\uuuuuu(self):pass
@eyllansc这可能是一个很好的建议,但与手头的问题无关。在给出建议时,最好解释一下原因,或者提供一个链接来解释这一点。我发现了这个,我想知道它是否可以用于CPP?当然,您只需将Java代码重新移植到Python@Alex我添加了一个快速示例片段你怎么能去解释输出树中的所有这些术语?当函数foo被调用时,它似乎在“unaryexpression”下:[…]然后它的参数又在“unaryexpression”下,这正常吗?我不确定我必须如何解释输出!我的意思是,这只是一个函数调用,但它在“unaryexpression”下expressionstatement、assignmentexpression、conditionalexpression、logicalorexpression和其他许多……我觉得很奇怪!是的,这是正常的。如果您遵循解析器最终到达函数调用的路径,解析器将以
translationunit
开始。
postfixexpression
   : primaryexpression                                     #otherPostfixexpression
   | postfixexpression '[' expression ']'                  #otherPostfixexpression
   | postfixexpression '[' bracedinitlist ']'              #otherPostfixexpression
   | postfixexpression '(' expressionlist? ')'             #functionCallPostfixexpression
   | simpletypespecifier '(' expressionlist? ')'           #otherPostfixexpression
   | typenamespecifier '(' expressionlist? ')'             #otherPostfixexpression
   | simpletypespecifier bracedinitlist                    #otherPostfixexpression
   | typenamespecifier bracedinitlist                      #otherPostfixexpression
   | postfixexpression '.' Template? idexpression          #otherPostfixexpression
   | postfixexpression '->' Template? idexpression         #otherPostfixexpression
   | postfixexpression '.' pseudodestructorname            #otherPostfixexpression
   | postfixexpression '->' pseudodestructorname           #otherPostfixexpression
   | postfixexpression '++'                                #otherPostfixexpression
   | postfixexpression '--'                                #otherPostfixexpression
   | Dynamic_cast '<' thetypeid '>' '(' expression ')'     #otherPostfixexpression
   | Static_cast '<' thetypeid '>' '(' expression ')'      #otherPostfixexpression
   | Reinterpret_cast '<' thetypeid '>' '(' expression ')' #otherPostfixexpression
   | Const_cast '<' thetypeid '>' '(' expression ')'       #otherPostfixexpression
   | typeidofthetypeid '(' expression ')'                  #otherPostfixexpression
   | typeidofthetypeid '(' thetypeid ')'                   #otherPostfixexpression
   ;