#include "stdafx.h"
#include <map>
#include <stdio.h>
#include <string>
#include <iostream>
#include <fstream>
#include "parser_edsl.h"
enum TokType {
END_OF_TEXT = 0,
PLUS = '+', MUNUS = '-', MUL = '*', DIV = '/', SET = '=',
SEMICOLON = ';', COMMA = ',', LP = '(', RP = ')',
PRINT, READ, VARNAME, NUMBER, STRING
};
// <тип токена, возвращаемое значение функции (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> {
public:
MyLexer(char *input_file);
Token<TokType> *next_token() {
//
int coord = 0;
return new Token<TokType>(PLUS, coord);
//
/*return new Token<TokType>(PRINT, coord);
return new AttrToken<TokType, std::string>(VARNAME, varname, coord);
...
return new AttrToken<TokType, double>(NUMBER, value, coord);
...
return new Token(0);*/ // Конец ввода всегда должен иметь значение 0
}
};
// Основная программа
int main(int argc, char *argv[]) {
if (argc > 1) {
//MyLexer lexer(argv[1]);
//Program.parse(lexer);
}
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);
//std::cout << size << '\n';
char* buffer = new char[size];
pbuf->sgetn(buffer, size);
file.close();
//std::cout.write(buffer, size);
MyLexer lexer(buffer);
//Program.parse(lexer);
delete[] buffer;
}
else
{
std::cout << "Где файл? Нет файла." << '\n';
}
return 0;
}
template<
class T,
class U
>
struct TypeList
{
typedef T head;
typedef U tail;
};
struct NullType {};
#define TYPELIST1(T1) TypeList<T1, NullType>
#define TYPELIST2(T1, T2) TypeList<T1, TYPELIST1(T2) >
#define TYPELIST3(T1, T2, T3) TypeList<T1, TYPELIST2(T2, T3) >
// Промежуточный тип RuleAux, возвращаемый не последним оператором <<
template <
typename TokenType,
class TypeList
>
struct RuleAux
{
// Пока ничего
};
// Промежуточный тип TermAux
template <
typename TokenType,
typename AttrType
>
struct TermAux
{
// пока ничего
};
// Промежуточный тип RuleRes, возвращаемый тип последнего оператора <<
template <
typename TokenType,
typename AttrType
>
struct RuleRes
{
// пока пусто
};
// промежуточный тип Alt, возвращаемый оператором |
template<
typename TokenType,
typename Attr
>
struct Alt
{
// Пока пусто
};
// определение типа Term
template<
typename AttrType,
typename TokenType
>
TermAux<TokenType, AttrType>
Term(TokenType tokType)
{
return TermAux<TokenType, AttrType>();
};
//NTerm
template <
typename TokenType,
typename Attr
>
struct NTerm
{
NTerm() {}
NTerm(Alt<TokenType, Attr>) {}
NTerm(RuleRes<TokenType, Attr>) {}
NTerm(RuleAux<TokenType, TYPELIST1(Attr)>) {}
};
//перегрузка оператора <<
struct Rule {};
// Rule() << терминал без атрибута (Rule() << READ)
template<
typename TokenType
>
RuleAux<TokenType, NullType>
operator<<(Rule, TokenType)
{
return RuleAux<TokenType, NullType>();
}
// Rule() << терминал с атрибутом
template<
typename TokenType,
typename AttrType
>
RuleAux<TokenType, TYPELIST1(AttrType)>
operator<<(Rule, TermAux<TokenType, AttrType>)
{
return RuleAux<TokenType, TYPELIST1(AttrType)>();
}
// Rule() << нетерминал без атрибута
template<
typename TokenType
>
RuleAux<TokenType, NullType>
operator << (Rule, NTerm<TokenType, void> &next_nterm)
{
return RuleAux<TokenType, NullType>();
}
// Rule() << нетерминал с атрибутом
template<
typename TokenType,
typename NewAttr
>
RuleAux<TokenType, TYPELIST1(NewAttr)>
operator << (Rule, NTerm<TokenType, NewAttr> &next_nterm)
{
return RuleAux<TokenType, TYPELIST1(NewAttr)>();
}
// RuleAux << терминал без атрибута (Rule() << Program << ';')
template<
typename TokenType,
class Types,
typename TokenTypeValue
>
RuleAux<TokenType, Types>
operator<<(RuleAux<TokenType, Types>, TokenTypeValue v)
{
TokenType t = TokenType(v);
return RuleAux<TokenType, Types >();
}
// RuleAux << терминал с атрибутом
template<
typename TokenType,
class Types,
typename AttrType
>
RuleAux<TokenType, TypeList<AttrType,Types>>
operator<<(RuleAux<TokenType, Types>, TermAux<TokenType, AttrType>)
{
return RuleAux<TokenType, TypeList<AttrType, Types>>();
}
// RuleAux << нетерминал без атрибута
template<
typename TokenType,
class Types
>
RuleAux<TokenType, Types>
operator<<(RuleAux<TokenType, Types>, NTerm<TokenType, void>)
{
return RuleAux<TokenType, Types>();
}
// RuleAux << нетерминал с атрибутом
template<
typename TokenType,
class Types,
typename NewAttr
>
RuleAux<TokenType, TypeList<NewAttr, Types>>
operator << (RuleAux<TokenType, Types> rule, NTerm<TokenType, NewAttr> &next_nterm)
{
return RuleAux<
TokenType,
TypeList<NewAttr, Types>
>();
}
// RuleAux пустой << функция (без параметров, так как RuleAux пустой), возвращающая void
template <
typename TokenType,
typename AttrRes
>
RuleRes<TokenType, void>
operator<<(RuleAux<TokenType, NullType>, AttrRes(*func)())
{
return RuleRes<TokenType, AttrRes>();
}
// RuleAux непустой << функция (принимающая один параметр, так как RuleAux непустой), возвращающая void
template <
typename TokenType,
typename Attr1
>
RuleRes<TokenType, void>
operator<<(RuleAux<TokenType, TYPELIST1(Attr1)>, void(*func)(Attr1))
{
return RuleRes<TokenType, void>();
}
// RuleAux(один параметр) << функция, возвращающая AttrRes, принимающая один параметр
template <
typename TokenType,
typename Attr1,
typename AttrRes
>
RuleRes<TokenType, AttrRes>
operator<<(RuleAux <TokenType, TYPELIST1(Attr1) >, AttrRes(*func)(Attr1))
{
return RuleRes<TokenType, AttrRes>();
}
// RuleAux(список параметров) << функция, возвращающая AttrRes, принимающая список из двух параметров
template <
typename TokenType,
typename Attr1,
typename Attr2,
typename AttrRes
>
RuleRes<TokenType, AttrRes>
operator<<(RuleAux<TokenType, TYPELIST2(Attr2, Attr1)>, AttrRes(*func)(Attr1, Attr2))
{
return RuleRes<TokenType, AttrRes>();
}
//перегрузка оператора |
// RuleRes | RuleRes
template<
typename TokenType,
typename Attr
>
Alt<TokenType, Attr>
operator | (RuleRes<TokenType, Attr>, RuleRes<TokenType, Attr>)
{
return Alt<TokenType, Attr>();
}
// RuleRes | Rule
template<
typename TokenType
>
Alt<TokenType, void>
operator | (RuleRes<TokenType, void>, Rule)
{
return Alt<TokenType, void>();
}
// Alt| RuleRes
template<
typename TokenType,
typename Attr
>
Alt<TokenType, Attr>
operator | (Alt<TokenType, Attr>, RuleRes<TokenType, Attr>)
{
return Alt<TokenType, Attr>();
}
// RuleRes | RuleAux
template<
typename TokenType,
typename Attr
>
Alt<TokenType, Attr>
operator | (RuleRes<TokenType, Attr>, RuleAux<TokenType, TYPELIST1(Attr) >)
{
return Alt<TokenType, Attr>();
}
// RuleAux | RuleRes
template<
typename TokenType,
typename Attr
>
Alt<TokenType, Attr>
operator | (RuleAux<TokenType, TYPELIST1(Attr)>, RuleRes<TokenType, Attr>)
{
return Alt<TokenType, Attr>();
}
// RuleAux пустой | RuleAux пустой
template<
typename TokenType
>
Alt<TokenType, void>
operator | (RuleAux<TokenType, NullType >, RuleAux<TokenType, NullType >)
{
return Alt<TokenType, void>();
}
// RuleAux | RuleAux
template<
typename TokenType,
class Types,
typename Attr
>
Alt<TokenType, Attr>
operator | (RuleAux<TokenType, Types >, RuleAux<TokenType, Types >)
{
return Alt<TokenType, Attr>();
}
// Alt | RuleAux
template<
typename TokenType,
class Types,
typename Attr
>
Alt<TokenType, Attr>
operator | (Alt<TokenType, Attr>, RuleAux<TokenType, Types>)
{
return Alt<TokenType, Attr>();
}
//lexer
template<
typename TokenType
>
class Lexer
{
};
template<
typename TokenType
>
class Token
{
TokenType token;
int coord;
public:
Token (TokenType token, int coord)
{
this->token = token;
this->coord = coord;
}
Token(int coord)
{
this->coord = coord;
}
};