2015-06-20 2 views
1

я получаю ошибку компиляции, когда я пытаюсь скомпилировать этот код:Execute время компиляции скомпилированных регулярных выражений во время компиляции

import std.regex; 
enum truth = "baba".matchFirst(ctRegex!`[ab]+$`) ? true : false; 
void main() {} 

/usr/local/Cellar/dmd/2.067.1/include/d2/std/regex/package.d(671): Error: malloc cannot be interpreted at compile time, because it has no available source code

Как обойти это?

+0

Это может быть полезно для вас, я верю: http://forum.dlang.org/thread/[email protected] – ShellFish

+0

Хмм .. Я сворачиваю результат в одно логическое, поэтому проблема заключается в том, не то, что я хочу использовать класс в CT и RT. – Tamas

ответ

2

Вы не можете, регулярное выражение может быть скомпилировано во время компиляции, но не выполняется. Вам придется написать матч другим способом, возможно, комбинацию indexOf или других более простых функций. (Причина в том, не потому, что регулярное выражение является слишком сложным, это на самом деле, потому что он внутренне вызывает malloc для повышения эффективности, которая не поддерживается во время компиляции, так как она является внешней функцией C.)

Понимания ctRegex нуждается в объяснении Фобоса двигатель регулярного выражения. Он работает в два этапа: при регулярном выражении он сначала компилирует это в некоторый байт-код, а затем сопоставляет его по строке, он запускает этот код.

В обычном regex оба эти этапа выполняются во время выполнения. Когда вы создаете объект regex, он компилирует его в байт-код. Затем, когда вы сопоставляете строку, он запускает этот код.

С ctRegex, первая часть происходит во время компиляции, но вторая часть все еще происходит во время выполнения. Таким образом, он компилирует регулярное выражение в байт-код при компиляции D ... затем заставляет этот байт-код через остальную часть компилятора D оптимизироваться на полностью собственный код. Это то преимущество, которое он может предложить. (Кстати, разница часто не имеет значения, вам нужно проверить свои входные строки, чтобы увидеть, какой из них лучше.)

Как правило, CTFE (оценка функции компиляции) означает, что код времени выполнения можно запускать и во время компиляции , но только если источник доступен. Это не относится к malloc, поэтому ошибка говорит об этом.

Таким образом, ответ будет зависеть только от вашего регулярного выражения. Вероятно, вы захотите упростить его и переписать его в терминах других функций string и/или std.algorithm.

... или перепишите исходный код std.regex, чтобы избавиться от этих вызовов malloc. Замените их на new и if(_ctfe). Я попытался сделать это раньше, и, если код не будет реорганизован с тех пор, вы просто столкнетесь с другой проблемой: для производительности во время выполнения std.regex также использует такие вещи, как объединения, которые также не поддерживаются в ctfe .. вам придется переписать кучу этого и быть осторожным, чтобы не нарушать производительность во время выполнения.

Наверное, проще просто справиться с конкретным случаем с другими функциями.

+0

Подано https://issues.dlang.org/show_bug.cgi?id=17070 – timotheecour

Смежные вопросы