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

このQ&Aのポイント
  • C言語のプログラム問題に対応するBNFの書き方がわかりません。
  • C言語のプログラムからBNFにする方法を習っていますが、やり方がわかりません。
  • プログラムに対応するBNFを教えてほしいです。また、BNFの書き方も教えてください。
回答を見る
  • ベストアンサー

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はどのように書くのかも教えていただけませんか。

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

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

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

BNFを考える前に、提示されているプログラムが受け付ける記号列が具体的にどんなものか分かりますか? 頭の中で考えても分からなければ、実際にこのプログラムを実行して試してみましたか? 残念ながら、このプログラムはどんな入力をしても #PARSE ERROR# か #UNKNOWN TOKEN# を表示して終了するはずです。 > qa4701108.exe hello #PARSE ERROR# > qa4701108.exe bye #PARSE ERROR# > qa4701108.exe (*_*) #PARSE OK# #PARSE ERROR# > qa4701108.exe abc #UNKNOWN TOKEN# なので、「このプログラムに対応するBNF」はありません。

k1234
質問者

お礼

いえ、頭で考えてもわからなかったので プログラムを実行してみたんですが、どうも結果がおかしかったので 必ずPARSEOKになるはずなので、どうしてもわかりませんでした。 それと、教えていただいて申し訳ありませんが、解決しました。 後で、知人に聞いてみたところ複数のデータを入力するんです。 (*_*) (*_*) のようにするのですから、わからなかったのです。 私の至らなさが足りないばかりに皆さんにご迷惑をおかけしました。 そして、ご協力いただいてありがとうございました。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

や, だから, 「C言語のプログラムからBNFにする方法を習っている」 んだよね? だとしたら, 「あなたに教えている人がいる」はずでしょ? なんでその人に聞かないのかってのが「最大の疑問」として挙げたこと. ちなみに「なんか違う」と思ったら「どこがどう違うと思ったのか」をなるべく書くようにしてください. じゃないと, 同じことを繰り返すことになりかねない. で「プログラムに対応する BNF」とは何?

k1234
質問者

補足

そういう意味でしたか。 ご迷惑をおかけして誠に申し訳ございません。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

http://oshiete1.goo.ne.jp/qa4700530.html とはどこが違うの? 「プログラムに対応する BNF」とは何? そして最大の疑問なんだけど, 教えている人に聞かないのはなぜ?

k1234
質問者

補足

問題自体は一緒ですが、プログラムとしてどこかおかしくても、そのまま作ってほしいんです。 どうも、うまく説明できなくてすみませんm(_ _)m その最大の疑問ですが、もうこれでいいかなと思い、質問を締め切ってしまったんです。 やってみて、なんか違うなと思ってしまったので、新たに投稿したんです。 これを利用するのは初めてなので、質問を締め切ってしまったから、もう質問できないと思ったので、新しく作ったのです。

