Skip to content

Instantly share code, notes, and snippets.

@gigasquid
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gigasquid/9f846a6fda136e2ba176 to your computer and use it in GitHub Desktop.
Save gigasquid/9f846a6fda136e2ba176 to your computer and use it in GitHub Desktop.
Instaparse Introduction
(ns coollang.parser
(:require [instaparse.core :as insta]))
;;; Steps to building a language
;;;; Step 1 parse an integer
(def parser
(insta/parser
"number = #'[0-9]+'"))
(parser "1") ;=> [:number "1"]
(def transform-options
{:number read-string})
(defn parse [input]
(->> (parser input)
(insta/transform transform-options)))
(parse "1") ;=> 1
;;;; Step 2 parse integers as vector
;;;; MyCoolLang> 1 2 3 4
;; [1 2 3 4]
(def parser
(insta/parser
"expr = number | vector
vector = ((space)* number (space)*)+
<space> = <#'[\\s\\t\\n\\,]+'>
number = #'[0-9]+'"))
(parser "1 2 3 4")
;;[:expr
;; [:vector [:number "1"]
;; [:number "2"]
;; [:number "3"]
;; [:number "4"]]]
(def transform-options
{:number read-string
:vector (comp vec list)
:expr identity})
(defn parse [input]
(->> (parser input)
(insta/transform transform-options)))
(parse "1 2 3 4") ;=> [1 2 3 4]
;;; Step 3 Add integers MyCoolLang> + 1 2 3 4
; 10
(def parser
(insta/parser
"expr = number | vector | operation
operation = operator space+ vector
operator = '+' | '-' | '*' | '/'
vector = ((space)* number (space)*)+
<space> = <#'[\\s\\t\\n\\,]+'>
number = #'[0-9]+'"))
(parser "+ 1 2 3 4");=>
;;[:expr
;; [:operation
;; [:operator "+"]
;; [:vector [:number "1"] [:number "2"]
; [:number "3"] [:number "4"]
;; ]]]
(defn choose-operator [op]
(case op
"+" +
"-" -
"*" *
"/" /))
(def transform-options
{:number read-string
:vector (comp vec list)
:operator choose-operator
:operation apply
:expr identity})
(parse "+ 1 2 3 4")
;; -> 10
(defn get-input [input]
(str input (read-line)))
(defn repl []
(do
(print "MyCoolLang> ")
(flush))
(let [input (get-input "")]
(if-not (= input "quit")
(do
(println (try (parser/parse input)
(catch Exception e (str "Sorry: " e " - " (.getMessage e)))))
(recur))
(do (println "Bye!")
(System/exit 0)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment