# Lexer for SQL statements

**URL:** <https://discourse.julialang.org/t/lexer-for-sql-statements/87695>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [September 23, 2022, 12:20pm UTC](https://discourse.julialang.org/t/lexer-for-sql-statements/87695 "2022-09-23T12:20:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)\
**Post date:** [September 23, 2022, 12:20pm UTC](https://discourse.julialang.org/t/lexer-for-sql-statements/87695/1 "2022-09-23T12:20:30Z")

</div>

hi,

First of, I prefer functions over everything else. But I am in a situation in which I only know the correct argument AFTER the SQL statement is tokenized. I won’t bother you with the details but just know that I can’t see another solution to this problem then metaprogramming.

this is the example SQL statement:

```julia
a ="select column_2, column_3 from Table_X"

```

This is the Lexer

```julia
function Lexer(a::String) 
   G = Tokenize(split_up(replace_all(a,cleaning_up)))
   End_List = esc(copy(G))
   for i in G
      eval(Meta.parse(i[2]))
   end   
   return End_List
end

```

this is the error statement:

```julia
ERROR: UndefVarError: End_List not defined
Stacktrace:
 [1] top-level scope
   @ none:1

```

now the `End_List` does not refer to` End_List` in the function Lexer (as far as I can tell) but to the function that I want to evaluatie which is a string in a Token (which is a `Struc`t).

```julia
Token("SELECT", "SELECT","select(@@,^^,##)")

```

this is what it actually lookslike once I want to evaluate it in the for loop for the first element:

```julia
"select(End_List,G,1)"

```

This is the function to which it refers to:

```julia
function select(End_List,G, num)
   if End_List[num+1][2]== "Nothing" && occursin("comma", G[num+2][2]) 
      End_List[num+1][2] = "COLUMN"
      End_List[num][2] = "SELECT"
   end
end

```

my Question:  
How do I let the `eval` function know that there is indeed a Vector called `End_List` just outside the for-loop it is currenlty in?

I have though long about rewriting my whole code but:

1. I am unsure if this is possible.
2. as far as I can tell `eva`l is specifically made to deal with these types of situations. So I now kinda want to know what I am doing wrong.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [September 23, 2022, 2:03pm UTC](https://discourse.julialang.org/t/lexer-for-sql-statements/87695/2 "2022-09-23T14:03:12Z")

</div>

`eval` works at global scope: [Essentials · The Julia Language](https://docs.julialang.org/en/v1/base/base/#Base.MainInclude.eval)

---

<div class="post-metadata">

**Author:** ![AlexanderChen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alexanderchen/32/22007_2.png) [@AlexanderChen](https://discourse.julialang.org/u/AlexanderChen)\
**Post date:** [September 23, 2022, 3:16pm UTC](https://discourse.julialang.org/t/lexer-for-sql-statements/87695/3 "2022-09-23T15:16:12Z")

</div>

so what does that mean for my specific usecase? I don’t want to declare Global variable because its not a clean solution. Is there another type of evaluation I can do that I can use in my specific case?

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [September 23, 2022, 5:16pm UTC](https://discourse.julialang.org/t/lexer-for-sql-statements/87695/4 "2022-09-23T17:16:56Z")

</div>

It is often better to not use eval, but instead generate the code that has the desired effect when being executed as a whole.  
Must admit that I do not really understand your use case/example, but maybe something like this could work:

```julia
julia> a = 10
10

julia> function foo(s)
           x = split(s, " ")
           y = :([1, 2])
           for e in x
               code = :(let end_of_it = $y; $(Meta.parse(e)) end)
               @show eval(code)
           end
       end
foo (generic function with 1 method)

julia> foo("a end_of_it")
eval(code) = 10
eval(code) = [1, 2]

```
