Flex/Bison based compiler and interpreter written in C++ (using Boost)
File detail
Source code
/*
* Copyright (C) 2008 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
*
* This file is part of vyp08 (compiler and interpreter of VYP08 language).
*
* vyp08 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* vyp08 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with vyp08. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "parser.h"
#include "vypIO.h"
#ifndef BUILDING_DOX
# include <string>
# include <sstream>
#endif
using namespace StreamDecorator;
using std::string;
class TestBuilder: public IBuilder {
public:
TestBuilder() { }
virtual bool hasError() const { return false; }
virtual void errorDetected() { std::cerr << "\t" << Color(C_LIGHT_CYAN) << "ERROR_DETECTED" << Color(C_NO_COLOR) << std::endl; }
virtual void glVar(EToken type, Token id) { std::cerr << Color(C_LIGHT_BLUE) << "GL_VAR" << Color(C_NO_COLOR) << ":\t" << type << "\t"<< id << std::endl; }
virtual void fncDeclInit(EToken type, Token id) { std::cerr << Color(C_LIGHT_RED) << "FNC_DECL_INIT" << Color(C_NO_COLOR) << ":\t" << type << "\t" << id << std::endl; }
virtual void fncDeclArg(EToken type) { std::cerr << "\t" << Color(C_LIGHT_PURPLE)<< "FNC_DECL_ARG" << Color(C_NO_COLOR) << ":\t" << type << std::endl; }
virtual void fncDecl() { std::cerr << "\t" << Color(C_LIGHT_GREEN) << "FNC_DECL_OK" << Color(C_NO_COLOR) << std::endl << std::endl; }
virtual void fncDefInit(EToken type, Token id) { std::cerr << Color(C_LIGHT_RED) << "FNC_DEF_INIT" << Color(C_NO_COLOR) << ":\t" << type << "\t" << id << std::endl; }
virtual void fncDefArg(EToken type, Token id) { std::cerr << "\t" << Color(C_LIGHT_PURPLE)<< "FNC_DEF_ARG" << Color(C_NO_COLOR) << ":\t" << type << "\t" << id << std::endl; }
virtual void fncDefVar(EToken type, Token id) { std::cerr << "\t" << Color(C_LIGHT_BLUE) << "FNC_DEF_VAR" << Color(C_NO_COLOR) << ":\t" << type << "\t"<< id << std::endl; }
virtual void fncDefBody() { std::cerr << "\t" << Color(C_LIGHT_CYAN) << "FNC_DEF_BODY" << Color(C_NO_COLOR) << std::endl; }
virtual void fncDef() { std::cerr << "\t" << Color(C_LIGHT_GREEN) << "FNC_DEF_OK" << Color(C_NO_COLOR) << std::endl << std::endl; }
virtual void assign(Token dest) { std::cerr << "\t" << dest << " := " << Color(C_YELLOW) << "POP" << Color(C_NO_COLOR) << std::endl; }
virtual void ifEnter(Token) { std::cerr << "\t" << Color(C_LIGHT_RED) << "if" << Color(C_NO_COLOR) << " (EXPR) " << Color(C_LIGHT_RED) << "{" << Color(C_NO_COLOR) << std::endl; }
virtual void ifElse() { std::cerr << "\t" << Color(C_LIGHT_RED) << "} else {" << Color(C_NO_COLOR) << std::endl; }
virtual void ifLeave() { std::cerr << "\t" << Color(C_LIGHT_RED) << "}" << Color(C_NO_COLOR) << std::endl; }
virtual void whileInit(Token) { std::cerr << "\t" << Color(C_LIGHT_CYAN) << "while (" << Color(C_NO_COLOR) << std::endl; }
virtual void whileEnter() { std::cerr << "\t" << Color(C_LIGHT_CYAN) << ") {" << Color(C_NO_COLOR) << std::endl; }
virtual void whileLeave() { std::cerr << "\t" << Color(C_LIGHT_CYAN) << "}" << Color(C_NO_COLOR) << std::endl; }
virtual void pushToken(Token token) { std::cerr << "\t" << Color(C_YELLOW) << "PUSH" << Color(C_NO_COLOR) << ": " << token << std::endl; }
virtual void evalUnOp(Token token) { std::cerr << "\t" << Color(C_LIGHT_CYAN) << "EVAL_UNARY" << Color(C_NO_COLOR) << ": " << token << std::endl; }
virtual void evalBinOp(Token token) { std::cerr << "\t" << Color(C_LIGHT_PURPLE) << "EVAL_BINARY" << Color(C_NO_COLOR) << ": " << token << std::endl; }
virtual void fncCall(Token id, int argsToPop, bool pushResult) {
std::cerr << "\t" << Color(C_LIGHT_BLUE) << "FNC_CALL" << Color(C_NO_COLOR) << ": " << id << std::endl;
for(int i=0; i<argsToPop; i++)
std::cerr << "\t\t" << Color(C_LIGHT_PURPLE) << "POP" << Color(C_NO_COLOR) << " -> ARG" << std::endl;
if (pushResult)
std::cerr << "\t\t" << Color(C_YELLOW) << "PUSH" << Color(C_NO_COLOR) << " <- RESULT" << std::endl;
}
virtual void fncCallPrint(Token id, EToken valType) {
std::cerr << "\t" << Color(C_LIGHT_RED) << "FNC_CALL_PRINT" << Color(C_NO_COLOR) << ":\t" << id << ":\t" << valType << std::endl;
}
};
static char const *testName = "test-parser";
/// NOTE: following test is highly incomplete and maybe outdated
static char const *testContent = "var\n\
int glInt,\n\
double glDouble,\n\
string glString\n\
\n\
void f();\n\
double toDouble(string);\n\
string strcat(string;string);\n\
int main(int argc;string argv) {\n\
f();\n\
main := 1.2e-3 - argc - toDouble(argv);\n\
}\n\
\n\
string strcat(string a; string b)var string c;\n\
{\n\
while a + b eq a+b {\n\
c := a + b;\n\
if \"\" <= c {\n\
strcat := main(0,c);\n\
} else {\n\
strcat := strcat(c,a+b);\n\
};\n\
};\n\
}\n";
int main(int argc, char *argv[]) {
#if CONSOLE_COLOR_OUTPUT
StreamDecorator::Color::enable(true);
#endif
string fn(testName);
IScanner *scanner = 0;
std::istringstream *stream = 0;
if (argc == 2 && string(argv[1]) == string("-")) {
// read from std::cin if "-" is the only arg
fn = "-";
scanner = ScannerFactory::createScanner(std::cin, fn);
} else {
// use built-in test input otherwise
stream = new std::istringstream(testContent);
scanner = ScannerFactory::createScanner(*stream, fn);
}
// run parser
IBuilder *builder = new TestBuilder;
int status = Parser::parse(scanner, builder, fn);
// cleanup
delete builder;
delete scanner;
delete stream;
return status;
}