Skip to content

Instantly share code, notes, and snippets.

@aemarkov
Last active April 11, 2016 22:19
Show Gist options
  • Save aemarkov/d373230fd41b4528f82f9038d6b1eacd to your computer and use it in GitHub Desktop.
Save aemarkov/d373230fd41b4528f82f9038d6b1eacd to your computer and use it in GitHub Desktop.
`
// ParserTest.cpp: определяет точку входа для консольного приложения.
//
#include "stdafx.h"
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
//Структурка, чтобы удобно параметры передавать в функцию парсенные значения
//можно так не делать, а внести next_state в цикл
//Я просто эстет
struct Params
{
int number;
double time;
double value;
double k1, k2, k3, k4, k5, k6;
};
//Парсит число
bool parse_number(const char* string, double & number);
//Парсит целое число
bool parse_int_number(const char* string, int & number);
//Парсит время
bool parse_time(const char* string, double & milliseconds);
//Новая строка?
bool is_newline(const char* string);
//Переход автомата в новое состояние
int next_state(const char* string, int current_state, Params & params);
int main()
{
setlocale(LC_ALL, "Russian");
const char separators[] = " \t\n"; //Разделители
char test_string[] = "1 1,1004000 5"; //Тестовая строка
char* substring; //Текущая обрабатываемая подстрока
Params params; //Параметры, которые будут считаны со строки
int state = 0; //Текущее состояние автомата
substring = strtok(test_string, separators);
do
{
state = next_state(substring, state, params);
substring = strtok(NULL, separators);
} while ((state != 0) || (state == -1));
return 0;
}
//Парсит число
bool parse_number(const char* string, double & number)
{
if (string == NULL)return false;
double value;
try
{
value = stod(string);
}
catch (invalid_argument exp)
{
//stod кидает исключение, если преобразование накрылось
return false;
}
number = value;
return true;
}
//Парсит целое число
bool parse_int_number(const char* string, int & number)
{
if (string == NULL)return false;
int value;
try
{
value = stoi(string);
}
catch (invalid_argument exp)
{
//stoi кидает исключение, если преобразование накрылось
return false;
}
number = value;
return true;
}
//Парсит время
bool parse_time(const char* string, double & milliseconds)
{
if (string == NULL)return false;
double value;
if (!parse_number(string, value))
return false;
milliseconds = value * 1000;
return true;
}
//Новая строка?
bool is_newline(const char* string)
{
return (string==NULL) || (!strcmp(string, "\n"));
}
//Пишет ошибку для неверных входных символов
int error(const char* string)
{
cout << "Введено неверное значение:" << string;;
return -1;
}
//Переход автомата в новое состояние
int next_state(const char* string, int current_state, Params & params)
{
if (current_state == 0)
{
//Начало строки
if (parse_int_number(string, params.number))
return 1; //-> Считан номер
else if (is_newline(string))
{
cout << "Нет номера";
return -1; //-> Нет номера
}
else
return error(string); //-> Ошибка
}
else if (current_state == 1)
{
//Считан номер
if (parse_time(string, params.time))
return 2; //-> Считано время
else if (is_newline(string))
{
cout << "Нет времени";
return -1; //-> Нет времени
}
else
return error(string); //-> Ошибка
}
else if (current_state == 2)
{
//Считано время
if (parse_number(string, params.value))
return 3; //-> Считано значение
else if (is_newline(string))
{
cout << "Нет значения";
return -1; //-> Нет значения
}
else
return error(string); //-> Ошибка
}
else if (current_state == 3)
{
//Считано значение
if (is_newline(string))
return 0; //-> начало строки
else if (parse_number(string, params.k1))
return 4; //->Считан коэф. 1
else
return error(string); //-> Ошибка
}
else if (current_state == 4)
{
//Считан коэф 1
}
else if (current_state == 5)
{
//Считан коэф 2
}
else if (current_state == 6)
{
//Считан коэф 3
}
else if (current_state == 7)
{
//Считан коэф 4
}
else if (current_state == 8)
{
//Считан коэф 5
}
else if (current_state == 9)
{
//Считан коэф 6
}
return 0;
}
`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment