Simple Bison文件无法编译

Simple Bison file does not compile

本文关键字:编译 文件 Bison Simple      更新时间:2023-10-16

我是flex和Bison的新手。下面的bison文件不会编译成。cpp和。h文件:

如果我删除代码来支持If语句,那么它就可以工作了。statement:中的|ifStmt{$$=$1;},规则ifStmt: TOKEN_IF expression TOKEN_DO statement TOKEN_ELSE TOKEN_DO statement{$$=makeIf($2, $3, $7);};,并通过删除TOKEN_IFTOKEN_ELSE来更改令牌声明

%error-verbose /* instruct bison to generate verbose error messages*/
%{
#include "astgen.h"
#define YYDEBUG 1
/* Since the parser must return the AST, it must get a parameter where
 * the AST can be stored. The type of the parameter will be void*. */
struct AstElement* astDest;
extern int yylex();
%}
%union {
    int val;
    char op;
    char* name;
    struct AstElement* ast; /* this is the new member to store AST elements */
}
%token TOKEN_BEGIN TOKEN_END TOKEN_WHILE TOKEN_DO TOKEN_IF TOKEN_ELSE
%token<name> TOKEN_ID
%token<val> TOKEN_NUMBER
%token<op> TOKEN_OPERATOR
%type<ast> program block statements statement assignment expression whileStmt call
%start program
%{
/* Forward declarations */
void yyerror(const char* const message);

%}
%%
program: statement';' { astDest = $1; };
block: TOKEN_BEGIN statements TOKEN_END{ $$ = $2; };
statements: {$$=0;}
    | statements statement ';' {$$=makeStatement($1, $2);}
    | statements block';' {$$=makeStatement($1, $2);};
statement: 
      assignment {$$=$1;}
    | whileStmt {$$=$1;}
    | ifStmt{$$=$1;}
    | block {$$=$1;}
    | call {$$=$1;}
assignment: TOKEN_ID '=' expression {$$=makeAssignment($1, $3);}
expression: TOKEN_ID {$$=makeExpByName($1);}
    | TOKEN_NUMBER {$$=makeExpByNum($1);}
    | expression TOKEN_OPERATOR expression {$$=makeExp($1, $3, $2);}
whileStmt: TOKEN_WHILE expression TOKEN_DO statement{$$=makeWhile($2, $4);};
ifStmt: TOKEN_IF expression TOKEN_DO statement TOKEN_ELSE TOKEN_DO statement{$$=makeIf($2, $4, $7);};
call: TOKEN_ID '(' expression ')' {$$=makeCall($1, $3);};
%%
#include "astexec.h"
#include <stdlib.h>
void yyerror(const char* const message)
{
    fprintf(stderr, "Parse error:%sn", message);
    exit(1);
}
上面的lex文件是:
%option noyywrap
%{
#include "parser.tab.h"
#include <stdlib.h>
%}
%option noyywrap
%%
"while" return TOKEN_WHILE;
"{" return TOKEN_BEGIN;
"}"   return TOKEN_END;
"do"    return TOKEN_DO;
"if"    return TOKEN_IF;
"else"  return TOKEN_ELSE;
"=="    {yylval.op = *yytext; return TOKEN_OPERATOR;}
"!="    {yylval.op = *yytext; return TOKEN_OPERATOR;}
[a-zA-Z_][a-zA-Z0-9_]* {yylval.name = _strdup(yytext); return TOKEN_ID;}
[-]?[0-9]+    {yylval.val = atoi(yytext); return TOKEN_NUMBER;}
[()=;]  {return *yytext;}
"<="    {yylval.op = *yytext; return TOKEN_OPERATOR;}
">="    {yylval.op = *yytext; return TOKEN_OPERATOR;}
[*/+-<>] {yylval.op = *yytext; return TOKEN_OPERATOR;}
[ tn] {/* suppress the output of the whitespaces from the input file to stdout */}
#.* {/* one-line comment */}
%%

我在这里做错了什么?

您错过了ifStmt%type声明,因为bison的错误消息告诉您:

t.y:46.17-18: $1 of `statement' has no declared type
t.y:58.78-79: $$ of `ifStmt' has no declared type
t.y:58.92-93: $3 of `ifStmt' has no declared type

ifStmt添加到第23行的%type<ast>声明中,将修复前两个错误;第三个可以通过使用$4而不是$3来修复。