Tclの基本的な文法と文法規則ついて

この記事では、 Tclの基本的な文法と文法規則について紹介します。

Tclの基本的な文法

Tclの基本的な文法は、スペースで区切られたリスト構造をもつコマンドで構成されています。条件分岐や繰り返しなどの制御構造もコマンドとして実装されています。

[基本的な文法]

コマンド名 引数1 引数2 引数3 …

  • 空白文字はコマンド名やその引数の区切り文字として扱われます。
  • 全角スペースは区切り文字として扱われない。
  • 改行やセミコロン「;」はコマンドの終端として扱われます。

公式サイトではコマンドの書式を以下のような表現で記述してます。

puts ?-nonewline? ?channelID? string

「?」で囲まれた引数は省略可能です。

[実行例] 画面に文字を出力する。

% puts stdout {hello, world!}
hello, world!

実行例のputsコマンドの動作は以下のようになります。

  1. putsコマンドに標準チャネルの識別子「stdout」と文字列「hello, world!」の2つの引数が渡されます。
  2. 引数で渡された文字列の末尾に「改行」を付加して、指定されたchannelID(例ではstdout)へ出力します。
メモ
  • 「{ }」または「” “」は複数の語を1つの引数としてまとめます。 「” “」で囲むと置換がおこなわれます。 置換については本記事の「置換について」の項目で説明します。
  • 引数(ひきすう)とは、コマンドに渡す数値や文字列などの値のことです。
  • 「stdout」 は標準出力チャネルのことで、通常はディスプレイ(画面)と接続されています。入出力チャネルについては別記事で説明します。

コメント

「#」で始まる行はコメントとして扱われます。

[コメントの記述例]

# hello, world を表示するプログラム

#------------------------------------------------
# xxxxの処理
#------------------------------------------------

# もしも1行が長いコメントを記載する場合は \
バックスラッシュを使って継続する; ここもコメントである。

set speed 30    ;# 速度
set time 60     ;# 時間

[コメントのルール]

  • 「#」で始まる行はその行の改行までをコメントとして扱います。
  • コメント中のセミコロンは無視されます。
  • コメント行を継続させたい場合は末尾にバックスラッシュを入れる。
  • コマンドの末尾にコメントを記述するには、セミコロンを用いて直前のコマンドを区切っておく必要があります。
メモ

「\(バックスラッシュ)」はASCIIコード:0x5Cになります。ASCIIコード:0x5Cは、日本語環境では「¥(円記号)」が割り当てられています。

[参考]

バックスラッシュ - Wikipedia

変数について

プログラミングにおいて、変数(variable)とは値を入れておく箱のようなものです。

プログラムで扱う文字列や数値などのデータを変数に記憶しておき、必要に応じてデータの参照や書き換えをします。Tclで変数を扱うにはsetコマンドを使います。

コンピューターで扱うことができるデータは、文字、整数、浮動小数点数など色々ありますが、Tclでは全て文字列として変数に格納されます。

数値計算を行う場合は、読み出した変数データを自動的に数値へ変換して数値として使われます。

[書式]

set varName ?value?

varName:変数名
value   :値

変数名の長さは任意で、大文字、小文字は区別されます。変数名に使用できる文字の種類に制約はありません。

setコマンドの使用例をいくつか紹介します。

[使用例]

% set data 5  ----(1)
5
% set data    ----(2)
5
% set DATA    ----(3)
can not read "DATA": no such variable
% set x $data  ----(4)
5
% set Data {Hello, World!}   ----(5)
Hello, World!
% set でーた {こんにちわ}    ----(6)
こんにちわ
% unset x ----(7)
% set x
can't read "x": no such variable

[説明]
(1)変数名:data に値:5 を代入する。

(2)setコマンドに変数名だけ渡すと、変数の値を返します。

(3)使われていない変数名を渡すとエラーになります。

(4)$記号による参照

