Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.61/54: Рейтинг темы: голосов - 54, средняя оценка - 4.61
4 / 4 / 0
Регистрация: 23.01.2009
Сообщений: 18

Преобразование строки в исполняемую инструкцию.

05.07.2009, 12:05. Показов 10336. Ответов 32
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, пожалуйста, возможно ли задать строку, к примеру:
string str="sin(x)*log(x)", а затем преобразовать в вид: double f=sin(x)*log(x)?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.07.2009, 12:05
Ответы с готовыми решениями:

Перевод строки в исполняемую функцию
Недавно столкнулся с проблемой перевода вводимой строки в исполняемую программой функцию. Ну например пользователь вводит Sin(x+pi), а...

Как вставить ресурсы локализации в исполняемую сборку?
Привет, народ! Делаю приложение на windows forms (.NET Framework 4.6). Понадобилось сделать локализацию. Сделал как указано здесь....

Зашить в исполняемую программу дополнительный файл (файлы)
Задача: создать один exe, содержащий в себе интерпретатор питоновский + некоторый набор файлов. Тобишь, чтобы юзер запускал программу не...

32
85 / 85 / 6
Регистрация: 13.10.2008
Сообщений: 144
05.07.2009, 13:39
Можно, это называется парсингом. копайте в сторону "парсеров". Могу посоветовать книгу "Полный справочник по C#" Г. Шилдта, там предпоследняя глава посвящена созданию синтаксического анализатора (парсера) методом рекурсивного спуска.
1
 Аватар для exe-dealer
308 / 161 / 11
Регистрация: 07.06.2009
Сообщений: 538
05.07.2009, 14:24
не совсем понятно что нужно. Где это будет использоваться?
0
4 / 4 / 0
Регистрация: 23.01.2009
Сообщений: 18
05.07.2009, 16:31  [ТС]
Цитата Сообщение от exe-dealer Посмотреть сообщение
не совсем понятно что нужно. Где это будет использоваться?
К примеру, мне надо вводить функцию для построения графика. Не переписывать же каждый раз код для разных функций. Я сделал такую программу с использованием Excel, но это не совсем то, что хочется.

Добавлено через 2 минуты 29 секунд
Цитата Сообщение от Feuer Посмотреть сообщение
Можно, это называется парсингом. копайте в сторону "парсеров". Могу посоветовать книгу "Полный справочник по C#" Г. Шилдта, там предпоследняя глава посвящена созданию синтаксического анализатора (парсера) методом рекурсивного спуска.
Спасибо, такая книга у меня есть, но я , видимо, не дошел до этой главы.
0
 Аватар для exe-dealer
308 / 161 / 11
Регистрация: 07.06.2009
Сообщений: 538
05.07.2009, 17:17
можешь впрячь компиллер C# или vb.net которые лежат в папке с фреймворком, а потом подключать скомпиленную сборку динамически
0
68 / 24 / 2
Регистрация: 16.05.2009
Сообщений: 73
10.07.2009, 21:05
я кстати сейчас дописываю анализатор формул..... бинарные операторы, скобки, функции, константы, переменные (все можно добавлять своё). для разных значений (числа, вектора, матрицы и тд)..... как закончу - выложу. Естесно бесплатно))) если интересно - пиши в асю 37611678пять. (ответ на анти-спам "М" русская)
0
84 / 83 / 6
Регистрация: 13.07.2009
Сообщений: 107
14.07.2009, 00:25
Невик, а вот когда ты разложишь строку на элементы, есть несколько способов, как ты вызовешь функции.
Можно просто писать, что-то примитивное типа:

