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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 72, средняя оценка - 4.78
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
#1

Дерево разбора - C++

12.03.2011, 02:03. Просмотров 10100. Ответов 33

Вообщем суть - нужно уметь распарсить любую логическую формулу и затем сделать с ней нечто по заданию (курсовик). Спросили у препода как лучше, он сказал, что лучше через дерево...
Ну с деревом вопросов нет...
Но вот как распарсить и расставить приоритет у формул - вопрос.

Допустим есть некая формула (x&y&z)|t

Получается дерево должно выглядеть как.
корень - |
лево - (x&y&z)
право - t

Ну и так, далее. Я правильно уловил суть? Вопрос, как расставить так приоритеты, но мне не нужен код, просто некое небольшое объяснение и мысли по этому поводу. Заранее спасибо)
1
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.03.2011, 02:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Дерево разбора (C++):

Бинарное дерево. Удалить из дерева часть вершин так, чтобы оставшееся дерево стало пирамидой - C++
Дано бинарное дерево. Удалить из дерева часть вершин так, чтобы оставшееся дерево стало пирамидой.

Дано дерево. Распечатать дерево по уровням - C++
Дано дерево. Распечатать дерево по уровням.

Ошибка в функции разбора уравнения - C++
часть программы. функция принимает от пользователя уравнение формата 1x + 2x + 3x = 5 ну, там дальше она должна будет брать коэффициенты...

Получить переменные из строки путём её разбора - C++
Во время работы программы функция задается в виде строки, что имеет формат "axx + bx + c", включая числа, арифметические операции,...

