Česky
Kamil Dudka

Flex/Bison based compiler and interpreter written in C++ (using Boost)

File detail

Name:Downloadtest-parser.cc [Download]
Location: vyp08 > vyp08-1.0pre1 > src
Size:6.4 KB
Last modification:2009-07-04 19:51

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;
}