C#
1
2
3
if (s=="sin") res=sin(a);
else if (s=="cos") res=cos(a);
else if (...)
А можно использовать средства отражения (reflections):
У любого класса можно получить список методов, полей, свойств. Вот так например получить все методы произвольного класса, например стандартного Math
C#
1
2
3
4
5
Type aType=typeof(Math);
//в качестве attr можно конкретизироваться список каких методов нужно получить (см. документацию по отражениям)
MethodInfo[] methodsList=aType.GetMethods(attr);
//имя i метода
string name=methodsList[i].Name;
В последствии вызвать конкретную функцию можно так:
C#
1
2
3
4
5
6
      MethodInfo method=methodsList[i];
      //в массиве parameters можно передать произвольное число параметров, но если у тебя простые математические функции, то скорее всего параметр будет 1
      object[] parameters=new object[1];
      parameters[0]=0.5;
      //первый параметр функции Invoke равен null для статических методов или нужно указать объект класса, для нестатических методов
      method.Invoke(null,parameters);
Для своих нужд я реализовывал класс-контейнер объектов типа MethodInfo, полученных из произвольного класса, а потом вызывал необходимые методы, просто находя их в списке по имени и передавая необходимые параметры (метод Invoke в этом классе).
Короче, отражения мощный инструмент, о котором немнго можно почитать у того же Шилдта.
0
MCSD: APP BUILDER
 Аватар для IT_Exp
8795 / 1074 / 104
Регистрация: 17.06.2006
Сообщений: 32,602
14.07.2009, 01:12
Невик,
Подскажите, пожалуйста, возможно ли задать строку, к примеру:
string str="sin(x)*log(x)", а затем преобразовать в вид: double f=sin(x)*log(x)?

возможно.
гооглить "c# dynamic method"
для c# 3.0 и linq может оказаться полезным класс System.Linq.Expression
2
14.07.2009, 12:56

Не по теме:

Rififi, у меня есть достаточно большая подборка книг по C#, но нигде, даже в достаточно свежей "Pro C# 2008 and the NET 3.5 Platform Fourth Edition" Троэльсена, я не видел упоминания о классе DynamicMethod.

Оказывается этот способ позволяет получить максимальную скорость вызова эмитируемых функций, особенно по сравнению в вызовами через рефлексию.
Но у этого способа есть и обратная сторона, как пишут здесь:
There is a drawback to writing emitters: they are harder to write and harder to debug. So consider replacing general, Reflection code with emitted hard-code when the Reflection code is making your application sluggish.

Действительно, с рефлексией я разобрался сразу, а вот в этом случае беглого взгляда на пример в MSDN и в статье мне оказалось недосаточно.

В любом случае спасибо за еще один вариант.

0
MCSD: APP BUILDER
 Аватар для IT_Exp
