何故かEBNFのrepeateパーサだけ ‘{‘, sequence, ‘}’になっていて、気になっていた。
// repeate = "{" sequence "}" ;
const repeate = _lazy(() => {
return _map('repeate',
'{', sequence, '}'
, (parsed) => {
parsed = this.arrayFlat([], parsed);
const lparen = parsed[0];
const seq = parsed[1];
const rparen = parsed[2];
let rc = seq['#sequence'];
return { '#repeate0': rc };
});
});
他に合わせて'{‘, choice, ‘}’にするとエラってしまう。
仕方が無いから、パースの動きをずーっと追っていくと・・・・・・・・・・・・・・・・・・・・・
灯台元暗しで、このパーサで、return { ‘#repeate0’: undefined }になっていた。
原因は、seq[‘#sequence‘];。
choiceは、{#choice: xxxx}と返すので、当然の結果。
うっかりミスを減らす様に修正。
// repeate = "{" choice "}" ;
const repeate = _lazy(() => {
return _map('repeate',
'{', choice, '}'
, (parsed) => {
parsed = this.arrayFlat([], parsed);
const choiceResult = parsed[1];
// 同じ繰り返しなら省略
if (choiceResult['#repeate0']) {
return choiceResult;
}
return { '#repeate0': choiceResult };
});
});
やっとこれで、
{ ( A | B | C) }
の様に助長的な書き方をしなくても、
{ A | B | C }
で済むようになったし、
choice = sequence, { '|', sequence } ;
なので、{ … } の中は choiceでもsequenceでもOK。
しかし、
- 数式のrepeate ※まだ未実装
- ENBFのrepeate ※今回の主役
- パーサ・クラスのrepeate ※今回の悪役
- コア・クラスのrepeate ※今回はモブ
と、repeateが多くて紛らわしい。
ENBFのrepeateの文法は、'{‘, choice, ‘}’ になって便利になった。
しかし、パーサ・クラスのrepeateのパラメータは、ebnfParserのmakeParserメソッド中でmapメソッドのパラメータの文法部分をsequenceっぽく書きたいので、sequenceにまとめて処理している。目的が違うから仕様も違うんだけど、後で見返すとちんぷんかんぷんになってしまう。
動作確認をしているとパースの結果の内部構造が倍くらいに長くなっていたので短くした。
{
"syntax": {
"#syntax": {
"#rule_list": [
{
"rule_list": {
"#definition": {
"#repeate1": {
"#choice": [
{ "#identifier": "rule" },
{ "#identifier": "special_effect" },
{ "#identifier": "comment" }
]}}}}]}}