aboutsummaryrefslogtreecommitdiff
path: root/src/cljcc/parser.clj
blob: 8852d91d1559c0304d94efb245ab894eedcab13a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
(ns cljcc.parser
  (:require
   [instaparse.core :as insta]))

(def whitespace
  (insta/parser
   "whitespace = #'\\s+'"))

(declare parse)

(def c-parser
  (insta/parser
   "<program> = function+
    function = #'int\\b' identifier <'('> #'void\\b' <')'> <'{'> statement <'}'>
    statement = #'return\\b' exp <';'>
    exp = exp-prime
    <exp-prime> = constant | unop-exp | <'('> exp-prime <')'>
    unop-exp = unop exp
    unop = #'-' | #'~'
    identifier = #'[a-zA-Z_]\\w*\\b'
    constant = #'[0-9]+\\b'
    keyword = #'int\\b' | #'return\\b' | #'void\\b'"
   :auto-whitespace whitespace))

(defn parseable? [result]
  (not (insta/failure? result)))

(defn parse [source]
  (c-parser source))

(comment

  (parse "int main(void) {return 2;}")

  (parse "
  int main(void) {
  return 2;
  }")

  (parse "int main(void) {
   return -(((((10)))));
   }")

  (parse "int main(void) {
   return -(((((10)))));
   }"))