しょぼいマシンで自作プログラミング言語を作ってみる (7)

数値リテラルの字句解析が整った

不正なトークンの扱い

 ひとまず、前回の最後に出てきた不正な文字を認識した場合の扱いについて触れます。
 まず、トークン情報でトークン種別の枝番を採用しました。
 10進数値についてはそもそも整数、小数、指数付きの整数、指数付きの小数がありますし、不正なトークンについても不正種別が色々とあることが想定されます。
 ですので、トークン種別に枝番を設けることにしました。

 不正トークンであることを返すタイミングは不正な文字を検知した、もしくは不完全な状態でEOFを検知した場合です。
 数値系について不正な文字を検知した場合は、その時点から連続している数字、英字、アンダーライン(0x5f)を全部読み進めます。そして、その読み進めた文字列を不正なトークンとして返却します。
 例えば、10進の判別で"10e1a0_00 "が判別関数に渡された場合は、'a'の時点で不正な文字を検知し、その時点から続く"a0_00"も含めた"10e1a0_00"が不正なトークンであったとして返却されます。

アンダーラインも数値リテラルに含めよう

 どのプログラミング言語においてもアンダーライン(0x5f)を数値リテラルに含めています。
 理由としては桁数があまりにも多い場合に何桁目かがわからなくなることを防ぐためというのがあります。
 10桁単位でもよし、4桁単位でもよし、3桁単位でもよしですが、アンダーラインがあることでそれなりに可読性が増すことは間違いないとは思うので、数値リテラルとして含めてしまいます。
 ただし、アンダーバーを含めてもいいのはリテラルの先頭に数字がある場合のみです。

2進、8進、16進もサポートしよう

 10進数の字句解析ができたので2進、8進、16進のリテラルもサポートします。
 2進、8進、16進については、まずは接頭辞で判別します。

  1. 先頭に"0b"、"0B"がついていれば2進数です。bはbinaryのイニシャルですね。

  2. 先頭に"0o"、"0O"がついていれば8進数です。oはoctalのイニシャルですね。C言語などでは0から始まる数値リテラルは8進あつかいですが、gallopでは0から始まる数値リテラルは10進あつかいです(Pythonもそうなんだし、いいでしょう)。

  3. 先頭に"0x"、"0X"がついていれば16進数です。xはhexadecimalから取ったものですが、イニシャルのhにしなかったのはhとbだったりHとBを見間違えないようにとのことでしょうかね?

 判別できたらそれぞれの字句解析に進みます。
 当然、0bなり0oなり0xで終わっていれば、不正です。

  1. リテラルが0もしくは1、それとアンダーラインからなるのが2進リテラルです。そうでない英数字が含まれれば不正です。

  2. リテラルが0から7までの数字、それとアンダーラインからなるのが8進リテラルです。そうでない英数字が含まれれば不正です。

  3. リテラルが数字、aからf(大文字小文字の区別なく)、それとアンダーラインからなるのが16進リテラルです。そうでない英字が含まれれば不正です。

 ここまでで10進、2進、8進、16進の数値リテラルを解析することができました。

識別子も解析

識別子の解析は意外と簡単

 識別子の解析は意外と簡単だったりします。
 識別子は英数字とアンダーラインからなるリテラルです。
 なので、for文を一発ぶん回して読み進めればいいだけです。
 識別子の解析を始める段階で、英字、数字、アンダーラインを使ったリテラルの不正はすべて洗い出されているはずです。……多分。

 とりあえず、ここまでやったら、今度は演算子の字句解析といったところでしょうか。

いいなと思ったら応援しよう!