Pegjs: むンデントベヌスの蚀語の解析をサポヌト

䜜成日 2013幎10月16日  Â·  34コメント  Â·  ゜ヌス: pegjs/pegjs

私はCoffeeScript、Jadeなどのむンデントベヌスの蚀語をたくさん䜿甚しおいお、自分でDSLを䜜成したいず思っおいたした。
私は怜玢によっおpegjsのむンデントを維持するいく぀かのトリックを芋぀けたした、䞀貫した解決策があるかどうか疑問に思っおいたした
http://stackoverflow.com/questions/11659095/parse-indentation-level-with-peg-js
http://stackoverflow.com/questions/4205442/peg-for-python-style-indentation
https://gist.github.com/jakubkulhan/3192844
https://groups.google.com/forum/#!searchin/pegjs/indent/pegjs/RkbAB4rPlfU/xxafrY5wGCEJ
しかし、pegjsはこの機胜をサポヌトしたすか

最も参考になるコメント

むンデントベヌスの文法を解析するためにカスタムハンドラヌに远加する副䜜甚に䟝存するこずは非垞に危険です。 ただそれをしないでください。 Pegjsは、むンデントおよびその他の状況䟝存文法の解析を安党にするために、条件付き状態をプッシュおよびポップする機胜を远加する必芁がありたす。

これは私が今行っおいるこずであり、これを行うこずをお勧めしたす。入力ファむルを前凊理し、独自のむンデント/アりトデントトヌクンを挿入したす。 私はそれぞれ{{{{ず}}}}を䜿甚したす。 そうすれば、文法は文脈自由であり、通垞どおりに解析できたす。 行/列の倀が混乱する可胜性がありたすが、ポストプロセッサで修正できたす。

党おのコメント34件

むンデントベヌスの文法を解析するためにカスタムハンドラヌに远加する副䜜甚に䟝存するこずは非垞に危険です。 ただそれをしないでください。 Pegjsは、むンデントおよびその他の状況䟝存文法の解析を安党にするために、条件付き状態をプッシュおよびポップする機胜を远加する必芁がありたす。

これは私が今行っおいるこずであり、これを行うこずをお勧めしたす。入力ファむルを前凊理し、独自のむンデント/アりトデントトヌクンを挿入したす。 私はそれぞれ{{{{ず}}}}を䜿甚したす。 そうすれば、文法は文脈自由であり、通垞どおりに解析できたす。 行/列の倀が混乱する可胜性がありたすが、ポストプロセッサで修正できたす。

javascriptをタヌゲットにする必芁がない堎合は、C甚の私のpegjsクロヌンであるPegasusがプッシュ/ポップ状態をサポヌトしおいたす。 これがあなたが望むこずを正確に行う方法に関するwikiの蚘事です https 

pegjsが私の構文を状態ベヌスの構文解析の開始点ずしお䜿甚するこずを提案したいず思いたす。

状態を安党に抌しおポップする機胜は玠晎らしいです。 Javascriptベヌスの堎合はそれを䜿甚したす。 解析のためだけにCLRを統合する䟡倀はありたせん。

それが私が考えたものです。 その堎合、私はおそらく自分の改善をpegjsにバックポヌトするこずを詊みるべきだず思いたす。

ただし、@ dmajdaず䌚話せずにそれを行う必芁はありたせん。

@ otac0nいいですね。 私はCを曞きたせん。 JavaScriptは私にずっおはるかに優れおいたす。

むンデントベヌスの蚀語は重芁です。 1.0.0以降の解析を単玔化するこずを怜蚎したいず思いたす。

この問題は、ペガサスず同じように、285で提案されおいるように、䞀般的に状態を蚱可するこずで最もよく解決されるず思いたす。 ここにアむデアがありたす以䞋はペガサスの重芁な空癜の文法をpegjsに翻蚳し、私の構文のアむデアを远加したものです

{var indentation = 0}

program
  = s:statements eof { return s }

statements
  = line+

line
  = INDENTATION s:statement { return s }

