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

如何在Bison表达式的开头、中间或末尾插入任意符号?

代码失效原因

现有代码无法正常运行是几个低级逻辑问题导致的:

  • 词法层没处理!和_:yylex遇到这两个字符直接返回ERROR,语法里写的匹配规则永远触达不到
  • 数字读取逻辑错漏:循环读多位数时反复覆盖yylval,最后只会存最后一位的值;读完数字后多取的字符没回退输入流,后续所有字符识别都会错位
  • 错误处理逻辑粗暴:碰到任意非法字符就直接吞掉整行,根本做不到格式校验
  • 存在死代码:return ERROR之后的yyerror调用永远不会执行
可运行修正版代码
%{
#define YYDEBUG 1
#include <stdio.h>
#include <string.h>
int yylex(void);
void yyerror(char *);
int line=0;
%}

%token INTEGER NEWLINE

%%

program:
    | program '!' expr '_' expr NEWLINE  { 
        printf("NUMERICAL EXPRESSION\n");
        line++; 
    }
    | program NEWLINE { line++; }
    ;

expr:
    INTEGER { $$ = $1; }
    ;

%%

int yylex() {
    char c;
    // 不需要跳过空格、制表符的话可以删掉下面这行循环
    while((c = getchar()) == ' ' || c == '\t');
    
    if (c >= '0' && c <= '9') {
        int val = 0;
        while(c >= '0' && c <= '9' ){
            val = val * 10 + (c - '0');
            c = getchar();
        }
        yylval = val;
        ungetc(c, stdin); // 把多读的非数字字符塞回输入流
        return INTEGER;
    }

    if (c == '\n'){ 
        return NEWLINE;
    }

    // 单独识别!和_,直接返回字符本身作为终结符
    if (c == '!' || c == '_') {
        return c;
    }

    // 其他非法字符直接返回本身,触发语法报错
    return c;
}

void yyerror(char *s) {
    fprintf(stderr, "Line %d: invalid input, %s\n", line+1, s);
}
  
int main(void) {
    yyparse();
    return 0;
}
运行效果
  • 输入!44_22回车,会正确输出NUMERICAL EXPRESSION
  • 输入!123_456这类多位数组合也能正常识别
  • 输入不符合格式的内容(比如44_22、!4422、!_44)会直接抛出语法错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:09:58