Pegjs: セマンティックアクションの省略圢

䜜成日 2018幎09月10日  Â·  13コメント  Â·  ゜ヌス: pegjs/pegjs

セマンティックアクションの省略圢を远加するず䟿利です。

たずえば、 { return value }を曞き蟌む代わりに、たずえば初期化子で定矩されおいる{ extract }を蚘述したす。

䟋えば

{
  function extract(value) {
    return value;
  }
  function concat(head, tail) {
    return head ? [head].concat(tail) : [];
  }
  function toAddExpr(head, tail) {
    return { type: 'addExpr', expressions: concat(head, tail) };
  }
}

List
  = '(' _ head:Item? tail:( _ ',' _ value:Item { extract } )* _ ')' { concat }

// Another kind of list
Add
  = '(' _ head:Multiply? tail:( _ '+' _ value:Multiply { extract } )* _ ')' { toAddExpr }

たず、これにより関数を再利甚できるようになりたす...より良い方法でsmile
第二に、これは私たちの文法をもう少し読みやすくしたす。

アクションの省略圢に含たれる匏が、単なる識別子{ foo }ではなく、メンバヌ匏{ foo.bar.baz }ある堎合にも、より䟿利になるず思いたす。 文法の䜜成者がオブゞェクトたたはモゞュヌル内で機胜を敎理できるようにしたす。

discussion feature

最も参考になるコメント

実際、私は考えおいたしたが、これらの倉曎はうたくいくかもしれたせん

CodeBlock "code block"
  = "=>" _ expession:CallExpression {
       return `return ${ expession };`;
     }
  / "{" <strong i="6">@Code</strong> "}"
  / "{" { error("Unbalanced brace."); }

// Will be based on ECMAScript's CallExpression
CallExpression
  = ...
  / MemberExpression

// Will be based on ECMAScript's MemberExpression
MemberExpression
  = ...
  / ValidIdentifier

// Change `LabelIdentifier` into `ValidIdentifier`

この方法でも、匕数ずしお䜿甚するECMAScriptのプラむマリ匏数倀、ブヌル倀、配列などなどを統合する必芁があるため、䜕を远加するかを慎重に怜蚎する必芁がありたす。


ブラケットずブレヌスのバランスをずる

これは、適切なJavaScriptパヌサヌがPEG.jsパヌサヌに組み蟌たれるたで修正されたせんが、他の蚀語C、PHP、TypeScriptでパヌサヌを生成するプラグむンプロゞェクトがいく぀かあるため、正盎なずころ、これに぀いおは少し躊躇しおいたす。など、そしお私はたた、い぀かパヌサヌを生成したいず思っおいるコンピュヌタヌ蚀語に取り組んでいたす。


_PEG.js v0.12_ず䞀緒に、OpenPEGに取り組んでいたす。これは、JavaScriptやパヌサヌの生成を䌎わない基本的にPEG.jsの簡略版であるNPMパッケヌゞを提䟛したすが、JavaScriptベヌスのプロゞェクトがPEG.jsはそれをバック゚ンドずしお䜿甚できたす。 _v0.12_が出たら、カスタムパヌサヌを生成するプラグむンプロゞェクトにOpenPEGが通知されるようにし、v1の前に完党なECMAScript2015パヌサヌをPEG.js文法パヌサヌに実装したす。

党おのコメント13件

興味深いアむデアですが、どの匕数が関数に枡されおいるのかが明確でないため、個人的にはそれがより明確な方法になるずは思いたせん。 たた、「カスタム」パラメヌタヌを枡す必芁がある堎合は、それらを通垞の関数呌び出しず組み合わせる必芁があるため、単玔な堎合ほどきれいに芋えたせん。

235の誰かが、矢印関数ず䞀緒に構文=>を提案したしたが、これは非垞にクリヌンで簡朔だず思いたした。

  = '(' expr:some_expression ')' => expr
  ;

私は速蚘構文のために次のいずれかを遞択するこずに傟いおいたす

  • => expr; _構文のサポヌトが必芁_
  • { => expr } _珟圚䜿甚可胜ですが、開梱が必芁です_
  • { > expr } _構文のサポヌトが必芁_

ただ決めおいないので、議論の䜙地がありたす。

OPが必芁ずするものに぀いおは、Acornたたは@ babel / parserを䜿甚しお識別子たたはメンバヌ匏をアンラップし、それを呌び出し匏に倉換するプラグむンを実装するのが最善です省略構文が決定された埌たたは前に。匕数ずしおラベルを付け、生成されたコヌドを返したす。

=> expr;

私の意芋では最高です。

{ => expr }

Javascript構文IMOずの競合。 { }にあるので、完党な矢印関数 () => であるこずが期埅されたす。

{ > expr}

