【问题标题】:yytext contains characters not in matchyytext 包含不匹配的字符
【发布时间】:2016-02-25 16:30:50
【问题描述】:

背景

我正在使用 flex 为我正在实现的编程语言生成词法分析器。

我对标识符的这条规则有一些问题:

[a-zA-Z_][a-zA-Z_0-9]* {
    printf("yytext is %s\n", yytext);    
    yylval.s = yytext;
    return TOK_IDENTIFIER;
}

当我的解析器解析这样的表达式时,该规则会正常工作:

var0 = var1 + var2;

printf 语句将打印出以下内容:

yytext is 'var0'
yytext is 'var1'
yytext is 'var2'

这是应该的。

问题

但是当我的解析器解析这样的函数声明时:

func(array[10] type, arg2 wef, arg3 afe);

现在printf 语句将打印:

yytext is 'array['
yytext is 'arg2 wef'
yytext is 'arg3 afe'

问题是yytext 包含不匹配的字符。

问题

flex 为什么在yytext 中包含这些字符,我该如何解决这个问题?

【问题讨论】:

    标签: regex string match flex-lexer lex


    【解决方案1】:

    我看不出你的词法分析器是如何产生该输出的,但很容易看出它是如何在你的解析器中产生的。

    基本上保留yytext的值是不正确的:

    yylval.s = yytext;  /* DON'T DO THIS */
    

    实际上,这是一个悬空指针,因为yytext 指向词法分析器框架内的私有内存,并且该指针仅在下次调用词法分析器时才有效。由于解析器通常需要在执行归约操作之前查看下一个输入标记,因此几乎可以肯定,在执行操作时,生产中每个终端的s 成员中的指针已经失效。

    如果你想保留yytext所指向的token的字符串值,你必须复制它:

    yylval.s = strdup(yytext);
    

    然后您将负责在不再需要时释放该副本。

    【讨论】:

    • 这很可能是问题所在,但事实并非如此。我的解析器中有strdup 代码来避免这个问题。我描述的输出直接来自代码示例中的printf 语句。我不知道出了什么问题,但yytext 在匹配规则后立即出错。中间没有代码。
    • 啊!我知道了。问题是我在解析器中有strdup 代码。因为解析器需要向前读取一个标记,所以下一个标记也包含在我之前的字符串中 strdup 它!谢谢你。这帮助我解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-06-02
    • 2022-11-19
    • 2019-04-24
    • 2010-11-22
    • 2020-12-25
    • 2019-05-12
    • 2010-11-22
    • 2019-06-05
    相关资源
    最近更新 更多