Я пытаюсь изучить C, написав простой парсер / компилятор. До сих пор это был очень поучительный опыт, однако, исходя из сильного опыта в C #, у меня возникли некоторые проблемы с настройкой - в частности, из-за отсутствия исключений.
Теперь я ' Мы читали Чище, элегантнее и труднее узнавать , и я согласен с каждым словом в этой статье; В моем коде на C # я стараюсь по возможности не генерировать исключения, однако теперь, когда я столкнулся с миром, в котором я не могу генерировать исключения, моя обработка ошибок полностью затмевает чистую и легкую для чтения логику. моего кода.
В настоящий момент я пишу код, который должен быстро выходить из строя , если есть проблема, а также потенциально глубоко вложен - я остановился на шаблоне обработки ошибок, согласно которому " Функции Get возвращают NULL в случае ошибки, а другие функции возвращают -1
в случае ошибки. В обоих случаях функция, которая терпит неудачу, вызывает NS_SetError ()
, поэтому все, что нужно сделать вызывающей функции, - это очистить и немедленно вернуться в случае ошибки.
Моя проблема в том, что количество if (Action () операторов, которые у меня есть, мешает мне - это очень повторяющееся и полностью скрывает основную логику. В итоге я создал себе простой макрос, чтобы попытаться улучшить ситуацию, например:
#define NOT_ERROR(X) if ((X) < 0) return -1
int NS_Expression(void)
{
NOT_ERROR(NS_Term());
NOT_ERROR(Emit("MOVE D0, D1\n"));
if (strcmp(current->str, "+") == 0)
{
NOT_ERROR(NS_Add());
}
else if (strcmp(current->str, "-") == 0)
{
NOT_ERROR(NS_Subtract());
}
else
{
NS_SetError("Expected: operator");
return -1;
}
return 0;
}
Каждая из функций NS_Term
, NS_Add
и NS_Subtract
выполните NS_SetError ()
и верните -1
в случае ошибки - его лучше , но все равно кажется, что я злоупотребляю макросами и не t допускают любую очистку (некоторые функции, в частности функции Get
, которые возвращают указатель, более сложны и требуют запуска кода очистки).
В целом это похоже на то, что я ' > ...
Документация, с которой я столкнулся, исследуя это, указывает на то, что способ сделать это для других баз данных - это использовать несколько операторов в вашем запросе, а-ля:
>>> cursor = connection.cursor()
>>> cursor.execute("set session transaction isolation level read uncommitted;
select stuff from table;
set session transaction isolation level repeatable read;")
К сожалению, это не дает результатов, поскольку очевидно, Python DB API (или, может быть, его реализация?) не поддерживает несколько наборов записей в одном запросе.
Кто-нибудь еще добился успеха с этим в прошлом?