Bison 保持十六进制数字和只有A-F的文本分开

Bison 保持十六进制数字和只有A-F的文本分开,bison,flex-lexer,Bison,Flex Lexer,在其他更具体和无问题的规则中,我有以下lexer规则: [a-zA-Z][a-zA-Z0-9]+ { yylval.string = strdup(yytext); return FILENAME; } /* 32-bit numbers */ [a-fA-F0-9]{1,8} { std::stringstream ssh; ssh << std::hex << yytext; ssh >> yylval.u32.

在其他更具体和无问题的规则中,我有以下lexer规则:

[a-zA-Z][a-zA-Z0-9]+ {
    yylval.string = strdup(yytext);
    return FILENAME;
}

 /* 32-bit numbers */
[a-fA-F0-9]{1,8} {
    std::stringstream ssh;
    ssh << std::hex << yytext;
    ssh >> yylval.u32.hex;
    std::stringstream ssd;
    ssd << std::dec << yytext;
    ssd >> yylval.u32.dec;
    return NUMBER;
}
然后我将有一个更聪明的解析器,检查初始alpha,并使用正确的struct字段


这是一个共同的妥协吗?这感觉是错误的,而且词法的自由度越高,我肯定我会制造一些我没有测试过的漏洞,这些漏洞要么会失败,要么会捕获太多。我将不必要地将大量字符串(如“hello”)转换为
hex
dec
值。

我将对dec和hex进行区分,比如hexnumber和decnumber,但是纯粹基于上下文,您必须定义一些约束,例如文件名必须至少使用9个字符,因为这不是有效的32位十六进制。

通常的方法是对可能出现的不同类别的标记使用不同的flex规则,对于可能是两种不同的东西使用a或B标记:

[0-9]+ {
    yylval.u32 = strtol(yytext, 0, 10);
    return NUMBER; }
[a-fA-F][a-fA-F0-9]* {
    yylval.string = strdup(yytext);
    return NUMBER_OR_NAME; }
[a-fA-F0-9]+ {
    yylval.u32 = strtol(yytext, 0, 16);
    return NUMBER; }
[a-zA-Z][a-zA-Z0-9]* {
    yylval.string = strdup(yytext);
    return NAME; }
Flex将始终尝试匹配最长的匹配,但当多个模式匹配相同的长度时,它将匹配第一个

在解析器中,可以使用如下规则:

name: NAME | NUMBER_OR_NAME ;

number: NUMBER | NUMBER_OR_NAME { $$ = strtol($1, 0, 16); free($1); } ;

如果十六进制数
face
在某些上下文中是不明确的,那么这不仅会让你的词法分析器感到困惑。这也会让你的用户感到困惑。(另外,将文件名限制为字母开头的字母数字似乎有点不自由,但我想您对其他文件名还考虑了一些其他语法。)谢谢,这会让事情变得更清楚。我会尝试一下。如果我定义语法,我会要求字符串被引用,十六进制数字的前缀是0x,等等。。。但不幸的是,这不是我的语法来定义的。:)
name: NAME | NUMBER_OR_NAME ;

number: NUMBER | NUMBER_OR_NAME { $$ = strtol($1, 0, 16); free($1); } ;