Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.10.2018, 13:18   #11
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Обычно, СА проще писать через конечные автоматы. Знаете что это такое?
p51x вне форума Ответить с цитированием
Старый 22.10.2018, 14:00   #12
Алексей9912
Пользователь
 
Регистрация: 30.09.2018
Сообщений: 30
По умолчанию

нет, не знаю


вот чуть подправил код:


Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int check(char c, char che[]);
int is_enum(char* c, int beg, int end);
int is_log(char* c, int beg, int end);


int main()
{
    char* c = (char*)malloc(100 * sizeof(char));
    fgets(c, 100, stdin);
    int l = strlen(c);
    if (is_log(c, 0, l - 1)) printf("Logical expression was arranged correctly");
    else printf("Logical expression wasn't arranged correctly");
    return 0;
}


int check(char c, char che[]) {
    int l = strlen(che);
    int n = 0;
    for (int i = 0; i < l; i++) {
        if (c == che[i]) {
            n++;
            break;
        }
    }
    return n;
}  /*проверка вхождения символа в массив*/


int is_enum(char* c, int beg, int end) {
    int n, p, j, k , nbeg;
    char op[] = "+-*/";
    if ((beg == end) && isalnum(c[beg])) return 1;
    if ((isalnum(c[beg]) != 0) && (check(c[beg + 1], op) != 0)) return is_enum(c, beg + 2, end);
    if (c[beg] == '(') {
            p = 0;
            for (int i = 0; i <= end; i++) {
                if (c[i]  == '(') p++;
                if (c[i] == ')') p--;
                if (p == 0) {
                    k = i + 1;
                    nbeg = i + 2;
                    break;
                }
            }
            if (c != 0) return 0;
            if (k < end) {
                if (check(c[k], op) return is_enum(c, beg + 1, k - 2) * is_enum(c, nbeg, end);
            }
            else {
                return is_enum(c, beg + 1, k - 2);
            }
        }
        return 0;
} /*проверка выражений*/

int is_log(char* c, int beg, int end) {
    if (check(c[beg], "TtFf")) return 1;
    if (check(c[beg], "Aa") && check(c[beg + 1], "Nn") && check(c[beg + 2], "Dd")) return is_enum(c, beg + 3, end);
    if (check(c[beg], "Nn") && check(c[beg + 1], "Oo") && check(c[beg + 2], "Tt")) return is_enum(c, beg + 3, end);
    if (check(c[beg], "Oo") && check(c[beg + 1], "Rr")) return is_enum(c, beg + 2, end);
    return 0;
}
хотя это еще тоже не совсем готовый код, ибо еще надо добавить вложенность. но код все равно работает некорректно. не подскажете, почему?

Последний раз редактировалось Алексей9912; 22.10.2018 в 14:12.
Алексей9912 вне форума Ответить с цитированием
Старый 22.10.2018, 14:16   #13
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Где проверка на длины строк? Вы так спокойно разыменовываете различные указатели...

Код:
if ((beg == end) && isalnum(c[beg])) return 1;
And1, Orw, Not1, NotA, ... все пройдет

Код:
if ((isalnum(c[beg]) != 0) && (check(c[beg + 1], op) != 0)) return is_enum(c, beg + 2, end);
Это обработка случаев And(+, Or=-, Not~1, ... ?

Что вы вообще со скобками делаете? Зачем их подсчитывать? Вам же выражения надо в них разбирать... Правильность надо контролировать, но обычно оно само вылазит при разборе выражения, если не смогли найти конец.
p51x вне форума Ответить с цитированием
Старый 22.10.2018, 14:50   #14
Алексей9912
Пользователь
 
Регистрация: 30.09.2018
Сообщений: 30
По умолчанию

1. у меня почему-то nota, допустим, не проходит. и проблема не в регистрах. а в чем - не понимаю..
2.
Код:
            if (k < end) {
                if (check(c[k], op)) return is_enum(c, beg + 1, k - 2) * is_enum(c, nbeg, end);
            }
я разбираю выражения в скобках и далее вот здесь. то бишь перемножаю результаты разбора в скобках с результатами разбора вне их (может быть еще множество скобок)

Код:
           if ((beg == end) && isalnum(c[beg])) return 1;
            }
этот код подправил, чтобы при конце строки был результат:

Код:
            if (beg == end) return 1;
            }

где я разыменовываю указатели? разыменовать указатель значит, если не ошибаюсь, изменить значения по адресу, на который указывает указатель. или я не прав?
Алексей9912 вне форума Ответить с цитированием
Старый 22.10.2018, 15:08   #15
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
1. у меня почему-то nota, допустим, не проходит. и проблема не в регистрах. а в чем - не понимаю..
Все проходит https://ideone.com/pzUqxO а вот если "nota ", то не проходит, хотя тоже должно.

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
2.
И "(T+F) - T" сломает, т.к. ' ' не в op. ")()(" что в скобках? что разбирать будете?

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
этот код подправил, чтобы при конце строки был результат:
Т.е. результат не зависит от последнего символа? "T+" что даст?

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
где я разыменовываю указатели? разыменовать указатель значит, если не ошибаюсь, изменить значения по адресу, на который указывает указатель. или я не прав?
Ошибаетесь. Условно разыменование это доступ по адресу, указанному в указателе. Бывает на чтение - это все ваши с[...], бывает на запись.
Попробуйте https://ideone.com/QzCCUL а ведь записи там нет...

