Форум программистов, компьютерный форум CyberForum.ru

Парсер для математических выражений - C++

Восстановить пароль Регистрация
Другие темы раздела
SFML Ввод текста в переменную (sfml) http://www.cyberforum.ru/cpp-beginners/thread1493472.html
Всем привет!Как в sfml осуществить ввод текста в переменную?Заранее спасибо!
C++ Убрать/скрыть окно консоли Всем привет!Я пишу на notepad++,компилирую через командную строку.Как мне убрать консольное окно?Заранее благодарен! http://www.cyberforum.ru/cpp-beginners/thread1493471.html
C++ ReadProcessMemory медленно читает значение адреса
while (true) { if (isRun) { try { ReadProcessMemory(ProcessHandle, (void*)TimeAddress, &Time, sizeof(osuTime), NULL); std::cout << Time << std::endl; } catch (const std::exception&) {} }
ReadProcessMemory медленно читает значение адреса C++
while (true) { if (isRun) { try { ReadProcessMemory(ProcessHandle, (void*)TimeAddress, &Time, sizeof(osuTime), NULL); std::cout << Time << std::endl; } catch (const std::exception&) {} }
C++ Вычислить значения функции на заданном интервале http://www.cyberforum.ru/cpp-beginners/thread1493454.html
Написать программу вычисления функции y на заданном промежутке с шагом 0.2 и построить график функции y, причем y={e}^{-(x+0.8)} при х>3.61 y=1 при x\in \left y=0.5x при x<0
C++ Заполнить квадратную матрицу натуральными числами по спирали Составить программу, которая заполняет квадратную матрицу порядка n натуральными числами 1, 2, 3, …, n2, записывая их в нее «по спирали» против часовой стрелки. подробнее

Показать сообщение отдельно
Мизантроп_Лол
13 / 13 / 2
Регистрация: 26.02.2013
Сообщений: 282
Завершенные тесты: 1
05.07.2015, 18:27     Парсер для математических выражений
Здравствуйте уважаемые товарищи форумчане. Я пишу интерпретатор математических выражений и, собственно, для этого, сначала перевожу выражение в обратную польскую нотацию. Уже было вроде как закончил и хотел проверить работоспособность перевода, однако CodeBlocks посчитал иначе. Приложение запускается, однако в консоль вылетает ошибка и все. Приложение виснет. Я хотел пройтись пошагово, однако это нечто вылетает сразу же при старте. Ошибку можно увидеть на скриншоте. Исходники:
parser.h
C++
1
2
3
4
5
6
7
8
9
#ifndef PARSER_H_INCLUDED
#define PARSER_H_INCLUDED
 
namespace Parser
{
    std::string toPolish(std::string s);
}
 
#endif // PARSER_H_INCLUDED
parser.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#include <string>
#include <map>
#include <stdio.h>
#include "errors.h"
#include "parser.h"
 
namespace __Stack
{
    struct Stack
    {
        std::string value;
        Stack *next;
    };
 
    Stack *tail = NULL;
 
    void        push(std::string);
    std::string pop();
    void        clear();
}
 
void __Stack::push(std::string value)
{
    Stack *stk = new Stack();
 
    stk->value = value;
    stk->next = tail;
 
    tail = stk;
}
 
std::string __Stack::pop()
{
    std::string result = tail->value;
    Stack *stk = tail;
 
    tail = tail->next;
    delete stk;
 
    return result;
}
 
void __Stack::clear()
{
    Stack *stk;
 
    while (tail)
    {
        stk = tail;
        tail = tail->next;
        delete stk;
    }
}
 
///////////////////////////////////////////////////////////////////
 
namespace __Parser
{
    enum eTokens
    {
        NAME,           NUMBER,          FUNC,      U_MINUS,
        PLUS = '+',     MINUS = '-',     MUL = '*', DIV = '/',
        POW  = '^',     SQRT  = '\\',
        L_BRUNCH = '(', R_BRUNCH = ')'
    };
 
    eTokens curr_token;
    uint16_t char_pos = 0;
    //Используется для определения, является знак '+' или '-'
    //унарным или бинарным.
    //Если это начало выражения или перед текущим знаком была бинарная
    //операция или открывающая скобка - знак унарный.
    bool sign = true;
    //Имя переменной
    std::string x_name;
    std::string functions = {"sin", "cos"};
    std::map<eTokens, int> token_priority = {{L_BRUNCH, 0},
                                             {R_BRUNCH, 0},
                                             {PLUS,     1},
                                             {MINUS,    1},
                                             {MUL,      2},
                                             {DIV,      2},
                                             {POW,      3},
                                             {SQRT,     3},
                                             {U_MINUS,  4},
                                             {FUNC,     5}};
    const int funcs_count = 2;
 
    inline char getChar(std::string &);
    inline void backChar();
    bool        isFunc(std::string &);
    std::string getNumber(std::string &);
    std::string getName(std::string &);
    std::string getToken(std::string &);
    std::string pop();
    void        deleteSpaces(std::string);
    std::string toPolish(std::string &);
}
 
char __Parser::getChar(std::string &s)
{
    return s[char_pos++];
}
 
void __Parser::backChar()
{
    char_pos--;
}
 
bool __Parser::isFunc(std::string &s)
{
    for (int i = 0; i<funcs_count; i++)
    {
        if (s.find(functions[i]))
        {
            return true;
        }
    }
    return false;
}
 
std::string __Parser::getNumber(std::string &s)
{
    std::string result;
    char c = getChar(s);
 
    while ((c>'0') && (c<'9'))
    {
        result += c;
        if (char_pos == s.length() - 1)
        {
            return result;
        }
        c = getChar(s);
    }
    backChar();
 
    return result;
}
 
std::string __Parser::getName(std::string &s)
{
    std::string result;
    char c = getChar(s);
    bool end_str = false;
 
    while (isalpha(c))
    {
        result += c;
        if (char_pos == s.length() - 1)
        {
            end_str = true;
            break;
        }
        c = getChar(s);
    }
    if (!end_str)
    {
        backChar();
    }
 
    if (isFunc(result))
    {
        curr_token = FUNC;
    }
    else
    {
        curr_token = NAME;
        if (x_name.empty())
        {
            x_name = result;
        }
        else
        {
            throw Error("ошибка: неверное имя переменной", char_pos - result.length());
        }
    }
 
    return result;
}
 
std::string __Parser::getToken(std::string &s)
{
    char c = getChar(s);
 
    switch (c)
    {
        case '+': case '-':  case '*': case '/':
        case '^': case '\\': case '(': case ')':
            curr_token = (eTokens)c;
            std::string result;
            result += c;
            return result;
    }
 
    if ((c>'0') && (c<'9'))
    {
        backChar();
        curr_token = NUMBER;
        return getNumber(s);
    }
 
    return getName(s);
}
 
std::string __Parser::pop()
{
    std::string result = __Stack::pop();
    return getToken(result);
}
 
void __Parser::deleteSpaces(std::string s)
{
    for (uint16_t i = 0; i<s.length(); i++)
    {
        if (s[i] == ' ')
        {
            s.erase(i, 1);
        }
    }
}
 
std::string __Parser::toPolish(std::string &s)
{
    char_pos = 0;
    sign = true;
 
    int last = s.length() - 1;
    std::string result;
    std::string token_value;
    __Stack::clear();
 
    using __Stack::push;
    while (char_pos != last)
    {
        token_value = getToken(s);
        switch (curr_token)
        {
            case NUMBER:
            {
                sign = false;
                result += token_value + " ";
                break;
            }
 
            case L_BRUNCH:
            {
                sign = true;
                push(token_value);
                break;
            }
 
            case R_BRUNCH:
            {
                sign = false;
                while (true)
                {
                    token_value = pop();
                    if (curr_token == L_BRUNCH)
                    {
                        break;
                    }
                    result += token_value + " ";
                }
                break;
            }
 
            case PLUS:{} case MINUS:{} case MUL:{}
            case DIV:{}  case POW:{}   case SQRT:{}
            case FUNC:
            {
                if (curr_token == MINUS)
                {
                    if (sign)
                    {
                        curr_token = U_MINUS;
                    }
                }
                sign = false;
                eTokens tok = curr_token;
                std::string buff;
                while (true)
                {
                    buff = pop();
                    if (token_priority[curr_token]>=token_priority[tok])
                    {
                        result += buff + " ";
                    }
                    else
                    {
                        break;
                    }
                }
                push(buff);
                push(token_value);
                break;
            }
 
            case NAME:
            {
                sign = false;
                result += token_value + " ";
                break;
            }
 
            default:
            {
                throw Error("ошибка: неизвестный токен", char_pos);
                break;
            }
        }
    }
 
    return result;
}
 
std::string Parser::toPolish(std::string s)
{
    __Parser::deleteSpaces(s);
    return __Parser::toPolish(s);
}
main.cpp
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>
#include "parser.h"
 
using namespace std;
 
int main()
{
    cout << Parser::toPolish("x + 2");
}
P.S.
Еще хотел бы попросить, если не сложно, оценить код, может что-то посоветовать, за что-то наругать, за что-то кинуть тапком и т.д. А то мало ли.
P.P.S.
Обработка ошибок пока что только в зародыше, поэтому на нее не смотрите.

Благодарю за внимание.
Миниатюры
Парсер для математических выражений  
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 15:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru