ステップ11

字句解析

字句解析とは…

 入力された文字を順番に調べて、数値/演算子/記号/変数など、意味のある「かたまり(トークン)」に分解することです。

図11-1 字句解析状態遷移図

 S1は開始地点です。0~9の数字を打った場合S2に移行します。連続して数字を打った場合S2をループします。これが12や3、14という風に数値として分解します。演算子や記号を打った場合、数値以外の文字なので読み取りは終わり、次のところへ移行します。S3に関しましては、変数としての読み取りとなるため、英字で始まり英字、数字でS3をループするといった形になります。

■使用したツール

ここからはWindows SDK 7.1 Command Promptを使って
字句解析や数式解析のプログラムを書いていきます。

■プログラムの書き方

 ①まずWindows SDK 7.1 Command Promptを立ち上げます。

②作業したいフォルダに移動します。

②-1作業したいフォルダがない場合は作成します。

③terapadで開きます。        

④プログラムを書きます。

⑤上書き保存します。

⑥インクルードします。

下の写真の通りになったらOK

⑦実行します。

■字句解析プログラム

 ●main.c

#include <stdio.h>

#define BUFFSIZE	256
#define NOTOKEN		(-3)
#define TokenError	(-2)
#define EOF			(-1)
#define Number	0	// 整数
#define Plus	1	// +
#define Minus	2	// -
#define Aster	3	// *
#define Slash	4	// /
#define LPar	5	// (
#define RPar	6	// )


// 字句操作関数群
void setText(char *s);
int  nextToken(int *value);
void putBack(void);
/*
 * 1行の文字列を字句へ分解する。
 */
void split(char *s){
	int code, value;

	setText(s);
	code = nextToken(&value);
	while (code != EOF){
		if (code == Number)
			printf("\t整数:%d\n", value);
		else if (code == TokenError)
			printf("\tエラー\n");
		else
			printf("\t記号:%d\n", code);
		code = nextToken(&value);
	}
}

int main(){
	char buff[BUFFSIZE];

	fprintf(stderr, "%% ");
	while (gets(buff)){
		split(buff);
		fprintf(stderr, "%% ");
	}
	fprintf(stderr, "See you.");

	return 0;
}

char *nextch = "";
int has_stock = -1; // -1:初期状態  0:字句を戻していない状態  1:字句を戻した状態
int stock_code;
int stock_value;

void setText(char *s){
	nextch = s;
}

int getToken(int *value){
	int c;

	// 空白を読み捨てる。
	while (isspace(*nextch))
		nextch++;

	if (!*nextch)
		return EOF;

	c = *nextch++;
	if (c == '+')
		return Plus;
	if (c == '-')
		return Minus;
	if (c == '*')
		return Aster;
	if (c == '/')
		return Slash;
	if (c == '(')
		return LPar;
	if (c == ')')
		return RPar;

	if (isdigit(c)){
		*value = 0;
		while (isdigit(c)){
			*value = 10 * *value + c - '0';
			c = *nextch++;
		}
		nextch--;
		return Number;
	}

	return TokenError; // エラー
}

/*
 * 字句をひとつ戻す。(ように見せかける)
 */
void putBack(void){
	if (has_stock == 0)
		has_stock = 1;

}

/*
 * 次の字句の字句コードを返す。
 * 次の字句が整数の場合は、
 * その数値を *valueへセットし、字句コードNumberを返す。
 */
int nextToken(int *value){
	if (has_stock > 0){
		has_stock = 0;
		*value = stock_value;
		return stock_code;
	}
	has_stock = 0;
	stock_code = getToken(&stock_value);
	*value = stock_value;
	return stock_code;
}

■完成写真

次のステップでは、数式解析について学びましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です