|
@@ -1,6 +1,6 @@
|
|
|
#include "Parser.hpp"
|
|
#include "Parser.hpp"
|
|
|
|
|
|
|
|
-Parser::Parser(Lexer lexer) : lexer(lexer), curToken(Token()), peekToken(Token()), symbols({})
|
|
|
|
|
|
|
+Parser::Parser(Lexer lexer, Emitter *emitter) : lexer(lexer), curToken(Token()), peekToken(Token()), symbols({}), emitter(emitter)
|
|
|
{
|
|
{
|
|
|
nextToken();
|
|
nextToken();
|
|
|
nextToken();
|
|
nextToken();
|
|
@@ -46,7 +46,9 @@ bool Parser::isComparisonOperator()
|
|
|
|
|
|
|
|
void Parser::program()
|
|
void Parser::program()
|
|
|
{
|
|
{
|
|
|
- std::cout << "PROGRAM" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "PROGRAM" << std::endl;
|
|
|
|
|
+ this->emitter->headerLine("#include <stdio.h>");
|
|
|
|
|
+ this->emitter->headerLine("int main(void){");
|
|
|
while (checkToken(TokenType::NEWLINE))
|
|
while (checkToken(TokenType::NEWLINE))
|
|
|
{
|
|
{
|
|
|
nextToken();
|
|
nextToken();
|
|
@@ -56,22 +58,27 @@ void Parser::program()
|
|
|
statement();
|
|
statement();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- for (const Symbol& sym : this->symbols) {
|
|
|
|
|
- if (sym.sym_kind() == SymbolKind::LABEL_GOTOED){
|
|
|
|
|
|
|
+ for (const Symbol &sym : this->symbols)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (sym.sym_kind() == SymbolKind::LABEL_GOTOED)
|
|
|
|
|
+ {
|
|
|
Symbol label(sym.str(), SymbolKind::LABEL_DECLARATION);
|
|
Symbol label(sym.str(), SymbolKind::LABEL_DECLARATION);
|
|
|
- if (this->symbols.find(label) == this->symbols.end()){
|
|
|
|
|
- abort ("GOTO to an undeclared label "+sym.str());
|
|
|
|
|
|
|
+ if (this->symbols.find(label) == this->symbols.end())
|
|
|
|
|
+ {
|
|
|
|
|
+ abort("GOTO to an undeclared label " + sym.str());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- Symbol label("TOTO", SymbolKind::LABEL_DECLARATION);
|
|
|
|
|
- this->symbols.insert(label);
|
|
|
|
|
- this->symbols.insert(label);
|
|
|
|
|
- this->symbols.insert(label);
|
|
|
|
|
- std::cout << "*** SYMB TABLE ***" << std::endl;
|
|
|
|
|
- for (const Symbol& sym : this->symbols) {
|
|
|
|
|
- std::cout << sym.str() << "-" << sym.sym_kind() << std::endl;
|
|
|
|
|
|
|
+ this->emitter->emitLine("return 0;");
|
|
|
|
|
+ this->emitter->emitLine("}");
|
|
|
|
|
+
|
|
|
|
|
+ for (const Symbol &sym : this->symbols)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (sym.sym_kind() == SymbolKind::VARIABLE)
|
|
|
|
|
+ {
|
|
|
|
|
+ this->emitter->headerLine("float " + sym.str() + ";");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -80,53 +87,63 @@ void Parser::statement()
|
|
|
// "PRINT" (expression | string)
|
|
// "PRINT" (expression | string)
|
|
|
if (checkToken(TokenType::PRINT))
|
|
if (checkToken(TokenType::PRINT))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-PRINT" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-PRINT" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
|
|
|
|
|
if (checkToken(TokenType::STRING))
|
|
if (checkToken(TokenType::STRING))
|
|
|
{
|
|
{
|
|
|
|
|
+ this->emitter->emitLine("printf(\"" + this->curToken.get_text() + "\\n\")");
|
|
|
|
|
+ ;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
|
|
+ this->emitter->emit("printf(\"\%.2f\\n\", (float)(");
|
|
|
expression();
|
|
expression();
|
|
|
|
|
+ this->emitter->emitLine("));");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// "IF" comparison "THEN" nl {statement} "ENDIF"
|
|
// "IF" comparison "THEN" nl {statement} "ENDIF"
|
|
|
else if (checkToken(TokenType::IF))
|
|
else if (checkToken(TokenType::IF))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-IF" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-IF" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
|
|
+ this->emitter->emit("if(");
|
|
|
comparison();
|
|
comparison();
|
|
|
match(TokenType::THEN);
|
|
match(TokenType::THEN);
|
|
|
nl();
|
|
nl();
|
|
|
|
|
+ this->emitter->emitLine("){");
|
|
|
while (!checkToken(TokenType::ENDIF))
|
|
while (!checkToken(TokenType::ENDIF))
|
|
|
{
|
|
{
|
|
|
statement();
|
|
statement();
|
|
|
}
|
|
}
|
|
|
match(TokenType::ENDIF);
|
|
match(TokenType::ENDIF);
|
|
|
|
|
+ this->emitter->emitLine("}");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// "WHILE" comparison "REPEAT" nl {statement nl} "ENDWHILE"
|
|
// "WHILE" comparison "REPEAT" nl {statement nl} "ENDWHILE"
|
|
|
else if (checkToken(TokenType::WHILE))
|
|
else if (checkToken(TokenType::WHILE))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-WHILE" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-WHILE" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
|
|
+ this->emitter->emit("while(");
|
|
|
comparison();
|
|
comparison();
|
|
|
match(TokenType::REPEAT);
|
|
match(TokenType::REPEAT);
|
|
|
nl();
|
|
nl();
|
|
|
|
|
+ this->emitter->emitLine("){");
|
|
|
while (!checkToken(TokenType::ENDWHILE))
|
|
while (!checkToken(TokenType::ENDWHILE))
|
|
|
{
|
|
{
|
|
|
statement();
|
|
statement();
|
|
|
}
|
|
}
|
|
|
match(TokenType::ENDWHILE);
|
|
match(TokenType::ENDWHILE);
|
|
|
|
|
+ this->emitter->emitLine("}");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// "LABEL" ident
|
|
// "LABEL" ident
|
|
|
else if (checkToken(TokenType::LABEL))
|
|
else if (checkToken(TokenType::LABEL))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-LABEL" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-LABEL" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
ident(SymbolKind::LABEL_DECLARATION);
|
|
ident(SymbolKind::LABEL_DECLARATION);
|
|
|
}
|
|
}
|
|
@@ -134,25 +151,32 @@ void Parser::statement()
|
|
|
// "GOTO" ident
|
|
// "GOTO" ident
|
|
|
else if (checkToken(TokenType::GOTO))
|
|
else if (checkToken(TokenType::GOTO))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-GOTO" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-GOTO" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
ident(SymbolKind::LABEL_GOTOED);
|
|
ident(SymbolKind::LABEL_GOTOED);
|
|
|
}
|
|
}
|
|
|
// "LET" ident "=" expression
|
|
// "LET" ident "=" expression
|
|
|
else if (checkToken(TokenType::LET))
|
|
else if (checkToken(TokenType::LET))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-ASSIGN" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-ASSIGN" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
ident(SymbolKind::VARIABLE);
|
|
ident(SymbolKind::VARIABLE);
|
|
|
match(TokenType::EQ);
|
|
match(TokenType::EQ);
|
|
|
|
|
+ this->emitter->emit(" = ");
|
|
|
expression();
|
|
expression();
|
|
|
}
|
|
}
|
|
|
// "INPUT" ident
|
|
// "INPUT" ident
|
|
|
else if (checkToken(TokenType::INPUT))
|
|
else if (checkToken(TokenType::INPUT))
|
|
|
{
|
|
{
|
|
|
- std::cout << "STATEMENT-INPUT" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "STATEMENT-INPUT" << std::endl;
|
|
|
nextToken();
|
|
nextToken();
|
|
|
|
|
+ this->emitter->emit("if (0 == scanf(\"\%f\", &");
|
|
|
|
|
+ const std::string identext = this->curToken.get_text();
|
|
|
ident(SymbolKind::VARIABLE);
|
|
ident(SymbolKind::VARIABLE);
|
|
|
|
|
+ this->emitter->emitLine(")){");
|
|
|
|
|
+ this->emitter->emitLine(identext + " = 0;");
|
|
|
|
|
+ this->emitter->emitLine("}");
|
|
|
|
|
+ this->emitter->emitLine("scanf(\"\%*s\");\n}");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
else
|
|
else
|
|
@@ -165,7 +189,7 @@ void Parser::statement()
|
|
|
|
|
|
|
|
void Parser::comparison()
|
|
void Parser::comparison()
|
|
|
{
|
|
{
|
|
|
- std::cout << "COMPARISON" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "COMPARISON" << std::endl;
|
|
|
expression();
|
|
expression();
|
|
|
if (isComparisonOperator())
|
|
if (isComparisonOperator())
|
|
|
{
|
|
{
|
|
@@ -186,7 +210,7 @@ void Parser::comparison()
|
|
|
|
|
|
|
|
void Parser::term()
|
|
void Parser::term()
|
|
|
{
|
|
{
|
|
|
- std::cout << "TERM" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "TERM" << std::endl;
|
|
|
unary();
|
|
unary();
|
|
|
while (checkToken(TokenType::ASTERISK) || checkToken(TokenType::SLASH))
|
|
while (checkToken(TokenType::ASTERISK) || checkToken(TokenType::SLASH))
|
|
|
{
|
|
{
|
|
@@ -197,7 +221,7 @@ void Parser::term()
|
|
|
|
|
|
|
|
void Parser::unary()
|
|
void Parser::unary()
|
|
|
{
|
|
{
|
|
|
- std::cout << "UNARY" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "UNARY" << std::endl;
|
|
|
if (checkToken(TokenType::PLUS) || checkToken(TokenType::MINUS))
|
|
if (checkToken(TokenType::PLUS) || checkToken(TokenType::MINUS))
|
|
|
{
|
|
{
|
|
|
nextToken();
|
|
nextToken();
|
|
@@ -207,7 +231,7 @@ void Parser::unary()
|
|
|
|
|
|
|
|
void Parser::primary()
|
|
void Parser::primary()
|
|
|
{
|
|
{
|
|
|
- std::cout << "PRIMARY" << " (" << (this->curToken).get_text() << ")" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "PRIMARY" << " (" << (this->curToken).get_text() << ")" << std::endl;
|
|
|
if (checkToken(TokenType::NUMBER))
|
|
if (checkToken(TokenType::NUMBER))
|
|
|
{
|
|
{
|
|
|
nextToken();
|
|
nextToken();
|
|
@@ -230,7 +254,7 @@ void Parser::primary()
|
|
|
|
|
|
|
|
void Parser::expression()
|
|
void Parser::expression()
|
|
|
{
|
|
{
|
|
|
- std::cout << "EXPRESSION" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "EXPRESSION" << std::endl;
|
|
|
term();
|
|
term();
|
|
|
while (checkToken(TokenType::PLUS) || checkToken(TokenType::MINUS))
|
|
while (checkToken(TokenType::PLUS) || checkToken(TokenType::MINUS))
|
|
|
{
|
|
{
|
|
@@ -241,7 +265,7 @@ void Parser::expression()
|
|
|
|
|
|
|
|
void Parser::ident(SymbolKind k)
|
|
void Parser::ident(SymbolKind k)
|
|
|
{
|
|
{
|
|
|
- std::cout << "IDENT" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "IDENT" << std::endl;
|
|
|
const std::string identText = this->curToken.get_text();
|
|
const std::string identText = this->curToken.get_text();
|
|
|
match(TokenType::IDENT);
|
|
match(TokenType::IDENT);
|
|
|
Symbol curSymb(identText, k);
|
|
Symbol curSymb(identText, k);
|
|
@@ -251,13 +275,16 @@ void Parser::ident(SymbolKind k)
|
|
|
if (this->symbols.find(curSymb) != this->symbols.end())
|
|
if (this->symbols.find(curSymb) != this->symbols.end())
|
|
|
abort("Label already exists " + identText);
|
|
abort("Label already exists " + identText);
|
|
|
this->symbols.insert(curSymb);
|
|
this->symbols.insert(curSymb);
|
|
|
|
|
+ this->emitter->emit(identText + ": ");
|
|
|
break;
|
|
break;
|
|
|
case LABEL_GOTOED:
|
|
case LABEL_GOTOED:
|
|
|
this->symbols.insert(curSymb);
|
|
this->symbols.insert(curSymb);
|
|
|
|
|
+ this->emitter->emitLine("goto " + identText + ";");
|
|
|
break;
|
|
break;
|
|
|
case VARIABLE:
|
|
case VARIABLE:
|
|
|
- std::cout << identText << std::endl;
|
|
|
|
|
|
|
+ // std::cout << identText << std::endl;
|
|
|
this->symbols.insert(curSymb);
|
|
this->symbols.insert(curSymb);
|
|
|
|
|
+ this->emitter->emit(identText);
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
break;
|
|
break;
|
|
@@ -266,7 +293,7 @@ void Parser::ident(SymbolKind k)
|
|
|
|
|
|
|
|
void Parser::nl()
|
|
void Parser::nl()
|
|
|
{
|
|
{
|
|
|
- std::cout << "NEWLINE" << std::endl;
|
|
|
|
|
|
|
+ // std::cout << "NEWLINE" << std::endl;
|
|
|
match(TokenType::NEWLINE);
|
|
match(TokenType::NEWLINE);
|
|
|
while (checkToken(TokenType::NEWLINE))
|
|
while (checkToken(TokenType::NEWLINE))
|
|
|
{
|
|
{
|