Думаю данный топик следует поместить в блог «Ненормальное программирование»… Вот бы кто переместил…
Поздравляю всех с наступившим годом какого-то там дракона! Как бы там его астрологи не называли, но для меня дракон всегда черно-красный!
Для начала — картинка:

Не бойтесь, она единственная, дальше чуть-чуть текста и немного кода )
Картинка вверху — вполне работающий кусок кода, правда её надо разделить на блоки, поставить один за одним и тогда скомпилить, но оно работает…
А всё к чему? Просто когда я общался с папой, олдскульным прогером любящим фортран я всегда аргументировал нежелание учить этот язык отсутствием сводного позиционирования кода (он предлагал обмен опытом: он учит шарп, я -фортран))) ). Но только недавно я задумался над тем что по факту мне дает это самое свободное позиционирование… Ну да, можно расставить отступы, абзацы, пробелы, все красиво, понятно, но… скучно!
А вот как бы сделать код веселее и попутно скрыть его от случайных глаз? Скажем вы программируете за общественным ПК и храните свои творения там-же, забирая только удавшиеся проекты (чур меня от такого). А что если ваши исходники откроет знающий человек и «позаимствует» хорошую идею? Печально. А станет ли даже самы лучший спец без веского основания вчитываться в такой вот код:
Ну так станет, а?
Думаю нет. Да, знаю что скажете: в MVS надо просто убрать и поставить последнюю фигурную скобку и всё выровняется. Я тоже так думал пока не попробовал. БОльшая часть кода так и останется не отформатированной. «Так-то дружок» как сказал-бы ДоДо из сказки о Алисе.
А знаете к чему я это всё? Неа, не знаете :) Просто решил поделится свой простенько прогой на шарпе, которая из любой строчки вида sin(Pi/2)*3^3 или такого вида Integral(ln(cosh(tan(x)))(0)(5)(x) /*интеграл выражения на интервале от 0 до 5 dx*/ в адекватный результат…
Вообщем сделал я парсер математических выражений на шарпе, сделал возможность добавлять новые распознаваемые функции в виде подключаемых библиотек и решил подарить вам всем, кому потребуется… Только с основным классом парсера прийдется повозится, что-бы к нормальному виду привести, ведь это именно он там вверху так изнасилован :)
Спасибо за внимание, проектик с парсером, пачкой функций, и простенькое приложение-калькулятор вот тут
Поздравляю всех с наступившим годом какого-то там дракона! Как бы там его астрологи не называли, но для меня дракон всегда черно-красный!
Для начала — картинка:

