/* expC - Expressions analyzator and viewer Copyright (C) 2004 Samuel Kupka This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <string.h> #include <allegro.h> #include "expC.h" /* Globalne premenne */ EXPR_NODE *expr_tree; int tree_size; int tree_used; int num_leaves; int expr_max_x; int expr_max_y; EXPR_ATOM atom[MAX_ATOM]; int num_atom; /* Program */ int err_pos; int expr_show_node(BITMAP *bmp,int node,int orig,int x,int y) { if(node<=orig) return x; if(node<0||node>=tree_used) return x; if(expr_tree[node].node<=0) return x; if(expr_tree[node].node<=MAX_ATOM){ x+=expr_draw_atom(bmp,x,y,expr_tree[node].node,0,-1,1); return x; } x+=expr_draw_string(bmp,x,y,"(",0,-1,1); x=expr_show_node(bmp,expr_tree[node].next[0],node,x,y); x+=expr_draw_node(bmp,x,y,node,0,-1,1); x=expr_show_node(bmp,expr_tree[node].next[1],node,x,y); x+=expr_draw_string(bmp,x,y,")",0,-1,1); return x; } void expr_show_text(BITMAP *bmp,int x,int y) { x+=expr_draw_string(exp_bmp,x,5,"Vyrok: ",0,-1,1); expr_show_node(bmp,0,-1,x,y); } int expr_draw_string(BITMAP *bmp,int x,int y,char *str,int c1,int c2,char draw) { int w=0,symbol=0; char buf[10]; if(!stricmp(str,"alfa")) symbol='a'; if(!stricmp(str,"alpha")) symbol='a'; if(!stricmp(str,"beta")) symbol='b'; if(!stricmp(str,"gamma")) symbol='g'; if(!stricmp(str,"gama")) symbol='g'; if(!stricmp(str,"delta")) symbol='d'; if(!stricmp(str,"&")) symbol='Ù'; if(!stricmp(str,"|")) symbol='Ú'; if(!stricmp(str,"!")) symbol='Ø'; if(symbol!=0){ sprintf(buf,"%c",symbol); w=text_length(data[sfont].dat,buf)+2; if(draw==1) textout_ex(bmp,data[sfont].dat,buf,x+2,y,c1,c2); } else{ w=text_length(font,str); if(draw==1) textout_ex(bmp,font,str,x,y,c1,c2); } return w; } int expr_draw_atom(BITMAP *bmp,int x,int y,int num,int c1,int c2,char draw) { if(num<1||num>num_atom) return 0; return expr_draw_string(bmp,x,y,atom[num-1].str,c1,c2,draw); } int expr_draw_node(BITMAP *bmp,int x,int y,int node,int c1,int c2,char draw) { char str[3]; if(node<0||node>=tree_used) return x; if(expr_tree[node].node<=0) return x; if(expr_tree[node].node<=MAX_ATOM){ x+=expr_draw_atom(bmp,x,y,expr_tree[node].node,0,-1,draw); return x; } str[0]=0; if(expr_tree[node].node==OPER_AND) str[0]='&'; if(expr_tree[node].node==OPER_OR) str[0]='|'; if(expr_tree[node].node==OPER_NOT) str[0]='!'; str[1]=0; x=expr_draw_string(bmp,x,y,str,0,-1,draw); return x; } void expr_init(void) { tree_size=0; } void expr_exit(void) { if(tree_size>0){ free(expr_tree); } } int expr_which_oper(unsigned char c) { if(c=='&') return OPER_AND; if(c=='|') return OPER_OR; if(c=='!') return OPER_NOT; return 0; } int expr_find_oper(char *expr,int s,int e,int *vysl_hl) { int i,f_p=-1,f_h=10000,f_o=0,h=0,o; if(e<s){err_pos=s; return -1;} for(i=s;i<=e;i++){ if(expr[i]=='(') h++; if(expr[i]==')') h--; o=expr_which_oper(expr[i]); if(o>0){ if(h<f_h){f_p=i;f_h=h;f_o=o;} if(h==f_h&&o<f_o){f_p=i;f_h=h;f_o=o;} } } if(h!=0){err_pos=s; return -1;} *vysl_hl=f_h; return f_p; } int expr_find_atom(char *str) { int i; for(i=0;i<num_atom;i++){ if(!stricmp(str,atom[i].str)) return i+1; } if(num_atom>=MAX_ATOM) return -1; strcpy(atom[num_atom].str,str); num_atom++; return num_atom; } int expr_str_to_atom(char *expr,int s,int e,int tp) { int i,h=0,z=0,ok,ss=-1,ee=-2; char str[16]; for(i=s;i<=e;i++){ ok=0; if(expr[i]=='('){ if(z){err_pos=i; return -1;} h++; expr[i]=' '; } if(expr[i]==')'){ h--;z=1;expr[i]=' '; if(h<0){err_pos=i; return -1;} } if(expr[i]==' ') ok=1; if(expr[i]=='_') ok=1; if(expr[i]>='a'&&expr[i]<='z') ok=1; if(expr[i]>='A'&&expr[i]<='Z') ok=1; if(expr[i]>='0'&&expr[i]<='9') ok=1; if(ok!=1){err_pos=i; return -1;} } for(i=s;i<=e;i++){ if(expr[i]!=' '){ ss=i; break; } } for(i=e;i>=s;i--){ if(expr[i]!=' '){ ee=i; break; } } if(ee<ss){err_pos=ss; return -1;} z=0; for(i=ss;i<=ee;i++){ str[z]=expr[i]; if(str[z]==' ') str[z]='_'; z++; } str[z]=0; z=expr_find_atom(str); if(z<0){ return -1;err_pos=s; } expr_tree[tree_used].node=z; expr_tree[tree_used].x=num_leaves*100; num_leaves++; tree_used++; return 0; } int expr_str_to_tree(char *expr,int s,int e,int tp) { int p,h,o,n,ss,ee,i; if(tree_used>=tree_size) return -1; expr_tree[tree_used].prev=tp; p=expr_find_oper(expr,s,e,&h); if(p>=0){ o=expr_which_oper(expr[p]); expr_tree[tree_used].node=o; tp=tree_used; tree_used++; ss=s; ee=e; if(h>0){ n=0; ss=-1; ee=-1; for(i=s;i<p;i++){ if(expr[i]=='(') n++; if(n==h){ ss=i+1; break; } } n=0; for(i=e;i>p;i--){ if(expr[i]==')') n++; if(n==h){ ee=i-1; break; } } if(ss<0){err_pos=s; return -1;} if(ee<0){err_pos=e; return -1;} } if(o!=OPER_NOT){ expr_tree[tp].next[0]=tree_used; if(expr_str_to_tree(expr,ss,p-1,tp)<0) return -1; } expr_tree[tp].next[1]=tree_used; if(expr_str_to_tree(expr,p+1,ee,tp)<0) return -1; } else{ if(expr_str_to_atom(expr,s,e,tp)<0) return -1; } return 0; } int expr_calc_xy_positions(int p,int h) { int x,poc; expr_tree[p].y=h*80; if(expr_tree[p].y>expr_max_y) expr_max_y=expr_tree[p].y; if(expr_tree[p].node<=MAX_ATOM){ if(expr_tree[p].x>expr_max_x) expr_max_x=expr_tree[p].x; return expr_tree[p].x; } x=0;poc=0; if(expr_tree[p].next[0]>0){ x+=expr_calc_xy_positions(expr_tree[p].next[0],h+1); poc++; } if(expr_tree[p].next[1]>0){ x+=expr_calc_xy_positions(expr_tree[p].next[1],h+1); poc++; } if(poc>0){ x/=poc; expr_tree[p].x=x; if(x>expr_max_x) expr_max_x=x; return x; } return 0; } int expr_to_tree(char *expr) { int l,r; char tbuf[64]; l=strlen(expr); if(l<1){ alert("Validator","Vyrok musi obsahovat aspon jeden atom!",NULL,"&OK",0,'o',0); return -1; } if(tree_size>0) free(expr_tree); tree_size=l; num_atom=0; tree_used=0; num_leaves=0; expr_max_x=0; expr_max_y=0; err_pos=0; expr_tree=(EXPR_NODE *)malloc(tree_size*sizeof(EXPR_NODE)); memset(expr_tree,0,tree_size*sizeof(EXPR_NODE)); r=expr_str_to_tree(expr,0,l-1,-1); if(r<0){ sprintf(tbuf,"Chyba je pri %d. znaku vyroku.",err_pos+1); alert("Validator",tbuf,NULL,"&OK",0,'o',0); return r; } r=expr_calc_xy_positions(0,0); if(r<0){ alert("Validator","Vygenerovany strom nie je korektny.","Jedna sa o chybu v programe!","&OK",0,'o',0); return r; } return 0; }