Программа разбора и вычисления значения арифметического выражения - C++
Написать программу разбора и вычисления значения арифметического выражения. На входе программы — строка, содержащая числа, скобки «(» и...

Исходное бинарное дерево превратить в бинарное дерево поиска, при этом сохранив его структуру - C++
Помогите, не могу понять!( Нужно исходное бинарное дерево превратить в бинарное дерево поиска, при этом сохранив его структуру. вот...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
silent_1991
Эксперт С++
4964 / 3040 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
12.03.2011, 13:39 #16
alex_x_x, да, но что мешает сделать его для выражения?
0
Ma3a
Эксперт C++
617 / 461 / 31
Регистрация: 28.01.2011
Сообщений: 605
12.03.2011, 13:47 #17
Вообще, обратная польская может здесь сработать, так как по сути она обозначает инверсный порядок обхода дерева, когда первым посещаются сыновья узла слева направо, и только потом уже родительский узел, так что запись вида " a b c * +" в принципе в дерево перевести не сложно, набираем операнды в стек, ну и при встрече оператора генерируем узел и цепляем к дереву.
А так я лично, если требуется разобрать что-нибудь маленькое, обычно обхожусь LL-анализом или алгоритмом Эрли (нерационально конечно малость, но зато писать легко), хоть и приходится целую грамматику определять ради этого.

Добавлено через 7 минут
И еще если есть больше желания получить работающий код, чем даже просто интерес к парсингу, чтобы всё от руки набивать, то я бы рекомендовал попробовать генераторы парсеров. К bison'у и flex'у у меня конечно отношение не очень, но вот boost::spirit рекомендовать могу, там грамматику забить не сложно, да и генерация дерева делается по сути очень просто, только позаботиться о рекурсивной обертке для дерева типа
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Tree;
 
typedef boost::variant<
        boost::recursive_wrapper<Tree>
        , std::string
    > Tree_node;
 
struct Tree
    {
    std::string _operator;
    std::vector<Tree_node> children;
    };
 
BOOST_FUSION_ADAPT_STRUCT(
    Tree,
    (std::string,_operator)
    (std::vector<Tree_node>,children)
    )
Дабы основу для построения дерева обозначить, обозначить синтезируемые атрибуты у правил грамматики необходимые и, если хочется перевести это дерево в своё деревянное представление, то наследуете посещатель узлов дерева от boost::static_visitor и определяете те действия, что нужны.
2
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
12.03.2011, 13:52 #18
Цитата Сообщение от silent_1991 Посмотреть сообщение
alex_x_x, да, но что мешает сделать его для выражения?
нужно знать про цепочки, грамматики, синтаксические деревья итп отдельная тема
тут же тривиальный подход

Добавлено через 2 минуты
Цитата Сообщение от Ma3a Посмотреть сообщение
boost::spirit
про него говорят, что он либо не нужен, потому что слишком сложен для задачи, либо не нужен потому что становится слишком тормозным для нее
вообщем не вижу смысла в учебной программе использовать черноящиковые алгоритмы разбора
1
silent_1991
Эксперт С++
4964 / 3040 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
12.03.2011, 13:53 #19
Ну, это же было только предложение глянуть пару ссылочек, а не подстрекательство немедленно писать анализатор и больше никого не слушать
1
Ma3a
Эксперт C++
617 / 461 / 31
Регистрация: 28.01.2011
Сообщений: 605
12.03.2011, 13:59 #20
alex_x_x, в данном случае я просто предложил, что можно сделать. Да, он не быстрый, писать много надо, да и вообще люди либо любят его, либо ненавидят, известный момент Я лично за польскую запись, а boost просто пришелся к слову, как вариант.
1
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
12.03.2011, 15:21  [ТС] #21
Нашел ошибочку...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Parser::create_tree(std::string& str)
{
        if(!lays_check(str))
                throw std::runtime_error("Expression is incorrect");
        std::string left;
        std::string right;
        std::pair<std::string, std::string> left_right=create_tree_helper(str, find_first_without_brakes);
        if(left_right.first.empty() && left_right.second.empty() && str.find('(') != std::string::npos)
        left_right=create_tree_helper(str, find_first_in_brakes);
        left=left_right.first;
        right=left_right.second;
        if(!left.empty())
                create_tree(left);
        if(!right.empty())
                create_tree(right);
}
Так, все работает нормально, ранее он вызывал и вторую функцию... Теперь все верно...

Только остается 1 вопрос, который я решить никак не могу... Ну допустим у нас есть дерево и функция insert в нем выглядит след. образом.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void tree_node::insert_h(T val_)
{
    if(left && val_ <= val)
       left->insert_h(val_);
    else if(!left && val_ <= val)
       left=new tree_node(val_);
    else if(right && val_ > val)
       right->insert_h(val_);
    else
       right=new tree_node(val_);
}
 
void tree::insert(T val_)
{
    !curr ? curr=new tree_node(val_) : curr->insert_h(val_);
}
Допустим есть структура Token с приоритетами.
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
class Token
{
public:
        Token(char c_='0', int t_=0, Prior::Priority pr_=Prior::one):
          c(c_), t(t_), pr(pr_)
        {
        }
        const char GetKind() const
        {
                return c;
        }
        const int GetNumb() const
        {
                return t;
        }
        const Prior::Priority GetPrior() const
        {
                return pr;
        }
private:
        int t;
        char c;
        Prior::Priority pr;
};
У каждого токена есть приоритет... Если оператор сравнения делать по приоритету, т.е.
C++
1
2
3
4
5
6
7
8
bool operator <(const Token& f, const Token& s)
{
    return f.GetPrior() < s.GetPrior();
}
bool operator <=(const Token& f, const Token& s)
{
    return f.GetPrior() <= s.GetPrior();
}
Допустим есть выражение
3+4*7-5
Имеем при такой вставке
__________+
_____3 ______*
___5____-
__4
_7

При приоритетах соответственно число - 1, + - 2, * - 3...
Следовательно не вариант... Вообщем я немного в ступоре...

Что можете подсказать по этому поводу?
0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
12.03.2011, 16:14 #22
Цитата Сообщение от ForEveR Посмотреть сообщение
При приоритетах соответственно число - 1, + - 2, * - 3...
какие у тебя приоритеты не пойму..

Добавлено через 4 минуты
если разбор идет слева направо дерево должно получится таким
Bash
1
2
3
4
      +
  3        -
        *       5
     4    7
Добавлено через 2 минуты
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
#include <string>
#include <iostream>
#include <sstream>
#include <cassert>
 
enum Type{PLUS,MUL,VAL};
 
struct Node;
 
struct Node
{ 
   Type type;
   Node* left, *right;
   int data;
   bool reverse; 
};
 
void recurs( std::string str, Node* node )
{
  
   int i, c; 
   bool reverse; 
   std::cout << str << std::endl; 
   static const std::string c_str = "+-*/()"; 
   for( unsigned t = PLUS; t < VAL; ++t )
      for( i=0, c=0;i<str.size();++i )
      {
          size_t pos = c_str.find( str[i] ); 
          if( pos == 4 )
            ++c;
          else if( pos == 5 )
            --c;
          else if( !c && pos < (t==PLUS?2:4) )
          {
            node->left = new Node;
            node->right = new Node; 
            node->type = static_cast<Type>( t ); 
            node->reverse = pos % 2;
            std::cout << ( node->type == PLUS ? "+" : "*" ) << std::endl; 
            recurs( str.substr( 0, i ), node->left );
            recurs( str.substr( i+1, str.size() - i ), node->right ); 
            return; 
          }        
      } 
     
   if( str[0] == '(' && str[str.size()-1] == ')' )
   { 
      recurs( str.substr( 1, str.size() - 2 ), node ); 
      return; 
   } 
     
   node->type = VAL;
   std::stringstream istr( std::stringstream::in | std::stringstream::out );
   istr << str;
   istr >> node->data; 
}
 
int recurs( Node* node )
{
  std::cout << "<<" << std::endl;
  int val = 0; 
  switch( node->type )
  {
    case PLUS:  
      val = recurs( node->left ) + (node->reverse ? 
                                    - recurs( node->right ) :
                                    + recurs( node->right ) )  ;
      break; 
    case MUL:
      val = recurs( node->left ) * (node->reverse ? 
                                     1.0/recurs( node->right ) :
                                     recurs( node->right ) )  ; 
      break; 
    case VAL:
      val = node->data;
      std::cout << "(" << val << ")" << std::endl;
      break; 
    default:
      assert( 0 );  
      return -1;  
  }   
  delete node; 
  return val; 
} 
 
int main()
{
   std::string str = "3+4*7-5";
   Node* node = new Node;;
   recurs( str, node );
   std::cout << "result = " << recurs( node );  
}
добавил -/
унарный минус за бортом
1
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
12.03.2011, 19:42  [ТС] #23
М... Вот что вышло.

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
#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
#include <stack>
 
template<class T>
class Tree
{
public:
    struct Node
    {
        Node(T elem_):elem(elem_), left(0), right(0)
        {
        }
        Node* left;
        Node* right;
        T elem;
        void in_order_print_helper()
        {
            if(left)
            {
                std::cout<<'\t';
                left->in_order_print_helper();
            }
            std::cout<<'\t'<<elem<<'\n';
            if(right)
            {
                std::cout<<'\t';
                right->in_order_print_helper();
            }
        }
        int in_order_count_helper()
        {
            int val=0;
            switch(elem.GetKind())
            {
            case '+':
                {
                    val=left->in_order_count_helper() + 
                        right->in_order_count_helper();
                }
                break;
            case '-':
                {
                    val=left->in_order_count_helper() -
                        right->in_order_count_helper();
                }
                break;
            case '*':
                {
                    val=left->in_order_count_helper() *
                        right->in_order_count_helper();
                }
                break;
            case Token::number:
                {
                    val=elem.GetNumb();
                }
            }
            return val;
        }
    };
    Tree():curr(0)
    {
    }
    Node* curr;
    void in_order_print()
    {
        curr->in_order_print_helper();
    }
    int in_order_count()
    {
        return curr->in_order_count_helper();
    }
};
 
class Token
{
public:
        enum Type {add='+', multi='*', sub='-', div='/',
            number='8', No};
        Token(Type type_=No, int t_=0):
          type(type_), t(t_)
        {
        }
        const Type GetKind() const
        {
                return type;
        }
        const int GetNumb() const
        {
                return t;
        }
private:
        int t;
        Type type;
};
 
std::ostream& operator <<(std::ostream& os, const Token& tok)
{
    if(tok.GetKind() != Token::number)
        os<<static_cast<char>(tok.GetKind());
    else
        os<<tok.GetNumb();
    return os;
}
 
class Parser
{
public:
        Parser():sem_tree(Tree<Token>())
        {
        }
        void create_tree(Tree<Token>::Node** s_tree, std::string& str);
        Tree<Token> sem_tree;
private:
        bool lays_check(const std::string& str);
        template<class TernaryFunction>
        std::pair<std::string, std::string> create_tree_helper(Tree<Token>::Node** s_tree, std::string& str, TernaryFunction foo);
};
 
bool isNumeric(const std::string& some)
{
        int one=0;
        std::stringstream ss(some);
        ss >> one;
        std::stringstream ss2;
        ss2<<one;
        return (one && some.find_first_not_of(ss2.str()) == std::string::npos); 
}
 
std::string::iterator find_first_in_brakes_helper(std::string& some, const char first, const char second)
{
        std::string tmp;
        tmp+=first;
        tmp+=second;
        std::string::iterator iter;
        size_t idx=0;
        if(*some.begin() == '(' && *(some.begin()+1) == '(')
                idx=some.find_last_of(tmp);
        else
                idx=some.find_first_of(tmp);
        if(idx != std::string::npos)
        {
                iter=some.begin()+idx;
                some.erase(std::find(some.begin(), some.end(), '('));
                some.erase(std::find(some.begin(), some.end(), ')'));
                iter-=1;
                return iter;
        }
        return some.end();
}
 
std::pair<std::pair<std::string, std::string>, bool> find_first_in_brakes(std::string& some, const char first, const char second)
{
        if(isNumeric(some))
                return std::make_pair(std::make_pair(some, ""), true);
        std::string::iterator iter=find_first_in_brakes_helper(some, first, second);
        if(iter == some.end())
                return std::make_pair(std::make_pair("",""), false);
        std::string begin;
        begin.assign(some.begin(), ++iter);
        std::string end;
        end.assign(iter, some.end());
        return std::make_pair(std::make_pair(begin, end), true);
}
 
std::string::const_iterator find_first_without_brakes_helper(const std::string& some, const char first, const char second)
{
        std::stack<char> lays;
        for(std::string::const_iterator iter=some.begin(); iter != some.end(); ++iter)
        {
                if(*iter == '(')
                        lays.push(*iter);
                else if(*iter == ')')
                        lays.pop();
                if(lays.empty() && (*iter == first || *iter == second))
                {
                        return iter;
                }
        }
        return some.end();
}
 
std::pair<std::pair<std::string,std::string>, bool> find_first_without_brakes(const std::string& some, const char first, const char second)
{
        if(isNumeric(some))
                return std::make_pair(std::make_pair(some, ""), true);
        std::string::const_iterator iter=find_first_without_brakes_helper(some, first, second);
        if(iter == some.end())
                return std::make_pair(std::make_pair("", ""), false);
        std::string res;
        res.assign(some.begin(), ++iter);
        std::string end;
        end.assign(iter, some.end());
        return std::make_pair(std::make_pair(res, end), true);
}
 
int toInt(const std::string& some)
{
    int one;
    std::stringstream ss(some);
    ss>>one;
    return one;
}
 
template<class TernaryFunction>
std::pair<std::string, std::string> Parser::create_tree_helper(Tree<Token>::Node** s_tree, std::string &str, TernaryFunction foo)
{
        const std::string opers="+-*/";
        bool state=false;
        std::string left;
        std::string right;
        for(std::string::const_iterator iter=opers.begin(); iter != opers.end(); iter+=2)
        {
        std::pair<std::pair<std::string, std::string>, bool> pair;
        pair=foo(str, *iter, *(iter+1));
        if(pair.second == true)
        {
                left=pair.first.first;
                right=pair.first.second;
                char c='\n';
                if(opers.find(left[left.size()-1]) != std::string::npos && !left.empty())
                {
                        c=left[left.size()-1];
                        *s_tree=new Tree<Token>::Node(Token(static_cast<Token::Type>(c), 0));
                        left.resize(left.size()-1);
                }
                std::cout<<c<<'\n'<<left<<'\n'<<right<<'\n';
                std::cout<<'\n';
                if(isNumeric(left))
                {
                    (*s_tree)->left=new Tree<Token>::Node(Token(Token::number, toInt(left)));
                    left.clear();
                }
                if(isNumeric(right))
                {
                    (*s_tree)->right=new Tree<Token>::Node(Token(Token::number, toInt(right)));
                    right.clear();
                }
                state=true;
                break;
        }
        else
                continue;
        }
        return std::make_pair(left, right);
}
 
void Parser::create_tree(Tree<Token>::Node** s_tree, std::string& str)
{
        if(!lays_check(str))
                throw std::runtime_error("Expression is incorrect");
        std::string left;
        std::string right;
        std::pair<std::string, std::string> left_right=create_tree_helper(s_tree, str, find_first_without_brakes);
        if(left_right.first.empty() && left_right.second.empty() && str.find('(') != std::string::npos)
            left_right=create_tree_helper(s_tree, str, find_first_in_brakes);
        left=left_right.first;
        right=left_right.second;
        if(!left.empty())
                create_tree(&(*s_tree)->left, left);
        if(!right.empty())
                create_tree(&(*s_tree)->right, right);
}
 
bool Parser::lays_check(const std::string& str)
{
        std::stack<char> stck;
        for(std::string::const_iterator iter=str.begin(); iter != str.end(); ++iter)
        {
                if(*iter == '(')
                        stck.push(*iter);
                else if(*iter == ')')
                        stck.pop();
        }
        return stck.empty();
}
 
int main()
{
        Parser one;
        one.create_tree(&one.sem_tree.curr, std::string("(10+1)*(5+6*(3+1))+4*(3+1)"));
        one.sem_tree.in_order_print();
        std::cout<<one.sem_tree.in_order_count()<<'\n';
        return 0;
}
Считает верно. Собственно вот такой полубыдлокод) Буду усовершенствовать... Стоит думаю сделать производный класс от бинарного дерева (дерево разбора) - и работать с ним соответственно. Ну а пока как-то так.
1
Iron Bug
12.03.2011, 20:49
  #24

Не по теме:

Цитата Сообщение от alex_x_x Посмотреть сообщение
про него говорят, что он либо не нужен, потому что слишком сложен для задачи, либо не нужен потому что становится слишком тормозным для нее
вообщем не вижу смысла в учебной программе использовать черноящиковые алгоритмы разбора
boost::spirit действительно довольно медленный,хотя ничуть не сложный. хорошая замена spirit'у - boost::expressive.
вообще, существует много генераторов парсеров и LL, и LR, в том числе очень, очень быстрых. но для учебной работы это не годится, соглашусь

0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
13.03.2011, 01:34  [ТС] #25
Кстати, еще вопрос. Под парсинг разных вещей нужно будет переделывать код? Универсальность некая впринципе возможна?
Допустим парсим выражения +-*/ или же &| - отличия минимальные?
0
silent_1991
Эксперт С++
4964 / 3040 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
13.03.2011, 01:35 #26
В принципе, я думаю, да, ведь как-никак & - эквивалент *, а | - эквивалент +.
1
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
13.03.2011, 01:50 #27

Не по теме:

Цитата Сообщение от Iron Bug Посмотреть сообщение
boost::spirit действительно довольно медленный,хотя ничуть не сложный. хорошая замена spirit'у - boost::expressive.
вообще, существует много генераторов парсеров и LL, и LR, в том числе очень, очень быстрых. но для учебной работы это не годится, соглашусь
честно не пробовал, пока еще руки не доходили .. =)


