无符号实数的识别

例,文法G[<无符号数>],若把非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>分别用编号0,1,2,……6代表,并用1,2和6代表终态,则按上述方法所构造的状态转换图如图1所示。

对于文法G[<无符号数>]的状态图1,可按表1的形式来存放其状态矩阵。表中,第一列为各状态的编号,第二列分别列出了在每一状态下可扫视到的输入字符(其中“other”是一个集合符号,用来表示在相应状态所属的那一栏中,除其前所列字符之外的全部其它字符),第三列指出当(Si,ai)出现时应执行的语义动作(通常用若干个语句来实现,若其为空,则表示不进行任何处理),最后一栏用来指明下一状态的编号(若其为NULL或“结束”则表示无后继状态)。

表1 识别无符号数的状态矩阵

当前状态 0 扫视字符 d · other d · E other d E Other d Other d + - other d other d other 语义处理操作或接受动作 {n=0;p=0;e=1;w=d} { W=0;n=0;p=0;e=1} 识别失败 {w=w*10+d} {回送整常数ICON=w} {n++;w=w*10+d} {回送实常数FCON=w-pow(10,e-p-n)} {n++;w=w*10+d;} 识别失败 {p=p*10+d} {e=-1;} 识别失败 {p=p*10+d;} 识别失败 {p=p*10+d;} {回送实常数FCON=w*pow (10,e*p-n)} 1

图 1文法G[<无符号数>]的状态转换图

后继状态 1 3 NULL 1 2 4 结束 2 4 结束 2 NULL 6 5 5 NULL 6 NULL 6 结束 1 2 3 4 5 6

在状态矩阵(表3-1)中所嵌入的语义动作,其功能是在扫描源程序字符串的过程中,把识别出的字符串形式的无符号数,逐步转换为相应的二进制整数(ICON)或二进制实数(FCON)的内部形式,方法如下。

设无符号数有如下的一般形式

dmdm-1…d1d0·d-11d-2…d-nE±dd…d

或改写为

dmdm-1…d1d0·d-11d-2…d-n×10±dd…d-n

并引入下面的变量:

w —尾数累加器(初值为0)

p —指数累加器(初值为0)

n —十进制小数位数计数器(初值为0,当扫视到小数点后的数字时开始计数);

e —用来记录十进制指数的符号(初值为1,当遇到E后的负号时再改为-1)。

利用上述变量,可将一个无符号数写成

N=w*10e*p-n

其中

w=(…((dm*10+dm-1)*10+dm+2)*10+…)10+d-n

p=(…(d*10+d)*10+d…)*10+d

于是,语义加工可按如下的步骤进行:

1.处理整数部分 当遇到小数后的每一位数字d时,做

w=w*10+d

2.处理十进制小数部分 当遇到小数后的每一位数字d时,做

w=w*10+d n=n+1

3.处理指数部分

(1)若扫视到E之后的负号,做

e=-1

2

(2)当扫视到十进制指数中的每一位数字时,做

p=p*10+d

4.在识别程序的出口(即下一状态为终态时),按公式

ICON=w

FCON=w *10e*p-n

分别计算和回送无符号数的二进制整数和二进制浮点数的内部表示,然后退出识别程序。

据此,可写出识别无符号数的程序如程序3-3所示。

程序3-3 无符号数的识别程序

1 #include<stdio. h> 2 #include<ctype. h> 3 #include<math. h> 4 #define LETTER 0 5 #define DIGIT 1 6 #define POINT 2 7 #define OTHER 3 8 #define POWER 4 9 #definePLUS 5 10 #defineMINUS 6

11 #defineClassNo100 //Suppose the class of number is 100 12 #define ClassOther 200 13 #define EndState -1 14 int w, n, p, e, d;

15 int Class; //Used to indicate class of the word 16 int ICON; 17 float FCON;

18 static int CurrentState; //Used to present current state, the initial value:0 19

3

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4