- CoreParsser
- Parser
- EbnfParser
- CellValueParser
- CellExprParser
- ExportParser
- ImportParser
- EbnfParser
- Parser
とクラス継承をしているのに同じ名前のメソッドが内容は互いに独立しているため、ローカルメソッド名を使ってしのいでいたが、ほぼローカルメソッド名になってしまったので・・・・
CellValueParser以下は継承せず、フィールドにEbnfParserを保持し、
this._ebnfParser.parse('xxxxxxxxxxxxx')
のように変更した。
- CellValueParser
- CellExprParser
- ExportParser
- ImportParser
- CoreParsser
- Parser
- EbnfParser
- Parser
これにより、微妙だった初期化の手順が
- SpreadSheetクラスで、EbnfParserクラスオブジェクトを生成しEbnfパーサを保持
- EbnfParserクラスで、ExportParserとImportParserクラスオブジェクトを生成しExportとImportパーサを保持
- SpreadSheetクラスで、CellValueParserクラスオブジェクトを生成しCellの値パーサを保持
- SpreadSheetクラスで、CellExprParserクラスオブジェクトを生成しCellの数式パーサを保持
と安定してきたし、EBNFテキストでパーサを生成するクラスが全て独立したので、セルフテストの重複が減った。しかしsuper()でパーサを作るのが難しくなり、makeParserとselfTestに関連する処理をsetup()に纏める必要が出てきたついでにテンプレを作り、
/**
* EBNF関連のパーサのテンプレ
*/
class EbnfParserTemplate {
/**
* パーサクラスオブジェクト
* @memberof EbnfParserTemplate
*/
_parser = null;
/**
* 自前のパーサ
* @memberof EbnfParserTemplate
*/
myParser = null;
/**
* クラス名
* @memberof EbnfParser
*/
#className = 'EbnfParserTemplate';
className = this.constructor.name;
/**
* コンストラクタ
*/
constructor() {
// パーサクラスオブジェクトを生成する
this._parser = new Parser();
}
/**
* パーサ初期設定
* @param {SelfTestInfo} fSelfTest
*/
setup(fSelfTest = false) {
// 自前のパーサを生成する
console.log(`${this.className}.constructor: makeParser().`);
this.myParser = this.makeParser();
// セルフテストする
if (fSelfTest) {
const bk = this.DEBUG;
this.DEBUG = fSelfTest;
const selfTestRessult = this.selfTestList(this.getSelfTestList(), this.myParser);
this.DEBUG = bk;
}
}
/**
* パーサ生成
* @returns
*/
makeParser() {
const myParser = undefined;
return myParser;
}
/**
* EBNFルールと文法を作成
* @param {string} ebnf BNFテキスト
* @param {Function} syntax パーサ
* @param {Function} evalProcInfo パースした結果の評価関数情報
* @returns {EbnfParseMethodResult} パース結果
*/
parse(ebnfText, parser = this.myParser, evalProcInfo) {
// パース結果
const parseResult = new EbnfParseMethodResult(/*success, result, position, result.result, definitionList, evalProcInfo*/);
return parseResult;
}
/**
* テスト処理
* @param {Array of strung} testPatternList
* @param {function} parser
* @returns {Array of ParseResult}
*/
selfTestList(testPatternList, parser) {
const methodName = 'selfTestList';
const info = this.DEBUG;
const parseResultList = testPatternList.map((test, index, a) => {
if (info) {
console.log(`${this.className}.${methodName}: pattern[${index + 1}/${a.length}]`);
}
return this.selfTest(test, parser);
});
return parseResultList;
}
/**
* テスト処理
* @param {string} testPattern
* @param {function} parser
* @returns {Array of ParseResult}
*/
selfTest(testPattern, parser) {
const parseResult = this.parse(testPattern, parser);
return parseResult;
}
/**
* テストデータ取得
* @returns {array of object} テストデータリスト
*/
getSelfTestList() {
return [];
}
}
全般的にExport、Import、Ebnf、セル値、セル数式のパーサクラスを見直したら、ゴチャゴチャしていたコンストラクタがすっきりした。
class xxxParser extends EbnfParserTemplate{
・・・
/**
* コンストラクタ
* @param {EbnfParser} ebnfParser
*/
constructor(ebnfParser) {
super();
this._ebnfParser = ebnfParser;
this.setup(new SelfTestInfo(true, false, false, false));
}
・・・
}
今現在のクラス継承はこんな感じ
- CoreParser
- Parser
- EbnfParserTemplate
- _parser <- new Parser()
- EbnfParser
- _parserList <- new ExportParser()、new ImportParser()
- ExportParser
- _ebnfParser <- コンストラクタのebnfParserパラメータ
- ImportParser
- _ebnfParser <- コンストラクタのebnfParserパラメータ
- CellValueParser
- _ebnfParser <- コンストラクタのebnfParserパラメータ
- CellExprParser
- _ebnfParser <- コンストラクタのebnfParserパラメータ