Лексический анализ выражений. Формы записи выражений - C#

  1. Уважаемые форумчане помогите пожалуйста с задачей: Замечания: Исходное выражение читают последовательно слева направо; к выделенным, таким образом, символам применяют табличные правила; Правила построения ОПЗ рекурсивны, т.е. ОПЗ более сложных выражений описываются с помощью ОПЗ их более простых подвыражений; Из правил вытекает, что порядок операндов в выражении и в ОПЗ одинаковый; Порядок знаков операций изменяется: во входном выражении вида a-b знак “–” предшествует операнду b, а в выходном выражении ab- наоборот. Поэтому знак операции нужно запомнить, выдать второй операнд выражения, а затем уже вернуть знак операции. Такое изменение порядка знаков достигается с использованием стека; знаки операций поступают в него и удаляются в ОПЗ по принципу «последним вошел - первым вышел» (LastIn - FirstOut, или LIFO); На порядок знаков в ОПЗ влияет их старшинство, или приоритет. Операции “*” и “/” старше, чем “+” и “-”; Операции имеют свойство левостороннего связывания; Открывающая и соответствующая ей закрывающая скобки задают начало и конец выражения, все знаки операций которого должны появиться в ОПЗ раньше, чем знаки в стеке перед появлением открывающей скобки. Для отделения этих знаков открывающая скобка записывается в стек. При появлении на входе закрывающей скобки все знаки операций до открывающей скобки выталкиваются из стека в ОПЗ, а скобка удаляется из стека, т.е. скобки взаимно уничтожаются; После того как выражение прочитано, в стеке ещё могут остаться знаки операций; их нужно записать в ОПЗ. Все выше приведенные замечания необходимо учитывать в алгоритме построения ОПЗ. Задание: R=a-(b+c*d)/e a=3.1 b=5.4 c=0.2 d=9.6 e=7.8 R=2.16 Заранее спасибо!Добавлено через 19 часов 59 минут нашел пример, но переделать не получается. посмотрите плиз. Пример: R=(a+b)*(c-d)/e –вводимое выражение; а=3 b=5 c=6 d=9 е=7 –значения операндов. Результат выполнения программы: R=ab+cd-*e/ R=-3.42857C++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 #include<stdio.h> #include<stdlib.h>   /* Описание стpуктуpы(элемента стека) */ structst { charc;structst *next;}; structst *push(structst *, char); /* Пpототипыфункций */ char DEL(structst **); int PRIOR(char);   void main(void) { /* Стекопеpацийпуст */ structst *OPERS=NULL;                     char a[80], outstring[80]; int k, point; do   { puts("Введите выpажение(в конце '='):"); fflush(stdin);     /* Ввод аpифметическоговыpажения */ gets(a);                                     k=point=0;     /* Повтоpяем , пока не дойдем до '=' */ while(a[k]!='\0'&&a[k]!='=')           {     /* Если очеpедной символ - ')' */ if(a[k]==')')                 /* то выталкиваем из стека в выходную стpоку */       {                                         /* все знаки опеpаций до ближайшей */ while((OPERS->c)!='(')                 /* откpывающейскобки */ outstring[point++]=DEL(&OPERS);           /* Удаляемизстекасамуоткpывающуюскобку */ DEL(&OPERS);       }     /* Если очеpедной символ - буква , то */ if(a[k]>='a'&&a[k]<='z')             /* пеpеписываем её в выходную стpоку */ outstring[point++]=a[k];                 /* Если очеpедной символ - '(' , то */ if(a[k]=='(')                             /* заталкиваем её в стек */ OPERS=push(OPERS, '(');           if(a[k]=='+'||a[k]=='-'||a[k]=='/'||a[k]=='*')     /* Если следующий символ - знак опеpации , то: */       {                                 /* если стек пуст */ if(OPERS==NULL)                             /* записываем в него опеpацию*/ OPERS=push(OPERS, a[k]);                     /* если не пуст */ else /* если пpиоpитет поступившей опеpации больше пpиоpитетаопеpации на веpшине стека */ if(PRIOR(OPERS->c)<PRIOR(a[k]))       /* заталкиваем поступившую опеpацию на стек */ OPERS=push(OPERS, a[k]);                   /* еслипpиоpитетменьше */ else         { while((OPERS!=NULL)&&(PRIOR(OPERS->c)>=PRIOR(a[k]))) /* пеpеписываем в выходную стpоку все опеpации                    с большим или pавнымпpиоpитетом */ outstring[point++]=DEL(&OPERS);             /* записываем в стек поступившую  опеpацию*/           OPERS=push(OPERS, a[k]);           }       }     /* Пеpеход к следующему символу входной стpоки */       k++;                                         }     /* после pассмотpения всего выpажения */ while(OPERS!=NULL)                         /* Пеpеписываем все опеpации из */ outstring[point++]=DEL(&OPERS);             /* стекаввыходнуюстpоку */ outstring[point]='\0';                         /* ипечатаемеё */ printf("\n%s\n", outstring);             fflush(stdin); puts("\nПовтоpить(y/n)?"); } while(getchar()!='n'); }   /* Функция push записывает на стек (на веpшинукотоpого указывает HEAD)    символ a . Возвpащает указатель на новую веpшину стека */ structst *push(structst *HEAD, char a) { structst *PTR; /* Выделениепамяти */ if((PTR=malloc(sizeof(structst)))==NULL) { /* Если её нет - выход */ puts("ет памяти");exit(-1);               } /* Инициализация созданной веpшины */   PTR->c=a;                                 /* и подключение её к стеку */ PTR->next=HEAD;           /* PTR -новаявеpшинастека */ return PTR;                               }   /* Функция DEL удаляет символ с веpшины стека. Возвpащает удаляемый символ.    Изменяет указатель на веpшину стека */ char DEL(structst **HEAD) { structst *PTR; char a; /* Если стек пуст,  возвpащается '\0' */ if(*HEAD==NULL) return '\0'; /* в PTR - адpесвеpшины стека */ PTR=*HEAD;                     a=PTR->c; /* Изменяемадpесвеpшиныстека */   *HEAD=PTR->next;         /* Освобождение памяти */ free(PTR);   /* Возвpат символа с веpшины стека */ return a;                   }   /* Функция PRIOR возвpащаетпpиоpитетаpифм. опеpации */ int PRIOR(char a) { switch(a)   { case '*': case '/': return 3;   case '-': case '+': return 2;   case '(': return 1; } }


