考虑在词法分析中,识别一个数串:该串可以以任何数字前导,但必须以非零数字结束。生成该数串的文法可以表示为:G=({S,D,U},{0,1,2,3,4,5,6,7,8,9},P,S) ,其中P由下列产生式组成:
S→DS|U
U→1|2|3|4|5|6|7|8|9
D→0|U
或可描述为正则表达式:D*U,其中*标表示可由任意多个字符组成。
很简单不是吗?
但存在一个问题:在编程中,任何可以被该正则表达式识别的句子,其所有字符都将在循环中被D吃掉,而U就被活活饿死。为了使识别奏效,可以使用如下方案:
【方案1】 c=buffer.getc(); //从缓存中取得字符c
//D*
while(D(c)) //判断c是否满足D的规则,也即c是否在{0,1,2,3,4,5,7,8,9}中
c=buffer.getc(); //从缓存取得下一个字符
//U
if(U(buffer.last())) //判断缓存中的上一个字符是否满足U的规则,即c是否在{1,2,3,4,5,6,7,8,9}中
c=buffer.getc();
else
return false; //匹配不成功
return true; //匹配成功
挺简洁地解决了问题,但怎么觉得那么别扭呢?不妨换几个标识符看看:
c=stomach.eat(); //吃一个字符
//D*
while(D(c))
c=stomach.eat(); //不停地吃
//U
if(U(stomach.vomit())) //吐出来看看
c=stomach.eat(); //接着吃……
else
return false;
return true;
呃,好恶心……