Последний раз редактировалось p51x; 22.10.2018 в 15:12.
p51x вне форума Ответить с цитированием
Старый 22.10.2018, 15:58   #16
Алексей9912
Пользователь
 
Регистрация: 30.09.2018
Сообщений: 30
Печаль

t+ всегда даст положительный ответ, т. к. в случае t или f is_log даже не обращается к is_enum. кстати... надо туда еще добавить проверку на длину, чтобы не было такого бага.

Код:
    if (check(c[beg], "TtFf")) return is_enum(c, beg + 1, end);
и насчет последнего значения в строке. все правильно, потому что and дает положительный результат, а and+ дает отрицательный.


(t+f)-t всегда даст отрицательный ответ, т.к. нет начального оператора (and || or || not).


мне кажется по логике программы все должно нормально рассчитываться (например, and(a+b) должно быть правильным). но почему этого не происходит? я не внимаю... в сотый раз прошу хоть кого-нибудь помочь мне разобраться с этим.

замечания это конечно хорошо, они иногда показывают правильное направление мыслей, но все же... они мне не сильно помогли
Алексей9912 вне форума Ответить с цитированием
Старый 22.10.2018, 16:10   #17
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
t+ всегда даст положительный ответ, т. к. в случае t или f is_log даже не обращается к is_enum.
Ну засуньте в ваши скобки And(t+) или (t+).

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
и насчет последнего значения в строке. все правильно, потому что and дает положительный результат, а and+ дает отрицательный.
А ... + T что даст? 0, т.к. "+ " только обработалось?

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
(t+f)-t всегда даст отрицательный ответ, т.к. нет начального оператора (and || or || not).
А зачем тогда в вашей программе проверки на эти знаки сделаны?

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
мне кажется по логике программы все должно нормально рассчитываться (например, and(a+b) должно быть правильным).
Не должно. Вы же сами сказали + нет. Кто такие a,b ? В языке их нет.

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
в сотый раз прошу хоть кого-нибудь помочь мне разобраться с этим.
Так в этой теме уже все разжевано. Можно еще КА добавить и все.
p51x вне форума Ответить с цитированием
Старый 22.10.2018, 16:31   #18
Алексей9912
Пользователь
 
Регистрация: 30.09.2018
Сообщений: 30
По умолчанию

что такое КА?
не важно, какая буква. a и b это просто для примера
Алексей9912 вне форума Ответить с цитированием
Старый 22.10.2018, 16:41   #19
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
что такое КА?
https://ru.wikipedia.org/wiki/%D0%9A...BC%D0%B0%D1%82

Цитата:
Сообщение от Алексей9912 Посмотреть сообщение
не важно, какая буква. a и b это просто для примера
Важно. Есть алфавит и есть ошибки.

А ошибка простая:
Код:
for (int i = 0; i <= end; i++) {
                if (c[i]  == '(') p++;
                if (c[i] == ')') p--;
Вы скобки каждый раз пересчитываете сначала и баланс у вас не сходится.
p51x вне форума Ответить с цитированием
Старый 22.10.2018, 16:52   #20
Алексей9912
Пользователь
 
Регистрация: 30.09.2018
Сообщений: 30
По умолчанию

в смысле сначала? в любом случае это уже неважно, ибо я немного изменил цикл в функции, но он все равно не работает


Код:
    if (c[beg] == '(') {
            for (int i = 0; i <= end; i++) {
                if (check(c[beg], comp) && c[beg + 1] == '=') return is_enum(c, beg + 2, end);
                if (isdigit(c[i]) && isdigit(c[i + 1])) continue;
                else return 0;
                if (isalpha(c[i]) && isalpha(c[i + 1])) continue;
                else return 0;
                if (check(c[i], op) && isalnum(c[i + 1])) continue;
                else return 0;
                if (c[i] == ')') {
                    k = i + 1;
                    nbeg = i + 2;
                    break;
                }
            }
Алексей9912 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Синтаксический анализатор Battori JavaScript, Ajax 3 15.03.2018 10:57
Синтаксический анализатор Arturko Помощь студентам 62 14.06.2012 18:54
синтаксический анализатор(LL) Legato Общие вопросы Delphi 2 25.12.2011 18:29
Синтаксический анализатор Lisёноk Помощь студентам 2 12.12.2011 09:51
Синтаксический анализатор Lifefine Общие вопросы Delphi 3 09.10.2010 19:42