textual

Код:

for (; ; )
{
    string exp = Peremennie(); //Метод возвращающий выражение, например R=5-(1+3*78)/3     
 
    if (Checked(exp))
    {
        string outStr = GetExp(exp);
 
        Console.WriteLine("Ваше выражение в ОПН выглядит так: " + outStr);
 
        Console.WriteLine("Значение выражения: " + Reshenie(outStr) + "\n");
    }
}


Похожие ответы
  1. Всем доброго времени суток! Мне нужно распарсить Designer файл, собственно, большинство уже сделано, осталось только пройтись по той его части, где поочередно описываются свойства элементов управления. Синтаксис таков:

  1. Здравствуйте ! Прошу Вашей помощи в составлении , точнее советах по составлению Синтаксического анализатора дифференциальных уравнений. (уравнения однородные второго порядка вида y'' (плюc-минус) a*y (плюс-минус)b=0) Предложите пожалуйста идеи, как это можно "сконструировать" . Теорию то я понимаю, как это работает , но вся проблема в переводе этих мыслей на язык C# . Должно быть текстовое поле и по кнопке , анализатор должен проверять написанное в этом текстовом поле , естесственно с выдачей соответствующих ошибок , если таковые будут иметься. пробовал что-то подобное сделать для квадратного уравнения , к чему впринципе и сводится дифференциальное , но опять же результатов не добился. Жду.

  1. Доброго времени суток, форумчане! Подскажите как в анализатор арифметических выражений можно подставить вместо буквы значение из массива. Анализатор считает математические выражения (н-р: 10-5/2). Добавил в него возможность распознавания кроме цифр и знаков арифм. операций букв, которым присваивается тип "VARIABLE", но вот как в процессе вычисления вместо них подтянуть их значение из массива хранящего эти значения не знаю. Это нужно для того, что бы например если на вход подаётся функция x^2+2*x+1, программа рассчитала её значения, при х равном определённым значениям, которые будут хранится в массиве. Распознавание переменной прописано в функции get_token, её замена на конкретное значение в account7 (ref double rezult):

  1. Пишем код для шифровки и расшифровки по Цезарю. Дали задание: расшифровать без ключа(т.е. Методом частотных анализ) Вот код, который решает мою проблему , но только для частного случая, когда буква "о" встречается в тексте больше чем количество других букв. Помогите реализовать для всех случаев.

  1. Доброго времени суток, форумчане! Прошу помочь со следующей проблемой. Есть строка, в которое вводится выражение с консоли. Как в С# создать указатель на данную строку, который бы мог перемещаться по её элементам в зависимости от условия? Ну например если текущий элемент, на который указывает указатель является пробелом или кавычками, то указатель должен перейти на следующий элемент строки. Вариант через цикл for, пробегом по всем элементам не подходит, так как проверяться условие и соответственно смещаться указатель будет последовательно в разных функциях (в разных частях программы), начиная с той позиции, на которой он был в предыдущей функции. Следующий вариант, который я пробовал оказался не верным:

  1. Выполнить анализ кода программы на наличие в нем всех операторов присваивания языка C#

  1. Добрый день. Делаю скриншот части окна стороннего приложения и анализирую получившийся результат. Например, я хочу анализировать квадратик 100 x 100 пикселей в правом нижнем углу окна приложения. Очень много информации удалось найти, но понимания, как правильно, и почему именно так, нет. Использую как .Net 3.5, так и .Net 4.0. Хотелось бы, чтобы правильно работало везде. Сразу вопросы:Вопрос 1. Можно ли, в принципе, реализовывать задачу так (ниже подробное описание)? Вопрос такой потому, что я часто встречал реализации через SelectObject, CreateCompatibleDC, CreateCompatibleBitmap и так далее. Вопрос 2. Иногда в bitmap попадает чернота, почему? Именно иногда. То есть обычно всё работает, но, порой, просто чёрная картинка получается. Вопрос 3. Почему координаты части изображения в BitBlt так странно выставляются? Поясню. Берём картинку Width=400, Height=400. Хотим получить квадрат в правом углу размером 100x100. Координаты для второй части BitBlt какие надо ставить? Я ставлю Width * 0.25, Height * 0.25. И... Нет, не получается на выходе то, что требуется. Всё время область куда-то смещена. Почему так? Мне каждый раз приходится подбирать коэффициенты, чтобы вырезалось именно то, что я хочу. Итак, как делаю я:1. Получаю хендл окна приложения:

  1. Нужно разработать лексический анализатор, получающий на вход строку и выделяющий из неё лексемы Лексемы записываются в формате: код лексемы; пробел; выделенная лексема; виды лексем: десятичные числа(целые и вещественные); арифметическая операция; идентификаторы - буквы; Можно код пожалуйстаДобавлено через 1 час 55 минут Пример: целые числа - код 1, арифметическая операция - код 2, идентификаторы - код 3. исходная строка 23*b+a04*2 Массив лексем 1)23 2)* 3)b 2)+ 3)a04 2)* 1)2

  1. У меня есть программа шифрования методом Цезаря. Нужно доделать, добавив частотный анализ введенного текста, т.е. сколько раз встречаются в тексте буквы. Как это сделать?

  1. Привет! Пишу для себя простенький мат анализатор вводимой строки с целью вычислить введенное математическое выражение. Найденные мною синтаксичесические анализаторы большие и страшные. Он еще не готов, но ошибки не дают продолжить.