Chinaunix首页 | 论坛 | 博客
  • 博客访问: 319849
  • 博文数量: 32
  • 博客积分: 424
  • 博客等级: 准尉
  • 技术积分: 465
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-02 10:23
文章分类

全部博文(32)

文章存档

2012年(32)

分类: Python/Ruby

2012-03-02 14:25:21


代码下载: git clone git://git.code.sf.net/p/redy/code redy-code
这一章内容有:
用状态链的方法识别浮点数
用状态矩阵的方法识别浮点数


(1)简介
在Redy中符点数有下这么几种写法,例如:0.126,.2445,6854.557,155E78,455e47,0.254e78,0.147e-45,0.24E-36,255.E56
在有一些语言中,整数后面跟一个点号,例如  535.  是合法的浮点数,但是在Redy中,这种格式不合法。
(2)BNF文法
  1. floatnumber ::= pointfloat | exponentfloat
  2. pointfloat ::= [intpart] "." digit+
  3. exponentfloat ::= (intpart | pointfloat) exponent
  4. intpart ::= digit+
  5. exponent ::= ("e" | "E") ["+" | "-"] digit+
(3)状态图
(4)状态矩阵
对于浮点数来说,可以把字符分为这么几类:
  1. 点号.     (point)
  2. 数字0到9   (digit)
  3. 字母E和e   (S_e)
  4. 符号+和-    (sign)
  5. 除以上字符的所有字符  (other)
状态矩阵为:

状态\输入

Other

Digit

Point

Sign

S_e

FloatBegin


IntPart

FracBegin



FracBegin


Fraction




IntPart


IntPart

FracBegin


ExpBegin

Fraction


Fraction



ExpBegin

ExpBegin


Exponent


ExpSymbol


ExpSymbol


Exponent




Exponent


Exponent





其中开始状态为FloatBegin,终态为Fraction,Exponent
(5)程序数据--状态链
浮点数的状态机总共有7个状态,每一个状态都会在某些输入类型下发生状态转移,状态链和状态矩阵的不同点在于,状态矩阵需要关心整个状态机的结构,而状态链方法中,每一个状态只需要关心自己的信息,而不用去了解整个状态机的结构。
首先,我们对这七个状态进行申明,以便我们后面引用
  1. extern struct state ft_begin;
  2. extern struct state ft_frac_begin;
  3. extern struct state ft_int_part;
  4. extern struct state ft_fraction;
  5. extern struct state ft_exp_begin;
  6. extern struct state ft_exp_sign;
  7. extern struct state ft_exponent;
第二步,把用一个维数组来映射输入类型
  1. enum FLOAT_INPUT_TYPES
  2. {
  3.     F_OTHER=0,
  4.     F_DIGIT,
  5.     F_POINT,
  6.     F_SIGN,
  7.     F_S_E,
  8.     F_INPUT_NUM,
  9. };

  10. char float_type_map[ASCII_NUM]=
  11. {
  12.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  13.     0,0,0,0,0,0,0,0,0,0,0,3,0,3,2,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
  14.     0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  15.     0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  16.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  17.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  18.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  19.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  20. };
第三步,为每一个状态编写状态链

a)状态FloatBegin在输入类型point下转移到FractionBegin,在输入类型digit下转移到状态IntPart,
  1. struct state* ft_begin_targets[]=
  2. {
  3.     &lex_state_err,        /*F_OTHER*/
  4.     &ft_int_part,        /*F_DIGIT*/
  5.     &ft_frac_begin,        /*F_POINT*/
  6.     &lex_state_err,        /*F_SIGN*/
  7.     &lex_state_err,        /*F_S_E*/
  8. };
  9. struct state ft_begin=
  10. {
  11.     "ft_begin",
  12.     TOKEN_UNKOWN,
  13.     F_INPUT_NUM,
  14.     float_type_map,
  15.     0,
  16.     ft_begin_targets,
  17.     0,
  18. };
b)状态FractionBegin在输入类型Digit下转移到状态Fraction
  1. /*ft_frac_begin*/
  2. struct state* ft_frac_begin_targets[]=
  3. {
  4.     &lex_state_err,        /*F_OTHER*/
  5.     &ft_fraction,        /*F_DIGIT*/
  6.     &lex_state_err,        /*F_POINT*/
  7.     &lex_state_err,        /*F_SIGN*/
  8.     &lex_state_err,        /*F_S_E*/
  9. };
  10. struct state ft_frac_begin=
  11. {
  12.     "ft_fraction",
  13.     TOKEN_UNKOWN,
  14.     F_INPUT_NUM,
  15.     float_type_map,
  16.     0,
  17.     ft_frac_begin_targets,
  18.     0,
  19. };