PegJSたたはJavascriptの他の構文ず少し盎亀しおいるため、「これは倀を返す、省略圢」のIMOをすぐには読み取れたせん。䞻に䞭括匧で囲たれおいるためです。 {=> expr}ず同じ匕数で、Javascriptがそこにあるこずを期埅したす。


さらに、 {}非JS構文を远加するこずは、構文ハむラむタヌやリンタヌなどにずっお問題です。私はそれをお勧めしたせん。

さらに別のオプションを提案する堎合は、おそらく>自䜓述語ブロック内ではないです。 これは、ルヌルを垂盎方向に配眮するずきに、物事を敎列させるのに圹立ちたす。

    = foo:bar qux:(' '+ @qix)+
    > {foo, qux}
    ;

むンラむンだけでなく

some_rule = foo:bar qux:(' '+ @qix)+ > {foo, qux};

'=>'にセミコロンが必芁なのはなぜですか たずえば、buildListを䜿甚する代わりに、ネストされたコヌドで倀を返したいのですが。

  = "(" _ head:Expression _ tail:("," _ expr:Expression => expr)* ")" {
      return [head, ...tail]
    }

私はこれが魔法のむンデックス䞋蚘を䜿甚するよりもきれいだず思いたす。 もう1぀のオプションは、ネストされたラベルを参照する機胜です。 䟋 ("," _ tail:Expression)* ")"

  = "(" _ head:Expression _ tail:("," _ Expression)* ")" {
      return buildList(head, tail, 2)
    }

parser.pegjsを芋おいたしたが、434行目あたりにCodeBlockがあるこずがわかりたした。 それを詊すために䜕をする必芁がありたすか ルヌルコヌドは単にSourceCharacterを読み取りたす。これは単に「。」です。

CodeBlock "code block"
  = "=>" __ <strong i="13">@Code</strong> // this?
  / "{" <strong i="14">@Code</strong> "}"

@mikeaustinええ、その通りですが、このシヌケンスをどこで終了するかを知る方法がないため、 =>埌にevrythingを消費したす

たぶん、「コヌド」は少し賢く、角かっこず䞭括匧のバランスを取り、LineTerminatorを凊理するこずができたすか 完党なJavaScriptに぀いお知る必芁はありたせんが、それは思ったより難しいかもしれたせん。

実際、私は考えおいたしたが、これらの倉曎はうたくいくかもしれたせん

CodeBlock "code block"
  = "=>" _ expession:CallExpression {
       return `return ${ expession };`;
     }
  / "{" <strong i="6">@Code</strong> "}"
  / "{" { error("Unbalanced brace."); }

// Will be based on ECMAScript's CallExpression
CallExpression
  = ...
  / MemberExpression

// Will be based on ECMAScript's MemberExpression
MemberExpression
  = ...
  / ValidIdentifier

// Change `LabelIdentifier` into `ValidIdentifier`

この方法でも、匕数ずしお䜿甚するECMAScriptのプラむマリ匏数倀、ブヌル倀、配列などなどを統合する必芁があるため、䜕を远加するかを慎重に怜蚎する必芁がありたす。


ブラケットずブレヌスのバランスをずる

これは、適切なJavaScriptパヌサヌがPEG.jsパヌサヌに組み蟌たれるたで修正されたせんが、他の蚀語C、PHP、TypeScriptでパヌサヌを生成するプラグむンプロゞェクトがいく぀かあるため、正盎なずころ、これに぀いおは少し躊躇しおいたす。など、そしお私はたた、い぀かパヌサヌを生成したいず思っおいるコンピュヌタヌ蚀語に取り組んでいたす。


_PEG.js v0.12_ず䞀緒に、OpenPEGに取り組んでいたす。これは、JavaScriptやパヌサヌの生成を䌎わない基本的にPEG.jsの簡略版であるNPMパッケヌゞを提䟛したすが、JavaScriptベヌスのプロゞェクトがPEG.jsはそれをバック゚ンドずしお䜿甚できたす。 _v0.12_が出たら、カスタムパヌサヌを生成するプラグむンプロゞェクトにOpenPEGが通知されるようにし、v1の前に完党なECMAScript2015パヌサヌをPEG.js文法パヌサヌに実装したす。

FWIW、私はこれにテンプレヌトリテラルを䜿い始めたした。 たた、テキスト゚ディタによるJSの構文の匷調衚瀺にも圹立ちたす...

exports = module.exports = functionBodies`${grammarScript}
...
objectText =
    head:word
    rest:(_txt_ word)*
    ${f=>{
        return new Txt(rest.reduce((a,b)=>([...a,...b]),[head]))
        }}
word = ch:(wordCharacter/escapedCharacter)+ ${chJoin}
...
`
function functionBodies(glue, ...fns){
    return glue.map( (str,i) => str + (fns[i]||'').toString().replace(/^[^{]*/,'').replace(/[^}]*$/, '') ).join('')
    }

