首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在clojure中使用instaparse后按键检索元素?

如何在clojure中使用instaparse后按键检索元素?
EN

Stack Overflow用户
提问于 2018-12-23 10:10:05
回答 3查看 100关注 0票数 0

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

代码语言:javascript
复制
[:LangIF [:before_if "676767; "] [:condition_expression "0"] 
[:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]

如何从列表中获取"before_if“元素?

我试着理解get函数,但是在函数的用法中我必须要有一些内容。

以下是一些代码:

代码语言:javascript
复制
(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;};"))

预期的产出应该是"676767“而不是零。

谢谢你的帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-12-23 12:14:25

如果您不知道项目的确切位置:

代码语言:javascript
复制
(->> [: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))

或者如果你想用幽灵:

代码语言:javascript
复制
(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
       [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
    (select [1 1] A))

或者简单地得到:

代码语言:javascript
复制
(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
       [:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
    (get (get A 1) 1))
票数 2
EN

Stack Overflow用户

发布于 2018-12-23 13:43:59

我发现zippers在Instaparse中很有用,特别是当您需要找到一个特定的节点然后找到与它相关的另一个节点时。下面是一个在节点中搜索以找到匹配谓词的函数:

代码语言:javascript
复制
(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中找到:before_if

代码语言:javascript
复制
(-> [: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)
票数 1
EN

Stack Overflow用户

发布于 2018-12-23 18:25:54

您可以使用Tupelo森林库轻松地操作类似树的数据结构。这是你的问题的活生生的例子

代码语言:javascript
复制
(dotest
  (with-forest (new-forest)
    (let [data-hiccup  [:LangIF
                        [:before_if "676767; "]
                        [:condition_expression "0"]
                        [:statements_OK "1; 2;"]
                        [:statements_NOK "3+4;"]
                        [:after_if ""]]

          root-hid     (add-tree-hiccup data-hiccup)
          before-hid   (find-hid root-hid [:LangIF :before_if])
          before-node  (hid->node before-hid)
          before-value (grab :value before-node)]

      (is= before-node {:tupelo.forest/khids [], :tag :before_if, :value "676767; "})
      (is= before-value "676767; "))))

before-hid是指向所需节点的指针,我们通过从根节点指定所需的路径[:LangIF :before_if]来找到它。然后,我们可以将指针转换为整个节点,并从节点中提取:value。许多进一步的操纵是可能的。见医生们更多的例子

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53902722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档