免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5473 | 回复: 9
打印 上一主题 下一主题

请教大家一下用Lex怎么识别字符串? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-18 18:42 |只看该作者 |倒序浏览
以"开始,以"结束,中间任何字符都合法,包括""、" "、"\n"、"\t"......
我不知道,试了几个都不行。
比如:\"[^"]\",就匹配不了,向大家请教一下。

论坛徽章:
0
2 [报告]
发表于 2007-07-19 08:41 |只看该作者
没办法,用了个最苯的办法:

  1. \"  {count(); is_str(); return STRING;}

  2. is_str()
  3. {
  4. char ch, c[255];
  5. bzero(&c, strlen(c));
  6. int i;
  7. for (i=0; (ch=input()) != '"'; i++)
  8.   c[i]=ch;
  9. yytokval.strval=c;
  10. }
复制代码


俺比较愚笨,望大家拿出更好的方法。

论坛徽章:
0
3 [报告]
发表于 2007-07-19 10:05 |只看该作者
不好意思,昨天太晕了。

更好一点点的方法:

  1. \"[^"]*\"  {count(); is_str(); return STRING;}

  2. is_str()
  3. {
  4. int nu;
  5. char c[nu-2];
  6. nu=strlen(yytext);

  7. int i;
  8. for (i=1; i<nu-1; i++)
  9.   c[i-1]=yytext[i];
  10. yyltok.strval=c;
  11. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2007-07-19 12:50 |只看该作者
下面这个如何:
%x string

\"                                             { BEGIN(string); }
<string>[^\n]\"\n                      { BEGIN(INITIAL); }

论坛徽章:
0
5 [报告]
发表于 2007-07-19 15:28 |只看该作者
原帖由 bilbo0214 于 2007-7-19 12:50 发表
下面这个如何:
%x string

\"                                             { BEGIN(string); }
[^\n]\"\n                      { BEGIN(INITIAL); }


不太明白,请问{ BEGIN(string); }和{ BEGIN(INITIAL); }是Lex提供的函数吗?

论坛徽章:
0
6 [报告]
发表于 2007-07-19 18:51 |只看该作者
可以看一下Lex&Yacc这本书。
BGIN相当于LEX提供的函数,这个与处理注释的方法是一致的。

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2007-07-20 13:38 |只看该作者
原帖由 prolj 于 2007-7-19 15:28 发表


不太明白,请问{ BEGIN(string); }和{ BEGIN(INITIAL); }是Lex提供的函数吗?

lex提供,表示状态转移,INITIAL表示默认状态。

论坛徽章:
0
8 [报告]
发表于 2007-08-01 11:21 |只看该作者
原帖由 prolj 于 2007-7-18 18:42 发表
以"开始,以"结束,中间任何字符都合法,包括""、" "、"\n"、"\t"......
我不知道,试了几个都不行。
比如:\"[^"]\",就匹配不了,向大家请教一下。

我用的是:    \"[^"]*\"  
用了很多年了,没有问题啊.

论坛徽章:
0
9 [报告]
发表于 2007-08-01 12:32 |只看该作者
\"[^"]*\"  
有可能会导致lex缓冲区溢出,对于小应用很少出现这种情况,可以如果字符串很长很长的话就会出现问题。

论坛徽章:
0
10 [报告]
发表于 2007-08-02 03:18 |只看该作者
原帖由 bilbo0214 于 2007-8-1 12:32 发表
\"[^"]*\"  
有可能会导致lex缓冲区溢出,对于小应用很少出现这种情况,可以如果字符串很长很长的话就会出现问题。

晕,你说的是两个不同的问题啊. LZ问的是STRING的正则表达式如何定义的问题. 而你说的是扫描出来的词很大时如何缓存和传出的问题,这根本是两码事啊.
对于你说的问题,如果字符串很长的情况,你完全可以定义自已的YYSTYPE类型,预先从堆分配足够的针对单个NODE的值保存对象的方式来解决啊.例如我就是这样定义的:
struct NodeVal {
        NodeVal() { val = new char[OUTBUFMAX]; val[0]=0; type=0; len=0;}
        ~NodeVal() { if (val != NULL) delete[] val; }
       
        NodeVal& operator=(const NodeVal& rhs)
        {
                if ( this != &rhs )
                {
                        memcpy(this->val, rhs.val, rhs.len); this->val[rhs.len] = 0;
                        this->len = rhs.len;
                        this->type = rhs.type;
                }
                return *this;
        }

        char* val;
}

#define YYSTYPE NodeVal
解释时,保存值的内存就是你自已分配的了,不会占用lex的缓冲, 其中OUTBUFMAX是你要预计的最大的字符串大小,需要你提前定义.

使用时,我是这样使用的
\"[^"]*\" {
                memcpy(yylval->val, yytext+1, yyleng-2);
                yylval->len = yyleng-2;
                yylval->val[yylval->len] = 0;
                yylval->type = T_STRING;
                return STRING;
        }

当然,你完全可以加上判断,如果yyleng大于outbufmax时,报错终止解析.

[ 本帖最后由 zszyj 于 2007-8-2 03:20 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP