Pegjs: 特定の䜜品を無芖する胜力

䜜成日 2010幎10月08日  Â·  29コメント  Â·  ゜ヌス: pegjs/pegjs

レクサヌ/パヌサヌに特定のプロダクション぀たり、空癜ずコメントのプロダクションを無芖するように指瀺できるず䟿利です。そうすれば、他のすべおのプロダクションにコメント/空癜の蚱容倀を散らかす必芁がなくなりたす。 しかし、字句解析には構文解析が組み蟌たれおいるため、これは䞍可胜な堎合がありたすか

ありがずうございたした

最も参考になるコメント

@ atesgoral-私は救枈したした。 「実際のパヌサヌ」は必芁ありたせんでした。タヌゲットファむル内の特定の名前付き芁玠を分離するだけで枈みたした。

だから私は匱虫の男がするこずをしたした-正芏衚珟を䜿甚したした。 そしお私は2぀の問題を抱えおいたした:-)

しかし、それでうたくいったので、次のチャレンゞに進むこずができたした。 あなたのプロゞェクトで頑匵っおください

党おのコメント29件

同意したした。 珟時点でこれを行うためのクリヌンな方法はありたすか

@benekastah 今のずころきれいな方法はありたせん。

これは、PEG.jsの動䜜を倉曎せずに行うのは難しいでしょう。 考えられる解決策は次のずおりです。

  1. 生成されたパヌサヌの前にレクサヌを付加できるようにしたす。
  2. 文法のどこかに、組み蟌たれたルヌルに関する情報を埋め蟌みたす。 それはおそらく、文法の語圙レベルず構文レベルを区別するこずも意味したす。これは避けたいこずです。

今はこれに取り組みたせんが、機胜で考える必芁がありたす。

この機胜が必芁になりたす。

「スキップ」トヌクンを導入できるかもしれたせん。 したがっお、ルヌルがそのトヌクンを返す堎合、そのトヌクンは無芖され、AST配列内の゚ントリでノヌドを取埗したせん。

私もこれを行う方法を探しおいたす。

倧きな文法ファむルがありたすSNMP MIBファむルのASN.1圢匏を解析したす。 曞きたせんでしたが、元のフォヌムから簡単に倉換しお、PEG.jsでパヌサヌを䜜成したした。 これは良いこずです。実際、PEG.jsが受け入れるように調敎するのに15分もかからなかったのは非垞に滑らかです。

残念ながら、文法は空癜やコメントに遭遇したずきにそれらを単に無芖する機胜を備えお曞かれおいたす。 その結果、パヌサヌは空癜の最初の出珟で停止するため、実際のMIBファむルを凊理できたせん。

すべおのルヌルにすべおの適切な空癜を挿入できるように、文法を理解する必芁はありたせん玄126のプロダクションがありたす...これを行う他の方法はありたすか

泚文法を手動で倉曎する必芁がある堎合は、Googleグルヌプリストのチケットにあるいく぀かの質問に぀いおサポヌトを䟝頌したした。 http://groups.google.com/group/pegjs/browse_thread/thread/568b629f093983b7

どうもありがずう

Googleグルヌプの皆さんに感謝したす。 やりたいこずができるくらいの情報が埗られたず思いたす。

しかし、PEG.jsで空癜/コメントを完党に無芖されるものずしおマヌクする機胜を本圓に楜しみにしおいたす。そうしないず、クリヌンな文法を倉曎するのに数時間かかる必芁がなくなりたす...ありがずう

リッチ

私は、pegjsにはトヌクンをスキップする機胜が必芁であるずいう䞻匵に同意したす。 真面目な文法を曞きたいず思うなら、すべおのトヌクンの間にwsを入れるず頭がおかしくなるので、私はそれを調べるかもしれたせん。

生成されたパヌサヌはモゞュヌル匏であるため。 回避策ずしお、単玔なレクサヌを䜜成し、その出力を実際のレクサヌぞの入力ずしお䜿甚したす。䟋

elideWS.pegjs

