在clojure中使用instaparse后,如何通过键检索元素?

在clojure中使用instaparse后,如何通过键检索元素?,clojure,Clojure,我正在为一个学校项目做一个编译器。我是clojure的初学者。我已经完成了一个简单的程序(解释lang if),它可以使用instaparse解析字符串并返回如下向量: [:LangIF [:before_if "676767; "] [:condition_expression "0"] [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]] 如何从列表中获取“before_if”元素 我试图理解get函数,但我必

我正在为一个学校项目做一个编译器。我是clojure的初学者。我已经完成了一个简单的程序(解释lang if),它可以使用instaparse解析字符串并返回如下向量:

[:LangIF [:before_if "676767; "] [:condition_expression "0"] 
[:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]
如何从列表中获取“before_if”元素

我试图理解get函数,但我必须理解该函数的用法

下面是一些代码:

(prn (interpreting-lang-if "676767; if (0) {1; 2;}else{3+4;};"))
(get (interpreting-lang-if "676767; if (0) {1; 2;}else{3+4;};") :before_if)
(get :before_if (interpreting-lang-if "676767; if (0) {1; 2;}else{3+4;};"))
预期输出应该是“6767”,而不是零


感谢您的帮助。

如果您不知道物品的确切位置:

(->> [:LangIF [:before_if "676767; "] [:condition_expression "0"]
      [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]
     (tree-seq vector? rest)
     (filter vector?)
     (filter (comp (partial = :before_if) first))
     (first)
     (second))
或者,如果您想使用specter:

(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
       [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
    (select [1 1] A))
或者使用简单的get:

(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
       [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
    (get (get A 1) 1))

如果您不知道物品的确切位置:

(->> [:LangIF [:before_if "676767; "] [:condition_expression "0"]
      [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]
     (tree-seq vector? rest)
     (filter vector?)
     (filter (comp (partial = :before_if) first))
     (first)
     (second))
或者,如果您想使用specter:

(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
       [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
    (select [1 1] A))
或者使用简单的get:

(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
       [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
    (get (get A 1) 1))

我发现Zipper对于Instaparse AST非常有用,尤其是当您需要查找特定节点,然后再查找与之相关的另一个节点时。下面是一个函数,它搜索节点以查找与谓词匹配的节点:

(require '[clojure.zip :as zip])

(defn zip-to
  ([loc pred direction]
   (loop [loc loc]
     (if (and loc (not (zip/end? loc)))
       (if (pred (zip/node loc))
         loc
         (recur (direction loc)))
       loc))))
要在AST中查找
:如果
,则在\u之前:

(-> [:LangIF
     [:before_if "676767; "]
     [:condition_expression "0"]
     [:statements_OK "1; 2;"]
     [:statements_NOK "3+4;"]
     [:after_if ""]]
  zip/vector-zip
  (zip-to #{:before_if} zip/next)
  zip/right
  zip/node)

我发现Zipper对于Instaparse AST非常有用,尤其是当您需要查找特定节点,然后再查找与之相关的另一个节点时。下面是一个函数,它搜索节点以查找与谓词匹配的节点:

(require '[clojure.zip :as zip])

(defn zip-to
  ([loc pred direction]
   (loop [loc loc]
     (if (and loc (not (zip/end? loc)))
       (if (pred (zip/node loc))
         loc
         (recur (direction loc)))
       loc))))
要在AST中查找
:如果
,则在\u之前:

(-> [:LangIF
     [:before_if "676767; "]
     [:condition_expression "0"]
     [:statements_OK "1; 2;"]
     [:statements_NOK "3+4;"]
     [:after_if ""]]
  zip/vector-zip
  (zip-to #{:before_if} zip/next)
  zip/right
  zip/node)

您可以使用Tupelo林库轻松地操作树状数据结构。这是:


hid之前的
是指向所需节点的指针,我们可以通过从根节点指定所需路径
[:LangIF:before\u if]
找到该节点。然后,我们可以将指针转换为整个节点,并从节点中提取
:value
。许多进一步的操作是可能的。请参见和。

您可以使用Tupelo Forest库轻松地操作树状数据结构。这是:


hid之前的
是指向所需节点的指针,我们可以通过从根节点指定所需路径
[:LangIF:before\u if]
找到该节点。然后,我们可以将指针转换为整个节点,并从节点中提取
:value
。许多进一步的操作是可能的。请参阅和。

谢谢,这正是我要找的!第一个与我的项目及其发展更相关。简单的get在我的例子中也起作用。您的代码非常鼓舞人心。或者,对于
get
,还有
(get in A[1])
。谢谢,这正是我想要的!第一个与我的项目及其发展更相关。简单的get在我的例子中也起作用。您的代码非常鼓舞人心。或者,对于
get
,还有
(get in A[1])
。谢谢我尝试了它。这是一个有用的建议。我会记住的谢谢我试过了。这是一个有用的建议。我会记住的