You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LEX正则表达式匹配问题:程序结果异常且无法终止求助

LEX正则匹配不符合预期且程序无法终止的问题排查与解决

我用LEX编写正则定义,需要匹配以下模式并输出对应行:

  • 匹配以d开头、以t结尾的任意字符串
  • 匹配字符串def
  • 匹配一个或多个ab连接的字符串
  • 匹配一个或多个不含大写字母A-Z的字符组成的字符串

但程序输出不符合预期,还无法终止。以下是我的C代码:

%{
    #include <stdio.h>
%}

%%

def {
    printf("Matched 'def' string: %s\n", yytext);
}

d.*t {
    printf("Matched 'd...t' string: %s\n", yytext);
}

(ab)+ {
    printf("Matched 'ab' concatenated: %s\n", yytext);
}

[^A-Z]+ {
    printf("Matched string (no uppercase A-Z): %s\n", yytext);
}

%%

int main(int argc, char* argv[]){
    printf("Enter the string:\n");
    yylex();  // Start lexical analysis
    return 0;
}

int yywrap(){
    return 1;
}

执行后的输出如下:

PS C:\CODE\CST302-Compiler-Principles\Lab3\Q2> flex Q2.l
PS C:\CODE\CST302-Compiler-Principles\Lab3\Q2> g++ lex.yy.c
PS C:\CODE\CST302-Compiler-Principles\Lab3\Q2> ./a

Enter the string:
dooot def abc abab ABCd
Matched string (no uppercase A-Z): dooot def abc abab
ABC

abc

问题原因分析

  1. 正则匹配规则冲突
    LEX遵循最长匹配+先定义先匹配的优先级规则:

    • [^A-Z]+匹配范围过于宽泛,会优先匹配所有不含大写字母的长串(比如dooot def abc abab),导致更具体的def、(ab)+无法触发。
    • d.*t是贪婪匹配,.*会匹配包括换行在内的任意字符,若输入无t则完全不触发,且位置在def之后,会覆盖def的匹配(如果def处于d开头t结尾的串中)。
  2. 未匹配字符导致程序无法终止
    当输入出现大写字母(如ABCd中的ABC),现有正则无法匹配,LEX会默认将未匹配字符直接输出到标准输出,同时持续等待新输入,导致程序无法自动终止。

  3. 正则写法不严谨
    d.*t未限制单行匹配,会跨多行贪婪匹配,不符合常规的单行匹配需求。


修正方案

调整正则顺序(优先匹配具体模式)、修正正则写法、添加未匹配字符处理规则:

修正后的代码

%{
    #include <stdio.h>
%}

%%

// 最具体的模式放在最前面
def {
    printf("Matched 'def' string: %s\n", yytext);
}

// 限制单行内d开头t结尾的匹配,避免跨多行
d[^\n]*t {
    printf("Matched 'd...t' string: %s\n", yytext);
}

// 匹配连续ab组合
(ab)+ {
    printf("Matched 'ab' concatenated: %s\n", yytext);
}

// 匹配不含大写和换行的字符,避免跨多行
[^A-Z\n]+ {
    printf("Matched string (no uppercase A-Z): %s\n", yytext);
}

// 处理大写字母串,避免默认输出
[A-Z]+ {
    printf("Matched uppercase string: %s\n", yytext);
}

// 单独处理换行,避免被无大写规则匹配
\n {
    // 可留空或自定义换行处理逻辑
}

// 处理单个未匹配的特殊字符
. {
    printf("Unmatched character: %c\n", *yytext);
}

%%

int main(int argc, char* argv[]){
    printf("Enter the string:\n");
    yylex();
    return 0;
}

int yywrap(){
    return 1;
}

修正说明

  1. 正则优先级调整:将def、(ab)+等具体模式放在前面,确保优先匹配,避免被宽泛规则覆盖。
  2. 限制单行匹配:把d.*t改为d[^\n]*t,[^A-Z]+改为[^A-Z\n]+,避免跨多行匹配。
  3. 处理未匹配字符:添加[A-Z]+和.的匹配规则,解决LEX默认输出未匹配字符的问题,同时让程序能处理所有输入类型,输入结束后按Ctrl+Z(Windows)或Ctrl+D(Linux/macOS)即可正常终止。

内容的提问来源于stack exchange,提问作者user27828776

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:20:15