関連するQ&A

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

  • 文章中から特定の文字列を抜き出すプログラムについて C言語

    log.txtの文章からIPを抜き出しip.txtに書き込むというものです。log.txtの文章は基本的にfrom IP:port の順です。しかし文章中にfromがないとip.txtで空欄になってしまいます。 例192.168.1.100  192.168.1.110 理想はfromがない行はなにも追加せず次に移りたいのですがどうすればいいでしょうか? 例192.168.1.120 192.168.1.130 192.168.1.140 void addLine(const char*,FILE*); char *getFromIP(const char*,char*); int main() { FILE *pFileA = fopen("log.txt","rt"); char buff[256]; if(pFileA){ FILE *pFileB = fopen("ip.txt","wt"); if(pFileB){ for(;fgets(buff,256,pFileA) != NULL;){ char buff2[32] = {'\0'}; addLine(getFromIP(buff,buff2),pFileB); } fclose(pFileB); } fclose(pFileA); } return 0; } char *getFromIP(const char *line, char *buff) {  char *src, *dst;        src = strstr(line, "from");  if(src==NULL) { return buff; }   src += 4;            dst = buff;          while(1) {   if(isspace(*src))  {    src++;    continue;          }   else break;         }                    while(1) {   *dst = *src;          if(*dst == ':')        {    *dst = '\0';          break;           }   if(*dst == '\0')       {   break;           }  dst++;            src++;           }  return buff;         } void addLine(const char *str,FILE *pFile){ char buff[1024]; sprintf(buff,"%s\n",str); fputs(buff,pFile); }

  • C言語のプログラム

    以下のプログラムはハッシュテーブルを用いて文字列を探すプログラムなのですが、コンパイル時にセグメントエラーとなってしまいます。プログラム中に誤った箇所があれば教えて頂きたいです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 10 #define MAX_LEN 64 #define N_WORDS 4 struct list { char word [MAX_LEN]; struct list *next; }; struct list *hash_table[HASHSIZE]; char colors[N_WORDS][MAX_LEN] = {"red", "blue", "green", "yellow"}; void my_strcpy(char* a, const char* b) { int i = 0; while(*b != '\0'){ *(a+i) = *(b+i); i++; } *(a+i) = '\0'; } int hash(char *key) { int hashval = 0; while (*key != '\0') { hashval += *key; key++; } return (hashval % HASHSIZE); } int find_word (char *key) { struct list *p; for (p = hash_table[hash(key)]; p != NULL; p++) if (strcmp(key, p->word) == 0) return 1; return 0; } void init_hash_table() { int i, hashvalue; struct list *p, *q; for (i = 0; i < HASHSIZE; i++) { hash_table[i] = NULL; } for (i = 0; i < N_WORDS; i++) { if ((find_word(colors[i])) == 0){ p = (struct list *)malloc(sizeof(struct list)); my_strcpy(p->word, colors[i]); hashvalue = hash(colors[i]); if (hash_table[hashvalue] = NULL) { hash_table[hashvalue] = p; p->next=NULL; } else { q = hash_table[hashvalue]; while (q->next != NULL) q = q->next; q->next = p; p->next=NULL; } } } } void main(void) { init_hash_table(); printf("result = %d\n", find_word("red")); }

  • 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言語 strcmp 半角スペースがあるとだめ?

    C言語 strcmp 半角スペースが文字列に含まれている場合 文字列の比較がうまくいきません。半角スペースがあると比較できないのでしょうか? プログラム //strcmp #include <stdio.h> #include <string.h> int main(void){ char input[256]; char str[] = "HelloWorld!";   //char str[] = "Hello World!";だとうまくいかない。 printf("%s\n>", str); scanf("%s", input); if ( strcmp(input, str) == 0){ printf("同じです。\n"); }else{ printf("違います。\n"); } return 0; }

  • C言語のqsortについて

    現在、qsortのコードに取り組んでいます。 if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } 恐らくこちらのqsortでの第二引数が書き方を間違えていると思うのですが、修正の方法が分からず、どなたか教えて頂けないでしょうか? #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char c[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1, &op, &num2); if (r != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < 1000;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • c言語の問題です。ファイルからデータを読み込み連結リストに記憶しソートするプログラムです。お願いします

    ソート部分がどうしてもできません。 またソートは以下のアルゴリズムで行うものです 与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。 1.リストAの要素の中で、最大値をもつ要素Cを探す。 2.要素CをリストAから削除する。 3.要素CをリストBの先頭に挿入する。 4.リストAが空であれば終了。空でなければ 1. にもどる。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct physical Physical; struct physical { char name[41]; int age; float height; float weight; Physical *next; }; void read_data(char *file,Physical *p,Physical *tail); int comp1(const Physical *, const Physical *); int comp2(const Physical *, const Physical *); int comp3(const Physical *, const Physical *); int comp4(const Physical *, const Physical *); void sort(char *arg,Physical *p,Physical *q); Physical *listsort(Physical *p, int (*compar)(const void *, const void *)); int main(void) { char s[20],t,u[20]; Physical *p,*tail,*q; p=malloc(sizeof(Physical)); q=malloc(sizeof(Physical)); tail=malloc(sizeof(Physical)); while(1) { printf("CMD>"); fflush(stdout); fgets(s,20,stdin); sscanf(s,"%c %s",&t,u); switch(t){ case 'q':exit(0); case 'r':read_data(u,p,tail); break; case 's':sort(u,p,q); break; case 'd': while(q!=NULL) { printf("%s %d %.1f %.1f ",q->name,q->age,q->height,q->weight ); q=q->next;} break; } } free(p); return 0; } void read_data(char *file,Physical *p,Physical *tail){ FILE *fp; char string[100]; Physical header; tail=&header; header.next = NULL; p->next = NULL; tail->next = p; tail = p; if ((fp = fopen(file, "r")) == NULL) { exit(1); } while(fgets(string,sizeof(string),fp)!= NULL) { sscanf(string,"%s %d %f %f",p->name,&p->age,&p->height,&p->weight); Physical *tail2; tail2=malloc(sizeof(Physical)); tail2->next=NULL; p->next=tail2; p=tail2; } fclose(fp); } void sort(char *arg,Physical *p,Physical *q){ if(strcmp(arg,"name") == 0) q=listsort(p,(int(*)(const void*, const void*))comp1); if(strcmp(arg,"age") == 0) q=listsort(p,(int(*)(const void*, const void*))comp2); if(strcmp(arg,"height") == 0) q=listsort(p,(int(*)(const void*, const void*))comp3); if(strcmp(arg,"weight") == 0) q=listsort(p,(int(*)(const void*, const void*))comp4); } Physical *listsort(Physical *p,int (*compar)(const void *, const void *)){ Physical *q, *max,*s,*head; s=malloc(sizeof(Physical)); head=malloc(sizeof(Physical)); head=NULL; while(p->next){max = p, q = p->next; while( q->next ) { if( compar(q->next,max->next) ) max = q; q = q->next;} s=max->next; max->next=max->next->next; if(head==NULL) {head=s;} s->next=s; } return head; } int comp1(const Physical *a, const Physical *b){ return (strncmp(a->name,b->name,sizeof(Physical))); } int comp2(const Physical *a, const Physical *b){ if(a->age > b->age) return 1; else return 0; } int comp3(const Physical *a, const Physical *b){ if(a->height > b->height) return 1; else return 0; } int comp4(const Physical *a, const Physical *b){ if(a->weight > b->weight) return 1; else return 0; }

  • c言語の難しい問題について

    (c言語の問題) 下記のプログラムを完成させ、キーボードから文字列を読み込み、-1文字ずらすことによって暗号化を行うプログラムを作りなさい。ただし、ピリオド、空白などはそのままにするようにすること。 例)this is a pen. sghr hr @ qdm. #include<stdio.h> #define CHAR_NUM 256 void angou( I ) { II } int main(void) { unsigned char text[CHAR_NUM]; char moji; int i; puts("暗号化する文字を入力しなさい。"); while((moji=getchar()) !=EOF){ text[i]=moji; i++; } angou(text i); printf("%s",text); return(0); } I、IIに入る文を書きなさい。 私はIには「char x[],int y」 IIには 「if('A'<x[i]<'Z' && 'a'<x[i]<'z') int j; for(j=0;j<y;j++) x[j]=x[j]-1 else」 といれたのですが、出力がうまくでません。どうすればいいのですか?

  • 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の式がいまいち理解できません。 解説できる方いませんか?

  • C言語のプログラムの流れについて

    下に貼り付けたプログラムの流れを順番に教えて頂きたいです。 特にadd関数とinsert関数の中身の動きについてが分からないので教えていただきたいです。 (a,b,c,sentouなどの動きなど。) 参考にですが リスト構造を用いて、read関数で読み込んだ単語をアルファベット順にソートしてリストのセルに入れ、同じ単語はまとめてその単語と個数を順に表示するプログラムです。 1からの説明を要求して申し訳ありませんがよろしくお願いいたします。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> typedef struct moji{ char w[50]; int cnt; struct moji *next; }moji; int main(){ FILE *fp; char data[50]; moji *sentou; moji *p=NULL; if((sentou=(moji *)malloc(sizeof(moji)))==NULL){ printf("malloc error\n"); exit(1); } fp=fopen("tango.txt","r"); if((fp = fopen("tango.txt","r"))==NULL){ printf("can't open\n"); exit(1); } while(read(data,fp)){ add(data,sentou); } p=sentou->next; while(p != NULL){ printf("%s %d\n",p->w,p->cnt); free(p); p=p->next; } fclose(fp); return (0); } int read(char data[],FILE *fp){ /*1つの単語(連続したアルファベット)をdataに格納して、スペースで区切られたらそこで格納をやめ、値1を返す。再度単語を格納するときはdataを初期化し、再度1つの単語を取得する。ファイルの単語がなくなれば(EOFなら)0を返す関数read()*/ } void add(char data[],moji *sentou){ moji *a,*c; for(c=sentou;c!=NULL;c=c->next){ if(strcmp(c->w,data)==0){ c->cnt++; return; } if(strcmp(c->w,data)>0){ break; } else{ a=c; } } insert(a,c,data); } void insert(moji *a,moji *c,char data[]){ moji *b; if((b=(moji *)malloc(sizeof(moji)))==NULL){ printf("malloc error\n"); exit(1); } strcpy(b->w,data); b->cnt=1; a->next=b; b->next=c; }

専門家に質問してみよう