首页 > 解决方案 > 将两个标记加在一起(整数)。弹性/野牛

问题描述

我有一个简单的 Bison 文件和一些简单的语法。我正在获取一个无穷无尽的表达式列表,我的目标是为将两个标记的值相加的表达式创建一个单一的定义。

在第 20 行,有一条语法规则显示了我想要实现的目标。不幸的是,它不起作用。我怎样才能实现这个功能?

野牛档案

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

%token INT
%token PLUS
%token END


%%
expr_list:    END
          { exit(0); }
        | expr
        | expr expr_list
;

expr:         INT PLUS INT
          { printf("%d\n", ($1 + $3)); }
;

%%


int main(int argc, char** argv) {
    yyparse();
    return 0;
}


void yyerror(const char* msg) {
    fprintf(stderr, "ERROR! %s\n", msg);
}

弹性文件

%{
#include "adder.tab.h"
%}

%%
(\+)        return PLUS;
[0-9]+      return INT;
(END)       return END;
%%

标签: bison

解决方案


在你的解析器中,你有这个:

expr:         INT PLUS INT
          { printf("%d\n", ($1 + $3)); }

这需要两个标记的语义值INT并将它们相加,这很好。如果这总是产生 0,则意味着令牌的语义值一定有问题。那么让我们看一下对应的词法分析器动作:

[0-9]+      return INT;

在这里,您永远不会为 分配任何东西yylval,因此您的解析器规则中的$1$3将被取消分配。要分配有意义的语义值,您可以使用strtol将字符串转换yytext为整数:

[0-9]+      yylval = strtol(yytext, NULL, 10); return INT;

为了正确处理int' 范围之外的数字的错误,您应该errno在调用strtol.


推荐阅读