Проблема с использованием $6 в парсере Bison.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Проблема с использованием $6 в парсере Bison.

Сообщение Anonymous »

Я работаю над проектом компилятора. Я пытаюсь понять, почему я постоянно получаю сообщение об ошибке при использовании оператора $6.
Это моя реализация моего parser.y`
%code requires {
#include
#include
#include
#include
#include
#include
#include
#include "ast.h"
#include "expressions/call.h"
#include "expressions/int.h"
#include "expressions/float.h"
#include "expressions/string.h"
#include "expressions/variable.h"
#include "expressions/addition.h"
#include "expressions/subtraction.h"
#include "expressions/multiplication.h"
#include "expressions/division.h"
#include "expressions/assignment.h"
#include "expressions/comparison.h"
#include "expressions/and.h"
#include "expressions/or.h"
#include "statements/block.h"
#include "statements/while.h"
#include "statements/if.h"
#include "statements/return.h"
#include "types/simple.h"
extern FILE *yyin;
}

%{
#include "parser.tab.hh"

extern int yylex(void);
void yyerror(const char *s);
void save_to_dot(FILE *);
int trav_and_write(FILE *, node *);

AST ast("TestMod");
%}

%start program

%define parse.error verbose

%union {
bool boolval;
int intval;
double fltval;
char *strval;
struct node *nodeval;
ASTFunctionParameter *var;
std::vector *vars;
ASTStatement *stmt;
std::vector *stmtVec;
ASTExpression *exp;
std::vector *exprVec;
VarType *type;
ASTExpressionComparisonType rel;
std::vector *varDecsPtr;
}

%token ID BOOL_TYPE INT_TYPE FLOAT_TYPE STRING_TYPE VOID_TYPE SEMICOLON LPAREN RPAREN COMMA LBRACE RBRACE IF ELSE WHILE BREAK RETURN EQUALS_SIGN LOGICAL_OR LOGICAL_AND LOGICAL_NOT RELOP_GT RELOP_LT RELOP_GE RELOP_LE RELOP_EQ RELOP_NE ARITH_PLUS ARITH_MINUS ARITH_MULT ARITH_DIV ARITH_MOD VARIADIC BOOL_LITERAL INT_LITERAL FLOAT_LITERAL STRING_LITERAL EOL

%type BOOL_LITERAL
%type ID STRING_LITERAL
%type int_lit INT_LITERAL
%type flt_lit FLOAT_LITERAL
%type varDec
%type params paramList varDecs
%type stmt exprStmt selStmt iterStmt jumpStmt
%type stmts
%type expr orExpr andExpr unaryRelExpr relExpr term factor primary call constant
%type args
%type type
%type relop

%expect 1 // Shift/reduce conflict when resolving the if/else production; okay

%%

program: | decList ;
decList: decList dec | dec ;
dec: funDef | funDec ;

type: BOOL_TYPE { $$ = new VarTypeSimple(VarTypeSimple::BoolType); }
| INT_TYPE { $$ = new VarTypeSimple(VarTypeSimple::IntType); }
| FLOAT_TYPE { $$ = new VarTypeSimple(VarTypeSimple::FloatType); }
| STRING_TYPE { $$ = new VarTypeSimple(VarTypeSimple::StringType); }
| VOID_TYPE { $$ = new VarTypeSimple(VarTypeSimple::VoidType); };

varDec: type ID {
$$ = new ASTFunctionParameter(std::unique_ptr($1), $2);
};

varDecs: varDecs varDec SEMICOLON {
$$ = $1;
$$->push_back($2);
} | {
$$ = new std::vector();
};

funDec: type ID LPAREN params RPAREN SEMICOLON {
auto parameters = ASTFunctionParameters();
bool variadic = false;
for(auto p : *$4) {
if (p) parameters.push_back(std::move(*p));
else variadic = true;
}
auto f = ast.AddFunction($2, std::unique_ptr($1), std::move(parameters), variadic);
};

funDef: type ID LPAREN params RPAREN LBRACE varDecs stmts RBRACE {
// Create an ASTStatementBlock for the function body
auto stmtBlock = std::make_unique();

// Convert the vector of statements into an ASTStatementBlock
for (auto s : *$8) {
stmtBlock->statements.push_back(std::move(s));
}

// Create the parameters for the function
auto parameters = ASTFunctionParameters();
bool variadic = false;
for (auto p : *$4) {
if (p) {
parameters.push_back(std::move(*p));
} else {
variadic = true;
}
}

// Create the function and add its parameters
auto function = ast.AddFunction($2, std::unique_ptr(new VarTypeSimple(VarTypeSimpleEnumeration::Int)), std::move(parameters), variadic);

// Add the variables declared in varDecs to the function as stack variables
for (auto var : *$6) {
// Access the type information from the variable declaration
auto varType = var->type.get();
function->AddStackVar(std::move(*var));
}

// Define the function with the ASTStatementBlock
function->Define(std::move(stmtBlock));
};

params: paramList | {$$ = new std::vector();};
paramList: paramList COMMA type ID {
$$ = $1;
$$->push_back(new ASTFunctionParameter(std::unique_ptr($3), $4));
} | type ID {
$$ = new std::vector();
$$->push_back(new ASTFunctionParameter(std::unique_ptr($1), $2));
} | paramList COMMA VARIADIC {
$$ = new std::vector();
$$->push_back(nullptr);
};

stmt: exprStmt {$$ = $1;} | LBRACE stmts RBRACE {
auto statements = new ASTStatementBlock();
for(auto s : *$2) {
statements->statements.push_back(std::unique_ptr(s));
}
$$ = statements;
}| selStmt {$$ = $1;} | iterStmt {$$ = $1;} | jumpStmt {$$ = $1;} ;

exprStmt: expr SEMICOLON {
$$ = $1;
} | SEMICOLON {
$$ = new ASTStatementBlock();
};

stmts: stmts stmt {
$$ = $1;
$$->push_back($2);
} | {
$$ = new std::vector();
};

selStmt: IF LPAREN expr RPAREN stmt {
$$ = new ASTStatementIf(std::unique_ptr($3), std::unique_ptr($5), std::unique_ptr(nullptr));
} | IF LPAREN expr RPAREN stmt ELSE stmt {
$$ = new ASTStatementIf(std::unique_ptr($3), std::unique_ptr($5), std::unique_ptr($7));
};

iterStmt: WHILE LPAREN expr RPAREN stmt {
$$ = new ASTStatementWhile(std::unique_ptr($3), std::unique_ptr($5));
};

jumpStmt: RETURN SEMICOLON {
auto retStmt = new ASTStatementReturn();
retStmt->returnExpression = std::unique_ptr(nullptr);
$$ = retStmt;
} | RETURN expr SEMICOLON {
auto retStmt = new ASTStatementReturn();
retStmt->returnExpression = std::unique_ptr($2);
$$ = retStmt;
};

expr: orExpr { $$ = $1;} | ID EQUALS_SIGN expr {
$$ = new ASTExpressionAssignment(std::unique_ptr(new ASTExpressionVariable($1)), std::unique_ptr($3));
};

orExpr: andExpr {$$ = $1;} | orExpr LOGICAL_OR andExpr {
$$ = new ASTExpressionOr(std::unique_ptr($1), std::unique_ptr($3));
};

andExpr: unaryRelExpr {$$ = $1;} | andExpr LOGICAL_AND unaryRelExpr {
$$ = new ASTExpressionAnd(std::unique_ptr($1), std::unique_ptr($3));
};

unaryRelExpr: LOGICAL_NOT unaryRelExpr {
$$ = $2;
} | relExpr {$$ = $1;};

relExpr: term relop term {
$$ = new ASTExpressionComparison($2, std::unique_ptr($1), std::unique_ptr($3));
} | term {$$ = $1;};

relop: RELOP_GT { $$ = ASTExpressionComparisonType::GreaterThan; }
| RELOP_LT { $$ = ASTExpressionComparisonType::LessThan; }
| RELOP_GE { $$ = ASTExpressionComparisonType::GreaterThanOrEqual; }
| RELOP_LE { $$ = ASTExpressionComparisonType::LessThanOrEqual; }
| RELOP_EQ { $$ = ASTExpressionComparisonType::Equal; }
| RELOP_NE { $$ = ASTExpressionComparisonType::NotEqual; };

term: factor {$$ = $1;}
| term ARITH_PLUS factor { $$ = new ASTExpressionAddition(std::unique_ptr($1), std::unique_ptr($3)); }
| term ARITH_MINUS factor { $$ = new ASTExpressionSubtraction(std::unique_ptr($1), std::unique_ptr($3)); };

factor: primary {$$ = $1;}
| factor ARITH_MULT primary { $$ = new ASTExpressionMultiplication(std::unique_ptr($1), std::unique_ptr($3)); }
| factor ARITH_DIV primary { $$ = new ASTExpressionDivision(std::unique_ptr($1), std::unique_ptr($3)); }
| factor ARITH_MOD primary { $$ = $1; };

primary: ID { $$ = new ASTExpressionVariable($1); }
| LPAREN expr RPAREN { $$ = $2; }
| call { $$ = $1; }
| constant { $$ = $1; };

call: ID LPAREN args RPAREN {
auto argVec = std::vector();
for(auto a : *$3) {
argVec.push_back(std::unique_ptr(a));
}
$$ = new ASTExpressionCall(ASTExpressionVariable::Create($1), std::move(argVec));
} | ID LPAREN RPAREN {
$$ = new ASTExpressionCall(ASTExpressionVariable::Create($1), std::vector());
};

args: args COMMA expr {
$$ = $1;
$$->push_back($3);
} | expr {
$$ = new std::vector();
$$->push_back($1);
};

constant: int_lit {$$ = new ASTExpressionInt($1);}
| flt_lit {$$ = new ASTExpressionFloat($1);}
| STRING_LITERAL {$$ = new ASTExpressionString(std::string($1));};

int_lit: INT_LITERAL | ARITH_MINUS INT_LITERAL {$$ = -1 * $2;};
flt_lit: FLOAT_LITERAL | ARITH_MINUS FLOAT_LITERAL {$$ = -1 * $2;};

%%
int main(int argc, char **argv) {

// Arg flags:
bool showHelp = false; // Show the help and exit.
std::string openFile = ""; // File to open. Nothing for standard in.
std::string outFile = ""; // File to write to. Nothing for standard out.
int outputFormat = 3; // 0 - LLVM Assembly. 1 - LLVM Bitcode. 2 - Object (TODO). 3 - AST tree.
bool printAST = true; // If to print the AST to console.

// Read the arguments. Don't count the first which is the executable name.
for (int i = 1; i < argc; i++)
{
bool hasNextArg = i + 1 < argc;
std::string arg(argv);
if (arg == "-i" && hasNextArg)
{
i++;
openFile = argv;
}
else if (arg == "-o" && hasNextArg)
{
i++;
outFile = argv;
}
else if (arg == "-nPrint")
{
printAST = false;
}
else if (arg == "-fAsm")
{
outputFormat = 0;
}
else if (arg == "-fBc")
{
outputFormat = 1;
}
else if (arg == "-fObj")
{
outputFormat = 2;
}
else if (arg == "-fAst")
{
outputFormat = 3;
}
else
{
showHelp = true;
}
}
printAST &= outputFormat != 3 && outFile != ""; // Always print AST by default in addition to whatever is being output.

// Show help if needed.
if (showHelp)
{
printf("Usage: LLVM-Lab [options]\n");
printf("\nOptions:\n\n");
printf("-h Show this help screen.\n");
printf("-i [input] Read from an input file (reads from console by default).\n");
printf("-o [output] Write to an output file (writes to console by default).\n");
printf("-nPrint If to not print the AST to the console.\n");
printf("-fAsm Output format is in LLVM assembly.\n");
printf("-fAst Output format is an abstract syntax tree.\n");
printf("-fBc Output format is in LLVM bitcode.\n");
printf("-fObj Output format is an object file.\n");
return 1;
}

// Fetch input.
if (openFile != "")
{
yyin = fopen(openFile.c_str(), "r");
}

if (yyparse() == 1)
{
printf("Irrecoverable error state, aborting\n");
return 1;
}

// Close input if needed.
if (openFile != "")
{
fclose(yyin);
}

// Do the compilation.
ast.Compile();

// Print AST if needed.
if (printAST) std::cout

Подробнее здесь: https://stackoverflow.com/questions/783 ... son-parser
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»