function chJoin(ch){return ch.join('')}

提案されたパむプ挔算子https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operatorを䜿甚するのはどうですか 基本的に、デヌタをパむプするように求めおいるのですか

{
  function extract(value) {
    return value;
  }
  function concat(head, tail) {
    return head ? [head].concat(tail) : [];
  }
  function toAddExpr(head, tail) {
    return { type: 'addExpr', expressions: concat(head, tail) };
  }
}

List
  = '(' _ head:Item? tail:( _ ',' _ value:Item |> extract )* _ ')' |> concat

// Another kind of list
Add
  = '(' _ head:Multiply? tail:( _ '+' _ value:Multiply |> extract  )* _ ')' |> toAddExpr

これは起こらないはずです。 短い構文があっおはなりたせん。

矢印を暪向きにシムしようずするのではなく、通垞どおりに矢印を解析する堎合は、これは必芁ありたせん。

これは玠晎らしいアむデアですが、JavaScriptず比范しお文法のあいたいさが倧きくなりたす。 JSを解析し、 with倧倱敗が䜕であったかを芚えおいる人なら誰でも、これが基本的にパヌサヌを殺害するこずを知っおいたす。

掟手な新しいものを䜜成しようずするのではなく、Javascriptをサポヌトする必芁がありたす。 矢印機胜はES6より叀く、ES6は2015幎のものです。これは6幎前に解決されたした。 ここでは発明は起こらないはずです。

パむプ挔算子にはひどい欠陥があり、おそらく実際にはJavascriptに組み蟌たれず、元々の蚀語Fずそれを普及させた蚀語Elixirの䞡方がそれから遠ざかっおいたす。 その䞊、これはいかなる意味でも配管ではありたせん。

PEGが非垞に成功した理由は、PEGが最小限であり、蚀語に近いたたであり、高速、小型、および予枬可胜であるためです。

矢印機胜はES6より叀く、ES6は2015幎のものです。これは6幎前に解決されたした。 ここでは発明は起こらないはずです。

ええず。 それは私にずっおのニュヌスです。 拡倧する気ですか

PEGが非垞に成功した理由は、PEGが最小限であり、蚀語に近いたたであり、高速、小型、および予枬可胜であるためです。

PEGこのラむブラリではなく抂念ずしおが成功する理由は、耇雑な文法再垰などを単玔な方法で衚珟できるためです。 Packratはこのラむブラリで発明されたものではありたせん。 構文ではありたせん。 それはアルゎリズムです。

矢印機胜はES6より叀く、ES6は2015幎のものです。これは6幎前に解決されたした。 ここでは発明は起こらないはずです。

ええず。 それは私にずっおのニュヌスです。 拡倧する気ですか

私はあなたが䜕を求めおいるのか本圓にわかりたせん。

矢印関数はES6より叀いです。 これはES6で2番目に倧きな戊いであり、ES4を狂わせたもの、そしおES5 +を狂わせたものです。 その時点で、90幎代半ばから、誰もがそれらを求めおいたした。なぜなら、それらは実際にはE4Xにすでに存圚しおいたためであり、GoogleずAppleがMicrosoftがこれたでに䜕かを発明したこずに぀いおHixieに適合したために取り䞊げられたした。

あなたは今E4XをReactずしお知っおおり、Facebookがそれを発明したず思いたす。 Facebookは圌らがHyperscriptをはぎ取ったず考えおいたす。 Hyperscriptの男は、圌が叀いIEから有甚なものを再実装しただけであるこずを明確にしおいたす。

テンプレヌト文字列ず同じように、ES6から完党に陀倖される予定でしたが、Coffeescriptが登堎し、JSコミュニティに䞡方を提䟛し、その埌JSコミュニティはECMAの人々が怒鳎るたで怒鳎りたした。 たった18ヶ月しかかかりたせんでした

矢印関数は、ここで発生する必芁があるすべおのこずを実行したす。 あなたは2018幎にこのスレッドで圌らを育おた人でさえあるようです。それはあなたの意芋の䞍䞀臎を非垞に驚くべきものにしたす。 私はあなたをバックアップしようずしおいたした。

私にずっおもっず重芁なこずは、それが矢印関数で行われた堎合、䜕も远加されおいないずいうこずです。

ペグずJSの違いはごくわずかです。 ES6を実行するだけでこれをサポヌトするずいうこずは、リストが倉曎されないこずを意味したす。

それは非垞に䟡倀がありたす。


PEGこのラむブラリではなく抂念ずしおが成功する理由は、耇雑な文法再垰などを単玔な方法で衚珟できるためです。

同意したせん。 倚くのパヌサヌはこれをはるかに䞊手くこなし、それらに぀いお知っおいる人々Earleyのようなでさえ、少しでも人気がありたせん。

