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

Задачи для тренировки и лучшего понимания - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Теория плагинов http://www.cyberforum.ru/cpp/thread123914.html
Всем привет. Для одной моей проги, нужно реализовать поддержку плагинов. Плагины предполагаются простенькие, написанные на Си. То, что плагин, это просто .so файл - понятно. То, что прога может дергать из .so файла функции - тоже понятно. 1. Непонятно то, как сам плагин сможет дергать функции из программы? 2. Программа написана на С++, но плагины предполагаю писать на Си, во избежания...
C++ ./massdown: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./massdown) всем хай! собираю свою программу на новом железе х86_64 долго не получалось скомпилить. при линковке получал вот такое сообщение: relocation R_X86_64_32 against `a local symbol' я так понял, это из-за того что часть библиотек от которых зависит цель, были собраны как 32-ух битные. но с этим вроде все нормально, пересобрал все либы - скомпилировалось. теперь при запуске получаю такое... http://www.cyberforum.ru/cpp/thread98890.html
Как понять этот константный указатель? C++
В общем, имеется класс Cat. Объект класса - SimpleCat. И имеется функция с константым указателем: const SimpleCat* const FunctionTwo(const SimpleCat* const theCat) Что обозначают все эти const? Насколько я понимаю: 1. Константный указатель. 2. Может ссылаться только на FunctionTwo 3. Ничего не изменяет в объекте. 4. Ничего не делает с объектом theCat.
C++ Перехват и подмена вызываемых функций
Здравствуйте. Нужно подменить вызов таких функций как open(), lstat(), stat(), read(), write(), mkdir(), chdir(), getcwd() для определенного процесса. Интересует мнение других. Как бы вы реализовали эту задачу. Спасибо!

Показать сообщение отдельно
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
09.08.2010, 00:37     Задачи для тренировки и лучшего понимания
Цитата Сообщение от nikkka Посмотреть сообщение
И тут fasked понял что его будут бить. Может даже ногами.
я исправлюсь! обязательно, обязательно!
Вот даже простейший анализатор арифметического выражения сочинил. Потом прикручу его к калькулятору.
В общем суть такова: анализатор принимает на вход строку и возвращает список токенов.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "parser.h"
 
int main()
{
   Parser pars;
   std::list<Token> expr = pars.DivideTextOnTokens("VAL + B/C *       2");
 
   for(auto it = expr.begin(); it != expr.end(); ++it)
      if(it->GetTokenText() != " ")
         std::cout << it->GetTokenText();
   std::cout << std::endl;
 
   system("PAUSE");
}
пробелы я решил не удалять из списка токенов. не знаю почему. может пригодятся
определение типа токена еще тоже не сделал... устал чего-то

HEADER_TOKEN_H
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
#pragma once
 
#include <string>
 
enum TokenTypes
{
   Unknown = 0,
   Integer,
   Operator
};
 
class Token
{
public:
   Token();
   Token(const Token &w);
   Token(const std::string &TokenText, TokenTypes TokenType);
 
   TokenTypes GetTokenType() const;
   std::string GetTokenText() const;
 
private:
   TokenTypes Type; 
   std::string Text;
};
 
 
Token::Token() : Type(Unknown)
{
}
 
Token::Token(const Token &w) : Type(w.Type), Text(w.Text)
{
}
 
Token::Token(const std::string &TokenText, TokenTypes TokenType)
{
   Text = TokenText;
   Type = TokenType;
}
 
 
TokenTypes Token::GetTokenType() const
{
   return Type;
}
 
std::string Token::GetTokenText() const
{
   return Text;
}

HEADER_PARSER_H
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
#pragma once
 
#include "token.h"
#include <list>
#include <vector>
#include <algorithm>
 
#include <iostream>
 
class Parser
{
public:
   Parser();
 
public:
   std::list<Token> DivideTextOnTokens(const std::string &Text);
 
private:
   Token GetFirstTokenFromText(const std::string &Text);
 
private: 
   static const std::string::size_type EndOffset = -1;
   std::string::size_type Offset;
 
   std::list<Token> Tokens;
 
   //std::vector<std::string> Keywords;
   std::string Operators;
   std::string Dividers;
};
 
Parser::Parser() : Offset(0)
{
   Operators = "-+*/()";
   Dividers = " ";
}
 
 
Token Parser::GetFirstTokenFromText(const std::string &Text)
{
   std::string ReturnTokenText;
   std::string Delimeters = Operators + Dividers;
   std::string::size_type DelimPosition = Text.find_first_of(Delimeters, Offset);
 
   if(DelimPosition == Text.npos)
   {
      ReturnTokenText = Text.substr(Offset);
      Offset = EndOffset;
   }
   else
   {
      ReturnTokenText = Text.substr(Offset, std::max((std::string::size_type)1, DelimPosition - Offset));
      Offset = std::max(DelimPosition, Offset + 1);
   }
 
   return Token(ReturnTokenText, TokenTypes::Unknown);
}
 
std::list<Token> Parser::DivideTextOnTokens(const std::string &Text)
{
   if(Text.empty())
   {
      std::cerr << "Parser::DivideTextOnTokens - Text is Empty" << std::endl;
   }
 
   while(Offset != EndOffset)
   {
      Token CurrentToken(GetFirstTokenFromText(Text));
      Tokens.push_back(CurrentToken);
   }
 
   return Tokens;
}


Вроде так неплохо вышло, а главное, что потом в принципе можно будет расширить.
В смысле на следующих этапах вычислений калькулятора можно предполагать, что список токенов уже составлен правильно, ну на край для тестирования составить его вручную.

Да и чуть самое главное не забыл. После запуска программки, текст которой приведен выше на экран выводится следующее:
Код
VAL+B/C*2
Сам список содержит такие элементы:
Код
+		[0]	{Type=Unknown Text="VAL" }	Token
+		[1]	{Type=Unknown Text=" " }	Token
+		[2]	{Type=Unknown Text="+" }	Token
+		[3]	{Type=Unknown Text=" " }	Token
+		[4]	{Type=Unknown Text="B" }	Token
+		[5]	{Type=Unknown Text="/" }	Token
+		[6]	{Type=Unknown Text="C" }	Token
+		[7]	{Type=Unknown Text=" " }	Token
+		[8]	{Type=Unknown Text="*" }	Token
+		[9]	{Type=Unknown Text=" " }	Token
+		[10]	{Type=Unknown Text=" " }	Token
+		[11]	{Type=Unknown Text=" " }	Token
+		[12]	{Type=Unknown Text=" " }	Token
+		[13]	{Type=Unknown Text=" " }	Token
+		[14]	{Type=Unknown Text=" " }	Token
+		[15]	{Type=Unknown Text=" " }	Token
+		[16]	{Type=Unknown Text="2" }	Token
Как я уже сказал, что пробелы не убирал и определение типа токена тоже не делал.
Поэтому видно, что все токены имеют неизвестный тип, а каждый пробел представлен как отдельный токен.

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