8795 / 1074 / 104
Регистрация: 17.06.2006
Сообщений: 32,602
14.07.2009, 13:02
max_cn,
ну да, из-за эмитов оно конечно будет посложнее обычного парсинга да и в msil'е придётся чуток подразобраться, но, в конце концов, комменты в коде рулят, и лишние знания никогда не помешают (:
0
4 / 4 / 0
Регистрация: 23.01.2009
Сообщений: 18
14.07.2009, 22:55  [ТС]
Спасибо всем за помощь. Я пока дописываю свой парсер, ради тренировки, хотя я понял, что проще всего использовать для этого Excel. В дальнейшем попробую использовать возможности отражения.
0
4 / 4 / 0
Регистрация: 23.01.2009
Сообщений: 18
02.08.2009, 12:25  [ТС]
Вот я набросал небольшой парсер.
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Parsing
{
    public class Parser
    {
        private string term="";
        private double nam,arg;
        //Конструктор для выражений без переменных
        public Parser(string str)
        {
            //Обработка входной строки
            foreach (char ch in str)
            {
                if (Char.IsLetterOrDigit(ch) || ch == '^' || ch == '*' || ch == '/' || ch == '+' || ch == '-' || ch == ','
                    || ch == '(' || ch == ')' || ch == '.')
                {
 
                    term += ch;
                    if (ch == '.') term = term.Substring(0, term.Length - 1) + ',';
                }
            }
            arg = 0.0;
            nam = Product(term);
        }
        //Конструктор для выражений с переменными
       public Parser(double x,string str)
        {
            //Обработка входной строки
           foreach(char ch in str)
           {
               if(Char.IsLetterOrDigit(ch)||ch=='^'||ch=='*'||ch=='/'||ch=='+'||ch=='-'||ch==','
                   || ch == '(' || ch == ')' || ch == '.')
               {
                   
                   term += ch;
                   if (ch == '.') term = term.Substring(0, term.Length-1) + ',';
               }
           }
            arg = x;
            nam = Product(term);
        }
        //Метод обработки функций и присваивания значения переменной
       protected double Func(string s)
       {
           double element=0.0;
           string el = "";
           foreach (char ch in s)
           {
               if (!Char.IsLetter(ch)) break;
               el += ch;
           }
           if (el == "sin") element = Math.Sin(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "cos") element = Math.Cos(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "tan") element = Math.Tan(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "asin") element = Math.Asin(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "acos") element = Math.Acos(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "atan") element = Math.Atan(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "exp") element = Math.Exp(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "ln") element = Math.Log(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "abs") element = Math.Abs(Convert.ToDouble(s.Substring(el.Length)));
           if (el == "pi") element = Math.PI;
           if (el != "sin" && el != "cos" && el != "tan" && el != "acos" && el != "asin"
               && el != "atan" && el != "exp" && el != "log" && el != "abs"&&el!="pi") element = arg;
           return element;
       }
        //Метод возведения в степень
        protected double Power(string s)
        {
            double element;
            string el = "";
            foreach (char ch in s)
            {
                if (ch == '^') break;
                el += ch;
            }
                if (Char.IsLetter(el[0])) element =arg;
                else element = Convert.ToDouble(el);
                if (s.Substring(el.Length+1) != "")
                {
                    element = Math.Pow(element, Element(s.Substring(el.Length+ 1)));
                }
            
            return element;
        }
        //Расчет умножения/деления
        protected double Element(string s)
        {
            double element;
            string el = "";
            foreach (char ch in s)
            {
                if (ch == '*'||ch=='/') break;
                el += ch;
            }
            if (Char.IsLetter(el[0]) && el.IndexOf('^') == -1) element = Func(el);
            else
                { 
                    if (el.IndexOf('^') == -1) element = Convert.ToDouble(el);
                else element = Power(el);
                }
                if (el.Length <s.Length-1)
                {
                    if (s[el.Length] == '*') element *= Element(s.Substring(el.Length + 1));
                    if (s[el.Length] == '/') element /= Element(s.Substring(el.Length + 1));
                }
            return element;
        }
        //Входная точка. Выделение элементов
       protected double Product(string s)
        {
            int co = 0;
            string el = "";
           double element;
           string s1 = s;
           string sstr;
           if (s!=""&&(s[0] == '+' || s[0] == '-')) co++;
           for (int i = co; i < s.Length;i++)
           {
               if (s[i] == '(')
               {
                   el += Breckets(s.Substring(el.Length + co), out sstr);
                   s =el+sstr;
                       co = 0;
                       i = el.Length;
                   if(sstr=="") break;
               }
               if (s[i] == '+' || s[i] == '-') break;
               el += s[i];
           }
           if (s1[0] == '-') element = -Element(el);
                  else element = Element(el);
           if (el.Length<s.Length-1) element += Product(s.Substring(el.Length+co));
               
           return element;
       }
        //Обработка выражений в скобках
        protected string Breckets(string s,out string sstr)
        {
            int co = 1;
            int open = 1;
            int quit = 0;
            string el = "";
            double element;
                while (open!=quit)
                {
                    if (s[co] == '(')
                    {
                       open++;
                    }
                    if (s[co] == ')') quit++;
                    if (open == quit) break;
                    el += s[co];
                    co++;
                }
            if(co<s.Length-1) sstr =s.Substring(co+1);
            else
            {
                sstr = "";
            }
                element = Product(el);
               
            return element.ToString();}
        //Результат
        public double Nam
        {
            get
            {
                return nam;
            }
        }
 
    }
}
2
0 / 0 / 0
Регистрация: 25.08.2013
Сообщений: 9
16.09.2013, 15:15
Ещё бы комментариев побольше, а то не очень понятно в некоторых местах, что и как делается и с какой целью.
0
835 / 643 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
17.09.2013, 13:09
Цитата Сообщение от Невик Посмотреть сообщение
Подскажите, пожалуйста, возможно ли задать строку, к примеру:
string str="sin(x)*log(x)", а затем преобразовать в вид: double f=sin(x)*log(x)?
Можно. Правильно будет написать нормальный парсер, что достаточно просто. Разумеется, безо всякой рефлексии, она тут не нужна. Другой вариант - использовать средства компиляции кода в рантайме и выполнять полученный код, но в данном случае это полный бред.