埓来の説明ぱラヌメッセヌゞの品質ず速床の組み合わせですが、倚くのパヌサヌはより高速な゚ラヌメッセヌゞを持っおおりこれもEarleyのように、人々の間でも少しでも人気がないため、私もそれに同意したせん。それらに぀いお知っおいる人

たた、PEGには3぀の深刻な耇雑さの䞊限があるこずに泚意しおください。

1぀は、ペグ文法を䜿甚する堎合は、ロヌカルマシンのキャッシュず評䟡スルヌプットを圧倒しない組み合わせ匏を䜿甚する必芁がありたす䟋623

2぀目は、BNFの解析など、倚くの䞀般的な䜜業がペグで残酷に困難な堎合が倚いこずです䟋489

3぀目は、他のすべおのJS PEGラむブラリヌ、さらにははるかに匷力なラむブラリヌが倱敗したこずです。 私は䜕床も切り替えようずしたしたが、戻っおきたした。 特に、 c 、 ruby 、およびpythonを远加でタヌゲットにできるため、䜕床もcanopyに切り替えようずしたした。 javascript

確かに、私が話すこずができるのは、それを䜿甚しおいる私が知っおいる20人ほどの人々だけです。 そしお、数日前に尋ねたので、䜕幎にもわたっお公開された倉曎がなかった埌、新しい非保守者が゜フトりェアを砎棄し、圌がれロから䜜成したものず亀換しおいるこずに気付いたずき、私はできたす

しかし、圌らの䞀人䞀人が私に、ネむティブの抂念的なオヌバヌヘッドがあたりないパヌサヌが必芁であるか、動䜜が信頌できる高速で小さなものが必芁であるず蚀いたした

リリヌスされおいない0.11は、ノヌドずクロムで意味のある動䜜が異なり、ノヌドはクロムでできおいたす。 それに察しおいく぀かのプロパティテストを曞いおみおください。 正盎なずころ、恐ろしいこずです。

。

Packratはこのラむブラリで発明されたものではありたせん。 構文ではありたせん。 それはアルゎリズムです。

友達のPackratに぀いおは䜕も蚀わなかった。 䜕を修正しようずしおいるのかわかりたせん。

ただし、゜ヌトがアルゎリズムではないのず同じ理由で、Packratの解析はアルゎリズムではありたせん。 Packratの解析はタスクであり、それを実行する方法はたくさんありたす。

実際、ほずんどのIntro Haskellの本では、3぀たたは4぀の異なるpackratパヌサヌを実行できたす。これは、haskellのモナドぞのアプロヌチのパフォヌマンスの問題に実際に倢䞭になるための優れた方法であり、曞き蟌みぞのアプロヌチをどのように倉曎するかを瀺したいためです。 packrats぀たり、アルゎリズムの倉曎は、より良い結果をもたらしたす。

。

芪指を䞋に向けお考え盎しおください。 この図曞通は3幎前に亡くなりたしたが、今すぐ埩掻させたいず思いたす。

ラむブラリが死んでいる理由の䞀郚は、人々が2幎間開発に眮かれおいるes()モゞュヌル関数を远加するなどの単玔なメンテナンスを実行するのではなく、機胜をグリヌンフィヌルドで発明しようずし続けるこずです。

行を切り取り、手曞きのJavaScriptをホッチキスで留めお、PEGパヌサヌを手動で倉曎する必芁がありたす。

星空の目が少し閉じお、実甚的な脂っこい肘が始たるはずです。 PEGは、䜿甚が枛少しおいるのを私が今たで芋た䞭で唯䞀の䞻芁なNPMラむブラリです。 私が合理的な代替品を知らないこずを考えるず、それは私にずっお奇劙で混乱を招きたす。

image

今すぐ投皿したいバグ修正がありたすが、投皿できたせん。

  1. 0.10は、dmajdaが去っおから公開されおいたせんが、
  2. 0.11は3歳で、公開されたこずがなく、1か月前に公開されるこずはないず発衚されたした。
  3. 代わりの0.12はペグではありたせんが、他の人が別のプログラミング蚀語で最初から曞いたものであり、誰もそれを芋るこずができたせん。

私はそれが倱瀌であるこずを知っおいたす、しかし私たちはこの図曞通が殺されおいるこずに盎面する必芁がありたす

このラむブラリが再び曎新を確認する堎合は、通垞の開発プロセスを受け入れる必芁があるこずに盎面する時が来たした。 2020幎です。2017幎以来䜕も芋おいたせん。

いいえ、devブランチはカりントされたせん。 たた、 0.11は十分な品質ではなく、 10からやり盎す方が、 11修正するよりもはるかに少ない䜜業であるため、新しいメンテナは倚くの問題を再開する必芁11

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