c)状态IntPart在输入类型digit转移到自身,输入类型point下转移到状态FractionBegin,输入类型S_e下转移到ExponentBegin
  1. /*ft_int_part*/
  2. struct state* ft_int_part_targets[]=
  3. {
  4.     &lex_state_err,        /*F_OTHER*/
  5.     &ft_int_part,        /*F_DIGIT*/
  6.     &ft_frac_begin,        /*F_POINT*/
  7.     &lex_state_err,        /*F_SIGN*/
  8.     &ft_exp_begin,        /*F_S_E*/
  9. };
  10. struct state ft_int_part=
  11. {
  12.     "ft_int_part",
  13.     TOKEN_UNKOWN,
  14.     F_INPUT_NUM,
  15.     float_type_map,
  16.     0,
  17.     ft_int_part_targets,
  18.     0,
  19. };

d)状态Fraction在输入digit下转移到自身,在输入类型S_e转移到ExponentBegin,并且Fraction为终态。
  1. struct state* ft_fraction_targets[]=
  2. {
  3.     &lex_state_err,        /*F_OTHER*/
  4.     &ft_fraction,        /*F_DIGIT*/
  5.     &lex_state_err,        /*F_POINT*/
  6.     &lex_state_err,        /*F_SIGN*/
  7.     &ft_exp_begin,        /*F_S_E*/
  8. };
  9. struct state ft_fraction=
  10. {
  11.     "float",
  12.     TOKEN_FLOAT,
  13.     F_INPUT_NUM,
  14.     float_type_map,
  15.     0,
  16.     ft_fraction_targets,
  17.     1,
  18. };

e)状态ExponentBegin在输入类型digit下转移到Exponent,在输入类型sign下转移到状态ExponentSymbol
  1. struct state* ft_exp_begin_targets[]=
  2. {
  3.     &lex_state_err,        /*F_OTHER*/
  4.     &ft_exponent,        /*F_DIGIT*/
  5.     &lex_state_err,        /*F_POINT*/
  6.     &ft_exp_sign,        /*F_SIGN*/
  7.     &lex_state_err,        /*F_S_E*/
  8. };
  9. struct state ft_exp_begin=
  10. {
  11.     "ft_exp_beign",
  12.     TOKEN_UNKOWN,
  13.     F_INPUT_NUM,
  14.     float_type_map,
  15.     0,
  16.     ft_exp_begin_targets,
  17.     0,
  18. };

f)状态ExponentSymbol在输入类型Digit下转移到状态Exponent
  1. struct state* ft_exp_sign_targets[]=
  2. {
  3.     &lex_state_err,        /*F_OTHER*/
  4.     &ft_exponent,        /*F_DIGIT*/
  5.     &lex_state_err,        /*F_POINT*/
  6.     &lex_state_err,        /*F_SIGN*/
  7.     &lex_state_err,        /*F_S_E*/
  8. };
  9. struct state ft_exp_sign=
  10. {
  11.     "ft_exp_sign",
  12.     TOKEN_UNKOWN,
  13.     F_INPUT_NUM,
  14.     float_type_map,
  15.     0,
  16.     ft_exp_begin_targets,
  17.     0,
  18. };

g)状态Exponent在输入类型Digit下转移到自身,并且该状态同时也为终态
  1. /*ft_exponent*/
  2. struct state* ft_exponent_targets[]=
  3. {
  4.     &lex_state_err,        /*F_OTHER*/
  5.     &ft_exponent,        /*F_DIGIT*/
  6.     &lex_state_err,        /*F_POINT*/
  7.     &lex_state_err,        /*F_SIGN*/
  8.     &lex_state_err,        /*F_S_E*/
  9. };
  10. struct state ft_exponent=
  11. {
  12.     "exp_float",
  13.     TOKEN_EXP_FLOAT,
  14.     F_INPUT_NUM,
  15.     float_type_map,
  16.     0,
  17.     ft_exponent_targets,
  18.     1,
  19. };

到现在为止,我们已经完成了状态链的制作,把状态FloatBegin找入我们的驱动程序,就可以识别浮点数了。
(6)运行结果
状态链识别方法的程序在tutorial/lexical/sl_float下面,具体的运行结果如下
状态矩阵识别浮点数程序大家可以在tutorial/lexical/float下面找到。


返回文档首页






阅读(2473) | 评论(3) | 转发(1) |
给主人留下些什么吧!~~

图片MM2012-03-19 01:41:29

NosicLin: 后面我还会继续更新,直到实现一门面向对象的脚本语言.....
( ^_^ )不错嘛,加油~

NosicLin2012-03-03 09:21:46

图片MM: 恩,不错的系列博文!.....
后面我还会继续更新,直到实现一门面向对象的脚本语言

图片MM2012-03-03 00:44:32

恩,不错的系列博文!