現在の動作: 2 * 5 + SUM(1, 2, 3)
[
"2",
"*",
"5",
"+",
"SUM",
"(",
[
"1",
",",
"2",
",",
"3"
],
")"
]
望ましい動作: 2 * 5 + SUM(1, 2, 3)
[
"2",
" ",
"*",
" ",
"5",
" ",
"+",
" ",
"SUM",
"(",
[
"1",
",",
" ",
"2",
",",
" ",
"3"
],
")"
]
コピーする文法: https ://pastebin.com/zpwqT6Uw
PEG.jsプレイグラウンドhttps://pegjs.org/online
私は何が欠けていますか?
@futagozaご迷惑をおかけして大変申し訳ありませんが、PEG.jsを扱うのは初めてであり、この問題は私にとって重大です。 ちょっとしたヒントをお願いしてもいいですか?
よろしくお願いします、
マレク
私はあなたの文法を(昨日と今)調べてみましたが、それを理解するのは本当に難しいので(命名規則はさておき、正直なところ、形式はいたるところにあります)、解決策を見つけるのに時間がかかりました:
const
は[left_space, cnst, right_space]
$を返します)[].concat.apply([], con)
それでも、あなたに正直に言うと、これは私にとってハッキーな解決策のように感じます。 スペックなどへのリンクはありますか? 上記のハッキーな解決策なしで望ましい結果を得るために私が変更できるルールと変更できないルールを知ることは役に立ちます。
そうでない場合は、時間をかけて文法を整理し、いくつかのルールの名前を変更することをいとわない限り(あなたが望むものを理解しやすくするため)、私は喜んでそれをもう一度突き刺そうとします😉
@ marek-baranowski-申し訳ありませんが、これは今まで見ていませんでした。 うまくいけば、これはまだあなたに役立ちます
スペースを保持したい場合は、それらを一致するコンテンツのように扱ってください。
2つのスペースに何が必要かは明確ではありません。 2つのスペースの文字列、または2つの1つのスペースの文字列の配列のいずれかを使用できます。 通常は前者を期待しますが...あなたのすべてはキャラクターごとです
また...関数呼び出しを除いて、なぜそのような迷子の文字が必要なのですか? パーサーはそれらを合計する必要があります。
ともかく
これはあなたが求めたものです:
Document = Expression*
Whitespace
= tx:[ \r\n]+ { return tx.join(''); }
Number
= str:[0-9]+ { return str.join(''); }
Oper
= '+'
/ '-'
/ '/'
/ '*'
/ ','
Label
= l:[a-zA-Z]+ { return l.join(''); }
Parens
= '(' Whitespace? ex:Expression* Whitespace? ')' { return ex; }
Expression
= Number
/ Oper
/ Whitespace
/ Label
/ Parens
/ [^()]+
実は、それが実際にあなたが望んでいるものだと私は確信していません。 代わりに、例として、数値と演算子を解析し、それぞれについて標準化されたノード形状を返すことができます。
Document = Expression*
Whitespace
= tx:[ \r\n]+ { return {
ast: 'whitespace', value: tx.join('')
}; }
Number
= str:[0-9]+ { return {
ast: 'number', value: parseInt(str,10)
}; }
Oper
= '+' { return { ast: 'oper', value: 'add' }}
/ '-' { return { ast: 'oper', value: 'subtract' }}
/ '/' { return { ast: 'oper', value: 'divide' }}
/ '*' { return { ast: 'oper', value: 'multiply' }}
/ ',' { return { ast: 'oper', value: 'sequence' }}
Label
= l:[a-zA-Z]+ { return {
ast: 'label', value: l.join('')
}; }
Parens
= '(' Whitespace? ex:Expression* Whitespace? ')' {
return { ast: 'parens', value: ex
}; }
Expression
= Number
/ Oper
/ Whitespace
/ Label
/ Parens
/ [^()]+
これでまだ空白がありますが、適切に解析されたツリーもあり、パーサーの出力を解析するためにパーサーを作成する必要はありません。また、行番号などの正規化された機能の追加を開始するのも簡単です。
@ marek-baranowski-この課題追跡システムのサイズをいくらか縮小したい
上記が必要な場合は、この問題を解決することを検討してください。 ありがとう😄
そうでない場合は、理由を教えてください。もう一度やり直します
@ marek-baranowskiもう1つの穏やかなping:smiley_cat:
また、文法のデバッグを容易にするためにPEG.jsプラグインpegjs-syntactic-actionsを作成しました。具体的には、アクションとは関係なく、どの文字がどのルールによってキャプチャされるかを確認します。これは、@ StoneCypherで説明されているようにおそらくここでの問題です。
このプラグインの理由は次のとおりです。グローバルな結果が期待どおりでない場合、それは多くの小さなアクションの組み合わせの結果であり、動作が悪い/スタンジェリーである可能性があるため、グローバルな結果を理解するのは難しい場合があります。時間がかかる。 このプラグインを使用すると、どのルールがどのキャラクターをキャプチャするかを確認し、アクションの名前を指定します。
ああすごいこれは実際には本当にきれいです
最も参考になるコメント
@ marek-baranowskiもう1つの穏やかなping:smiley_cat:
また、文法のデバッグを容易にするためにPEG.jsプラグインpegjs-syntactic-actionsを作成しました。具体的には、アクションとは関係なく、どの文字がどのルールによってキャプチャされるかを確認します。これは、@ StoneCypherで説明されているようにおそらくここでの問題です。
このプラグインの理由は次のとおりです。グローバルな結果が期待どおりでない場合、それは多くの小さなアクションの組み合わせの結果であり、動作が悪い/スタンジェリーである可能性があるため、グローバルな結果を理解するのは難しい場合があります。時間がかかる。 このプラグインを使用すると、どのルールがどのキャラクターをキャプチャするかを確認し、アクションの名前を指定します。