マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

某ZR流パラメタトークン思考法

課題

次のTeXコードを実行したときのTeXの動作を、字句解析を中心にして述べよ。

LaTeXフォーマットで\makeatletterの状態のカテゴリコードを仮定する。

\toks@{\def\xx@#1}\the\toks@{!#1}

某ZR氏の解答

表記

  • 制御綴のトークンを“[def]”等で表す。
  • 文字トークンを“‹A›₁₁”等で表す。
  • パラメタトークンを“①”等で表す。

動作の解説

  • \toks@を読み [toks@] と解釈する。\toks@(0番のtoksレジスタ)に対する代入文を開始する。
  • {を読み ‹{›₁ と解釈する。これ以降は代入すべきトークン列の内容であり、展開抑止の状態に入る。
  • \def\xx@#1を読み、[def] [xx@] ‹#›₆ ‹1›₁₂ と解釈する。
  • }を読み ‹}›₂ と解釈する。代入すべきトークン列が確定し、展開抑止が終わる。\tokS@に“[def] [xx@] ‹#›₆ ‹1›₁₂”が代入される。
  • \theを読み、[the] と解釈する。プリミティブ\theの引数を待つ状態になる。
  • \toks@を読み [toks@] と解釈する。\theの展開を行う。\theプリミティブの引数がtoksレジスタなので、そのレジスタの内容の“[def] [xx@] ‹#›₆ ‹1›₁₂”をバッファに吐き出し、以降はここからトークンを読み出す。
  • [def] を読む。\def文を開始し、展開抑止の状態に入る。以降に続く「代入先トークン」「パラメタテキスト」「置換テキスト」を待つ。
  • [xx@] を読む。これが「代入先トークン」である。
  • ‹#›₆ ‹1›₁₂ を読む。パラメタテキストの読取の途中に“‹#›₆ ‹1›₁₂”が現れたので、パラメタトークン“①”に置き換える。
  • (バッファのトークンが尽きたので再びソース文字列から読む。)
  • {を読み ‹{›₁ と解釈する。ここでパラメタテキストが終わり、“①”と確定する。
  • !#1を読み、‹!›₁₂ ‹#›₆ ‹1›₁₂ と解釈する。置換テキストの読取の途中に“‹#›₆ ‹1›₁₂”が現れたので、パラメタトークン“①”に置き換える。
  • }を読み ‹}›₂ と解釈する。ここで置換テキストが終わり、“‹!›₁₂ ①”と確定する。
  • すなわち、以下の引数を以て、\def文が実行される。展開抑止が終わる。`
    • 代入先=[xx@]
    • パラメタテキスト=①
    • 置換テキスト=‹!›₁₂ ①

補足

つまり、某ZRのモデルでは、パラメタトークン(① など)は「パラメタテキスト」や「置換テキスト」のトークン列の内容には現れるが、入力バッファの中には決して現れない。

もしこの後、\xx@?を実行したとすると、[xx@] ‹?›₁₂ の展開結果として、置換テキストの ① を ‹?›₁₂ に置き換えたトークン列である“‹!›₁₂ ‹?›₁₂”がバッファに吐き出される。この場合もパラメタトークン自体はバッファには現れない。