1、由以上可得出该语言的文法可表示如下:G(S) = (VN,VT,P,S)其中VN=S,X,Y,Z,M,W,VT= 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,G,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z= 0|1| 2|3|4|5|6|7|8|9= a|b|c|d|e|f|A|B|C|D|E|F=g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|G|H|I|G|K|L|M|N|O|P|Q|R|S|T|U|V|
2、W|X|Y|ZSX|Y|ZX|MM|M|Y|YZH|WHW|W|可见,上式方法中,X表示出了语言的标识符,而Y表示出了语言的无符号的十进制,Z表示出了语言中的十六进制。上式G(S)文法中,各式右边只有单个的终结符号显然,以上文法G(S)已是正规文法。(2)正规文法转成正规式:具体步骤如下:|M 可表示为M*|W可表示为W*|Z可表示为Z* 转换成正规表达式为:S=| * |H | *H |*代入可得:S= (|) | (|) (|)*(|) |H | (|)*(|)H |*(3)正规式转成NFA(分裂法)初始的NFA图下所示:图1初始NFA图经过替换规则替换后得到的最终NFA图如下所示:图2最
3、终的NFA图(4)NFA转成DFA及DFA最小化(造表法)对应以上的NFA图,我们可用造表法来表示如下:显然,由图可看出,状态2与状态5等价,而状态1与状态3等价,这里省去状态3和状态5,并将所以指向状态3的状态都指向状态1,指向状态5的都指向状态2。由此可画出最小化的DFA图如下:图3最小化的DFA图可见,终结状态1表示出了无符号的十进制,终结状态2表示出了标识符,状态6表示出了十六进制的整数。b、单词的BNF表示 -字母|下划线|无符号整数数字串 |加法运算符 +减法运算符 -大于关系运算符 大于等于关系运算符=由此可知,需将单词分为五种:关键字1标识符2常数3运算符4分隔符5printf
4、a+,mainb1_;intc2*(ifstudent3/)thensum4elsek5returnm6.789!(2)编码实现#include main(int argc,char *argv) int i,j,state,ERROR=-1; /* state控制状态的转移 1表示09数字, 2表示字母,4表示af,6表示H,0为未输入状态 * ERROR=-1表示未输入任何字符串 =1表示输入出错*/ char c; /* 暂时存放所取得的一个字符 */ char *string=,Unsigned IntegerIdentifierHex;/*输出结果时用*/ for(i=1;i0&ca
5、z)|(cAZ) state=2; else ERROR=1; break; /* ERROR=1,表示当前字符c为非法字符。 * 即此时无状态可转向。*/ case 1: else if(cfF) state=4; else if (c=H state=6; else ERROR=1; case 2: if(c case 4: else if(c= case 6: ERROR=1; /*end switch*/ if(ERROR=1) /* 退出内for的循环,完成一个词的分析。 /*end inside-for*/ if(ERROR=1) printf(%-15s is a un-iden
6、tify word!n,argvi); else if(ERROR=0)%-15s is a %sn,argvi,stringstate); /*end outside-for*/ /*未输入任何字符串时(除文件名外)*/ if(ERROR=-1) printf(You input nothing!); exit(0); /*正常退出程序*/*end main*/#includestdlib.hctype.h/定义关键字char *table7=continuemainintifthenelsereturn,TOKEN20,ch;bool zimu(char ch)/判断是否为字母 if(ch
7、ch return true; else return false;/判断是否为数字bool shuzi(char ch)int lookup(char *TOKEN) /关键字匹配函数,查询所述程序中的关键字 int m,i; for(i=0;6;i+) if(m=strcmp(TOKEN,tablei)=0) return 1; return 0;void out(int c,char *TOKEN) /输出函数 printf(%d,%s)n,c,TOKEN); void scanner(FILE *fp) /扫描函数 char TOKEN20= char ch; int i; ch=fg
8、etc(fp); /获取字符,指针fp并自动指向下一个字符 if(zimu(ch) /判断该字符是否是字母,若ch指的是字母,返回非0,否则返回0 TOKEN0=ch; ch=fgetc(fp); /fgetc(fp)从数据流中区下一个字符 i=1; while(shuzi(ch)| zimu(ch) /判断该字符是否是字母或数字 TOKENi=ch; ch=fgetc(fp); i+; fseek(fp,-1,1); if(lookup(TOKEN) /判断是关键字还是普通的标识符 out(1,TOKEN); else out(2,TOKEN); else if(shuzi(ch) TOKEN0=ch; while(shuzi(ch) /判断该字符是否是字母或数字 fseek(fp,-1,1); out
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1