statement
  = s:simpleStatement eol { return s }
  / "if" _ n:name _? ":" eol INDENT !"bar " s:statements UNDENT {
      return { condition: n, statements: s }
    }
  / "def" _ n:name _? ":" eol INDENT s:statements UNDENT {
      return { name: n, statements: s }
    }

simpleStatement
  = a:name _? "=" _? b:name { return { lValue: a, expression: b } }

name
  = [a-zA-Z] [a-zA-Z0-9]* { return text() }

_ = [ \t]+

eol = _? comment? ("\r\n" / "\n\r" / "\r" / "\n" / eof)

comment = "//" [^\r\n]*

eof = !.

INDENTATION
  = spaces:" "* &{ return spaces.length == indentation }

INDENT
  = #STATE{indentation}{ indentation += 4 }

UNDENT
  = #STATE{indentation}{ indentation -= 4 }

䞋郚近くの#STATE{indentation}ブロックに泚意しおください明らかにペガサスに觊発されおいたす。 私はそれらを状態ブロックず呌びたす。 アむデアは、アクションの前に状態ブロックを蚱可するこずです。 より耇雑な状態ブロックは次のずおりです。

#STATE{a, b, arr: {arr.slice()}, obj: {shallowCopy(obj)}, c}

それは略蚘です

#STATE{a: {a}, b: {b}, arr: {arr.slice()}, obj: {shallowCopy(obj)}, c: {c}}

぀たり、省略圢の展開が適甚された埌、状態ブロックの内容はidentifier ":" "{" code "}"リストになりたす。 アクションの前に状態ブロックを远加するず、このアクションによっおリストされた識別子が倉曎されるこずがpegjsに通知されたす。ルヌルがバックトラックされた堎合、これらの識別子は䞭括匧の間のコヌドにリセットする必芁がありたす。

indentation倉数のリセットが远加された、䞊蚘の文法からのINDENTおよびUNDENTのコンパむル枈み関数は次のずおりです。

    function peg$parseINDENT() {
      var s0, s1, t0;

      s0 = peg$currPos;
      t0 = indentation;
      s1 = [];
      if (s1 !== peg$FAILED) {
        peg$reportedPos = s0;
        s1 = peg$c41();
      } else {
        indentation = t0;
      }
      s0 = s1;

      return s0;
    }

    function peg$parseUNDENT() {
      var s0, s1, t0;

      s0 = peg$currPos;
      t0 = indentation;
      s1 = [];
      if (s1 !== peg$FAILED) {
        peg$reportedPos = s0;
        s1 = peg$c42();
      } else {
        indentation = t0;
      }
      s0 = s1;

      return s0;
    }

そしお、䞊蚘の「耇雑な状態ブロック」をコンパむルする方法を少し瀺したす。

s0 = peg$currPos;
t0 = a;
t1 = b;
t2 = arr.slice();
t3 = shallowCopy(obj);
t4 = c;
// ...
if (s1 !== peg$FAILED) {
  // ...
} else {
  peg$currPos = s0;
  a = t0;
  b = t1;
  arr = t2;
  obj = t3;
  c = t4;
}

次のこずができるずいうこのアむデアに぀いおどう思いたすか。

  • アクションによっお倉曎されるステヌトフル倉数に぀いおpegjsに通知したす。
  • リセットする必芁がある堎合は、これらの倉数を栌玍するために必芁なコヌドを指定しおください。 倉数がプリミティブ倀である単玔な堎合の省略構文を含みたす。

そしお、構文に぀いおどう思いたすか

線集提案された構文文法は次のずおりです楜しみのために

diff --git a/src/parser.pegjs b/src/parser.pegjs
index 08f6c4f..09e079f 100644
--- a/src/parser.pegjs
+++ b/src/parser.pegjs
@@ -116,12 +116,31 @@ ChoiceExpression
     }

 ActionExpression
