Syntax validation of a julia file

I am trying to come up with a script to check program’s syntax without running it. Ideally this should not rely on external packages as the goal in mind is to use this within online judge system at competitive programming platform codeforces.com. Initial request for this came up here https://github.com/MikeMirzayanov/binary-heap-benchmark/pull/16

I would appreciate your comments on whether something along these lines is reasonable, platform-independent and safe from false-positive. One particular point is whether [:incomplete, :error is an exhaustive list of the things that need to be caught. Thanks!

function validatesyntax(fname)
  inp = read(fname, String)

  ast = ccall(:jl_parse_all, Any, (Cstring, Int64, Cstring, Int64), inp, length(inp), fname, length(fname))
  if length(ast.args) > 1 && (ast.args[end].head in [:incomplete, :error])
    println("syntax error $(ast.args[end])")
  end
end

(length(ARGS) == 1) && validatesyntax(ARGS[1])

In Julia 1.5 or later, you can do:

validatesyntax(fname) = include(expr -> Meta.isexpr(expr, (:error, :incomplete)) ? expr : nothing, fname)

where you are passing a syntax-transformer to include that leaves parse errors as-is but replaces other expressions with nothing before executing them.

(Even in earlier Julia versions, you can repeatedly call Meta.parse rather than doing a low-level ccall. Doing a ccall correctly is tricky — for example, you really want to pass sizeof(fname) rather than length(fname), the latter being incorrect for non-ASCII strings.)

Yes, I believe so.

3 Likes

Hi, Steven, thanks for helping out! This looks much tidier indeed. I hope it’s ok if a variant of your code will be used in the aforementioned online judge system.

1 Like