したがって、sexpには、私たちの単純な文法で定義された数以上のものが含まれています。私たちがsexpを持つことができる1つの高レベルのビューは、それらを2つのかっこの間の操作として見ることです。基本的には(operation)
となります。これを文法に直接書くことができます。私は前述したように、それは構文解析ツリーを作っているとき
(def parser
(insta/parser
"sexp = lparen operation rparen
<lparen> = <'('>
<rparen> = <')'>
operation = ???
"))
、角度付きブラケットは<
、これらの値を無視するinstaparse言います。オペレーションとは何ですか?操作は、+
のような演算子と、数字1
と2
のようないくつかの引数で構成されます。私達はちょうど物事をシンプルに保つために、唯一の可能なオペレータ、+
を述べ
(def parser
(insta/parser
"sexp = lparen operation rparen
<lparen> = <'('>
<rparen> = <')'>
operation = operator + args
operator = '+'
args = number
number = #'[0-9]+'
"))
:だから私たちは私たちのような文法を書くと言うことができます。また、上記の単純な例の数値文法規則も示しました。しかし、私たちの文法は非常に限られています。解析できる唯一の有効なsexpは(+1)
です。スペースの概念は含まれておらず、argsには1つの数字しかないと述べているからです。したがって、このステップでは2つのことを行います。スペースを追加し、argsに複数の番号を付けることができるようにします。
(def parser
(insta/parser
"sexp = lparen operation rparen
<lparen> = <'('>
<rparen> = <')'>
operation = operator + args
operator = '+'
args = snumber+
<snumber> = space number
<space> = <#'[ ]*'>
number = #'[0-9]+'
"))
単純な例で定義したスペース文法ルールを使用してspace
を追加しました。 space
とnumber
と定義された新しいsnumber
を作成し、+
を追加して1回表示する必要がありますが、何回でも繰り返すことができると述べています。だから我々は、ように私たちのパーサを実行することができます。
(parser "(+ 1 2)")
=> [:sexp [:operation [:operator "+"] [:args [:number "1"] [:number "2"]]]]
我々は戻ってsexp
からargs
参照を持っていることによって私たちの文法をより堅牢にすることができます。そうすれば、私たちはsexpでsexpを持つことができます! ssexp
を作成し、space
をsexp
に追加してから、ssexp
をargs
に追加することでこれを行うことができます。
(def parser
(insta/parser
"sexp = lparen operation rparen
<lparen> = <'('>
<rparen> = <')'>
operation = operator + args
operator = '+'
args = snumber+ ssexp*
<ssexp> = space sexp
<snumber> = space number
<space> = <#'[ ]*'>
number = #'[0-9]+'
"))
今、私たちは
(parser "(+ 1 2 (+ 1 2))")
=> [:sexp
[:operation
[:operator "+"]
[:args
[:number "1"]
[:number "2"]
[:sexp
[:operation [:operator "+"] [:args [:number "1"] [:number "2"]]]]]]]
Instaparseは本当に豊富ですhttps://github.com/Engelberg/instaparse – Chiron
希望の結果の例を教えてください。 –
多分[:sexp [:sym +] [:num 1] [:num 2] [:sexp [:sym +] [:num 3] [:num 4]]] ??私は実際には知りません...それはこの質問と関係があります:http://stackoverflow.com/questions/18184834/how-would-you-get-the-clojure-reader-to-keep-formatting – zcaudate