Issue with using ANTLR4 from Julia via PyCall
AkhilAkkapelli opened this issue · comments
Akhil Akkapelli commented
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()