clojure - Clojure 中的递归下降解析器

标签 clojure expert-system recursive-descent

我正在用 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]*

这就是我检查语法的功能:
(defn wyr
  "new expression"
  [przetworzone doPrzetworzenia]
  (cond
   (empty? doPrzetworzenia) przetworzone
   (empty? przetworzone) (if (empty? (acceptLP (first doPrzetworzenia)))
               "error-poczatek";todo - error
               (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptLP (first przetworzone)))) (if (empty? (acceptFACT (first doPrzetworzenia)))
                            (if (empty? (acceptWSK (first doPrzetworzenia)))
                              (if (empty? (acceptLP (first doPrzetworzenia)))
                            "error-LP";todo - error
                            (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
                              (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
                            (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptFACT (first przetworzone)))) (if (empty? (acceptPP (first doPrzetworzenia)))
                              "error-FACT";todo - error
                              (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptWSK (first przetworzone)))) (if (empty? (acceptOpA (first doPrzetworzenia)))
                             (if (empty? (acceptPP (first doPrzetworzenia)))
                               "error-WSK";todo - error
                               (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
                             (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptOpA (first przetworzone)))) (if (empty? (acceptNUM (first doPrzetworzenia)))
                             (if (empty? (acceptWSK (first doPrzetworzenia)))
                               "error-OpA";todo - error
                               (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
                             (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptPP (first przetworzone)))) (if (empty? (acceptOpL (first doPrzetworzenia)))
                            (if (empty? (acceptImplication (first doPrzetworzenia)))
                              "error-PP";todo - error
                              (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
                            (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptOpL (first przetworzone)))) (if (empty? (acceptLP (first doPrzetworzenia)))
                             "error-OpL";todo - error
                             (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptImplication (first przetworzone)))) (if (empty? (acceptFACT (first doPrzetworzenia)))
                                 "error-Implication";todo - error
                                 (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   (not (empty? (acceptNUM (first przetworzone)))) (if (empty? (acceptPP (first doPrzetworzenia)))
                             "error-NUM";todo - error
                             (wyr (cons (first doPrzetworzenia) przetworzone) (rest doPrzetworzenia)))
   :else
   "error")
  )

现在我想从上面函数给我的字符串列表中创建一个 clojure 函数。你知道怎么做吗?

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

( ROC > 100 ) >> buy


(fn
  (cond
    (> (ROC) 100) "buy"
    :else
    ()
  )
)

最佳答案

你试过了吗instaparse ?:
它从上下文无关文法生成解析器

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

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

关于clojure - Clojure 中的递归下降解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17156019/

相关文章:

c++ - 在剪辑中复制环境的构造函数?

parsing - 解决语法问题的实用解决方案

javascript - javascript 应该如何集成到 Clojure/Ring 网络应用程序中?

clojure - Clojure 中#_ 的目的是什么?

expert-system - 在 CLIPS 中使用逻辑运算符

python - 我应该在 Python 中为专家系统使用知识引擎吗?

parsing - 理解 Haskell 中实现的递归下降解析器

sql - 递归计算后代数量

Clojure 应用与映射

multithreading - 与 Clojure 的线程同步