int LRParsing::leafcount(grammer* curr){ curr->leaf=0; for(int i=0;i<5; i++){ if(curr->link[i]!=NULL) curr->leaf+=leafcount(curr->link[i]); } if(curr->select==0) curr->leaf=1; return curr->leaf; }
int main() { root=create(50); root->left=create(40); root->right=create(60); root->left->right=create(44); root->right->right=create(80); display(root); printf("\n %d is count of leaf nodes the tree :)\n",leafcount(root)); return 0; }
int LRParsing::parsetree_mfc(FILE *read_fp, CDC *pDC, CSize *size){ top=-1; fseek(read_fp, 0, SEEK_SET); CString terminalString; LRParsing lex(read_fp); //모든내용을 읽어들여 분석한다. grammer *X, a, *temp; int *S; int k; cell_action_tbl action; int cnt=0, cnt_s = 0, cnt_r = 0; int err = parsetable_mfc(); if(err == -1) return -1; //상태0을 삽입. S = (int*) malloc(sizeof(int)); *S = 0; push((void*)S); //처음 심볼을 읽음. a = input_string(lex); if(a.select == -1) return -4; do{ cnt++; if(cnt == 95) cnt = 95; S = (int*)stack[top]; //stack의 탑의 상태를 읽는다. (popX) //각 액션테이블 값에 따른 행동 action = Action_Table[*S][a.location]; //해당 상태와 심볼에 대한 Action_Table값 switch (action.Kind){ //읽어드린 토큰을 푸시. 상태도 푸시. case 's': cnt_s++; X = (grammer*) malloc(sizeof(grammer)); linkinit(X); X->select = a.select; X->location = a.location; if(a.select == 0 && (a.location == 16 || a.location == 17 || a.location == 15)) strcpy_s(X->str, a.str); push((void*)X); S = (int*)malloc(sizeof(int)); *S = action.num; push((void*)S); //남은 input string의 첫 심볼을 읽고 다음심볼을 가리킴. a = input_string(lex); if(a.select == -1) return -4; break; //팝해서 리듀스하고 다시 푸시. 상태도 푸시. case 'r': cnt_r++; X = (grammer*)malloc(sizeof(grammer)); linkinit(X); X->select = rule_v[action.num].left.select; X->location = rule_v[action.num].left.location; //입실론을 리듀스할때, 팝하지말고 입실론을 추가로 링크. if(rule_v[action.num].rule_len == 1 && rule_v[action.num].right[0].select == 0 && rule_v[action.num].right[0].location == 22-1){ temp = (grammer*)malloc(sizeof(grammer)); linkinit(temp); temp->select = 0; temp->location = 22-1; X->link[0] = temp; } //다른기호에 대해선 정상적인 팝과 링크를 걸어준다. else{ for(int i=rule_v[action.num].rule_len-1; i>=0; i--){ free((int*)pop()); X->link[i] = (grammer*)pop(); }//상태와 심볼, 두배로 pop; } k = *(int*)stack[top]; //룰의 왼쪽심볼을 푸시 push((void*)X); //상태도 푸시. S = (int*)malloc(sizeof(int)); *S = Goto_Table[k][rule_v[action.num].left.location]; push((void*)S); break; //성공했으므로 파스트리를 그리는 함수 호출. case 'a': //상태는 팝해서 없애주고, 심볼은 루트에다 연결. free((int*)pop()); root = (grammer*)pop(); free((int*)pop()); break; //에러이므로 음수 리턴값 출력 case 'e': break; default: return -3; break; } }while(!(action.Kind == 'a' && a.select == 0 && a.location == 22-2)); width = leafcount(root)*70; CRect rect(0,5,5+width,5+35); height = 5; this->parsedraw_mfc(pDC, root, rect); size->cx = width; size->cy = height; return 0; }