C言語からBNFに変更する方法

このQ&Aのポイント
  • C言語のコードをBNF形式に変換したい場合、特定の部分を変更する必要があります。
  • コードの一部をBNFに変換する際、一貫した規則を適用する必要があります。
  • 提供されたコードの部分をBNFに変換する場合、<A>と<B>の相互参照などの規則を考慮する必要があります。
回答を見る
  • ベストアンサー

C言語からBNFに変更したいのですが・・

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となってしまいました。この答えであっているのかわからないので、誰か教えてください。もし、違っていた場合は、答えとなぜそうなるのか教えてほしいんです。よろしくお願いします。

  • k1234
  • お礼率40% (2/5)

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.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()で失敗する なので、このプログラムでパーズできるシンボル列はありません。

k1234
質問者

お礼

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

その他の回答 (1)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

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

k1234
質問者

補足

そうなんですか、すみません。説明が足りなかったようですね。 これは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 

関連するQ&A

  • C言語のプログラム問題に対応するBNFの書き方がわかりません

    C言語のプログラムからBNFにする方法を習っているのですが、どうしてもそのやり方がわかりません。 下にあるプログラムに対応するBNFを自分で作成してみたのですが、 <A>::=A|Bぐらいしかできませんでした。このBNFを作っても、なぜこうなるのかもわかりません。 #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#"); } このプログラムに対応するBNFを教えてほしいんです。 お願いしますm(_ _)m また、BNFはどのように書くのかも教えていただけませんか。

  • C言語 if文について

    #include <stdio.h> int main(void) { int a; printf("整数を入力してください:"); scanf("%d",&a); if(a % 10 == 5) puts("最下位の桁は5です。"); else puts("最下位の桁は5でありません。"); return 0; これでどうして読み込んだ整数値の最も下の桁が5であるかどうかを判断しているのでしょう? ifの式がいまいち理解できません。 解説できる方いませんか?

  • BNF→JAVA  基本問題らしいです

    学校の宿題でBNF→JAVAの課題が出て一応自分でやったんですが自身が無いので合ってるか見てください。 間違っていれば指摘お願いします。 特によくわからないのが繰り返し{}と省略可[]をどのようにしたらいいのかが迷いました。 問題 <B>::=[<DEC>]<S> <S>::="{"<S>"}"|<IF>|<WRITE> <IF>::="if"<E><S>";" <WRITE>::="int"<VAR>";"|"char"<VAR>";" 僕が考えた答え public void parseB(){ if parse Dec(); parseS(); } void parseS(){ if(tokenType==S_LBRACE)getToken(); while(tokenType==S_INT)parseS(); if(tokenType==S_RBRACE)getToken(); else if parseIf(); else if parseWrite(); elese error(); } void parseIf(){ if(tokenType==S_IF)getToken(); parseE(); parseS(); if(tokenType==S_SEMICOLON)getToken(); } void parseWrite(){ if(tokenType==S_INT)getToken(); parseVar(); if(tokenType==S_SEMICOLON)getToken(); parseVar(); if(tokenType==S_SEMICOLON)getToken(); }

  • C言語について

    C言語についてなのですが、error C4700: 初期化されていないローカル変数 'dright' が使用されますという表示がでてしまいます。今地下鉄の環状線の距離を計算して求めるというプログラミングを作っています。どうすれば直るのでしょうか。また、おかしいと思われる場所があれば教えていただきたいです。下がぼくが書いたソースです。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> float d[15] = { 0.0, 0.0, 1.6, 3.0, 4.3, 5.4, 8.2, 8.9, 9.7, 14.1, 15.1, 17.2, 20.7, 22.2, 23.4 }; float dright(int a, int b)//右回りのときの計算 { if (d[a]<d[b]) { return d[b] - d[a]; } else { return d[a] - d[b]; } } int main(void) { int a, b; float dright, dleft; printf("出発駅番号の入力"); scanf("%d", &a); printf("到着駅番号の入力"); scanf("%d", &b); if (a = b)//出発駅と到着駅が同じ場合 { printf("出発駅と到着駅が同じです。もう一回やり直してください。"); } else { dleft = 26.4 - dright;//左回りの計算 if (dleft > dright)//左回りのほうの距離が長い場合 { printf("%f", dright);//右回りの距離を表示 } else { printf("%f", dleft); } } return 0; } どなたかお願いします。

  • C言語の演算式

    C言語のプログラミングで、4×(1-1/3+1/5-1/7+・・・・・)の式を100000項まで合計した式を作りたいです。答えは3.141591になります。 自分で作成してみたのですが、なかなか上手くいきません。 どうすればよいでしょうか?以下自分の作成したプログラムを「」内に載せます。 答えは0になってしまいます。 「 #include <stdio.h> int main(void) { int i=0,a=1,b; do{ i++; if(i%2) { a+=(-1)/(2*(i-1)+1); } else{ a+=1/(2*(i-1)+1); } }while(i<100000); b=4*a; printf("π=%f\n",b-1); putchar('\n'); return (0); } 」

  • C言語

    #include <stdio.h> int main(void) { int month, days; puts("月を入力してください:"); scanf("%d",&month); // if(month == 2) days = 28; if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12); days = 31; else days=30; printf("%d月は%d日あります。\n", month, days); return(0); } // 月と日数の場合わけをしたいのですがうまくいきません。どこをなおせばいいのか誰か教えてください!

  • C言語

    #include <stdio.h> int main(void) { int month, days; puts(\"月を入力してください:\"); scanf(\"%d\",&month); // if(month == 2) days = 28; if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12); days = 31; else days=30; printf(\"%d月は%d日あります。\\n\", month, days); return(0); } // 月と日数の場合わけをしたいのですがうまくいきません。どこをなおせばいいのか誰か教えてください!

  • C言語 スタックを使ったプログラミングについて

    C言語のスタックを使った逆ポーランド記法を使ったプログラミングについて質問です。 今回作ったプログラムは、キーボードで入力した逆ポーランド記法の数式を計算してその結果を出力するといったものです。 実際に以下のプログラムをcygwin上で動かしてみたのですが、コアダンプ表示が出てうまく動作しませんでした。 一応printfなどを使って確認してみたところ。main関数までは辿り着いているみたいなのですが、スタックを使うあたりから怪しくなっているみたいでよくわかりませんでした。。 どこが間違っているのかわかりやすく教えていただけると大変助かります。 長々とすみません、よろしくお願いいたします。 #include <stdio.h> #include <ctype.h> #include <stdlib.h> typedef struct cell_{ double vall; struct cell_ *next; }cell; cell *sp = NULL; int empty(void){ cell *retnode = sp -> next; if(retnode == NULL){ return 1; } return 0; } void push(double x){ cell *newnode; newnode = (cell*)malloc(sizeof(cell)); newnode -> vall = x; newnode -> next = sp -> next; sp -> next = newnode; } double pop(void){ int i; double num; i = empty(); if(i == 1) exit(1); cell *shownode = sp -> next; num = shownode -> vall; sp -> next = shownode -> next; free(shownode); return num; } double print(void){ cell *printnode = sp -> next; return printnode -> vall; } int main(){ double a, b; double i; char c; char *ends; while((c = getchar()) != EOF){ if(isdigit(c)){ a = c; push(a); }else{ switch(c){ case '+': a = pop(); b = pop(); i = a + b; push(i); break; case '-': a = pop(); b = pop(); i = a - b; push(i); break; case '*': a = pop(); b = pop(); i = a * b; push(i); break; case '/': a = pop(); b = pop(); i = a / b; push(i); break; case EOF || '\n': a = print(); printf("%f\n", a); default: printf("Irregular character is found. Try again\n"); while((c = getchar()) != EOF && c != '\n'){} break; } } } return 0; }

  • c言語で

    c言語で /*a==bのとき商と余を求めるそれ以外は積を求める*/ # include<stdio.h> main () { int a,b,seki,sho,joyo; printf("aとbを入力してください\n"); scanf("%d %d", &a,&b); if(a==b) printf("sho=%d\n",(a/b)); printf("joyo=%d\n",(a%b)); else printf("seki=%d\n",(a*b)); return(0); } はどこがおかしいでしょうか? あと /*小数点*/ # include<stdio,h> main () { float a,b,seki,sho,joyo; printf("%f %f",&a,&b); if(a>b) printf("sho=%f4.3\n",(a/b)); printf("joyo=%f4.3\n",(a%b)); else printf("seki=%f4.3\n",(a*b)); return (0) にいたってはエラーの嵐なのですがどうすればいいでしょうか

  • c言語についての質問です。

    #include<stdio.h> int main(void){ int a; printf("1文字たいぷしてください。\n"); scanf("%d",&a); if(a>=65 && a<=90){ printf("大文字です。\n"); } else if(a>=97 && a<=122){ printf("小文字です。\n"); } else{ printf("大文字でも小文字でもありません\n"); } return 0; } このプログラムは正しくなくて、 intをchar %dを%cにかえなければなりません。 なぜintはダメなんでしょうか? できれば丁寧に教えてください。 お願いします。