理解没有声明类型的 Bison

发布于 2025-01-10 01:31:55 字数 3656 浏览 0 评论 0原文

我有下面的代码,并且收到以下错误

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝戈者 2025-01-17 01:31:55

基本问题是规则内操作在 bison 中没有默认类型(与 yacc 不同)。因此,在您的操作中,

REDUCE operator reductions ENDREDUCE {$ = $3;} ';'

$$ 没有 %type,因此您需要明确指定它 - 也许类似于 { $$ = $3; }。这相当于 yacc 在这里所做的,因为它给出了与 lhs 相同类型的规则内操作,即使实际上没有任何东西连接它们。

更大的问题是,这确实没有意义——像这样的规则内操作不会设置要减少的符号的值。这只能发生在规则结束行动中。所以这只是将一个值复制到临时值,然后将其丢弃,而不用它做任何事情。隐式最终规则操作仅执行 { $$ = $1; } 这没有任何意义,因为 statementREDUCE 具有不同的类型。

The basic problem is that in-rule actions do not get a default type in bison (unlike yacc). So in your action

REDUCE operator reductions ENDREDUCE {$ = $3;} ';'

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 as statement and REDUCE have different types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文