パーザークラスの宣言から RULEメソッドのプロファイルを見る。
/** * A Parser that outputs a Concrete Syntax Tree. * See: * - https://chevrotain.io/docs/tutorial/step3_adding_actions_root.html#alternatives * - https://chevrotain.io/docs/guide/concrete_syntax_tree.html * For in depth docs. */ export declare class CstParser extends BaseParser { /** * Creates a Grammar Rule * * Note that any parameters of your implementation must be optional as it will * be called without parameters during the grammar recording phase. */ protected RULE<F extends () => void>( name: string, implementation: F, config?: IRuleConfig<CstNode> ): ParserMethod<Parameters<F>, CstNode> // // 以下省略 // }
RULEの戻り値は ParserMethod<Parameters
export type ParserMethod<ARGS extends unknown[], R> = (...args: ARGS) => R
ということで、RULEというDSLメソッドは、Fというルール実装関数を引数にして、パーザーメソッドを返す。
TypeScriptのクラス定義文スコープ内で代入文を書くとクラスメンバーが定義されるから、次のようにしてパーザーメソッドをクラスメンバーとしてセットできる。
public class MyParser extends chev.Parser { // ... myParserMethod = this.RULE("myRuleName", myRuleImplFunc); // ... }
定義されたパーザーメソッドは、定義時の引数を取り、CstNode を返す関数となる。
ユーザー・パーザークラスに this.lexer を持たせるとして、
setInput(document : string) { this.input = this.lexer.tokenize(document).tokens; }
としておけば、
parser.setInput(doc); let cst : Cst = parser.myParserMethod();
と書ける。
Function.prototype.bind() (https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)参照を使って、パーザー関数(メソッド)を引っこ抜いて別オブジェクトで実行する事もできる。
let closure = parser.parser.myParserMethod.bind(otheParseObj); let cst:Cst = closure();