# Roundtrip String -\> Syntax Tree -\> String with JuliaSyntax.jl

**URL:** <https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714>\
**Category:** Tooling\
**Tags:** parser, juliasyntax\
**Created:** [August 11, 2023, 1:17pm UTC](https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714 "2023-08-11T13:17:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![theogf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/theogf/32/1987_2.png) [@theogf](https://discourse.julialang.org/u/theogf)\
**Post date:** [August 11, 2023, 1:17pm UTC](https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714/1 "2023-08-11T13:17:06Z")

</div>

Hi!

I am really hyped about [JuliaSyntax.jl](https://github.com/JuliaLang/JuliaSyntax.jl), however I could not figure out how to perform a round trip from the parsed String to a syntax tree and back to a String.  
Is this something possible already?

My usecase would be to use `JuliaSyntax` as a parser, work directly in the syntax tree form and then go back to a String representation.

Thanks!

---

<div class="post-metadata">

**Author:** ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)\
**Post date:** [August 11, 2023, 2:14pm UTC](https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714/2 "2023-08-11T14:14:05Z")

</div>

Here you have an example (hope this fits your use case well enough):

```julia
using JuliaSyntax

text = """inc(x) = x + 1"""
there = parsestmt(JuliaSyntax.SyntaxNode, text)

# do some work on `there` object

#back to string "inc(x) = x + 1"
andbackagain = JuliaSyntax.sourcetext(there)

```

This works at statement/expression level - but the same will work if you are doing the parsing at file-level (just switch the `parsestmt` with the appropriate `parse` function).

---

<div class="post-metadata">

**Author:** ![theogf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/theogf/32/1987_2.png) [@theogf](https://discourse.julialang.org/u/theogf)\
**Post date:** [August 30, 2023, 8:23pm UTC](https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714/3 "2023-08-30T20:23:23Z")

</div>

Hey,

I actually went back to this. Thanks for your answer but it unfortunately does not work for me.

`sourcetext` only works for `SyntaxNode` and not for `GreenNode`, additionaly it just return the source that it was given at the beginning (not that it’s actually easily possible to change the values in the `SyntaxNode`…)

I guess JuliaSyntax.jl is really more meant to be “read-only”

---

<div class="post-metadata">

**Author:** ![bellon-tiobe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bellon-tiobe/32/216597_2.png) [@bellon-tiobe](https://discourse.julialang.org/u/bellon-tiobe)\
**Post date:** [May 9, 2025, 1:28pm UTC](https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714/4 "2025-05-09T13:28:00Z")

</div>

Even so, I have trouble to only read the lossless tree. I can see the tree with its source, but I cannot find how to access the text in the trivia bits.

For instance:

```julia
  ...
│ 47:359 │ [block]
│ 47:48 │ NewlineWs "\n\t"
│ 49:68 │ [=]
│ 49:51 │ Identifier ✔ "vec"
│ 52:52 │ Whitespace " "
  ...

```

I want to check if there are tabs in indentation, as can be seen in the source text linked to that `NewlineWs` node above, but once I got hold of such a node, walking the tree, I don’t know how to retrieve the text for it:

```julia
> untokenize(node.head)
Internal Error: TypeError: in typeassert, expected String, got a value of type Nothing

> sourcetext(node)
Internal Error: MethodError: no method matching sourcefile(::JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead})
The function `sourcefile` exists, but no method is defined for this combination of argument types.

Closest candidates are: ...

Internal Error: MethodError: no method matching sourcefile(::JuliaSyntax.SyntaxHead)
The function `sourcefile` exists, but no method is defined for this combination of argument types.

Closest candidates are: ...

> untokenize(node)
Internal Error: MethodError: no method matching untokenize(::JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead})
The function `untokenize` exists, but no method is defined for this combination of argument types.

Closest candidates are: ...

> string(node)
"JuliaSyntax.GreenNode{JuliaSyntax.SyntaxHead}(JuliaSyntax.SyntaxHead(K\"NewlineWs\", 0x0001), 0x00000002, nothing)"

```

That last one at least is not a fail, but it is not what I need either.

Also, but more of the same: how to access the contents of comments?

---

<div class="post-metadata">

**Author:** ![theogf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/theogf/32/1987_2.png) [@theogf](https://discourse.julialang.org/u/theogf)\
**Post date:** [May 28, 2025, 3:09pm UTC](https://discourse.julialang.org/t/roundtrip-string-syntax-tree-string-with-juliasyntax-jl/102714/5 "2025-05-28T15:09:51Z")

</div>

I realized now that `JuliaFormatter.jl` relies on `JuliaSyntax.jl` see e.g. [this line](https://github.com/domluna/JuliaFormatter.jl/blob/master/src/JuliaFormatter.jl#L216-L217) and has to modify and print again.  
However there seems to be a lot of boilerplate coded needed to achieve this.
