0

私はPEG.jsで遊んで読んでいて、ネイサンズ大学で自分の言語を構築する方法を「説明」するのに良いものを見つけましたが、このステップで立ち往生しています

わかりprimaryません 説明してください

start =
    comma

comma = 
    left: additive "," right:comma 
        { return {tag: ",", left:left, right:right}; }
    / additive

additive =
    left:multiplicative "+" right:additive
        { return {tag: "+", left:left, right:right}; }
  / multiplicative

multiplicative =
    left:primary "*" right:multiplicative
        { return {tag: "*", left:left, right:right}; }
  / primary

primary =
    integer
  / "(" comma:comma  ")" # Can explain me why is necesary "(" and ")"
      { return comma; }

integer =
    digits:[0-9]+
        { return parseInt(digits.join(""), 10); }

テスト

var parse = wrapExceptions(PEG.buildParser(answer).parse);

assert_eq(parse("1+2"),
    {tag:"+", left:1, right:2},
    "parse 1+2");
assert_eq(parse("1+2*3"),
    {tag:"+", left:1, right:{tag:"*", left:2, right:3}},
    "parse 1+2*3");
assert_eq(parse("1,2"),
    {tag:",", left:1, right:2},
    "parse 1,2");
assert_eq(parse("1,2+3"),
    {tag:",", left:1, right:{tag:"+", left:2, right:3}},
    "parse 1,2+3");
assert_eq(parse("1*2,3"),
    {tag:",", left:{tag:"*", left:1, right:2}, right:3},
    "parse 1*2,3");

私の質問は/ "(" comma:comma ")"、エントリに括弧がない場合、その行を削除すると最後のテストが失敗する理由です

4

1 に答える 1

0

問題の行は、ルールの代替表現の最初の部分です。一致しないprimary場合にのみテストされます。integer

この代替表現は の後に始まり/、対応するアクション ブロックが含まれます。{ return comma; }

ここでは、「カンマ」が 2 つの異なる方法で使用されていることに注意してください。ルール名とラベル識別子の両方として使用されています。PEG.js - 式の種類の解析を参照してください。

ラベル:

式を一致させ、その一致結果を特定のラベルの下に記憶します。ラベルは JavaScript 識別子である必要があります。...

したがって、最初に;integer / "(" comma:comma ")"との一致を試みます。integerそれが失敗した場合は、2 番目の式全体との一致を試みます。

ラベルは、任意の有効な JavaScript 識別子にすることができます。あなたの例と機能的に同等である次のスニペットを検討してください。

primary =
    integer
  / "(" result:comma ")"
      { return result; }

括弧が関係ない場合は、2 番目の式全体を省略して、次のものだけを残すことができます。

primary =
    integer

ラベル付けの別の簡単な例として、これも機能します (ただし冗長です)。

primary =
    anumber:integer
      { return anumber; }
于 2013-11-05T06:12:01.783 に答える