Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure中的递归下降解析器_Clojure_Expert System_Recursive Descent - Fatal编程技术网

Clojure中的递归下降解析器

Clojure中的递归下降解析器,clojure,expert-system,recursive-descent,Clojure,Expert System,Recursive Descent,我正在用Clojure创建一些专家系统,我需要开发递归下降解析器,用于从文本文件读取规则并从中创建Clojure函数。我编写了一个函数,它检查文本文件是否符合我的语法,它给我一个字符串列表和元素,如函数名、数字、系统事实名称、算术和逻辑运算符。我的语法就是这样的: RULE := EXPR >> FACT EXPR := ( WSK OpA NUM ) || ( FACT ) || ( EXPR OpL EXPR ) || (WSK OpA WSK) OpL := AND

我正在用Clojure创建一些专家系统,我需要开发递归下降解析器,用于从文本文件读取规则并从中创建Clojure函数。我编写了一个函数,它检查文本文件是否符合我的语法,它给我一个字符串列表和元素,如函数名、数字、系统事实名称、算术和逻辑运算符。我的语法就是这样的:

 RULE := EXPR >> FACT 
 EXPR := ( WSK OpA NUM ) || ( FACT ) || ( EXPR OpL EXPR ) || (WSK OpA WSK)

 OpL := AND || OR 
 OpA := > || < || == 
 WSK := [A-Z]+ 
 FACT := [a-z]+ 
 NUM := [0-9]+\.?[0-9]*
现在我想从上面函数提供给我的字符串列表中创建一个clojure函数。你知道怎么做吗

更新 以下是规则和硬编码版本的示例:

(ROC>100)>>购买

你试过了吗

它从上下文无关的语法生成解析器

(ns example.core
  (:require [instaparse.core :as insta])

(def as-and-bs
  (insta/parser
    "S = AB*
     AB = A B
     A = 'a'+
     B = 'b'+"))

首先,我同意@Arthur关于生成语法的使用

下一步是编写一个函数,将语法转换为表示代码的Clojure数据结构

例如,如果语法解析为

[:S [:EXPR [:WSK "ROC"] [:OpA ">"] [:NUM "100"]] :>> [:FCT "BUY"]] ; "ROC > 100 << BUY"
试着跑步

(parse-expr [:EXPR [:WSK "B"] [:OpA "<"] [:NUM "1"]])

(parse expr[:expr[:WSK“B”][:OpA“您是否可以再包含一点上下文(双关语);)在哪里定义了acceptFACT acceptLP等。在您的示例中,ROC来自哪里(现有函数、参数等)?如果您调用它,它看起来像一个函数。另外,外部函数是否接受任何参数?我现在假设为函数,没有参数。语法正确吗?它不支持WSK和FACT有多个字符,FACT中只有小写,而您给出的示例使用大写。同样的问题我不知道它是从哪里来的。既然你没有调用它,我就假设变量,虽然它看起来也像一个字符串。好的,我更新了我的更新。deterb,ROC是一个没有参数的函数,我想返回字符串“BUY”"如果名为ROC的函数返回的值大于100。我还更新了语法,所以现在WSK和FACT可以有多个字符。感谢您的回答。我将研究它的文档并尝试在我的项目中使用。您能看一下吗?好的,但我是否可以创建一个字符串表达式,其中str函数使用适当的元素我还想在一些列表中列出我的规则,这样我就可以检查该列表,看我是否可以运行一些规则并生成新的事实。你不需要生成字符串,然后使用
str
对其求值。我希望代码生成类似
(列表(符号)的内容“deterb但(变量部分1 val)是什么意思例如?因为在此上下文中无法解析symbol:variable时出错。应该是
var
,而不是
variable
,很抱歉。运行时,您需要确保有一个具有该名称且可访问的变量。您可能希望改为将其解析为符号;我对您的运行代码是为了告诉您哪个更合适。感谢您的解释。我改用了symbol,但宏的扩展有一些问题。我想作为generate funcs的参数传递,比如(语法行),其中行是字符串,语法是我声明的语法分析器。这是一个问题,因为generate funcs宏上有引号。
[:S [:EXPR [:WSK "ROC"] [:OpA ">"] [:NUM "100"]] :>> [:FCT "BUY"]] ; "ROC > 100 << BUY"
(defn parse-expr [expr]
  (let [[_ [part1-type part1-val] [part2-type part2-val] [part3-type part3-val]] expr]
    (if (and (= :WSK part1-type) (= :OpA part2-type) (= :NUM part3-type))
      (let [wsk (variable part1-val)
            opa (variable part2-val)
            num (Integer/valueOf part3-val)]
        (list opa (list wsk) num)))))

(defmacro generate-funcs [parse-tree]
  (let [[_ expr _ [_ fact]] parse-tree
        expr (parse-expr expr)
        fact (symbol fact)]
    `(fn [] (if ~expr (str ~fact) ()))))
(parse-expr [:EXPR [:WSK "B"] [:OpA "<"] [:NUM "1"]])
(macroexpand-1 '(generate-funcs [:S [:EXPR [:WSK "B"] [:OpA "<"] [:NUM "1"]] :>> [:FCT "b"]]))