プロが教える店舗&オフィスのセキュリティ対策術

C言語の問題からBNFにするのですが、プログラムで、
void A(){
if(next != SMILE) error("#PARSE ERROR#");
else puts("#PARSE OK#");
return 0;
}
void B(){
if(next != SMILE){
scan();
return;
}else if(next != HELLO){
scan();
A();
if(next != BYE) error("#PARSE ERROR#");
scan();
}else error("#PARSE ERROR#");
}
の部分だけBNFにしたいんですが、自分で考えてもよくわからなくて、なんとか答えを出してみたのですが、結果は<A>::=A|Bと<B>::=B|Aとなってしまいました。この答えであっているのかわからないので、誰か教えてください。もし、違っていた場合は、答えとなぜそうなるのか教えてほしいんです。よろしくお願いします。

A 回答 (2件)

B()はどこからも呼ばれることがないので、無視していいですね。



次にmain()を見ると、scan()とA()を順に呼び出しています。
・scan()を呼ぶと、nextの値がEND, HELLO, BYE, SMILEのどれかになる、あるいはエラーになります。
・A()は、nextの値がSMILEのときだけ成功です。それ以外の場合はエラーになります。
・A()が成功してmain()に戻ると、そこでまたnextの値をチェックします。ENDのときだけ成功で、それ以外の場合はエラーです。

→ scan()でnextがSMILEになった場合: A()は成功するが、main()に戻ったところで失敗する
→ scan()でnextがSMILE以外になった場合: A()で失敗する

なので、このプログラムでパーズできるシンボル列はありません。
    • good
    • 0
この回答へのお礼

そうなのですか、ありがとうございます^^
参考にさせて、問題を解いてみます。

お礼日時:2009/02/08 22:50

質問に書いてある内容だけでは、答えられる人はいないと思います。



・「C言語からBNFに変更したい」とか「C言語の問題からBNFにする」というのは、「このC言語のプログラムがパーズできるシンボル列をBNF記法で表せ」という意味で合っているか
・next、SMILE、HELLO、BYEはそれぞれ何を表しているのか
・scan()は何をするのか
・A()の返り値型はvoidと宣言されているのに、return 0;と書かれているのはおかしい

この回答への補足

そうなんですか、すみません。説明が足りなかったようですね。
これはC言語のプログラムをパーズできるシンボル列をBNF記法で表してくださいという意味です。
SMILE、HELLO、BYEは、enum symboltype{SMILE,HELLO,BYE,END};
のことを表しています。
nextはenum symboltype next;のことを表しています。scan()は
void scan(){
char buff[10];
if(fgets(buff,10,stdin)==NULL){
next=END;
return;
}
if(strcmp(buff,"hello\n")==0) next=HELLO;
else if(strcmp(buff,"bye\n")==0) next=BYE;
else if(strcmp(buff,"(*_*)\n")==0) next=SMILE;
else error("#UNKNOWN TOKEN#");
}
のことです。
A()の返り値型はvoidと宣言されているのに、return 0;と書かれているのはおかしいについてですが、このプログラムに関する問題が他にもあります。プログラムの中で受理できない文を探せという問題があるので
もしかしたら受理できない文なのかもしれません。これだけではわからないかもしれないので、プログラム全体を下に表示したいと思います。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
enum symboltype{SMILE,HELLO,BYE,END};
void A();
void B();
void scan();
void error(char *msg);
enum symboltype next;
int main(int argc, char* argv[]){
scan();
A();
if(next != END) error("#PARSE ERROR#");
else puts("#PARSE OK#");
return 0;
}
void A(){
if(next != SMILE) error("#PARSE ERROR#");
else puts("#PARSE OK#");
return 0;
}
void B(){
if(next != SMILE){
scan();
return;
}else if(next != HELLO){
scan();
A();
if(next != BYE) error("#PARSE ERROR#");
scan();
}else error("#PARSE ERROR#");
}
void error(char *msg){
puts(msg);
exit(1);
}
void scan(){
char buff[10];
if(fgets(buff,10,stdin)==NULL){
next=END;
return;
}
if(strcmp(buff,"hello\n")==0) next=HELLO;
else if(strcmp(buff,"bye\n")==0) next=BYE;
else if(strcmp(buff,"(*_*)\n")==0) next=SMILE;
else error("#UNKNOWN TOKEN#");
}
となっています。わかりにくい説明ですみませんm(_ _)m 

補足日時:2009/02/08 21:45
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!