JuliaLang / JuliaSyntax.jl

The Julia compiler frontend
Other
267 stars 32 forks source link

Parser failure in docstring #352

Closed tecosaur closed 8 months ago

tecosaur commented 10 months ago

Hello, I just thought I'd report this issue I ran into with Julia master which popped up with a $ in a docstring I forgot to escape.

┌ Error: JuliaSyntax parser failed — falling back to flisp!
│   exception =
│    BoundsError: attempt to access 0-element Vector{Any} at index [1]
│    Stacktrace:
│      [1] getindex
│        @ Base ./essentials.jl:13 [inlined]
│      [2] _internal_node_to_Expr(source::Base.JuliaSyntax.SourceFile, srcrange::UnitRange{Int64}, head::Base.JuliaSyntax.SyntaxHead, childranges::Vector{UnitRange{Int64}}, childheads::Vector{Base.JuliaSyntax.SyntaxHead}, args::Vector{Any})
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/expr.jl:359
│      [3] _to_expr(node::Base.JuliaSyntax.SyntaxNode)
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/expr.jl:499
│      [4] _to_expr(node::Base.JuliaSyntax.SyntaxNode) (repeats 2 times)
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/expr.jl:498
│      [5] Expr(node::Base.JuliaSyntax.SyntaxNode)
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/expr.jl:503
│      [6] core_parser_hook(code::String, filename::String, lineno::Int64, offset::Int64, options::Symbol)
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/hooks.jl:209
│      [7] invoke_in_world(::UInt64, ::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
│        @ Base ./essentials.jl:926
│      [8] invoke_in_world(::UInt64, ::Any, ::Any, ::Vararg{Any})
│        @ Base ./essentials.jl:923
│      [9] (::Base.JuliaSyntax.var"#invoke_fixedworld#122"{Base.JuliaSyntax.var"#invoke_fixedworld#119#123"{typeof(Base.JuliaSyntax.core_parser_hook), UInt64}})(::String, ::Vararg{Any}; kws::@Kwargs{})
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/hooks.jl:118
│     [10] (::Base.JuliaSyntax.var"#invoke_fixedworld#122"{Base.JuliaSyntax.var"#invoke_fixedworld#119#123"{typeof(Base.JuliaSyntax.core_parser_hook), UInt64}})(::String, ::Vararg{Any})
│        @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/hooks.jl:117
│     [11] _parse_string(text::String, filename::String, lineno::Int64, index::Int64, options::Symbol)
│        @ Base.Meta ./meta.jl:200
│     [12] #parseall#6
│        @ Base.Meta ./meta.jl:294 [inlined]
│     [13] parseall
│        @ Base.Meta ./meta.jl:293 [inlined]
│     [14] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│        @ Base ./loading.jl:2056
│     [15] _include(mapexpr::Function, mod::Module, _path::String)
│        @ Base ./loading.jl:2130
│     [16] include(fname::String)
│        @ Base.MainInclude ./client.jl:589
│     [17] top-level scope
│        @ REPL[226]:1
│     [18] eval
│        @ Core ./boot.jl:383 [inlined]
│     [19] eval_user_input(ast::Any, backend::REPL.REPLBackend, mod::Module)
│        @ REPL ~/Desktop/TEC/Projects/available/julia/usr/share/julia/stdlib/v1.11/REPL/src/REPL.jl:150
│     [20] repl_backend_loop(backend::REPL.REPLBackend, get_module::Function)
│        @ REPL ~/Desktop/TEC/Projects/available/julia/usr/share/julia/stdlib/v1.11/REPL/src/REPL.jl:246
│     [21] start_repl_backend(backend::REPL.REPLBackend, consumer::Any; get_module::Function)
│        @ REPL ~/Desktop/TEC/Projects/available/julia/usr/share/julia/stdlib/v1.11/REPL/src/REPL.jl:231
│     [22] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool, backend::Any)
│        @ REPL ~/Desktop/TEC/Projects/available/julia/usr/share/julia/stdlib/v1.11/REPL/src/REPL.jl:387
│     [23] run_repl(repl::REPL.AbstractREPL, consumer::Any)
│        @ REPL ~/Desktop/TEC/Projects/available/julia/usr/share/julia/stdlib/v1.11/REPL/src/REPL.jl:373
│     [24] (::Base.var"#1097#1099"{Bool, Symbol, Bool})(REPL::Module)
│        @ Base ./client.jl:532
│     [25] #invokelatest#2
│        @ Base ./essentials.jl:892 [inlined]
│     [26] invokelatest
│        @ Base ./essentials.jl:889 [inlined]
│     [27] run_main_repl(interactive::Bool, quiet::Bool, banner::Symbol, history_file::Bool, color_set::Bool)
│        @ Base ./client.jl:516
│     [28] exec_options(opts::Base.JLOptions)
│        @ Base ./client.jl:336
│     [29] _start()
│        @ Base ./client.jl:652
│   offset = 0
│   code = "\n\"\"\"\n    @S_str -> StyledString\n\nConstruct a styled string. Within the string, `{<specs>:<content>}` structures\napply the formatting to `<content>`, according to the list of comma-separated\nspecifications `<specs>`. Each spec can either take the form of a face name,\nan inline face specification, or a `key=value` pair. The value must be wrapped\nby `{...}` should it contain any of the characters `," ⋯ 17405 bytes ⋯ "ource__.file, \"\"), ':', string(__source__.line),\n            #         \" contains unterminated styled constructs.\")\n        end\n    end\n\n    #------------------\n    # The actual body of the macro\n    #------------------\n\n    run_state_machine!(state)\n    if state.interpolated[]\n        :(\$styledstring(\$(state.parts...))) |> esc\n    else\n        styledstring(map(eval, state.parts)...)\n    end\nend\n"
└ @ Base.JuliaSyntax ~/Desktop/TEC/Projects/available/julia/base/JuliaSyntax/src/hooks.jl:258
ERROR: LoadError: syntax: invalid interpolation syntax: "${"
Stacktrace:
 [1] top-level scope
   @ /tmp/julia_stystr2.jl:50
 [2] include(fname::String)
   @ Base.MainInclude ./client.jl:589
 [3] top-level scope
   @ REPL[226]:1
in expression starting at /tmp/julia_stystr2.jl:50

Code to produce: http://ix.io/4FzI (with a few extra typos that haven't been fixed)

c42f commented 8 months ago

Great example, thanks! I believe this has been fixed in a recent PR but I'll try to hunt down which one before closing this.

Minimal (bizarre!) reproducer from the above code against the version currently downstream in Julia master

if a
    if x = y
    else
    end
elseif b
end
tecosaur commented 8 months ago

I think I managed to hit it again, at least here's another test case:

styled"{(fg=$c):$x}" for (c, x) in zip(ColorSchemes.rainbow1.colors, Iterators.cycle("rainbow"))
c42f commented 8 months ago

This was fixed in #371 :-)