分类:
2012-10-28 11:11:35
原文地址:Redy词法分析--浮点数的识别 作者:NosicLin
代码下载: 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中,这种格式不合法。
- floatnumber ::= pointfloat | exponentfloat
- pointfloat ::= [intpart] "." digit+
- exponentfloat ::= (intpart | pointfloat) exponent
- intpart ::= digit+
- exponent ::= ("e" | "E") ["+" | "-"] digit+
对于浮点数来说,可以把字符分为这么几类:
- 点号. (point)
- 数字0到9 (digit)
- 字母E和e (S_e)
- 符号+和- (sign)
- 除以上字符的所有字符 (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
浮点数的状态机总共有7个状态,每一个状态都会在某些输入类型下发生状态转移,状态链和状态矩阵的不同点在于,状态矩阵需要关心整个状态机的结构,而状态链方法中,每一个状态只需要关心自己的信息,而不用去了解整个状态机的结构。首先,我们对这七个状态进行申明,以便我们后面引用
- extern struct state ft_begin;
- extern struct state ft_frac_begin;
- extern struct state ft_int_part;
- extern struct state ft_fraction;
- extern struct state ft_exp_begin;
- extern struct state ft_exp_sign;
- extern struct state ft_exponent;
第二步,把用一个维数组来映射输入类型
- enum FLOAT_INPUT_TYPES
- {
- F_OTHER=0,
- F_DIGIT,
- F_POINT,
- F_SIGN,
- F_S_E,
- F_INPUT_NUM,
- };
- char float_type_map[ASCII_NUM]=
- {
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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
- };
第三步,为每一个状态编写状态链a)状态FloatBegin在输入类型point下转移到FractionBegin,在输入类型digit下转移到状态IntPart,
- struct state* ft_begin_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_int_part, /*F_DIGIT*/
- &ft_frac_begin, /*F_POINT*/
- &lex_state_err, /*F_SIGN*/
- &lex_state_err, /*F_S_E*/
- };
- struct state ft_begin=
- {
- "ft_begin",
- TOKEN_UNKOWN,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_begin_targets,
- 0,
- };
b)状态FractionBegin在输入类型Digit下转移到状态Fraction
- /*ft_frac_begin*/
- struct state* ft_frac_begin_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_fraction, /*F_DIGIT*/
- &lex_state_err, /*F_POINT*/
- &lex_state_err, /*F_SIGN*/
- &lex_state_err, /*F_S_E*/
- };
- struct state ft_frac_begin=
- {
- "ft_fraction",
- TOKEN_UNKOWN,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_frac_begin_targets,
- 0,
- };
c)状态IntPart在输入类型digit转移到自身,输入类型point下转移到状态FractionBegin,输入类型S_e下转移到ExponentBegin
- /*ft_int_part*/
- struct state* ft_int_part_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_int_part, /*F_DIGIT*/
- &ft_frac_begin, /*F_POINT*/
- &lex_state_err, /*F_SIGN*/
- &ft_exp_begin, /*F_S_E*/
- };
- struct state ft_int_part=
- {
- "ft_int_part",
- TOKEN_UNKOWN,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_int_part_targets,
- 0,
- };
d)状态Fraction在输入digit下转移到自身,在输入类型S_e转移到ExponentBegin,并且Fraction为终态。
- struct state* ft_fraction_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_fraction, /*F_DIGIT*/
- &lex_state_err, /*F_POINT*/
- &lex_state_err, /*F_SIGN*/
- &ft_exp_begin, /*F_S_E*/
- };
- struct state ft_fraction=
- {
- "float",
- TOKEN_FLOAT,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_fraction_targets,
- 1,
- };
e)状态ExponentBegin在输入类型digit下转移到Exponent,在输入类型sign下转移到状态ExponentSymbol
- struct state* ft_exp_begin_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_exponent, /*F_DIGIT*/
- &lex_state_err, /*F_POINT*/
- &ft_exp_sign, /*F_SIGN*/
- &lex_state_err, /*F_S_E*/
- };
- struct state ft_exp_begin=
- {
- "ft_exp_beign",
- TOKEN_UNKOWN,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_exp_begin_targets,
- 0,
- };
f)状态ExponentSymbol在输入类型Digit下转移到状态Exponent
- struct state* ft_exp_sign_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_exponent, /*F_DIGIT*/
- &lex_state_err, /*F_POINT*/
- &lex_state_err, /*F_SIGN*/
- &lex_state_err, /*F_S_E*/
- };
- struct state ft_exp_sign=
- {
- "ft_exp_sign",
- TOKEN_UNKOWN,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_exp_begin_targets,
- 0,
- };
g)状态Exponent在输入类型Digit下转移到自身,并且该状态同时也为终态
- /*ft_exponent*/
- struct state* ft_exponent_targets[]=
- {
- &lex_state_err, /*F_OTHER*/
- &ft_exponent, /*F_DIGIT*/
- &lex_state_err, /*F_POINT*/
- &lex_state_err, /*F_SIGN*/
- &lex_state_err, /*F_S_E*/
- };
- struct state ft_exponent=
- {
- "exp_float",
- TOKEN_EXP_FLOAT,
- F_INPUT_NUM,
- float_type_map,
- 0,
- ft_exponent_targets,
- 1,
- };
到现在为止,我们已经完成了状态链的制作,把状态FloatBegin找入我们的驱动程序,就可以识别浮点数了。(6)运行结果
状态链识别方法的程序在tutorial/lexical/sl_float下面,具体的运行结果如下
状态矩阵识别浮点数程序大家可以在tutorial/lexical/float下面找到。
返回文档首页