我正试图为一个学校项目做一个编译器。我是克洛尔的初学者。我已经完成了一个简单的程序(解释-lang),它可以使用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;};"))预期的产出应该是"676767“而不是零。
谢谢你的帮助。
发布于 2018-12-23 12:14:25
如果您不知道项目的确切位置:
(->> [: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))或者如果你想用幽灵:
(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
[:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
(select [1 1] A))或者简单地得到:
(let [A [:LangIF [:before_if "676767; "] [:condition_expression "0"]
[:statements_OK "1; 2;"] [:statements_NOK "3+4;"] [:after_if ""]]]
(get (get A 1) 1))发布于 2018-12-23 13:43:59
我发现zippers在Instaparse中很有用,特别是当您需要找到一个特定的节点然后找到与它相关的另一个节点时。下面是一个在节点中搜索以找到匹配谓词的函数:
(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:
(-> [: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)发布于 2018-12-23 18:25:54
您可以使用Tupelo森林库轻松地操作类似树的数据结构。这是你的问题的活生生的例子
(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。许多进一步的操纵是可能的。见医生们和更多的例子。
https://stackoverflow.com/questions/53902722
复制相似问题