だから、私は pegjs で非常に基本的な Lisp パーサーを書こうとしていて、Lisp コードが構文的に有効で 1 行に収まる限り、同じコードを吐き出すことができました。
コード内の任意の場所に挿入された改行文字と余分な空白を受け入れることができるようにパーサーを拡張したいと考えています。
したがって、すべてが1行にある限り機能するコードは次のとおりです。
Start
= List
Character
= [^\n" ""("")"]
LeftParenthesis
= "("
RightParenthesis
= ")"
WhiteSpace
= " "
NewLine
= "\n"
Token
= token:Character+{return token.join("");}
Tuple
= left:Token WhiteSpace+ right:List?{
return left.concat([" "]).concat(right);
}
/ Token
List
= left:LeftParenthesis tuple:Tuple right:RightParenthesis{
return left.concat(tuple).concat(right);
}
/ Tuple
次に、改行と空白を許可しようとして、「タプル」のルールを次のように変更してみました
Tuple
= left:Token WhiteSpace+ (NewLine* WhiteSpace*)* right:List?{
return left.concat([" "]).concat(right);
}
/ Token
しかし、この変更により pegjs は無限ループに入りますが、ルールへの追加は再帰的ではないように見えます。
注:私が何をしようとしているのか不明な場合は、pegjs が解析するパーサーを吐き出すような文法を書いています。
(f x
(g y
(h z t)))
文字列と同じコードを吐き出すか、単に
"(f x (g y (h z t)))"
どちらも私にとってはうまくいきます。
私の現在の作業文法が行うことは、
(f x (g y (h z t)))
と出力
"(f x (g y (h z t)))"
各「トークン」または「タプル」の後に改行文字を 1 つだけ許可するのは些細なことですが、合法的なコードとして次を受け入れたいと思います。
(f x
(g y (
h z t) ) )