Last active
August 29, 2015 14:20
-
-
Save gigasquid/9f846a6fda136e2ba176 to your computer and use it in GitHub Desktop.
Instaparse Introduction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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