私は現在、rabl とは異なり、小さな小さな DSL に取り組んでいます。ルールの 1 つの実装に苦労しています。問題に入る前に、構文/文法について少し説明します。私の小さな言語では、プロパティ、オブジェクト/配列ブロック、またはカスタム ブロックを定義できます (これらはすべて、json オブジェクト/配列を構築するために使用されます)。「カスタム ブロック」は、私の標準的な式 (プロパティ、オブジェクト/配列ブロックなど) または JavaScript を含むブロックのいずれかです。これらの表現は次のように書かれています -
-- An object block
object @model
-- A property node
property some, key(name="value")
-- A custom node
object custom_obj as
property some(name="key")
end
-- A custom script node
property full_name as (u)
// This is JavaScript
return u.first_name + ' ' + u.last_name;
end
end
私が直面している問題は、カスタム スクリプト ノードにあります。JISONがブロック内のものを適切にキャプチャできるように、スクリプトトークンを非常に難しい定義にしています。私のレクサーでは、現在...
# script_param is basically a regex to match "(some_ident)"
{script_param} { this.begin('js'); return 'SCRIPT_PARAM'; }
<js>(.|\n|\r)*?"end" %{
this.popState();
yytext = yytext.substr(0, yyleng - 3).trim();
return 'SCRIPT';
%}
その SCRIPT トークンは基本的に、(u) 以降の終了トークン (通常はブロックを終了する) まで (およびそれを含む) に一致します。私の通常のブロック ターミネータ (end) は、実際にはスクリプト トークンの一部であり、完全にハッキリしているため、これは本当に嫌いです。残念ながら、(..) と end の間の何かをキャプチャするより良い方法を見つけることができません。「;」で終わるものをすべてキャプチャする正規表現を作成しようとしましたが、DSL コードに複数のスクリプト ノードがある場合に問題が発生します。キャプチャの一部として「end」キーワードを含めることによってのみ、これを機能させることができました。
私の問題を解決するための洞察をいただければ幸いです。問題を明確に説明していない場合はお知らせください。明確にするために最善を尽くします。よろしくお願いします!
また、文法をきれいにする方法についてのアドバイスも喜んで受け入れます。私はまだこのことにかなり慣れていないので、今は自分のものがめちゃくちゃになっているように感じます :)