2

述語を使用して文法を作成する必要があります。以下の文法は、特定のケースでは失敗します。

startRule = a:namespace DOT b:id OPEN_BRACE CLOSE_BRACE {return {"namespace": a, "name": b}}

namespace = id (DOT id)*
DOT = '.';
OPEN_BRACE = '(';
CLOSE_BRACE = ')';
id = [a-zA-Z]+;

指定された入力に対して失敗します

com.mytest.create();

結果部分の「name」キーの値として「create」を指定する必要があります。

どんな助けでも素晴らしいでしょう。

4

1 に答える 1

1

ここにはいくつかのことがあります。

最も重要なことは、PEGが貪欲であることを認識する必要があるということです。つまり、ルールはas(DOT id)*にあるものを含むすべての DOT id シーケンスに一致します。startRuleDOT b:id

これは、先読みを使用して解決できます。

joinもう 1 つは、デフォルトでは各文字を配列のメンバーとして返すため、忘れずに を使用する必要があることです。

セミコロンのルールも追加しました。

これを試して:

start =
  namespace:namespace DOT name:string OPEN_BRACE CLOSE_BRACE SM nl?
    {
      return { namespace : namespace, name : name };
    }

/* Here I'm using the lookahead: (member !OPEN_BRACE)*  */
namespace =
  first:string rest:(member !OPEN_BRACE)* 
    {
      rest = rest.map(function (x) { return x[0]; });
      rest.unshift(first);
      return rest;
    }

member =
  DOT str:string
    { return str; }

DOT =
  '.'

OPEN_BRACE =
  '('

CLOSE_BRACE =
  ')'

SM =
  ';'

nl =
  "\n"

string =
  str:[a-zA-Z]+
    { return str.join(''); }

そして、私が知る限り、その行を正しく解析しています。

于 2014-11-06T02:44:35.767 に答える