+319
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
template<typename OpeningBracketRange,
typename ClosingBracketRange,
typename StopTokenRange,
typename CommentBlockRangePairRange,
typename RecursiveCommentBlockRangePairRange>
Meta::EnableIf<
IsFiniteForwardRange<OpeningBracketRange>::_ &&
IsFiniteForwardRange<ClosingBracketRange>::_ &&
IsFiniteForwardRange<StopTokenRange>::_ &&
IsFiniteForwardRange<CommentBlockRangePairRange>::_ &&
IsFiniteForwardRange<RecursiveCommentBlockRangePairRange>::_,
decltype(Meta::Val<R>().Take(0))> ReadRecursiveBlock(int& counter, size_t* ioIndex,
OpeningBracketRange openingBracket, ClosingBracketRange closingBracket, StopTokenRange stopToken,
CommentBlockRangePairRange commentBlocks, RecursiveCommentBlockRangePairRange recursiveCommentBlocks)
{
R start = me();
size_t index = 0;
const size_t openingBracketLen = openingBracket.Count();
const size_t closingBracketLen = closingBracket.Count();
const size_t stopTokenLen = stopToken.Count();
while(!me().Empty() && counter!=0)
{
if(openingBracketLen!=0 && me().StartsWith(openingBracket))
{
counter++;
me().PopFrontExactly(openingBracketLen);
index += openingBracketLen;
continue;
}
if(closingBracketLen!=0 && me().StartsWith(closingBracket))
{
counter--;
me().PopFrontExactly(closingBracketLen);
index += closingBracketLen;
continue;
}
if(stopTokenLen!=0 && me().StartsWith(stopToken))
{
me().PopFrontExactly(stopTokenLen);
index += stopTokenLen;
break;
}
bool commentFound = false;
for(auto& commentBlock: commentBlocks)
{
commentFound = me().StartsWith(commentBlock.Get<0>());
if(!commentFound) continue;
const size_t commentBlockOpeningLen = commentBlock.Get<0>().Count();
const size_t commentBlockClosingLen = commentBlock.Get<1>().Count();
me().PopFrontN(commentBlockOpeningLen);
index += commentBlockOpeningLen;
me().FindAdvance(commentBlock.Get<1>(), &index);
me().PopFrontN(commentBlockClosingLen);
index += commentBlockClosingLen;
break;
}
if(commentFound) continue;
for(auto& commentBlock: recursiveCommentBlocks)
{
commentFound = me().StartsWith(commentBlock.Get<0>());
if(!commentFound) continue;
int commentCounter = 1;
ReadRecursiveBlock(commentCounter, &index, commentBlock.Get<0>(), commentBlock.Get<1>(), null, null);
break;
}
if(commentFound) continue;
me().PopFront();
}
if(ioIndex!=null) (*ioIndex) += index;
return start.Take(index);
}
Это мои последние достижения в написании сверх универсального обобщённого кода.
Начиналось всё с функции, которая парсила блок кода до закрывающей фигурной скобки, учитывая встречающиеся открывающие скобки. Затем появилась поддержка комментариев и строк. Позже я решил, что нечего привязываться к какому-то конкретному языку, ведь можно же таким же образом парсить другой язык, где вместо скобок begin end и комментарии по-другому оформляются.
А потом я подумал, зачем вообще привязывать типы параметров к строкам и массивам строк? И почему код, который парсится, вообще должен быть строкой, хранящейся в памяти непрерывно? В итоге мои размышления привели к такой реализации, которая способна парсить всё подряд, в том числе и связные списки, причём необязательно состоящие из символов. При этом открывающуюся скобку можно передать связным списком, закрывающуюся - массивом, а блоки комментариев передавать как массивом кортежей, так и хеш-таблицей.
При этом эта функция относится к классу примеси и наследованием её можно подмешать к любому классу, имеющему нужные методы.
Запостил: gammaker,
15 Августа 2016
1024-- 15.08.2016 19:18 # +17
Иначе выходит как у того математика, который исписал 1000+ листов новой математики. Вроде бы и полезно, но прочитает целиком не каждый.
gammaker 15.08.2016 20:01 # +16
Это такой самый нормальный пример. А ненормальные типа парсинга списка структур вместо массива символов я пока ещё и сам не придумал.
А ещё в моей реализации поддержки экранирования строк нет. Писал прямо здесь, на компилируемость не тестировал.
HaskellGovno 15.08.2016 22:16 # +16
guesto 18.08.2016 03:44 # −10
Antervis 15.08.2016 20:44 # +18
gammaker 15.08.2016 21:17 # +15
CHayT 15.08.2016 21:55 # +17
gammaker 16.08.2016 02:14 # +15
j123123 18.08.2016 03:28 # +16
— Как я понял, твой успех был отчасти в том, что все пытались найти общее универсальное решение и впоследствии увязали в нарастающей сложности. Ты же решил узкоспециализированную задачу, зато смог это сделать эффективно и быстро. Немного отвлекаясь от основной темы, здесь мы снова возвращаемся к любимому тобой спору вокруг назначения языков C и C++.
— Каждый конкретный язык определяет мышление, хотим мы того или нет. Так вот, постоянно сталкиваюсь, что «плюсовики» тяготеют к решениям в общем виде, в то время как «сишники» решают задачу в частном виде, что в разы быстрее.
Одну текущую задачу сначала показали «плюсовику», спросив, сколько займёт её решение. Он сказал: «Здесь нужно писать могучий движок. Короче говоря, это проект на полгода». Его коллега-«сишник» поинтересовался: «А зачем?» Ведь поставленная задача укладывается в сотню строк кода! Ответ был ошеломляющим: «Ну и что, мы так и будем по сотне строк кода писать для решения частных задач, каждый раз, как они возникают? Нетушки, задачи надо решать раз и навсегда!».
По моему глубокому личному убеждению, проблемы нужно решать по мере их возникновения. Писать программы на вырост с избыточным универсализмом нужно лишь очень хорошо предварительно подумав, ибо это из серии «Почему сегодня не делают корабли, летающие к звёздам?» Ответ прост: потому что корабль, построенный завтра, прибудет быстрее, а корабль, построенный послезавтра, еще быстрее. И их обоих обгонит корабль, построенный лет через пятьдесят, но когда он вернётся обратно, то обнаружит, что у человечества совсем другие проблемы».
guesto 18.08.2016 03:30 # −10
nihau 18.08.2016 10:36 # +15
inkanus-gray 18.08.2016 12:13 # +15
guesto 16.08.2016 02:58 # 0
j123123 18.08.2016 03:20 # +16
guesto 18.08.2016 03:27 # −10
Antervis 18.08.2016 06:00 # +15
j123123 18.08.2016 14:29 # +14
1024-- 18.08.2016 14:50 # +15
Antervis 18.08.2016 15:24 # +15
j123123 18.08.2016 17:44 # +18
Soul_re@ver 18.08.2016 18:48 # +17
Anal_teacher 18.08.2016 18:49 # −17
inkanus-gray 18.08.2016 18:52 # +15
Antervis 19.08.2016 05:35 # +16
nihau 18.08.2016 16:53 # +16
ебаные человеки, что вы опять понавыдумывали
Soul_re@ver 18.08.2016 16:56 # +15
1024-- 18.08.2016 19:26 # +15
Каждая новая версия хрома будет написана на новом C++.
inkanus-gray 18.08.2016 19:36 # +18
void_main 18.08.2016 20:10 # −15
inkanus-gray 18.08.2016 20:22 # +15
j123123 18.08.2016 22:48 # +17
HaskellGovno 18.08.2016 22:56 # +18
guesto 18.08.2016 03:27 # −10
Antervis 18.08.2016 06:21 # +15
CHayT 15.08.2016 21:53 # +15
guest 15.08.2016 23:53 # −46
Bobik 15.08.2016 23:59 # +15
guest 16.08.2016 00:23 # −5
guest 16.08.2016 00:24 # −5
Я учитель! Я анальный учитель! Я БУДУ АНАЛЬНЫМ УЧИТЕЛЕМ!!!!