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

Lex/Yacc时间格式解析器解析结果交替异常问题求助

问题分析与修复方案

核心问题

你的解析器出现交替错误/正常的现象,根源在于三个关键问题:

  1. Yacc在语法错误后会保持错误状态,后续调用yyparse()会直接返回错误,不会重新初始化解析环境
  2. 错误地将换行符\n当作EOF_处理,混淆了行分隔符与真正的输入结束标志
  3. Lex中未处理的.规则会默默吞掉非法字符,导致解析状态混乱

具体修复步骤

1. 修改Yacc文件(.y)

调整语法规则,添加错误恢复逻辑,并移除错误的EOF_定义:

%token HOUR COLON MINUTE AM PM
%%

main: time_list
    ;

// 支持多行时间解析
time_list: time
         | time_list time
         ;

// 匹配合法时间格式,添加错误恢复
time: HOUR ampm          { printf("The time format is correct\n\n"); }
    | HOUR COLON MINUTE  { printf("The time format is correct\n\n"); }
    | HOUR COLON MINUTE ampm { printf("The time format is correct\n\n"); }
    | error '\n'         { yyerrok; /* 强制重置错误状态 */ printf("Skipping invalid line\n\n"); }
    ;

ampm: AM
    | PM
    ;

更新main函数,让解析器自然处理到真正的输入结束:

int main() {
  yyparse();
  return 0;
}

2. 修改Lex文件(.l)

完善词法规则,正确处理换行、空白和非法字符:

[0-9]{1,2}  { printf("HOUR: %s\n", yytext); return HOUR; }
:            { printf("COLON\n"); return COLON; }
[0-9]{2}     { printf("MINUTE: %s\n", yytext); return MINUTE; }
am           { printf("AM\n"); return AM; }
pm           { printf("PM\n"); return PM; }
\n           { /* 换行作为行分隔符,不返回token */ }
[ \t]        { /* 忽略空格和制表符 */ }
.            { printf("Invalid character: %c\n", yytext[0]); }

修复关键点说明

  • 错误状态重置:使用yyerrok宏在解析错误后强制重置Yacc的错误标志,确保下一行解析能正常启动
  • 正确区分换行与EOF:换行仅作为行分隔符处理,真正的输入结束由Lex自动识别并返回0,避免解析状态混乱
  • 完善Lex规则:移除不必要的行首锚定^,处理空白字符,对非法字符明确报错,避免输入被静默丢弃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:18:11