実現したいこと
Linux環境で以下のプログラムを書き、gccでコンパイルからの実行とした時は、正常に動いたのですが、windows環境で同じプログラムをgccでコンパイルからの実行とすると、上手く動いてくれません。何を変えればWindowsでも正常に動いてくれますか?
以下のプログラムはコンパイラー的なのをc言語で書いてみようというもので、構文解析をするものです。
windows環境だと、”<>”が”<”部分だけ読み込まれされ、その後、なにも読み込まなくなり、"Syntax Error"と表示されます。なので、おそらくcheck_word関数がおかしいのですが、なにぶんLinux環境では最後の”.”まで読み取れ”Complete”できるので、なにがおかしいのか分からずにいます。
c
1#include<stdio.h> 2#include<stdlib.h> 3#include<string.h> 4 5char outtoken[200][10]; //トークン出力用配列 6int tnum; 7 8char token[20]; 9char res[13][20]={"begin","end","if","then","while","do", 10 "return","function","var","const","odd", 11 "write","writeln"}; 12char sign[17][10]={"+","-","*","/","(",")","=","<",">", 13 "<>","<=",">=",",",".",";",":="}; 14FILE *fi; 15int a=0; 16//関数宣言 17void nexttoken(int); //次のトークンを読み込む関数 18int ch(char[]); //引数の文字列との比較 同じ:1 違う:0 19int ttype(); //トークンのタイプを返す 1:予約語 2:記号 20 // 3:名前 4:整数 21void exit_func(); //構文解析エラー 強制終了 22void backtoken(); //現在のトークンの番号を1つ前に戻す 23void block(), varDecl(), constDecl(), funcDecl(), 24 statement(), condition(), expression(), term(), 25 factor(); //構文規則を指定 26void get_token(); 27 28int check_word(char c){ 29 if(c>='0' && c<='9') // 数字なら 30 return 0; 31 else if(c>='a' && c<='z') //アルファベット 32 return 1; 33 else if(c=='\n' || c==' ' || c=='\t') //改行,スペース,タブ 34 return 2; 35 else if(c=='+' || c=='-' || c=='*' || c=='/' || c=='(' || c==')' || c=='=' || c==',' || c=='.' || c==';') //1文字のみの記号 36 return 3; 37 else if(c==':') //コロンは'='と必ず一緒になる 38 return 4; 39 else if(c=='<' || c=='>'){ //この場合は次の文字を見る必要がある 40 c=fgetc(fi); 41 fseek(fi,-1,1); //ファイルポインタを1つ戻す 42 if(c=='=' || c=='>'){ 43 return 4; 44 }else{ 45 return 3; 46 } 47 } 48} 49 50int main(int argc, char **argv) 51{ 52 get_token(); //トークン分割プログラム 53 tnum=0; 54 block(); 55 nexttoken(1); 56 if(ch(".")) printf("Complete\n"); 57 else printf("Syntax Error\n"); 58 59 return 0; 60} 61 62void block() 63{ 64 int c=0; 65 nexttoken(0); 66 while(ch("const")||ch("var")||ch("function")){ 67 c++; 68 if(ch("const")) constDecl(); 69 else if(ch("var")) varDecl(); 70 else if(ch("function")) funcDecl(); 71 } 72 if(!c) backtoken(); 73 statement(); 74} 75 76void varDecl() 77{ 78 nexttoken(1); 79 if(ttype()!=3) exit_func("verdecl"); 80 nexttoken(1); 81 while(ch(",")){ 82 nexttoken(1); 83 if(ttype()!=3) nexttoken(1); 84 else exit_func("verdecl"); 85 } 86 if(ch(";")){} 87 else exit_func("verdecl"); 88} 89 90void funcDecl() 91{ 92 nexttoken(3); 93 if(ttype()!=3) exit_func("funcdecl"); 94 nexttoken(3); 95 if(!ch("("))exit_func("funcdecl"); 96 nexttoken(3); 97 if(ttype()!=3) 98 exit_func("funcdecl"); 99 nexttoken(3); 100 while(ch(",")){ 101 nexttoken(3); 102 if(ttype()==3) nexttoken(3); 103 else exit_func("funcdecl"); 104 } 105 if(ch(")")) block(); 106 else exit_func("funcdec3"); 107 nexttoken(3); 108 if(ch(";")) nexttoken(3); 109 else exit_func("funcdec4"); 110} 111 112void constDecl() 113{ 114 do{ 115 nexttoken(2); 116 if(ttype()!=3) exit_func("constdecl"); 117 nexttoken(2); 118 if(!ch("=")) exit_func("constdecl"); 119 nexttoken(2); 120 if(ttype()!=4) exit_func("constdecl"); 121 nexttoken(2); 122 }while(ch(",")); 123 if(ch(";"))nexttoken(2); 124 else exit_func("constdecl"); 125} 126 127void statement() 128{ 129 int a,b,n; 130 int t_now, t_next; 131 132 nexttoken(4); 133 if(ttype()==3){ 134 nexttoken(4); 135 //if(ch(":=")!=) exit_func("Syntax Error"); 136 if(!ch(":=")) exit_func("Syntax Error"); 137 expression(); 138 } 139 else if(ch("begin")){ 140 statement(); 141 nexttoken(4); 142 while(ch(";")){ 143 statement(); 144 nexttoken(4); 145 } 146 if(!ch("end")) exit_func("Syntax Error"); 147 148 } 149 else if(ch("if")){ 150 condition(); 151 nexttoken(4); 152 if(!ch("then")) exit_func("Syntax Error"); 153 statement(); 154 } 155 else if(ch("while")){ 156 condition(); 157 nexttoken(4); 158 if(!ch("do")) exit_func("Syntax Error"); 159 statement(); 160 } 161 else if(ch("return")){ 162 expression(); 163 }else if(ch("write")){ 164 expression(); 165 }else if(ch("writeln")){ 166 }else{ //何もせずにスルー 167 backtoken(); 168 } 169} 170 171void condition() 172{ 173 nexttoken(5); 174 if(!ch("odd")){ 175 backtoken(); 176 expression(); 177 }else expression(); 178 if(!ch("=")&&!ch("<>")&&!ch("<")&&!ch(">")&&!ch("<=")&&!ch(">=")){ 179 exit_func("Syntax Error"); 180 }else{ 181 nexttoken(5); 182 expression(); 183 } 184} 185 186void expression() 187{ 188 nexttoken(6); 189 if(!ch("+")&&!ch("-")){ 190 backtoken(); 191 term(); 192 }else{ 193 term(); 194 } 195 nexttoken(6); 196 while(ch("+")||ch("-")){ 197 term(); 198 nexttoken(6); 199 } 200 backtoken(); 201} 202 203void term() 204{ 205 factor(); 206 nexttoken(7); 207 while(ch("*")||ch("/")){ 208 factor(); 209 nexttoken(7); 210 } 211 backtoken(); 212} 213 214void factor() 215{ 216 nexttoken(8); 217 if(ttype()==4){ 218 }else if(ttype()==3){ 219 nexttoken(8); 220 if(!ch("(")){ 221 backtoken(); 222 }else{ 223 nexttoken(8); 224 if(ch(")")){ 225 backtoken(); 226 }else{ 227 backtoken(); 228 expression(); 229 nexttoken(8); 230 while(ch(",")){ 231 expression(); 232 nexttoken(8); 233 } 234 } 235 if(ch(")")){ 236 }else{ 237 exit_func("factor1"); 238 } 239 } 240 }else if(ch("(")){ 241 expression(); 242 nexttoken(8); 243 if(ch(")")){ 244 }else{ 245 exit_func("factor2"); 246 } 247 } 248} 249 250void nexttoken(int s) 251{ 252 char state[30]; 253 switch(s){ 254 case 0: sprintf(state,"block"); 255 break; 256 case 1: sprintf(state, "constDecl"); 257 break; 258 case 2: sprintf(state, "verDecl"); 259 break; 260 case 3: sprintf(state, "funcDecl"); 261 break; 262 case 4: sprintf(state, "statement"); 263 break; 264 case 5: sprintf(state, "condition"); 265 break; 266 case 6: sprintf(state, "expression"); 267 break; 268 case 7: sprintf(state, "term"); 269 break; 270 case 8: sprintf(state, "factor"); 271 break; 272 } 273 strcpy(token,outtoken[tnum]); 274 tnum++; 275 printf("%-13s : [%s]\n",state,token); 276} 277 278int ch(char str[20]) //文字列の比較 279{ 280 if(strcmp(token,str)==0) return 1; 281 else return 0; 282} 283 284int ttype() //トークンのタイプを返す 285{ 286 int i,c; 287 for(i=0;i<13;i++){ 288 c=strcmp(token,res[i]); 289 if(c==0){ 290 return 1; 291 break; 292 } 293 } 294 295 for(i=0;i<16;i++){ 296 c=strcmp(token,sign[i]); 297 if(c==0){ 298 return 2; 299 break; 300 } 301 } 302 303 if(token[0] >='0' && token[0]<='9') 304 return 4; 305 else 306 return 3; 307} 308 309void backtoken() //トークン番号を1つ前に戻す 310{ 311 tnum--; 312} 313 314void exit_func(char str[20]) //文法規則に合わないため終了 315{ 316 printf("Syntax Error Near the Word \"%s\"\n",token); 317 printf("%s\n",str); 318 exit(1); //強制終了 319} 320 321 322void get_token() 323{ 324 int i,j,token_num; 325 char c; 326 fi=fopen("2.txt","r"); 327 token_num=0; //トークンの数の初期化 328 j=0; 329 while(1){ 330 c=fgetc(fi); //1文字ずつ入力 331 printf("%c\n",c); 332 if(c==EOF)break; 333 334 if(check_word(c)==0){//数字なら 335 outtoken[token_num][j]=c; 336 j++; 337 a=1; 338 } 339 else if(check_word(c)==1){//文字なら 340 if(a==1){ 341 outtoken[token_num][j]='\0'; 342 j=0; 343 token_num++; 344 a=0; 345 } 346 outtoken[token_num][j]=c; 347 j++; 348 } 349 else if(check_word(c)==2){ //改行,スペース,タブなら 350 if(j!=0){ 351 outtoken[token_num][j]='\0'; 352 j=0; 353 token_num++; 354 } 355 else{ 356 //do nothing!! 357 } 358 }else if(check_word(c)==3){ //記号なら(1文字) 359 if(j!=0){ 360 outtoken[token_num][j]='\0'; 361 j=0; 362 token_num++; 363 } 364 outtoken[token_num][j]=c; 365 j++; 366 outtoken[token_num][j]='\0'; 367 j=0; 368 token_num++; 369 a=0; 370 } else if(check_word(c)==4){ //記号なら(2文字) 371 if(j!=0){ 372 outtoken[token_num][j]='\0'; 373 j=0; 374 token_num++; 375 } 376 outtoken[token_num][j]=c; 377 j++; 378 c=fgetc(fi); 379 printf("%c\n",c); 380 outtoken[token_num][j]=c; 381 j++; 382 outtoken[token_num][j]='\0'; 383 j=0; 384 token_num++; 385 a=0; 386 } 387 } 388 389 for(i=0;i<token_num;i++){ 390 printf("%3d %s ",i,outtoken[i]); 391 if(check_word(outtoken[i][0])==0){ 392 printf("整数\n"); 393 }else if(check_word(outtoken[i][0])==3 || check_word(outtoken[i][0])==4){ 394 printf("記号\n"); 395 }else if(check_word(outtoken[i][0])==1){ 396 if(strcmp(outtoken[i],"begin")==0 || strcmp(outtoken[i],"end")==0 || strcmp(outtoken[i],"if")==0 || strcmp(outtoken[i],"then")==0 || strcmp(outtoken[i],"while")==0 || strcmp(outtoken[i],"do")==0 || strcmp(outtoken[i],"return")==0 || strcmp(outtoken[i],"function")==0 || strcmp(outtoken[i],"var")==0 || strcmp(outtoken[i],"const")==0 || strcmp(outtoken[i],"odd")==0 || strcmp(outtoken[i],"write")==0 || strcmp(outtoken[i],"writeln")==0){ 397 printf("予約語\n"); 398 } 399 else { 400 printf("名前\n"); 401 } 402 } 403 } 404 405} 406
入力するテキストファイル↓
function gcd(x,y) begin while x <> y do begin if x < y then y:=y-x; if y<x then x:=x-y; end; return x end; const bunsi=32,bunbo=88; var g; begin g:=gcd(bunsi,bunbo); write bunsi/g; write bunbo/g; writeln end.
回答2件
あなたの回答
tips
プレビュー