简体   繁体   中英

Is there a function to test literals in Clojure?

I saw functions like number? and string? .

Is there a function to test if a form is a literal?

I mean all literals in Clojure.

This is what I am trying to do.

;; Abstract Syntax Representation

(defrecord VarExp [id])
(defrecord LiteralExp [datum])
(defrecord LambdaExp [ids body])
(defrecord IfExp [pred true-exp false-exp])
(defrecord AppExp [rator rands])

(defn parse-expression [datum]
  (cond
   (symbol? datum) (VarExp. datum)
   (literal? datum) (LiteralExp. datum)
   (list? datum) (cond
              (= (first datum) 'fn) (LambdaExp. (map parse-expression (second datum))
                                                (parse-expression (nth datum 2)))
              (= (first datum) 'if) (IfExp.
                                     (parse-expression (second datum))
                                     (parse-expression (nth datum 2))
                                     (parse-expression (last datum)))
              :else (AppExp.
                     (parse-expression (first datum))
                     (map parse-expression (rest datum))))
   :else (throw
           (Exception. (str 'parse-expression
                       ": Invalid concrete syntax " datum)))))

I'd like to parse S-exp to AST without using any standalone parser because s-exp is very much like a parse tree.

My current solution is:

(defn literal? [datum]
  (or
   (true? datum)
   (false? datum)
   (string? datum)
   (nil? datum)
   (symbol? datum)
   (number? datum)))

Is this already the most practical one?

BTW, this is the grammar of Clojure literal : STRING | NUMBER | CHARACTER | NIL | BOOLEAN | KEYWORD | SYMBOL | PARAM_NAME ;

STRING : '"' ( ~'"' | '\\' '"' )* '"' ;

NUMBER : '-'? [0-9]+ ('.' [0-9]+)? ([eE] '-'? [0-9]+)? ;

CHARACTER : '\\' . ;

NIL : 'nil';

BOOLEAN : 'true' | 'false' ;

KEYWORD : ':' SYMBOL ;

SYMBOL: '.' | '/' | NAME ('/' NAME)? ;

PARAM_NAME: '%' (('1'..'9')('0'..'9')*)? ;

A literal is a compile time concept (ie the parsing of literals to corresponding value/object is done by compiler), where as functions are runtime concept (ie they work on values that are available at runtime) , so, no there is no such function possible as the function won't have any way to check if a value/object was a result of literal compilation. Only a macro can say if something is literal or not.

No, there is no such function in Clojure.

There are many kinds of literals, including compound collections like maps, sets, vectors, lists, etc so I'm not sure that "literal?" would actually be a meaningful question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM