* 川合のプログラミング言語自作のためのテキスト第二版#0009 -(by [[K]], 2019.06.30) ** (16) TL-2k -次はTL-2cを書き直してみます。なんとこれもTL-1kと同じく31行になってしまいました。 -機能的にはTL-2cなのですが、技術的にはTL-3dにかなり近いです。予約語を最初に登録し、あとはトークン番号だけで処理を進めます。したがってこれはTL-2cよりも高速に動作することになります。 #include "kll0.h" int main(int argc, const char **argv) { KLexer lx(NEW1(kautoreleasePool, KStringId)("; = + - print")); KLexer lx(NEW1(kautoreleasePool, KStringId)("; = + - print")); // lexerを準備(ついでに予約語も登録). char *txt = (char *) kerrorExitP0(kreadFileA(argv[1], "rt", 2), "usage>%s program-file", argv[0]); KLexer_Elmt *le = (KLexer_Elmt *) lx.add(txt)->p; KLexer_Elmt *le = (KLexer_Elmt *) lx.add(txt)->p; // ここで入力ファイルをlexerにかけて、トークン番号列を得る. int pc = 0, *var = (int *) kautoreleasePool->alloc((*lx.sid->n) * sizeof (int)); for (int i = 0; i < *lx.sid->n; i++) var[i] = lx.getConstInt(i); // intではないときは0を返す. var[i] = lx.getConstInt(i); // intではないときは0を返す. 指定されたトークン番号からそれを定数評価した場合の値を返す. for (int n = lx.getElmtLen(); pc < n; pc++) { if (le[pc + 1].i == 1) { // 2単語目が"=". if (le[pc + 3].i == 0) { // 単純代入. var[le[pc].i] = var[le[pc + 2].i]; } else if (le[pc + 3].i == 2 && le[pc + 5].i == 0) { // 加算. var[le[pc].i] = var[le[pc + 2].i] + var[le[pc + 4].i]; } else if (le[pc + 3].i == 3 && le[pc + 5].i == 0) { // 減算. var[le[pc].i] = var[le[pc + 2].i] - var[le[pc + 4].i]; } else goto err; } else if (le[pc].i == 4 && le[pc + 2].i == 0) { // print. printf("%d\n", var[le[pc + 1].i]); } else goto err; while (le[pc].i != 0) pc++; } exit(0); // ファイル終端. err: kerrorExit("syntax error : %.30s", le[pc].p0); } -こうしてTL-1kは31行で書けているわけです。 ** 次回に続く -次回: [[text0019]] *こめんと欄 #comment