FLEX代码中无效输入被拆分识别,无法判定为无效的问题求助
问题分析与解决方案
你的问题根源在于Flex的最长匹配规则:Flex会从当前扫描位置开始,匹配最长的符合规则的字符序列,然后返回对应的token。对于12abc,它会先匹配到最长的合法整数12,剩下的abc又符合标识符规则,因此被拆分成两个合法token返回,而非判定为整体无效。
要实现“输入串必须是单一合法token(或空白分隔的合法token)”的需求,分两种场景处理:
场景1:按行输入单个token
如果你的需求是每行输入一个token,要求整行内容必须完全符合标识符或整数的定义,否则判定为无效,可以通过正则锚点^(行首)和$(行尾)实现:
修改后的testProg.l代码:
%{ #define IDENTIFIER 10 #define INTEGER 11 #define INVALID 12 %} /* 整行匹配标识符:行首到行尾完全符合规则 */ IDENTIFIER ^[a-zA-Z_][a-zA-Z0-9_]*$ /* 整行匹配整数:支持0或非0开头的数字序列 */ INTEGER ^(0|[1-9][0-9]*)$ /* 匹配任何不符合规则的整行内容 */ INVALID_LINE .* %% {IDENTIFIER} { return IDENTIFIER; } {INTEGER} { return INTEGER; } {INVALID_LINE} { return INVALID; } \n { /* 忽略换行符,避免被判定为无效 */ } %% int main() { int token; while((token = yylex()) != 0) { if(token == IDENTIFIER) { printf("IDENTIFIER\n"); } else if(token == INTEGER) { printf("INTEGER\n"); } else if(token == INVALID) { printf("INVALID\n"); } } return 0; }
此时输入12abc整行,会直接触发INVALID_LINE规则,输出INVALID;输入sample或1993则正常返回对应类型。
场景2:空白分隔的多个token
如果需要支持一行内输入多个用空格/制表符分隔的token,每个token单独判定合法性,可以通过匹配非空白字符序列的规则处理无效token:
修改后的testProg.l代码:
%{ #define IDENTIFIER 10 #define INTEGER 11 #define INVALID 12 %} /* 匹配空白符:空格、制表符、换行 */ WS [ \t\n]+ /* 标识符规则 */ IDENTIFIER [a-zA-Z_][a-zA-Z0-9_]* /* 整数规则 */ INTEGER 0|[1-9][0-9]* /* 匹配任何非空白的无效字符序列 */ INVALID_TOKEN [^ \t\n]+ %% {WS} { /* 忽略空白符,不返回token */ } {IDENTIFIER} { return IDENTIFIER; } {INTEGER} { return INTEGER; } {INVALID_TOKEN} { return INVALID; } %% int main() { int token; while((token = yylex()) != 0) { if(token == IDENTIFIER) { printf("IDENTIFIER "); } else if(token == INTEGER) { printf("INTEGER "); } else if(token == INVALID) { printf("INVALID "); } } printf("\n"); return 0; }
此时输入12abc sample 123,会输出INVALID IDENTIFIER INTEGER ,其中12abc被整体判定为无效token。
内容的提问来源于stack exchange,提问作者Geeky Quentin
相关产品推荐
相关产品推荐

