ステップ11
字句解析
■字句解析とは…
入力された文字を順番に調べて、数値/演算子/記号/変数など、意味のある「かたまり(トークン)」に分解することです。
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;
}
■完成写真
次のステップでは、数式解析について学びましょう。