変数名の頭に$記号を付けると、その変数に保持している値に置き換えます。これを変数置換といいます。例では、変数 x に変数dataの保持する値を代入しています。

これは以下のように $data を変数dataの保持する値「5」に置き換えたものと考えることができます。

  set x 5

(5)空白文字を含むデーターは「{}」や「””」で囲みます。

(6)Tcl8.1以降では日本語の変数名も使用できます。

ただし、変数名に英数字とアンダースコア以外の文字を使用する場合、変数置換する時に明示的に「{}」で囲む必要があります。

(7)変数の削除

使わなくなった変数はunsetコマンドで削除してメモリを開放できます。

置換について

Tclには文字列の中に特別な記号を挿入することにより、別の値に置き換える事ができる機能が備わっています。その機能とは、変数置換コマンド置換バックスラッシュ置換になります。

変数置換

変数名の頭に「$」記号を付けると、その変数で保持している値に置き換えます。

コマンド置換

コマンドを「[]」で囲むと、そのコマンドの実行結果に置き換えます。

バックスラッシュ置換

「$」記号などの特別な文字の頭に「\」記号を付けることにより、普通の文字として扱うことができます。また、「\」記号に続く文字と合わせて特殊文字として扱います。

例.
「\a」はベル(ビープ音)を鳴らす。
「\n」は改行。
「\xhh」は16進コード

「\」記号は、複数行にまたがるような、長いコマンドにおいて、行の継続を指定する為にも使われます。

[参考:その他のバックスラッシュシーケンス]

Tcl manual page - Tcl Built-In Commands
メモ

Tclではブロックを表す記号として「{ }」、「” “」がありますが、「” “」で囲むと、変数置換、コマンド置換、バックスラッシュ置換のいずれも行われます。「{ }」で囲むといずれの置換も行われません。 ブロック記号で囲むことをグループ化ともいう。

置換の基本的な使い方

変数置換、コマンド置換、バックスラッシュ置換 の基本的な使い方の例です。

[使用例]

% set x 10
10
% set result [expr $x + 20]
30
% puts "$x + 20 を計算すると?\n結果:$result です。" ----(1) 10 + 20 を計算すると? 結果:30 です。
% puts {$x + 20 を計算すると?\n結果:$result です。} ----(2) $x + 20 を計算すると?\n結果:$result です。

% puts [expr $x * [expr 2 + 3]] ----(3)
50
メモ

上の使用例の補足説明をします。

  • exprコマンドは演算をするコマンドです。
  • 文字列中に「\n」があるので改行が行われて2行で表示しています。
  • 「{}」で囲むと置換しません。
  • 「[ ]」で囲まれたコマンドのみで引数が構成されている場合、それを明示的にグループ化する(「” “」で囲む)必要はありません。
  • コマンド置換は、入れ子になったコマンドを作ることもできます。

変数の値に変数名を代入する

変数の値に変数名をセットすることで、別の変数の値を間接的に参照することができます。

[使用例]

% set data {hello, world!}
hello, world!
% set x data
data
% set x
data
% set $x        ----(1)
hello, world!
% set [set x] ----(2)
hello, world!

[説明]

(1)変数名を変数置換で置き換える。

  1. $xがdataに置換えられる。
  2. setコマンドが変数dataの保持する値「hello, world!」を返す。

(2)変数名をコマンド置換で置き換える

(1)の「set $x」は、コマンド置換を使って下のように書き換えることもできます。
   set [set x]

「$」記号などの特殊文字を値に含む場合

「$」記号などの特殊文字を値に含めるには、バックスラッシュ置換を使います。

[使用例]

% set dollar \$300    ----(1)
$300
% set x $dollar       ----(2)
$300

% set c \x41         -----(3)
A

% set sum [expr 1 + 2 + 3 + 4 + 5 + \
    6 + 7 + 8 + 9 + 10]    -----(4)
55

[説明]

(1)

変数dollarの値に 「$記号」が含まれます。

(2)