Цитата Сообщение от ForEveR Посмотреть сообщение
Кстати, еще вопрос. Под парсинг разных вещей нужно будет переделывать код? Универсальность некая впринципе возможна?
Допустим парсим выражения +-*/ или же &| - отличия минимальные?
серьезный вопрос, если языки построены на одних грамматиках, то один прием пойдет
эти можно сказать эквивалентные (если + - только оставить), но не эквивалентные грамматике с++ например)
вообще прикольно было бы тему по грамматикам замутить
1
silent_1991
13.03.2011, 01:53
  #28

Не по теме:

Цитата Сообщение от alex_x_x Посмотреть сообщение
вообще прикольно было бы тему по грамматикам замутить
Вот я и говорю, давно хотел что-нибудь подобное написать, но руки пока не доходят)))

1
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
13.03.2011, 02:00  [ТС] #29
alex_x_x, Вообщем лучше все же переписывать я так понимаю, чем пытаться найти корректное и удобное обобщение, быстрее получится переписать...
Про тему по грамматикам - да, было бы очень интересно посмотреть как реализуются разного вида парсеры и создается разного вида грамматика.

Не по теме:

ЗЫ ты меня про компиляторы позавчера спрашивал, а сам ты пробовал их писать кстати? Просто интересно стало.

0
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
13.03.2011, 02:04 #30
Цитата Сообщение от ForEveR Посмотреть сообщение
ЗЫ ты меня про компиляторы позавчера спрашивал, а сам ты пробовал их писать кстати? Просто интересно стало.
ну это был не очень полноценный язык с одним одним типом данных, но поддерживал процедуры, ввод-вывод, условия, циклы итп))
и стековую машину к нему
это было небольшой курсовой

была тема пишем интерпретатор, но она кажись не была заточена под теорию
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2011, 02:04
Привет! Вот еще темы с ответами:

Что вернет стековая функция разбора пар скобок? - C++
Что вернет функция, если она принимает как параметр такую строку: (5*(x/(y*5))*z)+((1/7)*z*2)-x С точки зрения логики стека.

Процедура разбора полного пути к файлу, представленного строкой - C++
Разработать процедуру (и вспомогательную программу) разбора заданной текстовой строки (задается переменной окружения или параметром...

Что вернет стековая функция разбора пар скобок? - C++
Что вернет функция, проверяющая баланс скобок, если она принимает как параметр такую строку: ((х-((1/х)+у-4)*(z/4+(2-x*3)) Рассмотреть...

Напишите программу, которая бы читала дерево в формате (а) и затем печатала бы это дерево в формате (б). - C++
Представление дерева: а) Д (Б (А, Ф (В,)), Е (,З (Ж, И))) б) Д Б А Ф ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
13.03.2011, 02:04
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru