構文解析のアルゴリズムはこんな感じ。
/* E → TE' E' → +T[+}E'|ε E' → -T[-}E'|ε T → FT' T' → *F[*]T'|ε T' → /F[/]T'|ε F → (E)|i[i]|num[num] */ /* E'がsyntactic_analysis_2()関数に対応 T'がsyntactic_analysis_3()関数に対応 F がsyntactic_analysis_4()関数に対応 */
コード↓
/* ---------サブルーチン(構文解析1)ここから--------- */ int syntactic_analysis_1() { int m,l,gyou1; char *x; for(m=0;m<MAXLENG;m++) { for(l=0;l<MAXLENG;l++) { syntactic_result[m].jiku[l]=' '; } } i=0; j=0; l=0; n=1; o=1; fprintf(fp2,"\n【gyakupooranndokihou-siki】\n"); while(lexical_result[i].result!=10) { /* 1文字目の字句の構文解析の判定 */ if(lexical_result[i].result==1){ syntactic_result[j].result=1; for(m=0;m<MAXLENG;m++) { if(isalnum(lexical_result[i].jiku[m])) { syntactic_result[j].jiku[m]=lexical_result[i].jiku[m]; } } fprintf(fp2,"i%d.%d ",n,gyou_kaihi); n++; j++; } i++; /* 2文字目以降の字句の構文解析の判定 */ if(lexical_result[i].result==2||lexical_result[i].result==3||lexical_result[i].result==4 ||lexical_result[i].result==5||lexical_result[i].result==6||lexical_result[i].result==7 ||lexical_result[i].result==8||lexical_result[i].result==9) { syntactic_analysis_4(); syntactic_analysis_3(); syntactic_analysis_2(); } if(lexical_result[i].result==10) { syntactic_result[j].result=3; fprintf(fp2,":= "); break; } } fprintf(fp2,"\n\n【kigouhyou/teisuuhyou】\n");/* 記号表・定数表の作成 */ fprintf(fp2,"kigou1\t\tkigou2\t\taddress\n");/* 記号表の作成 */ n=1; for(m=0;m<MAXLENG;m++) { if(syntactic_result[m].result==1) { while(isalnum(syntactic_result[m].jiku[l])) { putc(syntactic_result[m].jiku[l],fp2); l++; } fprintf(fp2,"\t\ti%d.%d",n,gyou_kaihi); n++; x=syntactic_result[m].jiku; if(gyou_kaihi!=0) { /* アドレスの重複を防ぐために、行数によってアドレスをすすめておく */ for(gyou1=0;gyou1<=gyou_kaihi;gyou1++) { x++; } } temp[m]=x; fprintf(fp2,"\t\t%p\n",x); l=0; } } fprintf(fp2,"\nteisu1\t\tteisu2\t\taddress\n");/* 定数表の作成 */ n=1; for(m=0;m<MAXLENG;m++) { if(syntactic_result[m].result==2) { while(isdigit(syntactic_result[m].jiku[l])) { putc(syntactic_result[m].jiku[l],fp2); l++; } fprintf(fp2,"\t\tnum%d.%d",n,gyou_kaihi); n++; x=syntactic_result[m].jiku; if(gyou_kaihi!=0) { /* アドレスの重複を防ぐために、行数によってアドレスをすすめておく */ for(gyou1=0;gyou1<=gyou_kaihi*3;gyou1++) { x++; } } temp[m]=x; fprintf(fp2,"\t\t%p\n",x); l=0; } } fprintf(fp2,"\n"); return 0; } /* ---------サブルーチン(構文解析1)ここまで--------- */