Commit 4ecd8588 by Andrew Dahl

ref #14 Setup Flex/Bison Parsing

parent 5c1308d3
Showing with 49 additions and 28 deletions
......@@ -29,12 +29,12 @@
char* name;
}
%token NEWLINE PLUS MINUS SLASH ASTERISK LPAREN RPAREN EQUALS USERINPUT OUTPUT FUNCTION COMMA LCURLY RCURLY RETURN
%token NEWLINE PLUS MINUS SLASH ASTERISK LPAREN RPAREN EQUALS USERINPUT OUTPUT FUNCTION COMMA LCURLY RCURLY RETURN TYPEINT TYPEFLOAT
%token <inum> NUMBER
%token <fnum> FLOAT
%token <name> ID
%type <sym> stat additive_exp mult_exp primary_exp assignment_exp function_define argument_exp_list func_call_args function_decl
%type <sym> stat additive_exp mult_exp primary_exp assignment_exp function_define argument_exp_list func_call_args function_decl type_spec
%% /* Grammer Rules and Actions */
......@@ -51,12 +51,16 @@ external_decl: NEWLINE
| error { yyerrok; YYABORT;}
;
function_decl: FUNCTION ID LPAREN {
if(symbol_table->at(level)->ExistsInCurrentLevel($2)) {
type_spec: TYPEINT { $$ = new Symbol("temp", Symbol::INTEGER, Symbol::INTEGER); }
| TYPEFLOAT { $$ = new Symbol("temp", Symbol::FLOAT, Symbol::FLOAT); }
;
function_decl: FUNCTION type_spec ID LPAREN {
if(symbol_table->at(level)->ExistsInCurrentLevel($3)) {
yyerror(symbol_table,instructions,"Redeclaration of function");
YYABORT;
} else {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::FUNCTION, Symbol::INTEGER));
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($3, Symbol::FUNCTION, $2->getReturnType()));
if(temp->getType() == Symbol::VARIABLE) {
yyerror(symbol_table,instructions,"Function cannot have the same name as a previously declared variable!")
YYABORT;
......@@ -72,14 +76,7 @@ function_decl: FUNCTION ID LPAREN {
}
;
function_define: function_decl argument_exp_list RPAREN EQUALS additive_exp NEWLINE {
$1->setFunctionValue($2);
level = symbol_table->at(level)->getParentTable();
$1->setReturnType($5->getReturnType());
instructions->levelPop();
$$ = $1;
}
| function_decl argument_exp_list RPAREN LCURLY statlist RETURN additive_exp RCURLY {
function_define: function_decl argument_exp_list RPAREN LCURLY statlist RETURN additive_exp RCURLY {
$1->setFunctionValue($2);
level = symbol_table->at(level)->getParentTable();
instructions->levelPop();
......@@ -88,13 +85,13 @@ function_define: function_decl argument_exp_list RPAREN EQUALS additive_exp NEWL
;
argument_exp_list: { $$ = NULL;}
| ID {
$$ = (symbol_table->at(level))->Insert(new Symbol($1, Symbol::VARIABLE, Symbol::INTEGER));
}
| argument_exp_list COMMA ID {
| type_spec ID {
$$ = (symbol_table->at(level))->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
}
| argument_exp_list COMMA type_spec ID {
Symbol::value_t symbol_value; symbol_value.s = $1;
$$ = symbol_table->at(level)->Insert(new Symbol($3, symbol_value, Symbol::VARIABLE));
}
$$ = symbol_table->at(level)->Insert(new Symbol($4, symbol_value, Symbol::VARIABLE, $3->getReturnType()));
}
;
assignment_exp: additive_exp
......@@ -111,24 +108,46 @@ assignment_exp: additive_exp
}
;
statlist: stat { }
statlist:
| stat { }
| statlist stat { }
;
stat: OUTPUT additive_exp NEWLINE {
instructions->addInstruction(new Instruction(Instruction::OUTPUT));
}
| ID EQUALS assignment_exp NEWLINE {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
| type_spec ID EQUALS assignment_exp NEWLINE {
if(symbol_table->at(level)->ExistsInCurrentLevel($2)) {
yyerror(symbol_table,instructions,"Redeclaration of variable");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
} else {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($2, Symbol::VARIABLE, $1->getReturnType()));
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
}
}
| ID EQUALS assignment_exp NEWLINE {
if(symbol_table->at(level)->ExistsInCurrentLevel($1)) {
Symbol* temp = symbol_table->at(level)->Insert(new Symbol($1, Symbol::VARIABLE, $3->getReturnType()));
if(temp->getType() == Symbol::FUNCTION) {
yyerror(symbol_table, instructions, "Function used like variable!");
YYABORT;
} else {
instructions->addInstruction(new Instruction(Instruction::VARDECL, temp));
instructions->addInstruction(new Instruction(Instruction::MOV, temp));
instructions->addInstruction(new Instruction(Instruction::POP));
}
} else {
yyerror(symbol_table,instructions,"Variable used before declaration");
YYABORT;
}
}
;
additive_exp: additive_exp PLUS mult_exp {
......
......@@ -60,6 +60,8 @@ comma [,]
"readInput" { return USERINPUT; }
"output" { return OUTPUT; }
"return" { return RETURN; }
"int" { return TYPEINT; }
"float" { return TYPEFLOAT; }
{identifier} { yylval.name = strdup(yytext); return ID; }
{plus} { return PLUS; }
{minus} { return MINUS; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment