0

私は現在、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」キーワードを含めることによってのみ、これを機能させることができました。

ここに私の文法字句解析ファイルへのリンクがあります。

私の問題を解決するための洞察をいただければ幸いです。問題を明確に説明していない場合はお知らせください。明確にするために最善を尽くします。よろしくお願いします!

また、文法をきれいにする方法についてのアドバイスも喜んで受け入れます。私はまだこのことにかなり慣れていないので、今は自分のものがめちゃくちゃになっているように感じます :)

4

1 に答える 1

1

の最初のインスタンスまでの文字列を一致させるのは簡単ですが、これは含まれませんend

([^e]|e[^n]|en[^d])*

(そして、貪欲でない繰り返しも必要ありません。)

しかし、それはあなたが望むものではありません。含まれる JavaScript には、次のものが含まれる場合があります。

  • 名前に文字end( tendency)が含まれる変数

  • コメント ( /* Take the values up to the end of the line */)

  • 文字列 ( if (word == "end"))

  • そして、確かに、endjs の予約語ではない単語自体です。

本当に、唯一のクリーンな解決策は、JavaScript を lex できるようにすることです。幸いなことに、正確に解釈する必要はありません。解釈していないためですが、それでも少し手間がかかります。他の同様の言語と同様に、javascript 字句解析の最も厄介な部分は、いつ/正規表現の始まりで、いつそれが単なる除算であるかを識別することです。それを正しく行うには、特にセミコロン規則とも相互作用するため、ほとんどの JavaScript パーサーが必要です。

含まれている JavaScript が実際に という名前の変数を使用する可能性があるという事実に対処するには、end私が見る限り、いくつかの選択肢があります。

  1. endそれが予約語であることを文書化します。

  2. end括弧の外側と、ステートメントが始まる可能性のある場所に出現する場合にのみ認識します (正規表現を正しく識別するのに十分な JS パーサーを最終的に構築する場合は、それほど難しくありません)。

  3. end行に単独で表示される場合にのみ認識します。

この最後の選択は、実際には問題を大幅に単純化するので、あまりエレガントではありませんが、考えてみてください。

于 2014-05-01T03:10:41.347 に答える