構文解析のおおまかな順序 †
ただし、パイプ構文の場合は、for 制御変数の展開や、環境変数遅延展開の後でも & && | || < > >> 等の文の構文解析、% による環境変数展開が再度行われるようである。 構文解析 †以下の解析が同時になされる。 行末の ^ による継続行処理 †行末がクォートされていない ^ である場合は次の行とつなげて、構文解析を続ける。 文の区切りの認識 †1行に複数の文を書く場合がある。クォートされていない & && || | を区切りと 見なしてその前後で、それぞれ構文解析を行う。 括弧による複合文の認識 †改行や上記文区切り記号で区切られた複数の文を、クォートされていない括弧で
囲んで一つの文として扱う。プログラミング言語でよくある { } や begin/end
do/end などと同じ。 if/for という構造を持った構文の解析 †文頭が if か for ならそれぞれの構文に従って解析を進める。 リダイレクトの処理 †クォートされていない < > >> があればその次のトークンをファイル名と見なして
リダイレクト指定であるというマーキングを行う。実際のファイルオープンは
まだ先で環境変数遅延展開の後、コマンド実行の前である。 2個連続した % の1個の % への置換 †バッチスクリプトであれば連続した % は1つにして、環境変数展開には使わない。 % による環境変数の展開 †単独の % がありその後に % が出てくれば、環境変数展開と見なす。 :~ が途中にあれば部分文字列の修飾で、: = がこの順に途中にあれば文字列置換の 修飾である。 単独の % の削除 †対応する % が行内に無い単独の % を削除する。 空白文字の無視 †構文解析時にいくつかの箇所で、クォートされていない = ; , は空白と同じ
扱いを受ける。 ^ による特殊文字のクォート †^ の次の特殊文字 ^ " < > & | ( ) = ; ,の特殊な意味を失わせる。 また、リダイレクト記号の直前の1桁の数字も ^ によってクォートされると ファイルディスクリプタ番号としての意味を失う。 これら以外の文字が続く場合は ^ が削除される。 ! はこの時点では特殊文字ではないので、^! と書いても遅延展開の意味を失わない。 " による文字列のクォートと1トークン化 †クォートされていない " が出てきたらそこから次の " または行末までの
% 以外の全ての特殊文字が特殊な意味を失う。
途中に空白や、構文解析上空白と見なされる場合のある = ; , があっても
トークンの区切りとはみなさず複合した1つのトークンとみなす。 文頭の @ の認識 †クォートされていない @ が文頭にあれば、実行時に echo off しなくても その文が表示されないという印をつける。 実際に表示するのは、for 制御変数の展開を行ってから、環境変数遅延展開の前。 for 制御変数の展開 †for 文の制御変数の展開は、前項の構文解析が終わってからなので、
展開後に < > & | ( ) @ の特殊記号が出てきても、
前項の構文解析の結果は変更されない。 展開後に echo on で文頭に @ がなければ文が表示される。 この時、for 文や if 文の /オプション や if 文の比較演算子の英小文字は 英大文字として表示される。 環境変数遅延展開の展開 †遅延展開が有効でかつ ! が行内にあるとき、以下の処理が行われる。 ! が無い行については何もなされない。 コマンド別/setの「set /a 特殊記号の演算子」も参照。 ^ による ^ ! のクォート †% と違って文字として ! を残したい場合 !! と書くのは駄目で両方消える。
! を環境変数展開に使わず普通の文字として扱いたい場合は ^ でクォートする。
ただし、^ は構文解析時の特殊文字でもあるので、この時点で単独の ^ が必要なら
最初に ^^ と書いておくと構文解析時に1つの ^ になる。 ! による環境変数の展開 †単独の ! がありその後に ! が出てくれば、環境変数展開と見なす。 :~ が途中にあれば部分文字列の修飾で、: = がこの順に途中にあれば文字列置換の 修飾である。 クォートされなかった ! の削除 †クォートされていない残った ! を削除する。 コマンド実行時の特殊記号の扱い †コマンド実行時には、構文解析時の各特殊記号にどのような意味を与えるのかは 各コマンドの解釈次第である。 例:
dir や ren、del、call 等といった比較的単純な多くのビルトインコマンドでは、
クォートされていない = ; , は空白と同じ扱いを受ける。 例: ファイル A から " を含む行を検索し、ファイル B に入れることを意図して、次のように書いたとする。 findstr """ A >B 構文解析時には、3つ目の " から行末までは文字をクォートしているので、>B
はりダイレクトでなくそのままの文字列として扱われる。 FINDSTR: 開くことができません (>B) というエラーになる。 findstr >B """ A findstr < A > B """ 等と書けばよい。 |