【问题标题】:Clojure code parsingClojure 代码解析
【发布时间】:2016-02-23 15:40:44
【问题描述】:

我正在写一个 DSL,我想实现调试。

但是,我丢失了所有行信息,因为我使用 (read-string the-input) 读取用户输入,然后它不再是源,而是使用 eval 评估的 s 表达式。

我首先想到的是,只需在每行末尾添加代码(用户不知情),如下所示:

(user-func-a)
(user-func-b)

会变成:

(user-func-a) (my-source-index 0)
(user-func-b) (my-source-index 1)

但是,这会以多行形式分崩离析:

(+ (my-source-index 0)
 1 (my-source-index 1)
 2 (my-source-index 2)
 3) (my-source-index 3)

然后我想实现括号跟踪,所以只有当括号关闭时我才会添加源索引:

(+
 1
 2
 3) (my-source-index 3)

但后来我想,等等,cmets 呢?我必须跟踪';'也可以,否则就是这样:

(+
 1 ;) (my-source-index 1)
 2 (my-source-index 2)
 3) (my-source-index 3)

即使我实现了这一点,我也必须跟踪注释符号不在引号中的位置(文本的一部分)等等。

在那之后我并没有走得更远(可能会有更多的怪癖......)并来到这里。是否有任何用于 clojure 的库来解析代码,找出行周围的上下文并避免此类麻烦?

【问题讨论】:

    标签: parsing clojure


    【解决方案1】:

    来自clojure.tools.readerIndexingPushBackReader 应该可以完成这项工作。根据文档,它将行/列元数据添加到符号、向量和地图(但不是文字)。

    请参阅以下内容:

    (require '[clojure.tools.reader :as r])
    (require '[clojure.tools.reader.reader-types :as rt])
    
    (def reader (rt/indexing-push-back-reader
                 "(+ \n;; comment here \n 1 \n a)"))
    
    (def s-expr (r/read reader)) ;; => (+ 1 a)
    
    (meta s-expr) ;; => {:line 1, :column 1, :end-line 4, :end-column 4}
    
    (nth s-expr 0) ;; => +
    (meta (nth s-expr 0)) ;; => {:line 1, :column 2, :end-line 1, :end-column 3}
    
    (nth s-expr 1) ;; => 1
    (meta (nth s-expr 1)) ;; => nil (no metadata on literals)
    
    (nth s-expr 2) ;; => a
    (meta (nth s-expr 2)) ;; => {:line 4, :column 2, :end-line 4, :end-column 3}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      相关资源
      最近更新 更多