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
相关产品推荐
相关产品推荐

