#include "stdafx.h"
#include <map>
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include <regex>
#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;
public:
MyLexer(char *input_file)
{
buffer = input_file;
}
Token<TokType> *next_token() {
Coord coord;
coord.filename = "in.txt";
coord.line = 1;
coord.col = 1;
i++;
switch (i)
{
case 1:
return new Token<TokType>(PRINT, coord);
case 2:
return new AttrToken<TokType, double>(NUMBER, 8, coord);
case 3:
return new Token<TokType>(PLUS, coord);
case 4:
return new AttrToken<TokType, double>(NUMBER, 10, coord);
case 5:
return new Token<TokType>(PLUS, coord);
case 6:
// return new AttrToken<TokType, double>(NUMBER, 10, coord);
//case 7:
return new Token<TokType>(END_OF_TEXT, coord);
}
}
};
// Основная программа
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);
int p = sizeof(char);
pbuf->sgetn(buffer, size);
//std::cout.write(buffer, size);
MyLexer lexer(buffer);
PrintOperator.parse(lexer);
//delete[] buffer;
}
else
{
std::cout << "Где файл? Нет файла." << '\n';
}
}
return 0;
}