#include "stdafx.h"
#include <map>
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <regex>
#include <boost/algorithm/string.hpp>
//#include <boost/algorithm/string_regex.hpp>
#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<TokType, double> E =
//Rule() << E << PLUS << Term<double>(NUMBER) << add_func1
//| Rule() << Term<double>(NUMBER);
//
//void print_val_func(double value) {
// printf("%f", value);
//}
//
//NTerm<TokType, void> P =
//Rule() << PRINT << E << print_val_func;
// <тип токена, возвращаемое значение функции (void, если функции нет)>
// Program
extern NTerm<TokType, void> Operator;
NTerm<TokType, void> Program =
Rule() << Operator
| Rule() << Program << ';' << Operator;
// Operator
extern NTerm<TokType, void> InputOperator, PrintOperator, AssignOperator;
NTerm<TokType, void> Operator =
Rule() << InputOperator
| Rule() << PrintOperator
| Rule() << AssignOperator;
// InputOperator
extern NTerm<TokType, double*> Variable;
void input_func(double *variable) {
scanf("%lf", variable);
}
NTerm<TokType, void> InputOperator =
Rule() << READ << Variable << input_func
| Rule() << InputOperator << ',' << Variable << input_func;
// PrintOperator
extern NTerm<TokType, double> Expression;
void print_val_func(double value) {
printf("%f", value);
}
void print_str_func(std::string str) {
printf("%s", str.c_str());
}
NTerm<TokType, void> PrintOperator =
Rule() << PRINT << Expression << print_val_func
| Rule() << PRINT << Term<std::string>(STRING) << print_str_func
| Rule() << PrintOperator << ',' << Expression << print_val_func
| Rule() << PrintOperator << ',' << Term<std::string>(STRING) << print_str_func;
// AssignOperator
void assign_func(double *variable, double value) {
*variable = value;
}
NTerm<TokType, void> AssignOperator =
Rule() << Variable << '=' << Expression << assign_func;
// Variable
std::map<std::string, double> variables;
double *variable_func(std::string name) {
return &variables[name];
}
NTerm<TokType, double*> Variable =
Rule() << Term<std::string>(VARNAME) << variable_func;
// Expression
extern NTerm<TokType, double> ExprTerm; // Слагаемое
double add_func(double x, double y) {
return x + y;
}
double sub_func(double x, double y) {
return x - y;
}
NTerm<TokType, double> Expression =
Rule() << ExprTerm
| Rule() << Expression << '+' << ExprTerm << add_func
| Rule() << Expression << '-' << ExprTerm << sub_func;
// ExprTerm
extern NTerm<TokType, double> Factor;
double mul_func(double x, double y) {
return x * y;
}
double div_func(double x, double y) {
return x / y;
}
NTerm<TokType, double> ExprTerm =
Rule() << Factor
| Rule() << ExprTerm << '*' << Factor << mul_func
| Rule() << ExprTerm << '/' << Factor << div_func;
// Factor
double deref_var_func(double *variable) {
return *variable;
}
NTerm<TokType, double> Factor =
Rule() << Term<double>(NUMBER)
| Rule() << Variable << deref_var_func
| Rule() << LP << Expression << ')';
class MyLexer : public Lexer<TokType> {
int i = 0;
char* buffer;
Coord coord;
std::vector<Token<TokType>> tokens;
std::vector<std::string> lines;
std::vector<std::string> makeStrVector(char* buffer)
{
std::vector<std::string> l;
std::string str = buffer;
boost::split(l, str, boost::is_any_of("\n"));
return l;
}
std::vector<Token<TokType>> makeTokens(std::string &line)
{
std::vector<Token<TokType>> 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<TokType> 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<std::string>::iterator line = lines.begin(); line != lines.end(); line++)
std::vector<Token<TokType>> tokensAux = makeTokens(*line);
//this->tokens.insert(tokens.end(), tokensAux.begin(), tokensAux.end());
}
Token<TokType> *next_token() {
if (*buffer == '\0') {
return new Token<TokType>(0, coord);
}
while (*buffer != '\0' && isspace(*buffer)) {
if (*buffer == '\n') {
++coord.line;
coord.col = 1;
}
else {
++coord.col;
}
++buffer;
}
Token<TokType> *result = 0;
if (*buffer == '=') {
++buffer;
result = new Token<TokType>(SET, coord);
coord.col++;
}
else if (*buffer == '+') {
++buffer;
result = new Token<TokType>(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<TokType, double>(NUMBER, value, coord);
}
else if (isalpha(*buffer)) {
std::string ident = "";
while (isalnum(*buffer)) {
ident += *buffer;
++buffer;
}
if (ident == "print") {
result = new Token<TokType>(PRINT, coord);
}
else if (ident == "read") {
result = new Token<TokType>(READ, coord);
}
else {
result = new AttrToken<TokType, std::string>(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;
}