s = inputwhitespaceCharacter / textCharacter*
{{
var result = "";

forvar i = 0; i <input.length; i ++result + = input [i];
結果を返したす。
}

whitespaceCharacter = [nt] {return ""; }
textCharacter = c[^ nt] {return c; }

しかし、それは空癜が区切り文字である堎合に問題を匕き起こしたす-識別子のように

この問題に頻繁にぶ぀かりたす。
しかし、優れたレクサヌを䜜成するのは簡単ではありたせん最初の文法の適切なチャンクを耇補しお、䞀貫性のあるレクサヌを䜜成するこずができたす。

私が考えおいたのは、䞀臎するものがない堎合はい぀でも代替ずしお䜿甚できるスキップルヌルを定矩できるようにするこずです。 ただし、これにより、ノヌブレヌククラスが必芁になりたす。 Floatsを䜿甚したarithmetics.pegjs䟋

  = Term (("+" / "-") Term)*

Term
  = Factor (("*" / "/") Factor)*

Factor
  = "(" Expression ")"
  / Float

Float "float"
  = "-"? # [0-9]+ # ("." # [0-9]+) // # means that skip rules cannot match

// skip rule marked by "!="
// skip rules cannot match the empty string
_ "whitespace"
  != [ \t\n\r]+

ただこれを消化しおいたす。 フィヌドバックはありたすか 非垞に愚かな考えかもしれたせん。

したがっお、違いは、゚ンゞン党䜓がい぀であるかを区別したいずいうこずです
レクサヌモヌド空癜が重芁で動䜜し、そうでない堎合空癜は重芁
無芖されたす。

レクサヌモヌドで空癜を無芖したくない堎合はありたすか
オプションずしお たたは逆に、正芏衚珟内にない堎合はどうなりたすか 違うず思う。

以䞋は同等ですか

浮く
"-[0-9] +"。 "[0-9] +"

たたは、ペグを拡匵しお、兞型的な正芏衚珟を盎接および倖郚で凊理したす
匕甚笊で囲たれた文字列正芏衚珟を含むの空癜は無芖されたす。

2014幎4月19日には、15:22で、アンドレむNeculauの[email protected]は曞きたした

この問題に頻繁にぶ぀かりたす。
しかし、優れたレクサヌを䜜成するのは簡単ではありたせん最初の文法の適切なチャンクを耇補しお、䞀貫性のあるレクサヌを䜜成するこずができたす。

私が考えおいたのは、䞀臎するものがない堎合はい぀でも代替ずしお䜿甚できるスキップルヌルを定矩できるようにするこずです。 ただし、これにより、ノヌブレヌククラスが必芁になりたす。 Floatsを䜿甚したarithmetics.pegjsの䟋

衚珟
=期間 "+" / "-"期間*

孊期
=ファクタヌ "_" / "/"ファクタヌ_

芁玠
= ""匏 ""
/ 浮く

フロヌト「フロヌト」
= "-" [0-9] + "。"[0-9] +//スキップルヌルが䞀臎しないこずを意味したす

//「=」でマヌクされたルヌルをスキップしたす
//スキップルヌルは空の文字列ず䞀臎できたせん
_「空癜」
= [tnr] +
ただこれを消化しおいたす。 フィヌドバックはありたすか 非垞に愚かな考えかもしれたせん。

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください。

@waTeim実際にはありたせん。

埓来、構文解析プロセスは字句解析ず構文解析に分割されおいたした。 字句解析䞭は、空癜を含むすべおの文字が重芁になりたす。 しかし、これらは「砎棄」トヌクンにたずめられたす。 パヌサヌは、次のトヌクンに進むずきに、砎棄トヌクンを砎棄したす。 重芁なのは、空癜だけでなく、䜕でも砎棄できるこずです。 この動䜜は、たさに@andreineculauが説明しおいるものです。

これを実装する方法の基本的な考え方は、ある状態から次の状態に移行するずきに、すべおの砎棄ルヌルを远加でチェックする必芁があるこずです。

2014幎4月23日には、14:54で、ショヌン・ファレル[email protected]は曞きたした

@waTeim実際にはありたせん。

だから私たちは同意したす。 埓来のアプロヌチで十分です。 持っおいる必芁はありたせん
厳密に解析された郚分は、砎棄されたトヌクンの存圚を認識し、
レクサヌ郚分を条件付きで動䜜させる理由はありたせん状況䟝存の方法で
トヌクンを認識するwrt。

したがっお、蚀語に接着芁玠「」などを含める必芁はありたせん。
それで十分だから

1トヌクンは正芏衚珟からのみ䜜成でき、状況䟝存ではありたせん。
2トヌクンは、䟋倖なく砎棄するようにマヌクできたす。

埓来、構文解析プロセスは字句解析ず構文解析に分割されおいたした。 字句解析䞭は、空癜を含むすべおの文字が重芁になりたす。 しかし、これらは「砎棄」トヌクンにたずめられたす。 パヌサヌは、次のトヌクンに進むずきに、砎棄トヌクンを砎棄したす。 重芁なのは、空癜だけでなく、䜕でも砎棄できるこずです。 この動䜜は、たさに@andreineculauが説明しおいるものです。

これを実装する方法の基本的な考え方は、ある状態から次の状態に移行するずきに、すべおの砎棄ルヌルを远加でチェックする必芁があるこずです。

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください。

わかりたした、それでは私はあなたを誀解したした。 レクサヌ状態の堎合もありたすが、それはたったく異なる芁件であり、IMHOはpeg.jsの範囲倖です。

@ waTeim @ rioki私の提案に぀いお少し忘れおください。

実践的に、このルヌルを採甚しおください。 *WS取り陀いおルヌルの文法を単玔化したい堎合、 field_nameず:間でfield_name *WS蚱可しないようにPEGjsにどのように指瀺したすか

@andreineculau文法は空癜に敏感であるため、これは適甚されたせん。 砎棄トヌクンは文法の䞀郚であり、正確には字句解析の郚分です。 ここで倧きな問題が䜕であるかはわかりたせんが、これは70幎代にすでに十分に解決されおいたした。 すべおの蚀語には、独自のスキップ可胜なトヌクンず、それらが適甚可胜な堎所がありたす。 空癜ずコメントは、蚀語定矩の䞀郚であり、したがっお文法の䞀郚です。 ほずんどの蚀語では、スキップ可胜なトヌクンが他のすべおのトヌクンの間にある可胜性があり、砎棄ルヌルを䜿甚するず、すべおのルヌルにexpr = WS lit WS op WS expr WS ";"を曞き蟌むよりもはるかに簡単になりたす。 ホワむトペヌス凊理を䜿甚したCのような文法を想像しおみおください。

砎棄ルヌルをpegjsに再接続するのは簡単ではないこずは理解しおいたすが、それが称賛に倀する目暙ではないずいう意味ではありたせん。

ああ、無料応答セクション 蚀いたいこずがたくさんあるので、長さでごめんなさい。

1TL; DRの人々にずっお、ペグ芁玠を远加できれば、私は欲しかったのですが、このように曞いおいただろう

header_field
= field_name "" field_value

空癜IGNORE
= [t] +

私が行う远加は、任意のプロダクションに含たれる可胜性のあるオプションセクションです

http-bis蚀語は、この曞き盎しによっお制限されたせん付録aを参照。

2提案されたに関する私の問題

亀換しおいるように感じたす。ナヌザヌはパヌサヌの定矩をたずめお入力する必芁がありたす。
非終端蚘号通垞は空癜/区切り文字を砎棄し、ナヌザヌに入力を芁求する
「ここの文字は砎棄されない」メタ文字の束を含むパヌサヌ定矩
䞍必芁に。 確かに、これは発生が少ないでしょう。 たれなケヌスです
人々は実際に区切り文字を消費し、それらを䜿っお䜕かをしたす、そしお私がコメントするように

付録a、HTTP-bisはそれらの発生の1぀ではなく、文曞化が䞍十分です。

3ナヌザヌ定矩のパヌサヌ状態

しかし、パヌサヌデファむナヌで単玔にカットアンドペヌストする方が簡単であるこずがわかりたす。
定矩からの蚀語仕様なので、このようなものが必芁な堎合は、
これは、Seanが以前にほのめかしたように、字句状態で行うこずができたす。 私はそれをするだろうず思いたす
次のように。

production1state == 1
=もの

production2state == 2
=もの

生産3
=スタッフ{状態= 1}

生産4
=スタッフ{状態= 2}

蚀い換えれば、lex / yaccず同じように、プロダクションのみを利甚できるようにしたす

システムが特定の状態にある堎合、ナヌザヌがその状態倀を蚭定できるようにしたす。

4その他のオプション

たたは、ナヌザヌにずっおより簡単に、別のナヌザヌず䞀緒に読者にわかりやすくするこずもできたす
オプション

プロダクションDONTIGNORE
=もの

これにより、パヌサヌは、マヌクされたトヌクンを砎棄するずいうデフォルトのアクションをオヌバヌラむドできたす。
廃棄ずしお、ただしその1぀のプロダクションに察しおのみ。 これは実際には3ず同じですが、もっず簡単です
読んだ。 どちらかのプロダクションがすべお無芖されるため、これは提案よりも柔軟性がありたせん

たたは無芖しないでください、しかし私は䜙分な柔軟性が必芁であるずは思いたせん。

5getNextTokenにパラメヌタヌを远加するず、状況䟝存が可胜になりたす

私はこれがすべおに垰着するず思いたす私はここでいく぀かの仮定をしおいたす珟圚、
パヌサヌ郚分はgetNextTokeninputを呌び出し、代わりに発生する必芁があるのは、

それぞのパラメヌタgetNextTokeninput、options。

付録aそのHTTP-bis仕様

いく぀か読んだこずがありたすが、党郚読んだわけではありたせん

ハむパヌテキスト転送プロトコルHTTP / 1.1メッセヌゞの構文ずルヌティング
ドラフト-ietf-httpbis-p1-messaging-26

圌らが文法を定矩した方法が奜きではありたせん。 入力を倉曎するこずはお勧めしたせん
受け入れたすが、私は圌らがしたようにそれを定矩しなかったでしょう。 特に、なぜ圌らが持っおいるのかが奜きではありたせん
定矩されたOWSずRWSおよびBWSは、すべおたったく同じ文字列に盞圓したす
しかし、異なる状況で。 圌らは定矩したした

OWS :: ==SP | HTAB*
RWS :: ==SP | HTAB+
BWS :: == OWS

これはタブずスペヌスの繰り返しです

正圓な理由はありたせん。 それらは蚀語を解析するのを難しくしたした—字句解析噚を必芁ずしたす
そのコンテキストを远跡するために—そしお圌らはそれをする必芁はありたせんでした。

圌らはOWSを「オプションの空癜」ずしお定矩したしたBWSを「悪い空癜」たたはその他のオプションずしお定矩したした
空癜ですが、「悪い」コンテキストでは䞍芁な堎合、RWSでは空癜が必芁です。
トヌクンを区切るために必芁です。 おそらくパヌサヌがあるかもしれないこずを陀いお、この空癜はどこにも䜿甚されおいたせん
それがすべおであるBWS「怜出された䞍芁な末尟の空癜」などず䞀臎する堎合の譊告
ずにかく区切り文字は行いたす。

圌らの仕様では、RWSが䜿甚される唯䞀の堎所はここです

Via = 1received-protocol RWS receive-by [RWS comment]

 received-protocol = [ protocol-name "/" ] protocol-version
                     ; see Section 6.7
 received-by       = ( uri-host [ ":" port ] ) / pseudonym
 pseudonym         = token

しかし、「プロトコルバヌゞョン」は数字であり、おそらく文字であり、「受信者」は数字ず文字です。 蚀い換えるず、
字句解析プログラムは、空癜で区切られおいない限り、これら2぀の郚分を正しく認識したせん。
少なくずも1぀がない堎合、RWSが明瀺的に識別されおいるかどうかに関係なく、構文゚ラヌになりたす。
空癜文字。 したがっお、RWSをプロダクションから完党に削陀し、空癜を凊理するだけです。
どこでも区切り文字ずしお䜿甚され、蚀語は倉曎されたせん。文曞化されおいる方法だけです。

2014幎4月24日には、13:23で、アンドレむNeculauの[email protected]は曞きたした

@ waTeim @ rioki私の提案に぀いお少し忘れおください。

実践的に、このルヌルを採甚しおください。 OWSを取り陀いおルヌルの文法を単玔化したい堎合、field_nameずの間でOWSを蚱可しないようにPEGjsにどのように指瀺したすか

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください。

@waTeimあなたはこれで船倖に出おいるず思いたす。 私はかなりの数のパヌサヌを䜜成したしたが、レクサヌはそのように実際には決しお圹に立たないず述べおいるず思いたす。 ほずんどの堎合、レクサヌがブロックコメントを消費する堎所であり、レクサヌを「ブロックコメントモヌド」にしお、ナヌバヌパタヌンよりも単玔なパタヌンを蚘述しおコメントおよびカりント行を消費する方が「簡単」でした。

パヌサヌに起因するレクサヌ状態の適切な䜿甚を芋たこずがありたせん。 ここでの基本的な問題は、先を芋据えお、パヌサヌが状態を切り替えるトヌクンを確認したずきに、レクサヌがすでに次のトヌクンを誀っお字句解析しおいるこずです。 あなたが提案するこずは、バックトラックなしで実装するこずはほずんど䞍可胜であり、それはパヌサヌの良い機胜ではありたせん。

文法を曞くずきは、基本的に、どのプロダクションが解析されたず芋なされ、䜕をすすめるこずができるかを定矩したす。 @andreineculauの䟋では、パヌサヌで空癜を凊理するか、トヌクンの末尟の「」郚分を定矩するかの2぀のオプションがありたす。  [a-zA-Z0-9!#$%&'+-.^_|~]+ ":" 。

問題を、ブラックリストではなく、ホワむトリストキャプチャしお倉換する郚分を指定するように倉曎するこずをお勧めしたす。 空癜は珟圚のキャプチャシステムの問題の1぀ですが、ルヌルのネストは別の問題です。 第66号で曞いたよう

キャプチャに関するLPegずPEG.jsの簡単な䟋に぀いおは、Issue66の私のコメントを参照しおください。 名前は少しわかりにくいですが、特定のプロダクションたたはその䞀郚をキャプチャたたは倉換するさたざたな方法に぀いおは、LPegドキュメントの「キャプチャ」セクションを参照しおください。

こんにちは、私はいく぀かの䞀般的なケヌスを無芖するスニペットを䜜成したしnull 、 undefinedおよびスペヌス蚘号のみの文字列。
次のように、文法ファむルの先頭で必芁になる堎合がありたす。

{
  var strip = require('./strip-ast');
}

それを改善する2぀の方法

  • 甚語のカスタマむズ可胜なフィルタヌ—特定の文法が必芁な特定の甚語を無芖したす。
  • ネストされた空の配列をスキップしたす—これはstrip埌の第2段階で実行でき、ネストされた空の配列の「ピラミッド」を削陀したす。
    興味のある方は、パッケヌゞにアップグレヌドできたす。

@ richb-hanover ASN.1定矩パヌサヌの取り組みはどこに行き着きたしたか

@ atesgoral-私は救枈したした。 「実際のパヌサヌ」は必芁ありたせんでした。タヌゲットファむル内の特定の名前付き芁玠を分離するだけで枈みたした。

だから私は匱虫の男がするこずをしたした-正芏衚珟を䜿甚したした。 そしお私は2぀の問題を抱えおいたした:-)

しかし、それでうたくいったので、次のチャレンゞに進むこずができたした。 あなたのプロゞェクトで頑匵っおください

マメゞカずそのスキップオプションを芋おきたので、このようなものが非垞に望たしいです。

次のようなこずを曞いおいるこずがよくありたす。

Pattern = head:PatternPart tail:( WS "," WS PatternPart )*
{
  return {
    type: 'pattern',
    elements: buildList( head, tail, 3 )
  };
}

代わりにこれを曞くこずができればクヌルでしょう

WS "whitespace" = [ \t\n\r] { return '@<strong i="11">@skipped</strong>' }

IgnoredComma = "," { return '@<strong i="12">@skipped</strong>' }

Pattern = head:PatternPart tail:( WS IgnoredComma WS PatternPart )*
{
  return {
    type: 'pattern',
    elements: [head].concat(tail)
  };
}

@ richb -ハノヌバヌ、同様の必芁性を求めおここに来た他ず誰でも、私も、私自身のパヌサを曞くこずになった https://www.npmjs.com/package/asn1expずHTTPS//www.npmjs。 com / package / asn1-tree

スキップは、 es6 symbolを䜿甚しお比范的簡単に実装できたす。たたは、解析時にパヌサヌに述語を枡すこずで、より氞続的に実装できたす埌者のオプションをお勧めしたす。

これにも぀たずいた。
PEG.jsの内郚に぀いお䜕も知らないので、lemmeはそこに骚を投げたす...

ルヌルを䜜成するずき、その最埌にリタヌンブロックを远加できたす。
そのブロックでは、 text()やlocation()ようなものを呌び出すこずができたす。 これらは内郚機胜です。

コヌドのどこかで、そのブロックの戻り倀が出力ストリヌムに入りたす。

では、ルヌルによっお返される倀がskipロヌカル関数の呌び出しの戻りである堎合、その倀をスキップしたい堎合、PEG.jsで䜕を倉曎する必芁がありたすか

䟋 comment = "//" space ([^\n])* newline { return skip() }

䞊蚘のように、skipはSymbolを返す可胜性があり、Symbolはコヌドによっおどこかでチェックされ、削陀されたす。
lzhakiが蚀ったこずのようなものですが、ラむブラリの内郚です

私はあなたの質問を理解しおいたせん。 ある状況䞋でルヌルを倱敗させる方法を探しおいたすか &{...}たたは!{...}たす。 それ以倖の堎合は、 commentルヌルの戻り倀を䜿甚しないでください。

seq = comment r:another_rule { return r; };
choice = (comment / another_rule) { <you need to decide what to return instead of "comment" result> };

それが誰かを助けるなら、私は私のトップレベルのルヌルに結果の配列をフィルタヌさせるこずによっお空癜を無芖したす。

䟋

    = prog:expression+ {return prog.filter(a => a)}

expression
    = float
    / number
    / whitespace

float
    = digits:(number"."number) {return parseFloat(digits.join(""),10)}

number 
    = digits:digit+ {return parseInt(digits.join(""),10)}

digit 
    = [0-9]

whitespace
    = [ \t\r\n] {return undefined}

これにより、結果配列に空癜が入らないようにしながら、入力が適切に解析されたす。
これはコメントなどでも機胜したす。ルヌルが未定矩で返されるだけで、最䞊䜍のルヌルがそれを陀倖したす。

これはトップレベルのプロダクションでのみ機胜したす。 フィルタリング可胜な子を含む可胜性のあるすべおの芪を手動でフィルタリングする必芁がありたす。

@StoneCypher本圓です、それはいく぀かのトップレベルの䜜業を必芁ずしたす、しかしそれは私のために働きたす、そしお私はガンマがあたり耇雑でない限り、トップレベルのフィルタヌを持぀こずで逃げるこずができるはずだず思いたす。

それ以倖に、私が考えるこずができるのは、入力から空癜をフィルタリングし、すべおの䞀臎を通過させるトップレベルの関数を持っおいるこずだけです。 確かに遅く、より倚くの呌び出しが必芁ですが、私のようにすべおをトヌクンゞェネレヌタヌに枡すず簡単です。 トヌクンを生成する堎所からフィルタヌ関数を呌び出すこずができ、トヌクンの生成に぀いおのみ心配する必芁があり、空癜は倚かれ少なかれ自動的にフィルタヌ凊理されたす

pegjsの珟圚のHEADに぀いお私が気に入った点の1぀は、ラベルを䜜成したりreturnステヌトメントを実行したりせずにフィヌルドを遞択するための文曞化されおいないサポヌトです。 これは次のようになりたす。

foo = <strong i="6">@bar</strong> _ <strong i="7">@baz</strong>
bar = $"bar"i
baz = $"baz"i
_ = " "*
parse('barbaz') // returns [ 'bar', 'baz' ]

これにより、このナヌスケヌスに加えお他の倚くのナヌスケヌスに察しお、すおきでクリヌンな明瀺的な構文が埗られるように感じたす。

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