理解没有声明类型的 Bison
我有下面的代码,并且收到以下错误
parser.y:111.47-48: error: $$ for the midrule at $5 of 'statement' has no returned type 111 | 111 REDUCE 运算符归约 ENDREDUCE {$$ = $3;} ';'|
我知道它是生成的,因为我没有在语句中声明某些内容的类型,我需要帮助理解第 111 行。此外,REAL_LITERAL 是一个浮点数,我应该向联合体添加一个浮点数并创建像这样的令牌 %token < f_value>REAL_LITERAL。
include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
#include "math.h"
#include "values.h"
#include "listing.h"
#include "symbols.h"
int yylex();
void yyerror(const char* message);
Symbols<int> symbols;
int result;
double *params;
%}
%define parse.error verbose
%union
{
CharPtr iden;
Operators oper;
int value;
}
%token <iden> IDENTIFIER
%token <value>INT_LITERAL REAL_LITERAL BOOL_LITERAL CASE TRUE FALSE
%token ARROW
%token <oper> ADDOP MULOP RELOP OROP NOTOP REMOP EXPOP
%token ANDOP
%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS
%token THEN WHEN
%token ELSE ENDCASE ENDIF IF OTHERS REAL
%type <value> body statement_ statement reductions expression binary relation term
factor primary
%type <oper> operator
%left OROP
%left ANDOP
%left RELOP
%left ADDOP
%left MULOP REMOP
%right EXPOP
%left NOTOP
%%
function:
function_header optional_variable body {result = $3;} ;
function_header:
FUNCTION IDENTIFIER parameters RETURNS type ';' |
FUNCTION IDENTIFIER RETURNS type ';' |
FUNCTION IDENTIFIER optional_parameters RETURNS type ';' |
error ';' ;
optional_variable:
optional_variable variable |
error ';' ;
;
variable:
IDENTIFIER ':' type IS statement_ {symbols.insert($1, $5);} ;
variables:
variable variables |
;
type:
INTEGER |
BOOLEAN ;
optional_parameters:
parameters |
;
parameters:
parameter ',' parameters |
parameter ;
parameter:
IDENTIFIER ':' type ;
type:
INTEGER |
REAL |
BOOLEAN ;
body:
BEGIN_ statement_ END ';' {$$ = $2;} ;
statement_:
statement ';' |
error ';' {$$ = 0;} ;
statement:
expression |
REDUCE operator reductions ENDREDUCE {$$ = $3;} ';'|
IF expression THEN statement_ ELSE statement_ ENDIF
{
if ($2 == true) {
$$ = $4;
}
else {
$$ = $6;
}
}';' /*|
CASE expression IS cases OTHERS ARROW statement_ ENDCASE
{$$ = $<value>4 == $1 ? $4 : $7;} ;
cases:
cases case
{$$ = $<value>1 == $1 ? $1 : $2;} |
%empty {$$ = NAN;};
case:
case WHEN INT_LITERAL ARROW statement_ |
;
*/
operator:
ADDOP |
RELOP |
EXPOP |
MULOP ;
reductions:
reductions statement_ {$$ = evaluateReduction($<oper>0, $1, $2);} |
{$$ = $<oper>0 == ADD ? 0 : 1;} ;
expression:
expression OROP binary {$$ = $1 || $3;} |
binary;
binary:
binary ANDOP relation {$$ = $1 && $3;} |
relation ;
relation:
relation RELOP term {$$ = evaluateRelational($1, $2, $3);} |
term ;
term:
term ADDOP factor {$$ = evaluateArithmetic($1, $2, $3);} |
factor ;
factor:
factor MULOP primary {$$ = evaluateArithmetic($1, $2, $3);} |
primary ;
primary:
'(' expression ')' {$$ = $2;} |
INT_LITERAL |
IDENTIFIER {if (!symbols.find($1, $$)) appendError(UNDECLARED, $1);} ;
%%
void yyerror(const char* message)
{
appendError(SYNTAX, message);
}
int main(int argc, char *argv[])
{
firstLine();
yyparse();
if (lastLine() == 0)
cout << "Result = " << result << endl;
return 0;
}
I have the following code below and I am receiving the following error
parser.y:111.47-48: error: $$ for the midrule at $5 of ‘statement’ has no declared type
111 | REDUCE operator reductions ENDREDUCE {$$ = $3;} ';'|
I know it's generated because I didn't declare a type for something in the statement, I need help understanding line 111. Also the REAL_LITERAL is a float, that I should add a float to the union and create token like this %token <f_value>REAL_LITERAL.
include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
#include "math.h"
#include "values.h"
#include "listing.h"
#include "symbols.h"
int yylex();
void yyerror(const char* message);
Symbols<int> symbols;
int result;
double *params;
%}
%define parse.error verbose
%union
{
CharPtr iden;
Operators oper;
int value;
}
%token <iden> IDENTIFIER
%token <value>INT_LITERAL REAL_LITERAL BOOL_LITERAL CASE TRUE FALSE
%token ARROW
%token <oper> ADDOP MULOP RELOP OROP NOTOP REMOP EXPOP
%token ANDOP
%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS
%token THEN WHEN
%token ELSE ENDCASE ENDIF IF OTHERS REAL
%type <value> body statement_ statement reductions expression binary relation term
factor primary
%type <oper> operator
%left OROP
%left ANDOP
%left RELOP
%left ADDOP
%left MULOP REMOP
%right EXPOP
%left NOTOP
%%
function:
function_header optional_variable body {result = $3;} ;
function_header:
FUNCTION IDENTIFIER parameters RETURNS type ';' |
FUNCTION IDENTIFIER RETURNS type ';' |
FUNCTION IDENTIFIER optional_parameters RETURNS type ';' |
error ';' ;
optional_variable:
optional_variable variable |
error ';' ;
;
variable:
IDENTIFIER ':' type IS statement_ {symbols.insert($1, $5);} ;
variables:
variable variables |
;
type:
INTEGER |
BOOLEAN ;
optional_parameters:
parameters |
;
parameters:
parameter ',' parameters |
parameter ;
parameter:
IDENTIFIER ':' type ;
type:
INTEGER |
REAL |
BOOLEAN ;
body:
BEGIN_ statement_ END ';' {$ = $2;} ;
statement_:
statement ';' |
error ';' {$ = 0;} ;
statement:
expression |
REDUCE operator reductions ENDREDUCE {$ = $3;} ';'|
IF expression THEN statement_ ELSE statement_ ENDIF
{
if ($2 == true) {
$ = $4;
}
else {
$ = $6;
}
}';' /*|
CASE expression IS cases OTHERS ARROW statement_ ENDCASE
{$ = lt;value>4 == $1 ? $4 : $7;} ;
cases:
cases case
{$ = lt;value>1 == $1 ? $1 : $2;} |
%empty {$ = NAN;};
case:
case WHEN INT_LITERAL ARROW statement_ |
;
*/
operator:
ADDOP |
RELOP |
EXPOP |
MULOP ;
reductions:
reductions statement_ {$ = evaluateReduction(lt;oper>0, $1, $2);} |
{$ = lt;oper>0 == ADD ? 0 : 1;} ;
expression:
expression OROP binary {$ = $1 || $3;} |
binary;
binary:
binary ANDOP relation {$ = $1 && $3;} |
relation ;
relation:
relation RELOP term {$ = evaluateRelational($1, $2, $3);} |
term ;
term:
term ADDOP factor {$ = evaluateArithmetic($1, $2, $3);} |
factor ;
factor:
factor MULOP primary {$ = evaluateArithmetic($1, $2, $3);} |
primary ;
primary:
'(' expression ')' {$ = $2;} |
INT_LITERAL |
IDENTIFIER {if (!symbols.find($1, $)) appendError(UNDECLARED, $1);} ;
%%
void yyerror(const char* message)
{
appendError(SYNTAX, message);
}
int main(int argc, char *argv[])
{
firstLine();
yyparse();
if (lastLine() == 0)
cout << "Result = " << result << endl;
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基本问题是规则内操作在 bison 中没有默认类型(与 yacc 不同)。因此,在您的操作中,
$$
没有%type
,因此您需要明确指定它 - 也许类似于{ $$ = $3; }
。这相当于 yacc 在这里所做的,因为它给出了与 lhs 相同类型的规则内操作,即使实际上没有任何东西连接它们。更大的问题是,这确实没有意义——像这样的规则内操作不会设置要减少的符号的值。这只能发生在规则结束行动中。所以这只是将一个值复制到临时值,然后将其丢弃,而不用它做任何事情。隐式最终规则操作仅执行
{ $$ = $1; }
这没有任何意义,因为statement
和REDUCE
具有不同的类型。The basic problem is that in-rule actions do not get a default type in bison (unlike yacc). So in your action
there's no
%type
for$$
so you need to specify it explicitly -- perhaps something like{ $<value>$ = $3; }
. That's equivalent to what yacc would do here, as it gives in-rule actions the same type as the lhs, even though there's not really anything connecting them.The bigger issue is that this really makes no sense -- an in-rule action like this does NOT set the value for the symbol being reduced. That can only happen in the end-of-rule action. So this is just copying a value to a temp and then throwing it away, never doing anything with it. The implicit end-rule action just does
{ $$ = $1; }
which makes no sense asstatement
andREDUCE
have different types.