0

で PEG を開始していPEG.jsます。

頭がよくわからないことがあります...単純なことだと思いますが、概念を理解しようとすると頭が痛くなります...

次の 2 規則文法を考えてみましょう。

name
  = name:.* {return name.join("")}

put
  = "put " a:name " into " b:name "." {put(a,b)}

「foo を bar に入れる」というパーサーを渡すことができるようにしたいと考えています。とput("foo","bar")評価させます。

しかし、PEG.jsは私にエラーを与えますExpected " into " or any character but end of input found.

nameルールの正規表現がより具体的である場合、この問題を修正できると思います.*が、なぜそうしなければならないのですか? パーサーは、「.」だけでなく、「 into 」が近づいていることを先読みして確認できるほどスマートではありませんか。最後に?

探しているものをどのように達成できますか? これはおそらく「ボトムアップ」文法と「トップダウン」文法の違いでしょうか?

編集:正規表現/put (.*) into (.*)/gは私が望むように機能します-私がそれを渡すと"put foo into bar"、それは私$1="foo"に andを与えます$2="bar". PEGjsまたはJisonを使用して、これと同じ機能を取得できるかどうかを尋ねているだけです(トークンの境界がどこにあるかを判断する前に文字列全体を考慮に入れます)。

4

2 に答える 2

1

「themirror」が正しいと確信しています。最初のルールはすべての入力を消費します。そのルールなしで試してみてください。

また、任意のスペースを許可する別のルールが必要です。私はこれをオンラインで見つけました...

_
  = [ \r\n\t]*

アンダースコアは、任意の数の空白文字に一致します。次に、ルールを次のように書き換えることができます...

put
   = "put" _ a:name _ "into" _  b:name _  "." {put(a,b)}
于 2014-08-05T11:30:54.917 に答える
0

私の悪い英語でごめんなさい。

最初のルール.*はすべての文字を読み取ろうとするため、ファイルの終わりに達します。

名前のルールをより具体的にすることができます (スペースやドットではなく任意の文字):

name = [^ .]+

これは機能します...しかし、内部にスペースが含まれる名前では機能しません。

put = "put " a:name " into " b:name "." {put(a,b);}

name = c:[^ .]+ {return c.join("");}

Node.js の場合

var PEG = require('pegjs');
var text = 'put foo into bar.';
var parser = PEG.buildParser('{function put(a,b){ console.log(a,b); }}put = "put " a:name " into " b:name "." {put(a,b);}\nname = c:[^ .]+ {return c.join("");}');
parser.parse(text);

名前のスペースに対する適切な解決策はありませんが、次のようなことを試してください。

nameBeforeInto = (!" into ".)+

nameBeforeDot = [^.]+

put = "put " nameBeforeInto " into " nameBeforeDot "."

nameBeforeInto 多次元配列を返す

ファブリス

于 2014-10-11T02:32:56.207 に答える