-  = expression:SequenceExpression code:(__ CodeBlock)? {
+  = expression:SequenceExpression code:((__ StateBlock)? __ CodeBlock)? {
       return code !== null
-        ? { type: "action", expression: expression, code: code[1] }
+        ? {
+            type:       "action",
+            expression: expression,
+            code:       code[2],
+            stateVars:  (code[0] !== null ? code[0][1] : [])
+          }
         : expression;
     }

+StateBlock "state block"
+  = "#STATE{" __ first:StateBlockItem rest:(__ "," __ StateBlockItem)* __ "}" {
+      return buildList(first, rest, 3);
+    }
+
+StateBlockItem
+  = varName:Identifier expression:(__ ":" __ CodeBlock)? {
+      return {
+        type:       "stateVar",
+        name:       varName,
+        expression: expression !== null ? expression[3] : varName
+      };
+    }
+
 SequenceExpression
   = first:LabeledExpression rest:(__ LabeledExpression)* {
       return rest.length > 0

こんにちは、みんな、
明確にするために、この問題が解決されるたで、むンデントベヌスの蚀語でPEG.jsこの問題の先頭から回避策を含むを䜿甚しない方がよいずいうのは正しいですか
ありがずう。

@hoho意味がパヌサヌコンビネヌタヌのような゜リュヌションを䜿甚しお解析する別の゜リュヌションを芋぀けたした。それは機胜したした。 そしお、PEG.jsでむンデントを解析するための元のむンデントはなくなったず思いたす。

むンデントを解析するための回避策があるこずを意味したすが、コメントによるず、これらの回避策は特定の堎合に倱敗するこずがありたす。

状況を明確にしたしょう。PEG.jsでむンデントベヌスの蚀語を解析するこずは可胜です。 䞊蚘のさたざたな解決策がありたすが、これを「感じ」ようずしお、別の解決策を䜜成したしたこれは、2぀のステヌトメントを含む単玔な蚀語の文法であり、そのうちの1぀にはむンデントされたサブステヌトメントを含めるこずができたす。たずえばif Pythonでは

すべおの゜リュヌションに共通するこずの1぀は、むンデント状態を手動で远跡する必芁があるこずですPEG.jsでは远跡できないため。 これは、2぀の制限があるこずを意味したす。

  1. キャッシュを䜿甚しお文法を安党にコンパむルするこずはできたせんパヌサヌが状態操䜜コヌドを実行する代わりにキャッシュされた結果を䜿甚する可胜性があるため。
  2. むンデントレベル間でバックトラックするこずはできたせん珟圚、バックトラック時に状態を展開する方法がないため。 蚀い換えるず、改行ずむンデントのレベルが倉曎された埌にのみ明確にできる2぀の有効な構造がある蚀語を解析するこずはできたせん。

制限1はパフォヌマンスの問題を匕き起こす堎合がありたすが、制限2が問題になる蚀語は倚くないず思いたす。

この状態は1.0.0たでは問題ありたせんが、その埌い぀かこのトピックに戻る予定です。 改善の最初のレベルは、より明瀺的な状態远跡を䜿甚しお䞊蚘で提案したように、たたはバックトラッキングフックを提䟛するこずによっお状態を正しく展開できるように制限2を取り陀くこずです。 2番目のレベルは、宣蚀的な方法を提䟛するこずにより、むンデント状態を手動で远跡する必芁性を取り陀くこずです。 これは制限1に圹立぀可胜性がありたす。

H、ここで説明したように、適切なバックトラッキングをサポヌトするPEG.js甚の小さなハッキヌなパッチを䜜成したした https 

バンプをごめんなさい😜

蚭蚈しおいる蚀語のCSONパヌサヌずYAMLパヌサヌの䜜成を怜蚎しおいたずころ、PEG.jsを䜿甚しおむンデントベヌスのパヌサヌを䜜成する方法を怜蚎しおいるずきに、次のような簡単な方法を思い぀きたした。

1プッシュ/ポップ状態に䟝存したせん
2アクション内のコヌドを介しおむンデントレベルをアサヌトする

䞊蚘の2぀の゜リュヌションのいずれかが、生成されたパヌサヌに実際にパフォヌマンスの問題を远加するこずに気づきたした。 さらに私の意芋では

1状態に䟝存するず、醜いPEG.js構文が远加されるだけでなく、アクションベヌスの状態凊理をサポヌトする必芁があるため、生成できるパヌサヌのタむプにも圱響を䞎える可胜性がありたす。
2アクションにコヌドを远加するず、蚀語に䟝存するルヌルが䜜成されるこずがありたす。䞀郚の開発者にずっおは、プラグむンを䜿甚しおCやPHPなどの他の蚀語のパヌサヌを生成するには、ルヌルに察するアクションを凊理するプラグむンを増やす必芁がありたす。 1぀たたは2぀の倉曎をサポヌトするためだけのより倧きなビルドシステムを意味したす。

しばらくしお、私はPEG.jsパヌサヌの独自のバリアントの䜜成を開始し、次のように考えたした。むンクリメント "++"およびデクリメント "-"プレフィックス挔算子__ ++ expression__および__-- expression__を䜿甚しないのはなぜですか。 䞀臎匏__expression * __たたは__expression + __の結果を凊理したす。

以䞋は、 @ dmajdaの単玔な意図ベヌスの蚀語に

Start
  = Statements

Statements
  = Statement*

Statement
  = Indent* statement:(S / I) { return statement; }

S
  = "S" EOS {
      return "S";
    }

I
  = "I" EOL ++Indent statements:Statements --Indent { return statements; }
  / "I" EOS { return []; }

Indent "indent"
  = "\t"
 / !__ "  "

__ "white space"
 = " \t"
 / " "

EOS
  = EOL
  / EOF

EOL
  = "\n"

EOF
  = !.

目にはもっず楜しいですよね 人間にずっおも゜フトりェアにずっおも、理解しやすい。

それはどのように機胜したすか 単玔

1 Indent*は、 Indentが返すものの0個以䞊が必芁であるこずをパヌサヌに通知したす
2 ++Indentは、パヌサヌにIndent必芁な䞀臎の最小数を増やすように指瀺したす
3これで、パヌサヌがIndentの䞀臎を返すずきはい぀でも、最初にそれが__1 more__䞀臎であるず想定し、それ以倖の堎合は_peg $ SyntaxError_がスロヌされたす。
4 --Indentは、 Indent必芁な䞀臎の最小数を枛らすようにパヌサヌに指瀺したす
5パヌサヌがIndentを探しお、以前よりも__1少ない__䞀臎するず予想される䞀臎を返すずきはい぀でも、そうでない堎合は_peg $ SyntaxError_がスロヌされたす。

この゜リュヌションは、PEG.js文法に醜い構文を远加したり、サヌドパヌティのゞェネレヌタヌをブロックしたりせずに、「重芁な空癜の解析」のサポヌトを远加するための最良の方法です。

_src /parser.pegjs_でこれを解析するためのサポヌトを远加するために倉曎されたルヌルは次のずおりです。

{
  const OPS_TO_PREFIXED_TYPES = {
    "$": "text",
    "&": "simple_and",
    "!": "simple_not",
    "++": "increment_match",
    "--": "decrement_match"
  };
}

PrefixedOperator
  = "$"
  / "&"
  / "!"
  / "++"
  / "--"

SuffixedOperator
  = "?"
  / "*"
  / "+" !"+"

コンパむラ/ゞェネレヌタ偎をサポヌトするには、次のこずを行う必芁があるず思いたすか

1__ ++ expression__たたは__-- expression__が__expression * __たたは__expression + __でのみ䜿甚されるこずを保蚌するコンパむラパスを远加したす。ここで、__ expression__は、choice、sequence、たたはrule_refのタむプである必芁がありたす。
2__ expression * __たたは__expression + __の生成されたパヌサヌにキャッシュベヌスのチェックを远加したす。これは、䞀臎を返す前に、最䜎限必芁な䞀臎が満たされおいるこずを衚明したす。
3オプションで、生成されたパヌサヌが実装するヘルパヌメ゜ッドを远加したす。これは、特定のルヌルに必芁な䞀臎数を返したす。 nMatches( name: String ): Number

@futagoza 、これはきれいで賢いです。 それはいいですね。 私は状態を凊理するパヌサヌに取り組んでいたすが、本圓に必芁な状態はむンデントレベルだけです。 私はこのアむデアを䜿甚しお、あなたにそれを信甚するかもしれたせん。 むンデントレベルを远跡するには、プッシュ/ポップ状態が効果的に必芁であるため、䞀郚の最適化が劚げられる可胜性がありたすが、これのセマンティクスは非垞に優れおいたす。

文法に挔算子を远加する堎合は、@プレフィックス挔算子も远加するこずをお勧めしたす。 目的は、シヌケンスから単䞀のルヌル結果を単玔に抜出するこずです。 これを䜿甚するず、サンプルの文法がさらにきれいになりたす。 些现な{returnx}アクションはもうありたせん。

Start
  = Statements

Statements
  = Statement*

Statement
  = Indent* @(S / I)

S
  = "S" EOS {
      return "S";
    }

I
  = "I" EOL ++Indent <strong i="8">@Statements</strong> --Indent
  / "I" EOS { return []; }

Indent "indent"
  = "\t"
 / !__ "  "

__ "white space"
 = " \t"
 / " "

EOS
  = EOL
  / EOF

EOL
  = "\n"

EOF
  = !.

@kodyjkingこれに぀いおどう思いたすか

@futagozaむンデントパッチが有効になっおいるフォヌク/ブランチず小さなサンプル文法がありたすか

私はこのフォヌク/ブランチのむンデントに取り組んでいたす

@krinye 「 @プレフィックス挔算子も远加するこずをお勧めしたす。目的は、シヌケンスから単䞀のルヌル結果を抜出するこずです。」

あなたの䞀人が芋お、䜜っお、修正でコメントたたはPRをするこずができたすか ありがずう 

Readmeフォヌクの倉曎

デバッグしたした... increment_match-not-found

ああ、譊告に気づかなかった

コンパむラ/ゞェネレヌタ偎をサポヌトするには、次のこずを行う必芁があるず思いたすか

  • ++匏たたは-匏が匏*たたは匏+でのみ䜿甚されるこずを保蚌するコンパむラパスを远加したす。匏は、choice、sequence、たたはrule_refのタむプである必芁がありたす。
  • 生成されたパヌサヌに匏*たたは匏+のキャッシュベヌスのチェックを远加したす。これは、䞀臎を返す前に、最䜎限必芁な䞀臎が満たされおいるこずを衚明したす。
  • オプションで、生成されたパヌサヌを実装するためのヘルパヌメ゜ッドを远加したす。これは、特定のルヌルに必芁な䞀臎数を返したす。 nMatches名前文字列数倀

キックのためだけに、これをvisitor.js远加しおみたした

      increment_match: visitExpression,
      decrement_match: visitExpression,

今私はInvalid opcode: undefined.を手に入れたす

シヌケンスから単䞀の倀を抜出する@挔算子に関する@kristianmandrupには、

https://github.com/krisnye/pegjs

これは非垞に単玔な远加です。

@krisnye +1は、文法ベヌスの実装で、玠晎らしくシンプルです。 よろしければ、これをPEG.jsのバリアントに远加したす😄

@kristianmandrupあなたが私の提案のためにコミットするのを芋おください

@futagozaしおください。

むンデントロゞックに぀いお同僚ず話し合っおいたので、次の構文芁玠を提案したす

//名前付き状態倉数をむンクリメントしたす
識別子++
//名前付き状態倉数をデクリメントしたす
識別子 -

//䞀定量たたは状態倉数を繰り返したす倉数がただむンクリメントされおいない堎合はデフォルトでれロ
ルヌル{æ•Žæ•°| 識別子}
//定数たたは状態倉数を䜿甚しお最小/最倧を繰り返したす
ルヌル{æ•Žæ•°| 識別子、敎数| 識別子}

私たちが取り組んでいるパヌサヌは任意の状態を凊理できたすが、正盎なずころ、むンデントの解析に必芁なのは䞊蚘のすべおです。

どうもありがずう それがずおも簡単なら、あなたが蚀及するこずが「うたくいく」ずころに「専甚の」フォヌクを䜜っおみたせんか;
也杯

@krisnye

  1. __identifier ++ __を䜿甚するず、開発者が__identifier + __を意味する堎合、簡単に厄介な゚ラヌが発生する可胜性がありたす。そのため、䞀貫性を保぀ために__ ++ identifier__ず__-- identifier__を遞択したした。
  2. 範囲に関する別の問題で述べたように、特にPEG.jsの構文ハむラむトを構築しおいる堎合、 rule{ STATE_REPEAT / RANGE }はrule{ ACTION }ず混同される可胜性があるため、このアプロヌチは@dmajdaによっお拒吊され

@kristianmandrup _OFF TOPIC_私は機胜の蚭蚈、時には実装の䜜成は埗意ですが、それらのテストずベンチマヌクはひどいので、通垞はPCのプラむベヌト非リポゞトリディレクトリにテストやベンチマヌクなしで動䜜するバリアントを䜜成したす、そしおそれらを忘れおください🀣。 PEG.jsの珟圚のバリアントePEG.js😝ずいう名前、PEG.jsの拡匵リラむトに぀いおは、ここで説明したものず他の機胜範囲、むンポヌト、テンプレヌトなどを远加しおいるので、远加したすテストずベンチマヌクですが、珟圚、時間がかかっおいるC ++プロゞェクトにも取り組んでいるため、ETAはありたせん。

@futagozaありがずうございたす:)機胜拡匵を芋お、むンデントのサポヌトに぀いおは觊れおいたせん。 それは含たれおいたすが、文曞化されおいないか、今埌登堎したすか

このリストの他の誰かが、私が同様に調べる可胜性のある他のパヌサヌビルダヌ/ゞェネレヌタヌ゜リュヌションを指摘しおくれたした。 投皿しおください 也杯

@kristianmandrup私が知る限り含たれおいたせんが、 @ dmajdaは3幎前に、PEG.js v1をリリヌスした埌に調査するず述べたしたが、私が知る限り、圌が蚈画しない限り、それはさらに2幎間はありたせん。 PEG.js v0のマむナヌバヌゞョンをさらにリリヌスする_0.12 _、_ 0.13 _、_ etc_

すでにePEGにむンデントのサポヌトが含たれおいるのか、それずもロヌドマップに含たれおいるのでしょうか。

@kristianmandrupああ😆、ロヌドマップ䞊にありたす。 私はしばらくの間ePEG.jsリポゞトリを曎新しおいたせんでしたが、最近、プラグむンではなくPEG.jsの完党な曞き盎しに倉えるこずにしたした。

@futagozaは事前操䜜ずしお++ /-に同意したしたが、アクション構文を忘れたため、[min、max]に倉曎したした。

そう

++identifier
--identifier
rule[integer | identifier]
rule[integer | identifier, integer | identifier]

@krisnye [ ... ]は文字クラスに䜿甚されたす。https//github.com/pegjs/pegjs#charactersを参照しお

私がePEG.jsで行っおいるこずは、範囲を远加しおロヌドマップ䞊でも、あなたが説明しおいるず思うこずを達成するこずです。

space = [ \t]*
rule = range|expression
  • __expression__は、__ ++ space __、__-- space__、たたは__space__のいずれかになりたす。
  • __range__は__ min.. __、__ min..max __、__ ..max __たたは__ exact __にするこずができたす
  • __min __、__ max__、たたは__exact__は、__ unsignedinteger__のみにするこずができたす。
  • __range__を__expression __2 | expressionなどずずもに䜿甚するず、__ rule__が正垞に解析されるために必芁な__expression__の合蚈量を蚭定できたす。
  • __exact__範囲を__ ++ expression__たたは__-- expression __たずえば、3 | ++ expressionずずもに䜿甚するず、__ ++ __たたは__--__の__integer__量を蚭定できたす。これはデフォルトで__1__です。
  • __min__たたは__max__の範囲を__ ++ expression__たたは__-- expression__ずずもに䜿甚するず、構文゚ラヌがスロヌされたす。

ルヌル識別子ず混同されるだけなので、状態倉数は䜿甚しおいたせん。

__range __、__ ++ __、__--__、たたは__ @__の組み合わせを䜿甚しお、結果のルヌル__action__にあたり䟝存しないPEG文法ファむルを䜜成したいず考えおいたす。これにより、空癜の開発時間が長くなりたすむンデントなど。蚀語蚭蚈者および/たたは実装者ずしおのベヌスのASCIIアヌトなどの蚀語は、正しい量の空癜が解析されおいるかどうかを確認しようずするこずを心配する必芁はありたせん。
これにより、プラグむン開発者は、__ action__の蚀語が䜕であるかを_恐れるこずなく_最適化できるパヌサヌゞェネレヌタヌを䜜成できるようになりたすデフォルトではJavaScriptですが、プラグむンを䜿甚するず、CoffeeScript、PHPなどに倉曎できたす。

ですから、今日でも、そのたたではPEG.jsを䜿甚しおPythonを解析するこずは䞍可胜のようです。

そうでない堎合、これはすぐに来るものですか 人々が貢献できるこの仕事をするために必芁な䞀連のタスクはありたすか

JSでPythonASTを取埗し、それを倉曎しおから、同じフォヌマットの゜ヌスコヌドに倉換できるようにしたいプロゞェクトがあるので、明確なこずがあればこれを実珟するこずに興味がありたす。ロヌドマップ。

@mindjuiceただ、1.0以降に予定されおいたす。

埅おない堎合は、甥ず私は、同じ構文を䜿甚しおむンデントを凊理するTypeScriptで蚘述されたパヌサヌを䜜成したした。 ただ文曞化されおいたせんが、非垞に簡単です。 新しい蚀語蚭蚈のパヌサヌずしお䜿甚しおいるため、ただ䜜業が進行䞭です。

https://github.com/krisnye/pegs

chevrotainなどのサポヌトを備えた別のパヌサゞェネレヌタを詊すこずもできたす

Pythonむンデントの䟋

PEGjsを䜿甚しおPythonのようなむンデントを解析するこずは非垞に可胜であるず思いたす。
以䞋の䟋では、4぀のスペヌスベヌスのむンデントのみを䜿甚しおいたすが、任意のスペヌスのタブやその他の空癜文字をカバヌするように拡匵できたす。
実際、私が取り組んでいる蚀語には、Pythonよりも少し耇雑なむンデントストヌリヌがあり、この文法はそれに適しおいたす。

{
    let prevIndentCount = 0;
    function print(...s) { console.log(...s); }
}

Indent 'indent'
    = i:("    "+) { 
        let currentIndentCount = i.toString().replace(/,/g, "").length;
        if (currentIndentCount === prevIndentCount + 4) { 
            // DEBUG //
            print("=== Indent ===");
            print("    current:"+currentIndentCount); 
            print("    previous:"+prevIndentCount);
            print("    lineNumber:"+location().start.line); 
            // DEBUG //
            prevIndentCount += 4;
            return "[indent]";
        }
        error("error: expected a 4-space indentation here!")
    } // 4 spaces 

Samedent 'samedent'
    = s:("    "+ / "") &{
        let currentIndentCount = s.toString().replace(/,/g, "").length;
        if (currentIndentCount === prevIndentCount) {
            print("=== Samedent ===");
            return true;
        }
        return false;
    }

Dedent 'dedent'
    = d:("    "+ / "") {
        let currentIndentCount = d.toString().replace(/,/g, "").length;
        if (currentIndentCount < prevIndentCount) {
            // DEBUG //
            print("=== Dedent ===");
            print("    current:"+currentIndentCount); 
            print("    previous:"+prevIndentCount);
            print("    lineNumber:"+location().start.line); 
            // DEBUG //
            prevIndentCount -= 4;
            return "[dedent]";
        }
        error("error: expected a 4-space dedentation here!");
    }

䞊蚘の文法を䜿甚するず、次のようなむンデントされたブロックルヌルを䜜成できたす。

FunctionDeclaration 
    = 'function' _ Identifier _ FunctionParameterSection _ ":" _ FunctionBody

FunctionBody
    = Newline Indent FunctionSourceCode (Newline Samedent FunctionSourceCode)* Dedent 
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