我使用 Flex 和 Bison 以及我的语法来实现一种非常简单的编程语言。但我是初学者,所以我不太确定如何使用它们。
除了一些基本运算(如算术和逻辑运算、赋值等)之外,我还有一个需要这种语言识别的函数:这个函数称为“ftoc”,它需要一个数字参数。
在我的 flex .l 文件中,我有(除其他外)以下定义:
DIGITO [0-9]
PUNTO ["."]
CONST_REAL {DIGITO}+{PUNTO}{DIGITO}+
CONST_ENTERA {DIGITO}+
P_A ["("]
P_C [")"]
我对“ftoc”函数也有这样的规则:
"FtoC" { printf("%s\n", yytext);return FTOC;}
我的 bison .y 文件有这个 union 来接受三种数据类型:
%union {
char *text;
int integer;
double real;
}
它还有以下标记定义:
%token <integer> CONST_ENTERA
%token <real> CONST_REAL
%token <text> INTEGER
%token <text> REAL
%token <text> STRING
%token P_A P_C
%token FTOC
涉及“ftoc”函数的规则如下:
conversion:
FTOC P_A constante P_C
;
constante:
CONST_ENTERA
| CONST_REAL
;
现在,我需要编写一个函数,每次找到该函数时都会打印“ftoc”及其参数。例如,如果解析器发现函数用作:FtoC(57.6),我需要它打印“ftoc57.6”。
我的打印函数看起来有点像这样:
printFtoc(char* function, double argument){
snprintf("%s, %f", function, argument);
}
我的问题是我应该如何将参数传递给这个函数。我尝试在“转换”规则中使用 $n,如下所示:
FTOC P_A constante P_C {printFtoC($1, $3)}
但随后我在 Bison 中收到 2 个错误(每个 $n 一个),表示“转换”没有声明类型。
我一直在尝试阅读 Bison 文档,但我并不真正明白我到底应该做什么。从其他问题和论坛中我知道我可能需要使用 %type 或 %token 做一些事情,但我真的不知道。
我只需要在找到函数名称和参数时获取它们,但不知道如何实现这一点,因为 $n 不起作用。
最佳答案
该错误准确地告诉您出了什么问题 - 您在与 constante
相对应的规则中使用了 $3
,但您尚未声明其类型康斯坦特
。您可能需要类似以下的声明:
%type<real> constante
告诉 bison 一个 constante
位于并集的 real
字段中。该操作中的 $1
也存在问题,因为 FTOC
没有类型。您可以通过给 FTOC
一个类型并适本地将 lex 规则修改为 yylval 来解决这个问题,或者通过删除 $1
并使用像 "这样的字符串文字来解决这个问题。 ftoc"
改为
任何给定的非终端只能有单一类型,因此您需要将操作添加到您的 constante
规则中。使用上面的 %type
声明,您将拥有:
constante: CONST_ENTERA { $$ = $1; /* implicit int->double conversion */ }
| CONST_REAL { $$ = $1; /* simple assignment of a double */ }
;
关于c - 操作没有声明类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23508496/