#include "stdafx.h" #include #include #include #include #include #include #include //#include #include "parser_edsl.h" enum TokType { END_OF_TEXT = 0, PRINT, READ, VARNAME, NUMBER, STRING, PLUS = '+', MINUS = '-', MUL = '*', DIV = '/', SET = '=', SEMICOLON = ';', COMMA = ',', LP = '(', RP = ')' }; //double add_func1(double x, double y) { // return x + y; //} //NTerm E = //Rule() << E << PLUS << Term(NUMBER) << add_func1 //| Rule() << Term(NUMBER); // //void print_val_func(double value) { // printf("%f", value); //} // //NTerm P = //Rule() << PRINT << E << print_val_func; // <тип токена, возвращаемое значение функции (void, если функции нет)> // Program extern NTerm Operator; NTerm Program = Rule() << Operator | Rule() << Program << ';' << Operator; // Operator extern NTerm InputOperator, PrintOperator, AssignOperator; NTerm Operator = Rule() << InputOperator | Rule() << PrintOperator | Rule() << AssignOperator; // InputOperator extern NTerm Variable; void input_func(double *variable) { scanf("%lf", variable); } NTerm InputOperator = Rule() << READ << Variable << input_func | Rule() << InputOperator << ',' << Variable << input_func; // PrintOperator extern NTerm Expression; void print_val_func(double value) { printf("%f", value); } void print_str_func(std::string str) { printf("%s", str.c_str()); } NTerm PrintOperator = Rule() << PRINT << Expression << print_val_func | Rule() << PRINT << Term(STRING) << print_str_func | Rule() << PrintOperator << ',' << Expression << print_val_func | Rule() << PrintOperator << ',' << Term(STRING) << print_str_func; // AssignOperator void assign_func(double *variable, double value) { *variable = value; } NTerm AssignOperator = Rule() << Variable << '=' << Expression << assign_func; // Variable std::map variables; double *variable_func(std::string name) { return &variables[name]; } NTerm Variable = Rule() << Term(VARNAME) << variable_func; // Expression extern NTerm ExprTerm; // Слагаемое double add_func(double x, double y) { return x + y; } double sub_func(double x, double y) { return x - y; } NTerm Expression = Rule() << ExprTerm | Rule() << Expression << '+' << ExprTerm << add_func | Rule() << Expression << '-' << ExprTerm << sub_func; // ExprTerm extern NTerm Factor; double mul_func(double x, double y) { return x * y; } double div_func(double x, double y) { return x / y; } NTerm ExprTerm = Rule() << Factor | Rule() << ExprTerm << '*' << Factor << mul_func | Rule() << ExprTerm << '/' << Factor << div_func; // Factor double deref_var_func(double *variable) { return *variable; } NTerm Factor = Rule() << Term(NUMBER) | Rule() << Variable << deref_var_func | Rule() << LP << Expression << ')'; class MyLexer : public Lexer { int i = 0; char* buffer; Coord coord; std::vector> tokens; std::vector lines; std::vector makeStrVector(char* buffer) { std::vector l; std::string str = buffer; boost::split(l, str, boost::is_any_of("\n")); return l; } std::vector> makeTokens(std::string &line) { std::vector> tkns; std::regex lp("\\("); std::regex rp("\\)"); std::regex comma(","); std::regex plus("\\+"); std::regex mul("\\*"); std::regex div("\\/"); std::regex semicolon(";"); std::regex set("="); std::regex minus("-"); std::regex print("PRINT"); std::regex read("READ"); std::regex varname("[A-Za-z][A-Za-z0-9]*"); std::regex number("\\d+"); std::regex str("\"[A-Za-z]\""); std::regex gap("\s"); int pos = 0; bool waserror = false; std::smatch m; for (; line.length() != 0;) { Token t(); if (std::regex_search (line, m, lp)) { } else { std::cout << "Ошибка: " + std::to_string(pos); pos++; } tkns.push_back(t); line = line.substr(); } return tkns; } void increment() { } public: MyLexer(char *input_file) { buffer = input_file; lines = makeStrVector(buffer); coord.col = 1; coord.line = 1; for (std::vector::iterator line = lines.begin(); line != lines.end(); line++) std::vector> tokensAux = makeTokens(*line); //this->tokens.insert(tokens.end(), tokensAux.begin(), tokensAux.end()); } Token *next_token() { if (*buffer == '\0') { return new Token(0, coord); } while (*buffer != '\0' && isspace(*buffer)) { if (*buffer == '\n') { ++coord.line; coord.col = 1; } else { ++coord.col; } ++buffer; } Token *result = 0; if (*buffer == '=') { ++buffer; result = new Token(SET, coord); coord.col++; } else if (*buffer == '+') { ++buffer; result = new Token(PLUS, coord); ++coord.col; } else if ('0' <= *buffer && *buffer <= '9') { double value = 0; while ('0' <= *buffer && *buffer <= '9') { value = 10 * value + *buffer - '0'; ++buffer; } if (*buffer == '.') { ++buffer; double power = 0.1; while ('0' <= *buffer && *buffer <= '9') { value += power * (*buffer - '0'); ++buffer; power *= 0.1; } } result = new AttrToken(NUMBER, value, coord); } else if (isalpha(*buffer)) { std::string ident = ""; while (isalnum(*buffer)) { ident += *buffer; ++buffer; } if (ident == "print") { result = new Token(PRINT, coord); } else if (ident == "read") { result = new Token(READ, coord); } else { result = new AttrToken(VARNAME, ident, coord); } } return result; /*Coord coord; coord.filename = "in.txt"; coord.line = 1; coord.col = 1;*/ i++; return &(tokens[i - 1]); } }; // Основная программа int main(int argc, char *argv[]) { setlocale(LC_ALL, "RUS"); if (argc > 1) { //MyLexer lexer(argv[1]); //Program.parse(lexer); } else { std::ifstream file; file.open("C:\\Users\\Lenovo\\Documents\\Visual Studio 2013\\Projects\\ConsoleApplication1\\ConsoleApplication1\\in.txt", std::ios::in); if (file) { std::filebuf* pbuf = file.rdbuf(); std::size_t size = pbuf->pubseekoff(0, file.end, file.in); pbuf->pubseekpos(0, file.in); char* buffer = new char(size + 1); pbuf->sgetn(buffer, size); buffer[size] = '\0'; //std::cout.write(buffer, size); MyLexer lexer(buffer); Expression.parse(lexer); //delete[] buffer; } else { std::cout << "Где файл? Нет файла." << '\n'; } } return 0; }