Добавлено через 45 секунд
PS: Тьфу.. Опять вторую страницу не заметил

Добавлено через 4 минуты
Цитата Сообщение от Невик Посмотреть сообщение
В дальнейшем попробую использовать возможности отражения.
Не надо

Цитата Сообщение от Невик Посмотреть сообщение
Вот я набросал небольшой парсер.
Какой-то он странный... Работа со строками явно неоптимальна, а изучать что именно делает код мне лень...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.09.2013, 21:43
Qwertiy, 4 года посту. Думаете, вернется и исправит?
0
835 / 643 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
17.09.2013, 22:33
Psilon, тема оказалась на первой странице раздела со вчерашней датой не из-за моего поста
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
18.09.2013, 13:03
Цитата Сообщение от Psilon Посмотреть сообщение
4 года посту.
Блин, а я уж начал ответ писать...
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.09.2013, 15:26
Qwertiy, ну так и пишите тому, кто вчера ответил, а не тсу )
0
835 / 643 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
18.09.2013, 15:30
Цитата Сообщение от dondublon Посмотреть сообщение
Блин, а я уж начал ответ писать...
Ну так дописывай, тут BlooDCrescent вроде интересуется

Добавлено через 2 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
Qwertiy, ну так и пишите тому, кто вчера ответил, а не тсу )
Во-первых, он ответил по поводу этого кода. А во-вторых, мне лень смотреть на дату каждого поста. Я тут целую страницу не заметил, пока ответ не отправил, а ты хочешь даты
0
Эксперт Python
 Аватар для dondublon
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 6
18.09.2013, 15:33
Цитата Сообщение от Qwertiy Посмотреть сообщение
Ну так дописывай, тут BlooDCrescent вроде интересуется
Ну ничего нового, этот вопрос задают часто, на разные лады.
Есть 3 подхода.
1. Динамическая компиляция (Гуглится по "C# dynamic compilation", CodeDomProvider). Самый быстрый с т.з. выполнения.
2. Использовать интерпретатор. Например, IronPython.
3. Найти-таки готовый парсер, которых в сети есть.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.09.2013, 15:33
Помогаю со студенческими работами здесь

Как сделать исполняемую программу в планировщике невидимой или невсплываемой
Добрый день! Имеется Windows 7. Познакомился с планировщиком заданий совсем не давно. Поставил свою первую программу на исполнение...

Преобразование строки Из AnsiString в Char, и копировие этой строки.
выходить ошибка при нажтии кнопки, хелп! void __fastcall TForm1::Button1Click(TObject *Sender) { AnsiString mystr = Edit1-&gt;Text; ...

Преобразование строки
есть строка: var s=&quot;2010-10-19 18:14:21\n1\nВася Пупкин\n--\nПривет\n--\n2010-10-19 18:21:06\n1\nИван Иванов\n--\nПривет\\nКак...

Преобразование строки
Хочу преобразовать строку '111,25' в число как сделать.Функция Val преобразовывает только '111.25'.Может с эти кто сталкивался.

Преобразование строки
Дано предложение.Напечатать все слова, предварительно преобразовав каждое из них по следующуму правилу:удалить из слова все вхождения...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru