判別プログラムについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
くろ丸

判別プログラムについて

#1

投稿記事 by くろ丸 » 16年前

標準入力で打ち込んだ文字列から識別子を判別して出力するプログラムを作りました。
このプログラムでは、 ( ) ; = といった4種類のトークンも判別することが可能なのですが、実行してもこれらのトークンを判別してくれません。なぜ実行されないのでしょうか。教えてください。
ちなみに、普通の文字列ではきちんと実行できます。

#include <stdio.h>
#include <ctype.h>

/* 識別子を構成する一文字目か? */
int isIdentFirstChar(int c)
{
return isalpha(c) || c == '_';
}

/* 識別子を構成する文字か? */
int isIdentChar(int c)
{
return isalpha(c) || isdigit(c) || c == '_';
}

/* 数値を構成する一文字目か? */
int isIntFirstChar(int c)
{
return isdigit(c);
}

/* 数値を構成する文字か? */
int isIntChar(int c)
{
return isdigit(c) || c == '_';
}

/*
識別子に属さない最初の文字へのポインタを返す

※ 一文字目は識別子の文字であることは仮定している
*/
char *getIdent(char *input)
{
while (isIdentChar(*++input)) /* empty */;

return input;
}

/*
数値文字列に属さない最初の文字へのポインタを返す

※ 一文字目は数値を構成する文字であることは仮定している
*/
char *getInt(char *input, int *pv)
{
int c;

*pv = isdigit(c = *input) ? c - '0' : 0;
while (isIntChar(c = *++input)) if (isdigit(c)) *pv = 10 * *pv + c - '0';

return input;
}

/* 空白類をスキップ(ただし、改行で止まる) */
char *skipSpaces(char *s)
{
while (isspace(*s) && *s != '\n') ++s;

return s;
}

int lex(char *input)
{
int num_of_tokens = 0;

while (*(input = skipSpaces(input))) {
char *endp;
int c, v;

if (isIdentFirstChar(*input)) {
c = *(endp = getIdent(input));
*endp = '\0';
printf("識別子: %s (%d文字)\n", input, (int)(endp - input));
*(input = endp) = c;
} else if (isIntFirstChar(*input)) {
endp = getInt(input, &v);
printf("整数定数: %d (%d文字)\n", v, (int)(endp - input));
input = endp;
} else {
switch (c = *input++) {
case '+': case '-': case '*': case '/':
printf ("演算子:%c\n", c);
break;
case '(': case ')': case ';': case '=':
printf ("区切子:%c\n", c);
break;
default:
if (c == '\n') printf("改行\n");
else printf("エラー:%cは不正な文字\n", c);
continue;
}
}
++num_of_tokens;
}

return num_of_tokens;
}

int main(int argc, char* argv[/url])
{
if (argc != 2) {
fprintf(stderr, "使いかた: %s '一行のテキスト'\n", argv[0]);
return 1;
}

printf("トークン数は%d個!\n", lex(argv[1]));

return 0;
}
(実行結果)
$./conp abc
$識別子:abc(3文字)
$トークン数は1個

$./conp abc(12)
$bash: syntax error near unexpected token'('
$

くろ丸

Re:判別プログラムについて

#2

投稿記事 by くろ丸 » 16年前

タグを付け忘れました。申し訳ございません。
また、使用しているOSはLunixです。よろしくお願いいたします。

#include<stdio.h>
#include<ctype.h>

//識別子を構成する一文字目か判断
int isIdentFirstChar(int c)
{
	return isalpha(c) || c == '_';
}

//識別子を構成する文字か判断
int isIdent Char(int c)
{
	return isalpha(c) || isdigit(c) || c == '_';
}

//数値を構成する一文字目か判断
int isIntFirstChar(int c)
{
	return isdigit(c);
}

//数値を構成する文字か判断
int isIntChar(int c)
{
	return isdigit(c) || c == '_';
}

//識別子に属さない最初の文字へのポインタを返す
char *getIdent(char *input)
{
	while(isIdentChar(*++input));
	return input;
}

//数値文字に属さない最初の文字へのポインタを返す
char *getInt(char *input, int *pv)
{
	int c;

	*pv = isdigit(c = *input) ? c - '0' : 0;
	while(isIntChar(c = *++input))if(isdigit(c))*pv = 10 **pv + c - '0';
	return input;
}

//空白を読み飛ばす
char *skipSpaces(char *s)
{
	while(isspace(*s)&& *s != '\n')++s;
	return s;
}

int lex(char *input)
{
	int num_of_tokens = 0;
	while(*(input = skipSpaces(input))){
		char *endp;
		int c,v;
		if(isIdentFirstChar(*input)){
			c=*(endp = getIdent(input));
			*endp = '\0';

			printf("識別子:%s(%d文字)\n",input,(int)(endp - input));
			*(input = endp) = c;
		}else if(isIntFirstChar(*input)){
			endp = getInt(input,&v);

			printf("整数:%d(%d文字)\n",v,(int)(endp - input));
			input = endp;
		}else{
			switch(c = *input++){
				case '+':case'-':case'*':case'/':

					printf("演算子:%c\n",c);
					break;

				case'(':case')':case';':case'=':
					printf("区切子:%c\n",c);
					break;
				default:
					if(c == '\n')printf("改行\n");
					else printf("エラー:%cは不正\n",c);
					continue;
			}
		}
		++num_of_tokens;
	}
	return num_of_tokens;
}
int main(int argc, char *argv[/url])
{
	if(argc != 2){
		fprintf(stderr,"使い方:%s '一行のテキストを入力'\n",argv[0]);
		return 1;
	}
	printf("トークンは%d個\n",lex(argv[1]));
	return 0;
}


non

Re:判別プログラムについて

#4

投稿記事 by non » 16年前

マルチポストかどうかはともかく、
>このプログラムでは、 ( ) ; = といった4種類のトークンも判別することが可能なのですが、
>実行してもこれらのトークンを判別してくれません。なぜ実行されないのでしょうか。教えてください。

どうなれば、期待通りの結果なのでしょうか?
試した結果は
(2+3)*4=100/5;TEST  を入力した場合
区切子:(
整数:2(1文字)
演算子:+
整数:3(1文字)
区切子:)
演算子:*
整数:4(1文字)
区切子:=
整数:100(3文字)
演算子:/
整数:5(1文字)
区切子:;
識別子:TEST(4文字)
トークンは13個
で、期待通りだと思うのですが。どういうこと?

閉鎖

“C言語何でも質問掲示板” へ戻る