yyless与yymore

这两个函数可以轻松地帮我们将词法分析器改为LALR(n)的词法分析器。

  1. yymore()
    yymore函数是指,将下次分析的结果词汇,接在当前yytext的后面,而不是替换已有内容。(当前已有内容并不会影响下次分析)
    比如如下代码:

    %x xdquote
    \" { BEGIN(xdquote); }
    <xdquote>[^"]+ { yymore(); }
    <xdquote>\"\" { yymore(); }
    <xdquote>\" { yylval->str = yytext; BEGIN(INITIAL); return STRING; }
    

    那么对于字符串"a""b",首先根据第一条规则匹配引号,进入xdquote模式。然后a匹配第二条规则,此时使用了yymore,因此接下来的两个引号匹配到第三条规则之后,此时的yytext不是"",而是a"",即匹配到的两个引号不是替换原有的a,而是接在了后面。同样,接下来匹配到的b以及最后的"同样接在了原本的yytext后面。所以最后返回时yytext中为a""b"(这里有个问题,那就是最后的引号会匹配进来,可以使用接下来的yyless或者其他方法来去掉最后的引号)。

  2. yyless(n)
    这个函数是将yytext中除了前n个字符以外的字符,重新放回输入流里进行重新匹配。说起来比较拗口,但是看一下代码应该就能明白了。
    比如PGSQL中,对于WTIH关键词,有不同的解析(这里不是源代码,而是另一种实现):

    %x xwith
    [Tt][Ii][Mm][Ee] { yylval->str = yytext; return TIME; }
    [Ww][Ii][Tt][Hh] { BEGIN(xwith); yymore(); }
    <xwith>[ \t\n\r\f]+ { yymore(); }
    <xwith>[Tt][Ii][Mm][Ee] {
    		yyless(yyleng - 4);
    		BEGIN(INITIAL);
    		return WITH_LA;
    	}
    <xwith>. {
    		yyless(4);
    		yylval->str = yytext;
    		BEGIN(INITIAL);
    		return WITH;
    	}
    

    这里匹配到WITH关键词后,并不直接返回,而是往后看,看看下一个词是什么。如果是TIME,那么就返回一个WITH_LA的token。同时将最后的四个字符time放回输入流中重新进行匹配。如果是其他的,那么只保留最开始的四个字符,也就是WITH,将其他的全部放回输入流中重新进行匹配。并将字符串WITH以及一个WITH token返回。

    这样,对于字符串WITH TIME,这个词法分析器就会返回WITH_LA和TIME两个token。

    另外这里需要注意的是,yymore()和yyless(0)配合,很容易产生死循环。一定要注意。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值