Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with using ANTLR4 from Julia via PyCall #4604

Open
AkhilAkkapelli opened this issue Apr 24, 2024 · 0 comments
Open

Issue with using ANTLR4 from Julia via PyCall #4604

AkhilAkkapelli opened this issue Apr 24, 2024 · 0 comments

Comments

@AkhilAkkapelli
Copy link

AkhilAkkapelli commented Apr 24, 2024

I'm attempting to integrate ANTLR4 libraries into my Julia project using the PyCall library.
I encounter an error when running my code:

akhil@KHUSHI:~/FortranStructureExtractor$ julia FSEFortran90.jl TestProgram/TestProgram.f90 TestProgram/TestProgramStructureJulia.DOT 
An unexpected error occurred:PyError ($(Expr(:escape, :(ccall(#= /home/akhil/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'AttributeError'>
AttributeError("'PyCall.jlwrap' object has no attribute 'enterEveryRule'")
  File "/usr/local/lib/python3.10/dist-packages/antlr4/tree/Tree.py", line 158, in walk
    self.enterRule(listener, t)
  File "/usr/local/lib/python3.10/dist-packages/antlr4/tree/Tree.py", line 177, in enterRule
    listener.enterEveryRule(ctx)
ERROR: LoadError: PyError ($(Expr(:escape, :(ccall(#= /home/akhil/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'AttributeError'>
AttributeError("'PyCall.jlwrap' object has no attribute 'enterEveryRule'")
  File "/usr/local/lib/python3.10/dist-packages/antlr4/tree/Tree.py", line 158, in walk
    self.enterRule(listener, t)
  File "/usr/local/lib/python3.10/dist-packages/antlr4/tree/Tree.py", line 177, in enterRule
    listener.enterEveryRule(ctx)
Stacktrace:
  [1] pyerr_check
    @ ~/.julia/packages/PyCall/1gn3u/src/exception.jl:75 [inlined]
  [2] pyerr_check
    @ ~/.julia/packages/PyCall/1gn3u/src/exception.jl:79 [inlined]
  [3] _handle_error(msg::String)
    @ PyCall ~/.julia/packages/PyCall/1gn3u/src/exception.jl:96
  [4] macro expansion
    @ ~/.julia/packages/PyCall/1gn3u/src/exception.jl:110 [inlined]
  [5] #107
    @ ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:43 [inlined]
  [6] disable_sigint
    @ ./c.jl:473 [inlined]
  [7] __pycall!
    @ ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:42 [inlined]
  [8] _pycall!(ret::PyObject, o::PyObject, args::Tuple{FSEFortran90Listener, PyObject}, nargs::Int64, kw::Ptr{Nothing})
    @ PyCall ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:29
  [9] _pycall!(ret::PyObject, o::PyObject, args::Tuple{FSEFortran90Listener, PyObject}, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PyCall ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:11
 [10] (::PyObject)(::FSEFortran90Listener, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PyCall ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:86
 [11] (::PyObject)(::FSEFortran90Listener, ::Vararg{Any})
    @ PyCall ~/.julia/packages/PyCall/1gn3u/src/pyfncall.jl:86
 [12] process_source_file(filePath::String, listener::FSEFortran90Listener)
    @ Main ~/FortranStructureExtractor/FSEFortran90.jl:161
 [13] main()
    @ Main ~/FortranStructureExtractor/FSEFortran90.jl:144
 [14] top-level scope
    @ ~/FortranStructureExtractor/FSEFortran90.jl:170
in expression starting at /home/akhil/FortranStructureExtractor/FSEFortran90.jl:170

My Julia Code (FSEFortran90.jl):

include("ProgramNode/ProgramNode.jl")
import .ProgramNodeMod: ProgramNode, ProgramNodeType, addChild, toDOT

using PyCall

antlr4 = pyimport("antlr4")
const ParseTreeWalker = antlr4.ParseTreeWalker

pushfirst!(PyVector(pyimport("sys")."path"), pwd())
Fortran90ParserListener = pyimport("Fortran90ParserListener")

mutable struct FSEFortran90Listener
    root::ProgramNode
    parentStack::Vector{ProgramNode}
end

function FSEFortran90Listener(root::ProgramNode)
    parentStack = Vector{ProgramNode}()
    push!(parentStack, root)
    return FSEFortran90Listener(root, parentStack)
end

function enterMainProgram(listener::FSEFortran90Listener, ctx)
    programStmtContext = ctx.programStmt()
    if programStmtContext !== nothing
        programNameNode = programStmtContext.NAME()
        programName = programNameNode.getText()
        programNode = ProgramNode(programName, ProgramNodeType("Program"))
        currentParent = last(listener.parentStack)
        addChild(currentParent, programNode)
        push!(listener.parentStack, programNode)
    end
end

function exitMainProgram(listener::FSEFortran90Listener, ctx)
    pop!(listener.parentStack)
end

#Some other routines ...

using ArgParse

# Import necessary modules from the local Python files
#FSEFortran90Listener = pyimport("FSEFortran90Listener")
Fortran90Lexer = pyimport("Fortran90Lexer")
Fortran90Parser = pyimport("Fortran90Parser")

# Importing necessary Python packages
const FileStream = antlr4.FileStream
const CommonTokenStream = antlr4.CommonTokenStream

function parse_arguments()
    s = ArgParseSettings()

    @add_arg_table! s begin
        "inputFilePath"
            help = "Path to the input file (.f90)"
            required = true
        "outputFilePath"
            help = "Path to the output file (.dot)"
            required = true
    end

    return parse_args(s)
end

function main()
    parsed_args = parse_arguments()

    inputFilePath = parsed_args["inputFilePath"]
    outputFilePath = parsed_args["outputFilePath"]

    fileName = basename(inputFilePath)
    root = ProgramNode(fileName, ProgramNodeType("File"))
    listener = FSEFortran90Listener(root)

    try
        process_source_file(inputFilePath, listener)
        dotRepresentation = toDOT(root)
        write_to_file(dotRepresentation, outputFilePath)
        println("DOT representation written to file successfully.")
    catch e
        println("An unexpected error occurred:", e)
        rethrow()
    end
end

function process_source_file(filePath, listener)
    input = FileStream(filePath)
    lexer = Fortran90Lexer.Fortran90Lexer(input)
    tokens = CommonTokenStream(lexer)
    parser = Fortran90Parser.Fortran90Parser(tokens)
    tree = parser.program()
    walker = ParseTreeWalker()
    walker.walk(listener, tree)
end

function write_to_file(content, filePath)
    open(filePath, "w") do f
        write(f, content)
    end
end

main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant