2017-09-22 2 views
4

Comment puis-je analyser plus de lignes de code?Comment analyser une chaîne multiligne dans Julia?

Cela fonctionne:

julia> eval(parse("""print("O");print("K")""")) 
OK 

Ce ne fonctionne pas:

julia> eval(parse("""print("N"); 
print("O")""")) 
ERROR: ParseError("extra token after end of expression") 
Stacktrace: 
[1] #parse#235(::Bool, ::Function, ::String) at ./parse.jl:237 
[2] parse(::String) at ./parse.jl:232 

BTW si j'essaie ligne par ligne, j'ai d'autres problèmes. Par exemple:

julia> parse("""for i in 1:3""") 
:($(Expr(:incomplete, "incomplete: premature end of input"))) 

bien:

julia> eval(parse("""for i in 1:2 
println(i) 
end""")) 
1 
2 

Répondre

2

parse est conçu pour analyser une seule expression (au moins c'est ce que les documents disent: étant donné ce que je suis en fait un peu surpris votre premier exemple fonctionne, sans jeter une erreur ...).

Si vous voulez analyser les expressions mutliple alors vous pouvez tirer profit du fait que:

  1. parse peut prendre un second argument start qui lui indique où début de l'analyse syntaxique.
  2. Si vous fournissez cet argument start, il renvoie un tuple contenant l'expression et l'endroit où l'expression s'est terminée.

pour définir vous-même une fonction parseall. Il y en avait un dans la base mais je ne suis pas sûr qu'il y en ait plus. Editer: il est encore dans les tests voir ci-dessous

# modified from the julia source ./test/parse.jl 
function parseall(str) 
    pos = start(str) 
    exs = [] 
    while !done(str, pos) 
     ex, pos = parse(str, pos) # returns next starting point as well as expr 
     ex.head == :toplevel ? append!(exs, ex.args) : push!(exs, ex) #see comments for info 
    end 
    if length(exs) == 0 
     throw(ParseError("end of input")) 
    elseif length(exs) == 1 
     return exs[1] 
    else 
     return Expr(:block, exs...) # convert the array of expressions 
            # back to a single expression 
    end 
end 
+1

Merci! C'est inspirant! :) Il semble qu'il y ait un problème avec l'expression multiple dans une ligne. Je modifie votre réponse pour l'afficher dans le code. Mais ne vous attendiez pas à ce qu'il ait besoin d'un examen par les pairs ... Vous pouvez vérifier 'eval (parseall (" print (1); print (2) \ n \ npour i dans 3: 4 \ n print (i) \ nend \ n "))' et 'eval (parseall (" print (1) \ nprint (2) \ n \ npour i dans 3: 4 \ n print (i) \ nend \ n "))' – Liso

+1

@Liso Vos exemples en effet error, et cela a quelque chose à voir avec l'analyseur qui génère une expression ': toplevel' lorsqu'il trouve un point-virgule. Remplacer 'push! (Exs, ex)' par 'ex.head ==: toplevel? append! (exs, ex.args): push! (exs, ex) 'résolu le problème pour moi. –

+0

Alexander_Morley et @Dan_Getz J'aime accepter la version corrigée. Comment pouvons-nous faire cela? – Liso