Не бойтесь, она единственная, дальше чуть-чуть текста и немного кода )
Картинка вверху — вполне работающий кусок кода, правда её надо разделить на блоки, поставить один за одним и тогда скомпилить, но оно работает…
А всё к чему? Просто когда я общался с папой, олдскульным прогером любящим фортран я всегда аргументировал нежелание учить этот язык отсутствием сводного позиционирования кода (он предлагал обмен опытом: он учит шарп, я -фортран))) ). Но только недавно я задумался над тем что по факту мне дает это самое свободное позиционирование… Ну да, можно расставить отступы, абзацы, пробелы, все красиво, понятно, но… скучно!
А вот как бы сделать код веселее и попутно скрыть его от случайных глаз? Скажем вы программируете за общественным ПК и храните свои творения там-же, забирая только удавшиеся проекты (чур меня от такого). А что если ваши исходники откроет знающий человек и «позаимствует» хорошую идею? Печально. А станет ли даже самы лучший спец без веского основания вчитываться в такой вот код:
using System; using System.Collections.Generic; using System.Text; using Math_Super.Consts; using System.IO; using Math_Super.Operators; using System.Reflection; using System. Globalization; namespace Math_Super { public class Math_Base { protected string tp = "Math_Base"; public bool can_cash = false; public bool is_cash = false; public double cash = 0; public static Dictionary < string,Type>Funcs =new Dictionary<string, Type>(); public virtual double Eval() {return double.NaN ; } public static void Init(string path) { string[ ] functions = Directory . GetFiles( path ,"Function_*.dll" , SearchOption. TopDirectoryOnly ); for ( int i = 0 ; i < functions.Length; i++) { Assembly asm= Assembly. LoadFrom(functions[i]); Type[] tp = asm. GetTypes(); for(int j = 0; j < tp.Length;j++ ) { Object ob = tp[j]. GetConstructor ( new Type[]{typeof(Math_Base) }).Invoke(new Object[] { Math_Base.Parse("PI", "") }); Funcs.Add(((Math_Function )ob).Alias, tp[j]);} }} public static Math_Base Parse(string s, string pre) { return Parse(s, pre, "",""); } public static Math_Base Parse(string s,string pre,string int_pre,string int_var) { if (s == "") { return new Math_Const(0); } for (int i = 0; i < s.Length; i++) { if (s[i] == '+') { string left = s.Substring( 0, i);string right=s.Substring(i + 1);output.Add("Found '+' operator"); return new Operator_Plus( Math_Base.Parse( left, pre, int_pre, int_var), Math_Base.Parse(right, pre, int_pre, int_var)); }if (s[i] == '-') { string left = s.Substring(0,i); string right = s.Substring(i+1); output.Add("Found"+ " '-' operator"); return new Operator_Minus(Math_Base.Parse(left, pre, int_pre, int_var), Math_Base. Parse(right, pre, int_pre, int_var)); }if (s[i] == '('){output.Add("Found"+ "'('. Ignoring"); i = ignore(s, i);if (i == -1)break;}} for (int i = 0; i < s.Length; i++){if (s[i] == '*'){output.Add("Found '*' operator");string left = s.Substring(0, i); string right = s.Substring( i + 1) ; return new Operator_Multiply(Math_Base.Parse(left, pre, int_pre, int_var), Math_Base. Parse(right, pre, int_pre, int_var));}if(s[i]== '/') {output.Add("Found '/'"+ " operator");string left = s.Substring( 0, i); string right = s.Substring(i + 1); return new Operator_Devide ( Math_Base.Parse ( left, pre, int_pre, int_var),Math_Base. Parse( right, pre, int_pre, int_var));} if (s[i] == '('){output.Add("Found '('. Ignoring"); i = ignore(s, i); if (i == -1)break;}}for (int i = 0; i < s.Length; i++) {if(s[i] == '^') { output.Add("Found '^' operator"); string left = s.Substring(0, i); string right = s.Substring(i + 1);return new Operator_Power(Math_Base.Parse (left, pre, int_pre, int_var), Math_Base.Parse(right, pre, int_pre, int_var ));}if (s[i] == '('){output.Add("Found '('. Ignoring"); i = ignore(s, i); if (i == -1)break;}}if (s[0] == '(' && ignore(s, 0) == s.Length - 1) { output.Add("Found"+ " '(' at start." + " ReParsing without"+ " breckets" ) ; return Math_Base. Parse(s.Substring (1, s.Length - 2), pre, int_pre, int_var);}bool ok = true; for (int i = 0; i < s.Length; i++) { if (!char.IsDigit(s[i]) && s[i] != ',' && s[i] != '.') { ok = false; }} if (ok) { output. Add("Found numeric constant."); return new Math_Const( double.Parse( s, CultureInfo. InvariantCulture)); }if (s == "E"){ output.Add("Found "+ "const E");return new Const_E();} if (s == "PI") {output. Add("Found const PI"); return new Const_PI(); } if (char.IsLetter(s[0])||s[ 0]=='!'){ bool br=false;for (int i = 1; i < s.Length; i++) {if (s[i] == '('){br=true; if (ignore(s, i) == s .Length - 1 ) { output . Add ( "Found" + " Function." + " Inditificating." ); return GetFunction ( s.Substring(0, i ), s.Substring(i + 1 , s.Length - i - 2 ),pre,int_pre,int_var); }else{break;}}} if (!br){if (s != int_var){ output . Add ( "Found Variable. Name: " + s + " Prefix: " + pre); return new Math_Variable ( pre + "_" + s); }else{output.Add ("Found "+ "Variable. Name:" + s+" Pre"+ "fix: " + int_pre); return new Math_Variable ( int_pre + "_" + int_var); }}}if(s.Length>8) if (s.Substring(0 , 8) == "Integral"){ if (s[8] == '(' ) { int k = ignore(s, 8); int k2 = ignore(s, k + 1); int k3 = ignore(s, k2 + 1); string inte = s. Substring (9, k - 9); string lft = s.Substring (k + 2, k2 -k-2); string rt = s. Substring(k2+ 2,k3- k2- 2); Random r =new Random(); string var = s.Substring(k3 + 2, s.Length - k3 - 3); output.Add("Found Integral."+ " Base: " + inte + " Left: " + lft + " Right: " + rt + " Variable: " +var);return new Math_Integral(Math_Base. Parse(inte,pre), Math_Base.Parse ( lft , pre ) , Math_Base.Parse (rt, pre),pre + "_"+var);} else {if(s.Substring (8,11)=="_Trape" +"cials"){int k = ignore(s, 20); int k2 = ignore (s, k + 1); int k3=ignore(s,k2+1);string inte=s.Substring(20, k-20);string lft=s.Substring(k+2, k2-k-2);string rt=s.Substring(k2+2,k3 -k2-2);Random r=new Random(); string var=s.Substring(k3+2, s.Length-k3-3);output.Add("Found Trapecial Integral. Base: " +inte+" Left: "+lft+" Right: "+rt+" Variable: "+var);return new Integral_Trapecials(Math_Base.Parse(inte,pre),Math_Base .Parse(lft, pre), Math_Base.Parse(rt, pre),var);}}} output. Add("Can't indefine sring: "+s+" Returning ZERO"); return new Math_Const(0);}private static int ignore(string s,int i) {int c = 1;if (s.Length < 3)return -1;for (int j = i + 1; j < s.Length; j++){if (s[j] == '(')c++;if (s[j] == ')') c--; if (c ==0)return j;}return-1;}static Math_Base GetFunction( string s,string val,string pre,string int_pre,string int_var ){s = s.ToLower();if (Funcs.ContainsKey(s)){ output.Add(s); return(Math_Base)Funcs[s].GetConstructor(new Type[]{ typeof (Math_Base) }).Invoke(new Object[] {Math_Base.Parse(val,pre) });}else{output.Add("Udefined function: " + s); return new Math_Const(0);}} public static Dictionary<string, double> vars = new Dictionary<string, double>();public static List <string> output = new List<string>();}}
Ну так станет, а?
Думаю нет. Да, знаю что скажете: в MVS надо просто убрать и поставить последнюю фигурную скобку и всё выровняется. Я тоже так думал пока не попробовал. БОльшая часть кода так и останется не отформатированной. «Так-то дружок» как сказал-бы ДоДо из сказки о Алисе.
А знаете к чему я это всё? Неа, не знаете :) Просто решил поделится свой простенько прогой на шарпе, которая из любой строчки вида sin(Pi/2)*3^3 или такого вида Integral(ln(cosh(tan(x)))(0)(5)(x) /*интеграл выражения на интервале от 0 до 5 dx*/ в адекватный результат…
Вообщем сделал я парсер математических выражений на шарпе, сделал возможность добавлять новые распознаваемые функции в виде подключаемых библиотек и решил подарить вам всем, кому потребуется… Только с основным классом парсера прийдется повозится, что-бы к нормальному виду привести, ведь это именно он там вверху так изнасилован :)
Спасибо за внимание, проектик с парсером, пачкой функций, и простенькое приложение-калькулятор вот тут