如何让Elixir执行与变量匹配的引用代码?

时间:2019-07-03 02:25:04

标签: elixir ecto leex yecc

也许这不是要走的路,但这是我最初的猜测,我愿意接受提示和更正。

have been writing a parser表示一种简化的查询方言,该查询方言已部分继承并扩展了很多,允许用户编写如下内容:

plant where accession.code='2018.0047'

还没有准备好,但是除了最后一个步骤之外,缺少的中间步骤很清楚:如何执行结果?

我的目标是等效的Ecto.Query.from查询的引用表示形式。对于上面的示例,就我而言,等效项是:

from(p in "plant", 
  select: [:id], 
  join: a in "accession", 
  on: a.id==p.accession_id, 
  where: a.code=="2018.0047")

我一直在研究__schema__函数返回的结构,并且看起来都很可行,我的意思是我知道如何从模块中提取表名,并从关联中提取所有者和相关模块以及键。给定它的名字,让我们假设我的解析器确实返回了这个值:

{:from, [context: Elixir, import: Ecto.Query],
 [
   {:in, [context: Elixir, import: Kernel], [{:p, [], Elixir}, "plant"]},
   [
     select: [:id],
     join: {:in, [context: Elixir, import: Kernel],
      [{:a, [], Elixir}, "accession"]},
     on: {:==, [context: Elixir, import: Kernel],
      [
        {{:., [], [{:a, [], Elixir}, :id]}, [], []},
        {{:., [], [{:p, [], Elixir}, :accession_id]}, [], []}
      ]},
     where: {:==, [context: Elixir, import: Kernel],
      [{{:., [], [{:a, [], Elixir}, :code]}, [], []}, "2018.0047"]}
   ]
 ]}

我如何让Ecto执行它?

或者从yecc解析器生成Elixir代码的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

简短答案:,我们无法让Elixir执行“引用”代码。

如果我正确理解在elixir论坛上收到的评论,则quoted格式仅适用于宏,即用于在编译时定义的内容。

回到示例:

from(p in "plant", 
  select: [:id], 
  join: a in "accession", 
  on: a.id==p.accession_id, 
  where: a.code=="2018.0047")

其结果是一个值,一个Ecto.Query结构,尽管不是立即看到正在定义的字段,但看看源代码,我发现我可以产生相同的结果逐步说明价值,例如:

q = %Ecto.Query{}
q = %{ q | from: %Ecto.Query.FromExpr{source: {"plant", nil}}}
q = %{ q | select: %Ecto.Query.SelectExpr{
  expr: [{{:., [], [{:&, [], [0]}, :id]}, [], []}]}}
q = %{ q | joins: [
  %Ecto.Query.JoinExpr{
    source: {"accession", nil}, 
    qual: :inner,
    on: %Ecto.Query.QueryExpr{
      expr: {:==, [], [
        {{:., [], [{:&, [], [0]}, :accession_id]}, [], []},
        {{:., [], [{:&, [], [1]}, :id]}, [], []}
      ]}}}]}
q = %{ q | wheres: [
  %Ecto.Query.BooleanExpr{
    op: :and, 
    expr: {:==, [], [{{:., [], [{:&, [], [1]}, :code]}, [], []}, "2018.0047"]}}]}

我知道它看起来并不容易,但是我可以在语法作品中使用它。