値としての$記号(「$300」の$記号)は、変数xへの代入における置換($記号による変数置換)に対して影響を与えません。置換などの解釈が行われるのは、一度に1段階だけであり、置換が行われた結果に対して、さらに変換を行うようなことはしません。

(3)

ASCIIコード0x41は英字の「A」になります。\x41は「A」に変換されて表示します。

(4)

行末にバックスラッシュを用いると、そのバックスラッシュと改行文字、さらに次の行の最初の非空白文字までを1つの空白文字に置き換えます。もしも行末にバックスラッシュがないと exprコマンドは+記号の後の改行文字で区切られてしまい、エラーになります。

変数名に使用する文字について

変数名に使用する文字の種類に制約はありませんが、Tclインタプリタでは、文字列中に変数置換を埋め込むために、いくつかルールが設けられています。

変数名の区切りについて

Tclインタプリタは、変数置換する際に、英数字とアンダースコア以外の文字が来ると区切りとみなします。

[使用例]

% set fname ReadMe
ReadMe
% set doc $fname.txt    ----(1)
ReadMe.txt

% set b BBB
BBB
% set abc aaa$bccc      ----(2)
can not read "bccc": no such variable
% set abc aaa${b}ccc    ----(3)
aaaBBBccc

[説明]

(1)

$fname.txtは、変数fnameの保持する値に .txtを付加した文字列になります。「.」文字の手前までを変数名とみなします。

(2)

変数名がbcccと認識される為エラーになります。

(3)

空白文字や英数字とアンダースコア以外の文字で区切ることができない場合は、波括弧「{}」で明示的に変数名を区切ります。

変数名に英数字とアンダースコア以外の文字を含める場合

変数名に「.」などの文字を含める場合は、変数置換する時に、波括弧「{}」で明示的に区切る必要があります。

[使用例]

% set 1.txt hello
hello
% set doc ${1.txt}  ----(1)
hello

% set $1.txt        ----(2)
can not read "1": no such variable

% set ${1.txt}      ----(3)
can not read "hello": no such variable

% set doc $1.txt    ----(4)
can not read "1": no such variable

% set でーた {こんにちは} ----(5)
こんにちは
% set jpn ${でーた}
こんにちは

[説明]

(1)

変数名 1.txt が保持する値 hello に置換えられて、変数名 docに代入されます。(2),(3),(4)は、よくある間違いです。

(5)

日本語の変数名を使用した場合も変数置換する時に、明示的に区切る必要があります。

グループ化について

波括弧(brace)「{ }」とダブルクォート「” “」は複数の語を1つの引数としてまとめる場合に使用します。それぞれの違いはダブルクォートによるグループ化は置換が行われるのに対して波括弧によるグループ化は置換が行われません。

置換はコマンド置換、変数置換、バックスラッシュ置換の3つすべてに対して適用されます。

グループ化の基本的な使い方は、これまでの項目の中で紹介済みなのでグループ化を行う場合の注意点を説明します。

[使用例]

% set s stdout
stdout

% puts ${s}{hello!}  ---(1)
stdout{hello!}
% puts ${s} {hello!}
hello!

% set x abc
abc

% set y "aaa {$x} bbb"  ---(2)
aaa {abc} bbb

---(3)---
% puts {
hello!
hello!
hello!
}

hello!
hello!
hello!

[説明]

(1)

「{ }」や「” “」はグループ化しか行いません。引数の区切りに空白を入れ忘れた場合、エラーになった意図した結果にならない。例では引数の間の空白を忘れている。

(2)

「” “」を使用してグループ化を行う場合、「{ }」による特別な効果は失われます。例では{}で囲まれていても置換されています。

(3)

Tclインタプリタは、コマンドと同じ行の末尾に開き波括弧「{」があると改行文字を無視し、対応する閉じ波括弧「}」が見つかるまでを1つのグループとします。もし開き波括弧を次の行に置くのであれば、バックスラッシュを使って改行文字をクオートする必要があります。

コメント

タイトルとURLをコピーしました