Clojure Instaparse Parser Tutorial: Total Parse

By Xah Lee. Date: . Last updated: .

The parses functions accepts optional argument:

:total true
when parsing fails, force return a parse tree with error embedded as a element in parse tree.

The function parse also accept the argument, but isn't useful. parse function basically just return the first element of parses.

Simple Example of Total Parse

;; example of partial parse

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

(def c4
  (insta/parser
    "S = 'a'+"))

(insta/parses c4 "aaa")
;; output
;; ([:S "a" "a" "a"])

;; this is a failure
(insta/parses c4 "ab")
;; output
;; ()

(insta/failure? (insta/parses c4 "ab"))
;; true

(insta/get-failure (insta/parses c4 "ab"))
;; output a failure object
;; prints as
;; Parse error at line 1, column 2:
;; ab
;;  ^
;; Expected:
;; "a"

;; embed failure in parse tree
(insta/parses c4 "ab" :total true)
;; output
;; ([:S "a" [:instaparse/failure "b"]])


;; now, try the same with parse

(insta/parse c4 "ab")
;; Parse error at line 1, column 2:
;; ab
;;  ^
;; Expected:
;; "a"

(insta/parse c4 "ab" :total true)
;; output
;; [:S "a" [:instaparse/failure "b"]]

More Examples

Here's a more complex example.

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

(def tp3
     (insta/parser
      "S = DIGIT (SPACES '+' SPACES DIGIT)*;
       SPACES = ' '*;
       DIGIT = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';"
      ))

(insta/parses tp3 "3 +4+ 5")
;; output
;; ([:S [:DIGIT "3"] [:SPACES " "] "+" [:SPACES] [:DIGIT "4"] [:SPACES] "+" [:SPACES " "] [:DIGIT "5"]])

(insta/parses tp3 "3 +4 -5")
;; output
;; ()

(insta/parses tp3 "3 +4 -5" :total true)
;; output
;; ([:S [:instaparse/failure "3 +4 -5"]])


(insta/parse tp3 "3 +4+ 5")
;; output
;; [:S [:DIGIT "3"] [:SPACES " "] "+" [:SPACES] [:DIGIT "4"] [:SPACES] "+" [:SPACES " "] [:DIGIT "5"]]

(insta/parse tp3 "3 +4 -5")
;; returns a failure object
;; prints as:
;; Parse error at line 1, column 6:
;; 3 +4 -5
;;      ^
;; Expected one of:
;; "+"
;; " "

(insta/parse tp3 "3 +4 -5" :total true)
;; output
;; [:S [:instaparse/failure "3 +4 -5"]]

back to Clojure Instaparse Parser Tutorial