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

Lex/Yacc中v紧跟s触发语法错误、疑问句解析失败问题求解

问题根因
  • 词法规则未处理空白字符:现有Lex规则没有匹配空格、制表符、换行的逻辑,Lex遇到未定义字符时会默认返回字符ASCII值作为无效token,Yacc收到无效token直接抛出语法错误,这是疑问句解析报错的核心原因。
  • 词法规则大小写不兼容:现有规则仅匹配全小写的关键字(如will/did),句首大写的Will/Did无法被识别为对应助动词token。
  • 顶层语法规则缺失一般现在时分支:起始非终结符sentence的产生式没有添加一般现在时陈述句的匹配分支,SUBJECT + VERB1 + 句号的结构没有合法归约路径,触发语法错误。
  • 归约动作打印顺序和位置错误:原有打印逻辑放在中层非终结符上,和自底向上的归约顺序冲突,输出文本不符合预期。

修复方案

修正后的Lex代码

添加空白忽略规则、开启大小写不敏感匹配,解决词法层问题:

%option noyywrap case-insensitive
%{
    #include<stdio.h>
    #include"y.tab.h"
%}

%%
I|you|we|they|he|she|it                 return SUBJECT;
will                                    return AUX1;
did                                     return AUX2;
not                                     return NOT;
eat|drink|run|play                      return VERB1;
ate|drank|ran|played                    return VERB2;
\.                                      return DOT;
\?                                      return QUE;
[ \t\n\r]                               ; /* 跳过所有空白字符,不生成token */
%%

修正后的Yacc代码

补全一般现在时分支、调整打印动作位置适配自底向上归约顺序:

%{
    #include<stdio.h>
    #include<stdlib.h>
    void yyerror(char *msg);
%}

%token  SUBJECT VERB1 DOT QUE VERB2 AUX1 AUX2 NOT

%% 
sentence:
    past DOT                {printf("Simple Past Tense Sentence Approved\n"); exit(0);}
    | pastneg DOT           {printf("Negative Simple Past Tense Sentence Approved\n"); exit(0);}
    | pastint QUE           {printf("Interrogative Simple Past Tense Sentence Approved\n"); exit(0);}
    | fut DOT               {printf("Simple Future Tense Sentence Approved\n"); exit(0);}
    | futneg DOT            {printf("Negative Simple Future Tense Sentence Approved\n"); exit(0);}
    | futint QUE            {printf("Interrogative Simple Future Tense Sentence Approved\n"); exit(0);}
    | present DOT           {printf("Simple Present Tense Sentence Approved\n"); exit(0);} /* 补全一般现在时陈述句分支 */
    ;
present:
    s v          
    ;
past:
    s p         
    ;
pastneg:
    s x2 neg v  
    ;
pastint:
    x2 present  
    ;
fut:
    s x1 v      
    ;
futneg:
    s x1 neg v  
    ;
futint:
    x1 present  
    ;
s:
    SUBJECT     {printf("Subject ");}
    ;
p:
    VERB2       {printf("Verb2 ");}
    ;
x1:
    AUX1        {printf("Auxiliary ");}
    ;
x2:
    AUX2        {printf("Auxiliary ");}
    ;
v:
    VERB1       {printf("Verb1 ");}
    ;
neg:
    NOT         {printf("Negative ");}
    ;

%%
void yyerror(char *msg){
    fprintf(stderr, "%s\n", msg);
    exit(1);
}

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

效果验证
  • 输入Will he eat?,输出:Auxiliary Subject Verb1 Interrogative Simple Future Tense Sentence Approved
  • 输入Did you run?,输出:Auxiliary Subject Verb1 Interrogative Simple Past Tense Sentence Approved
  • 输入I eat.,输出:Subject Verb1 Simple Present Tense Sentence Approved
  • 原有过去时、将来时的肯定/否定句式解析逻辑不受影响,可正常识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:42:29