Clojure Instaparse Parser Tutorial: Total Parse
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"]]