Чи варто використовувати генератор парсера чи слід накладати власний спеціальний лексер та код парсера?


81

Які конкретні переваги та недоліки кожного способу роботи над граматикою мови програмування?

Чому / коли я повинен катати свою? Чому / коли я повинен використовувати генератор?


Відповіді:


78

Насправді є три варіанти, всі три бажаніші в різних ситуаціях.

Варіант 1: генератори парсера

Скажімо, вас просять створити аналізатор для давнього формату даних ЗАРАЗ. Або вам потрібен ваш парсер, щоб бути швидким. Або вам потрібен ваш парсер, щоб бути легко ремонтом.

У цих випадках вам, мабуть, найкраще використовувати генератор парсера. Вам не доведеться поспішати з деталями, вам не потрібно мати багато складного коду для належної роботи, ви просто виписуєте граматику, до якої буде дотримуватися вхід, написати якийсь код обробки та presto: миттєвий парсер.

Переваги зрозумілі:

  • (Як правило) досить просто написати специфікацію, особливо якщо формат введення не надто дивний (варіант 2 буде краще, якщо він є).
  • Ви закінчуєте дуже легко досяжний твір, який легко зрозуміти: визначення граматики зазвичай протікає набагато природніше, ніж код.
  • Парсери, що генеруються хорошими генераторами парсера, зазвичай набагато швидше, ніж рукописний код. Рукописний код може бути швидшим, але лише якщо ви знаєте свої речі - ось чому найбільш широко використовувані компілятори використовують рукописний рекурсивно-розбірний аналізатор.

Є одна річ, з якою ви повинні бути обережними з генераторами аналізаторів: іноді вони можуть відкидати ваші граматики. Для огляду різних типів парсерів та того, як вони можуть вас вкусити, ви можете почати тут . Тут ви можете знайти огляд багатьох реалізацій та типів граматик, які вони приймають.

Варіант 2: рукописні парсери або "ви хочете створити власний аналізатор, і вам важливо бути зручним для користувачів"

Генератори парсерів приємні, але вони не дуже зручні для користувача (кінцевий користувач, не ви). Зазвичай ви не можете давати хороші повідомлення про помилки, а також не можете забезпечити відновлення помилок. Можливо, ваша мова дуже дивна, і парсери відкидають вашу граматику, або вам потрібно більше контролю, ніж дає вам генератор.

У цих випадках використання рукописного рекурсивно-розбірного аналізатора, мабуть, найкраще. Хоча виправити це може бути складним, ви маєте повний контроль над своїм парсером, щоб ви могли робити всілякі приємні речі, які ви не можете зробити з генераторами аналізаторів, як-от повідомлення про помилки та навіть відновлення помилок (спробуйте видалити всі крапки з комою з файлу C # : компілятор C # поскаржиться, але все одно виявить більшість інших помилок незалежно від наявності крапки з комою).

Рукописні парсери також зазвичай краще, ніж створені, якщо якість аналізатора є досить високою. З іншого боку, якщо вам не вдається написати хороший синтаксичний аналіз, як правило, через (поєднання) відсутності досвіду, знань чи дизайну - тоді ефективність, як правило, повільніше. Для лексерів справедливе все навпаки: загальногенеровані лексеми використовують пошукові таблиці, що робить їх швидшими, ніж (більшість) рукописних.

Навчання за освітою, написання власного аналізатора навчить вас більше, ніж використання генератора. Зрештою, ви повинні написати все більш складний код, плюс ви повинні зрозуміти, як саме ви розбираєте мову. З іншого боку, якщо ви хочете навчитися створювати свою власну мову (так, набудьте досвіду мовного дизайну), переважний варіант 1 або 3 - якщо ви розробляєте мову, це, ймовірно, дуже зміниться, а варіанти 1 і 3 полегшують час.

Варіант 3: генератори парсера, написані вручну, або "ви намагаєтесь багато чого навчитися в цьому проекті, і ви б не проти покінчити з вишуканим фрагментом коду, який ви можете повторно використовувати"

Це шлях, яким я зараз ходжу: ви пишете власний генератор парсера. Хоча це нетривіально, але це, мабуть, навчить вас найбільше.

Щоб дати вам уявлення, що стосується такого проекту, я розповім про власний прогрес.

Генератор лексерів

Я створив власний генератор лексерів першим. Зазвичай я розробляю програмне забезпечення, починаючи з того, як буде використовуватися код, тому я подумав про те, як я хотів би використовувати свій код, і написав цей фрагмент коду (це в C #):

Lexer<CalculatorToken> calculatorLexer = new Lexer<CalculatorToken>(
    new List<StringTokenPair>()
    { // This is just like a lex specification:
      //                    regex   token
        new StringTokenPair("\\+",  CalculatorToken.Plus),
        new StringTokenPair("\\*",  CalculatorToken.Times),
        new StringTokenPair("(",    CalculatorToken.LeftParenthesis),
        new StringTokenPair(")",    CalculatorToken.RightParenthesis),
        new StringTokenPair("\\d+", CalculatorToken.Number),
    });

foreach (CalculatorToken token in
             calculatorLexer.GetLexer(new StringReader("15+4*10")))
{ // This will iterate over all tokens in the string.
    Console.WriteLine(token.Value);
}

// Prints:
// 15
// +
// 4
// *
// 10

Пари вхідних рядків-лексеми перетворюються у відповідну рекурсивну структуру, що описує регулярні вирази, які вони представляють, використовуючи ідеї арифметичного стека. Потім він перетворюється на NFA (недетермінований кінцевий автомат), який у свою чергу перетворюється на DFA (детермінований кінцевий автомат). Потім можна зіставити рядки проти DFA.

Таким чином ви отримуєте гарне уявлення про те, як саме працюють лексеми. Крім того, якщо ви зробите це правильно, результати від вашого генератора лексерів можуть бути приблизно такими ж швидкими, як і професійні реалізації. Ви також не втрачаєте ніякої виразності порівняно з варіантом 2, і не надто виразною порівняно з варіантом 1.

Я реалізував свій генератор лексерів трохи більше 1600 рядків коду. Цей код робить вищезгадану роботу, але він все одно генерує лексеру під час кожного запуску програми: я збираюся додати код, щоб записати його на диск у якийсь момент.

Якщо ви хочете знати, як написати власний лексер, це хороше місце для початку.

Генератор парсера

Потім ви пишете генератор парсера. Я маю на увазі сюди знову для огляду на різних видах аналізаторів - як правило, тим більше вони можуть розібрати, тим повільніше вони.

Швидкість не була проблемою для мене, я вирішив реалізувати аналізатор Ерлі. Показано, що розширені реалізації парсера Earley виявляються приблизно вдвічі повільнішими, ніж інші типи парсера.

Натомість за цей швидкісний удар ви отримуєте можливість розбору будь -яких граматик, навіть неоднозначних. Це означає, що вам ніколи не потрібно турбуватися про те, чи є у вашого аналізатора будь-яка ліва рекурсія в ньому, або що таке конфлікт зменшення зрушення. Ви також можете визначити граматики легше, використовуючи неоднозначні граматики, якщо не має значення, яке дерево розбору є результатом, наприклад, що це не має значення, розбираєте 1 + 2 + 3 як (1 + 2) +3 або як 1 + (2 + 3).

Ось як може виглядати фрагмент коду за допомогою мого генератора аналізаторів:

Lexer<CalculatorToken> calculatorLexer = new Lexer<CalculatorToken>(
    new List<StringTokenPair>()
    {
        new StringTokenPair("\\+",  CalculatorToken.Plus),
        new StringTokenPair("\\*",  CalculatorToken.Times),
        new StringTokenPair("(",    CalculatorToken.LeftParenthesis),
        new StringTokenPair(")",    CalculatorToken.RightParenthesis),
        new StringTokenPair("\\d+", CalculatorToken.Number),
    });

Grammar<IntWrapper, CalculatorToken> calculator
    = new Grammar<IntWrapper, CalculatorToken>(calculatorLexer);

// Declaring the nonterminals.
INonTerminal<IntWrapper> expr = calculator.AddNonTerminal<IntWrapper>();
INonTerminal<IntWrapper> term = calculator.AddNonTerminal<IntWrapper>();
INonTerminal<IntWrapper> factor = calculator.AddNonTerminal<IntWrapper>();

// expr will be our head nonterminal.
calculator.SetAsMainNonTerminal(expr);

// expr: term | expr Plus term;
calculator.AddProduction(expr, term.GetDefault());
calculator.AddProduction(expr,
                         expr.GetDefault(),
                         CalculatorToken.Plus.GetDefault(),
                         term.AddCode(
                         (x, r) => { x.Result.Value += r.Value; return x; }
                         ));

// term: factor | term Times factor;
calculator.AddProduction(term, factor.GetDefault());
calculator.AddProduction(term,
                         term.GetDefault(),
                         CalculatorToken.Times.GetDefault(),
                         factor.AddCode
                         (
                         (x, r) => { x.Result.Value *= r.Value; return x; }
                         ));

// factor: LeftParenthesis expr RightParenthesis
//         | Number;
calculator.AddProduction(factor,
                         CalculatorToken.LeftParenthesis.GetDefault(),
                         expr.GetDefault(),
                         CalculatorToken.RightParenthesis.GetDefault());
calculator.AddProduction(factor,
                         CalculatorToken.Number.AddCode
                         (
                         (x, s) => { x.Result = new IntWrapper(int.Parse(s));
                                     return x; }
                         ));

IntWrapper result = calculator.Parse("15+4*10");
// result == 55

(Зауважте, що IntWrapper - це просто Int32, за винятком того, що C # вимагає, щоб це був клас, отже, мені довелося ввести клас обгортки)

Сподіваюсь, ви бачите, що код вище дуже потужний: будь-яка граматика, яку ви можете придумати, може бути проаналізована. Ви можете додати довільні біти коду в граматику, здатні виконувати безліч завдань. Якщо вам вдасться змусити все це працювати, ви можете повторно використовувати отриманий код, щоб зробити дуже багато завдань дуже легко: просто уявіть, як створити інтерпретатор командного рядка за допомогою цього фрагмента коду.


3
Я думаю, ви недооцінюєте кількість роботи, необхідної для створення синтаксичного аналізатора та лексеру.

Я вже закінчив будувати власний генератор лексерів, і я був досить далеко разом зі створенням власного генератора аналізаторів, коли вирішив застосувати інший алгоритм. Мені не потрібно було так довго, щоб все це працювало, але потім я знову не ставив собі за мету "високу продуктивність", просто "хорошу продуктивність" та "велику асимптотичну продуктивність" - Unicode - сука, щоб отримати хороший час роботи а використання C # вже накладає накладні витрати.
Олексій десять Брінк

Дуже приємна відповідь. Я погоджусь з вашим варіантом Nr. 3 з усіх причин, про які ви вказали вище. Але я можу додати, що якщо, як і в моєму випадку, ви також дуже серйозно ставитесь до розробки мови, можливо, вам слід також використовувати генератори парсера одночасно з спробою створити свій власний. Таким чином, ви можете почати з мовних питань і мати можливість швидше бачити свою мову
Lefteris

1
Є четвертий варіант: комбінатори парсерів.
ЮрійАльбукерке

@AlextenBrink Чи трапляється у вас випадковий рахунок на github? Я дуже хочу взяти на себе цей лексер / аналізатор. Вражаюча річ, яку ви зробили.
Бехроз

22

Якщо ви ніколи і ніколи не писали парсера, я б рекомендував вам це зробити. Це весело, і ти дізнаєшся, як все працює, і ти навчишся цінувати зусилля, які парсер і генератори лексерів рятують тебе від наступного разу, коли потрібен парсер.

Я б також запропонував вам спробувати прочитати http://compilers.iecc.com/crenshaw/, оскільки у нього дуже глибоке ставлення до того, як це зробити.


2
Гарна пропозиція та дуже корисне посилання.
Маньєро

14

Перевага написання власного рекурсивного аналізатора походження полягає в тому, що ви можете генерувати якісні повідомлення про помилки на синтаксичних помилках. Використовуючи генератори парсера, ви можете робити помилки та додавати власні повідомлення про помилки в певні моменти, але генератори аналізаторів просто не відповідають потужності повного контролю над синтаксичним розбором.

Ще одна перевага написання вашого власного полягає в тому, що простіше розібратися до більш простого представлення, яке не відповідає листуванню вашій граматиці.

Якщо ваша граматика виправлена, а повідомлення про помилки важливі, подумайте про те, як прокрутити своє або хоча б використовувати генератор аналізатора, який дає вам потрібні повідомлення про помилки. Якщо ваша граматика постійно змінюється, вам слід замість цього використовувати генератори парсера.

Bjarne Stroustrup розповідає про те, як він використовував YACC для першої реалізації C ++ (див . Дизайн та еволюція C ++ ). У цьому першому випадку він хотів, щоб він написав власний рекурсивний аналізатор спуску!


Я ледве переконаний, що перші експерименти повинні бути з генератором парсера. Ви дали мені кілька переваг, щоб перейти на користувацьке рішення. Я поки нічого не вирішую, але це корисна відповідь, щоб допомогти мені.
Маньєро

++ Ця відповідь - це саме те, що я б сказав. Я побудував численні мови і майже завжди використовував рекурсивне походження. Я хотів би лише додати, що були випадки, коли потрібна мені мова була побудована найпростіше, накладаючи кілька макросів поверх C або C ++ (або Lisp).
Майк Данлаве

Стверджується, що у JavaCC є найкращі повідомлення про помилки. Також помічайте повідомлення про помилки JavaScript та попереджувальні повідомлення на V8 та Firefox, я думаю, вони не використовували генераторів парсера.
Мінг-Тан

2
@SHiNKiROU: Дійсно, можливо, не випадково, що JavaCC використовує і рекурсивний синтаксичний аналіз.
Macneil

10

Варіант 3: Ні (згорніть власний генератор парсера)

Просто тому , що є причина , щоб не використовувати ANTLR , бізон , Coco / R , Grammatica , JavaCC , лимон , пропарений , SableCC , Quex , і т.д. - це не означає , що ви повинні негайно згорнути свій власний парсер + Лексер.

Визначте, чому всі ці інструменти недостатньо хороші - чому вони не дозволяють вам досягти своєї мети?

Якщо ви не впевнені, що дивацтва граматики, з якою ви маєте справу, унікальні, ви не повинні просто створювати єдиний спеціальний аналізатор + лексеру для нього. Натомість створіть інструмент, який створить те, що ви хочете, але також може бути використаний для задоволення майбутніх потреб, а потім випустіть його як безкоштовне програмне забезпечення, щоб не допустити інших людей до тієї ж проблеми, що і ви.


1
Я погоджуюсь спершу спробувати генератори парсера, а потім спробувати користувацьке рішення, але які конкретні переваги? Це майже загальна порада.
Маньєро

1
Це загальна порада - але тоді ви задали загальне запитання. : P Я розповсюджу його ще декілька конкретних думок щодо плюсів і мінусів завтра.
Пітер Бауфтон

1
Я думаю, ви недооцінюєте кількість роботи, необхідної для створення користувальницького аналізатора та лексеру. Особливо багаторазового використання.

8

Прокат власного парсера змушує задуматися безпосередньо про складність вашої мови. Якщо мову важко розібрати, ймовірно, це буде важко зрозуміти.

У ранніх часів у генераторів парсера був великий інтерес, мотивований сильно складним (дехто би сказав "мученим") синтаксисом мови. JOVIAL був особливо поганим прикладом: для нього потрібні два символи пошуку, в той час, коли все інше вимагало не більше одного символу. Це зробило створення аналізатора для компілятора JOVIAL складніше, ніж очікувалося (оскільки General Dynamics / Fort Worth Division дізнався важкий шлях, коли вони закуповували компілятори JOVIAL для програми F-16).

Сьогодні рекурсивний спуск є загальнолюдським способом, оскільки це легше для письменників-укладачів. Компілятори рекурсивного походження сильно винагороджують просту, чисту мовну конструкцію, оскільки набагато простіше написати рекурсивно-розбірний аналізатор для простої, чистої мови, ніж для перекрученої, безладної.

Нарешті: Ви думали про те, щоб вкласти свою мову в LISP та дозволити перекладачеві LISP зробити важкий підйом для вас? AutoCAD зробив це, і виявив, що це полегшило їхнє життя. Існує досить багато легких перекладачів LISP, деякі вбудовані.


Цікавий аргумент, щоб розгорнути нестандартне рішення.
Маньєро

1
Дуже хороша. Я просто додам як інформацію про те, що Фортран вимагав майже довільного (цілого рядка) пошуку, щоб проаналізувати речі, перш ніж JOVIAL. Але в той час вони не мали іншої ідеї, як зробити (або реалізувати) мову.
Macneil

Ходьба - найкращий засіб транспорту, оскільки це дає вам час подумати, чи варто їхати туди, куди ви їдете. Це теж здорово.
Бабу

6

Я написав аналізатор комерційного застосування один раз, і я використав yacc . Був конкуруючий прототип, де розробник писав все це вручну в C ++, і він працював приблизно в п’ять разів повільніше.

Щодо лексеру для цього аналізатора, то я написав його цілком від руки. Знадобилося - вибачте, це було майже 10 років тому, так що я не пам'ятаю точно - близько 1000 рядків в C .

Причиною, чому я написав лексеру вручну, була граматика введення парсера. Це було вимогою, моєму виконанню аналізатора довелося відповідати, на відміну від того, що я задумав. (Звичайно, я б спроектував це інакше. І краще!) Граматика сильно залежала від контексту і навіть лексика залежала від семантики в деяких місцях. Наприклад, крапка з комою може бути частиною лексеми в одному місці, а роздільник в іншому місці - на основі семантичної інтерпретації якогось елемента, який був розібраний раніше. Отже, я "закопав" такі семантичні залежності в рукописному лексемі, і це залишило мене досить прямим BNF, який було легко реалізувати в yacc.

ДОБАВЕНО у відповідь на Macneil : yacc надає дуже потужну абстракцію, яка дозволяє програмісту думати над терміналами, нетерміналами, виробництвами тощо. Також при реалізації yylex()функції мені допомогло зосередитись на тому, щоб повернути поточний маркер і не турбуватися про те, що було до або після нього. Програміст на C ++ працював на рівні символів, без вигоди такої абстракції, і в кінцевому підсумку створив складніший і менш ефективний алгоритм. Ми зробили висновок, що повільна швидкість не має нічого спільного з самим C ++ або будь-якими бібліотеками. Ми вимірювали чисту швидкість розбору з файлами, завантаженими в пам'ять; якби у нас була проблема буферизації файлів, yacc не був би нашим інструментом вибору для її вирішення.

ТАКОЖ ХОЧЕ ДОДАТИ : це взагалі не рецепт написання парсерів, а лише приклад того, як це працювало в одній конкретній ситуації.


Мені цікаво п'ять разів повільніше впровадження C ++ вручну: Можливо, це було поганим буферизацією файлів? Це може змінити велике значення.
Macneil

@Macneil: я збираюся опублікувати додаток до своєї відповіді; коментар занадто довгий.
ажеглов

1
++ Хороший досвід. Я не став би занадто багато ваги на продуктивність. Інакше хороші програми легко уповільнити чимось дурним і непотрібним. Я написав достатньо рекурсивно-парсерних аналізаторів, щоб знати, що не робити, тому сумніваюся, чи є щось набагато швидше. Адже персонажів потрібно читати. Я підозрюю, що парсери, які біжать за столами, будуть трохи повільнішими, але, мабуть, недостатньо, щоб помітити.
Майк Данлаве

3

Це повністю залежить від того, що потрібно розбирати. Чи можете ви скочувати своє швидше, ніж ви могли б вдарити криву навчання лексеру? Чи потрібно проаналізувати матеріал досить статично, щоб згодом ви не пошкодували про рішення? Чи вважаєте Ви існуючі реалізації надмірно складними? Якщо так, то весело прокатуйте свої власні, але лише у тому випадку, якщо ви не втягуєте криву навчання.

Останнім часом мені дуже подобається аналізатор лимона , який, мабуть, найпростіший і найпростіший, що я коли-небудь використовував. Для того, щоб зробити речі легкими в обслуговуванні, я просто використовую це для більшості потреб. SQLite використовує його, як і деякі інші помітні проекти.

Але мене лексери зовсім не цікавлять, поза ними вони не заважають, коли мені потрібно використовувати один (отже, лимонний). Ви можете бути, і якщо так, то чому б не зробити його? У мене є відчуття, що ти знову повернешся до того, хто існує, але почухаєш свербіж, якщо треба :)


3
+1 для "Чи можете ви скочувати свій власний швидше, ніж ви могли б вдарити криву навчання лексеми?"
бобах

Так, хороший момент.
Маньєро

3

Це залежить від того, яка ваша мета.

Ви намагаєтесь дізнатися, як працюють парсери / компілятори? Тоді напишіть своє з нуля. Це єдиний спосіб, коли ти насправді навчишся цінувати всі плюси і мінуси того, що вони роблять. Я писав один за останні кілька місяців, і це було цікавим і цінним досвідом, особливо "ах, так ось чому мова X робить це ..." моменти.

Вам потрібно швидко скласти щось для подання заявки? Тоді можливо скористайтеся інструментом розбору.

Вам потрібно щось, що ви хочете розгорнути протягом наступних 10, 20, може, навіть 30 років? Напишіть своє та знайдіть час. Це буде добре того варте.


Це моя перша робота над компіляторами, я навчаюсь / експериментую, і це мій намір підтримувати її довгий час.
Маньєро

3

Чи ви розглядали підхід до роботи з мовою у стилі Мартіна Фаулерса ? Цитуючи із статті

Найбільш очевидною зміною, яку вносить мовний робочий стіл до рівняння, є простота створення зовнішніх DSL. Вам більше не потрібно писати аналізатор. Вам потрібно визначити абстрактний синтаксис - але це насправді досить простий крок моделювання даних. Крім того, ваш DSL отримує потужний IDE - хоча вам доведеться витратити деякий час на визначення цього редактора. Генератор - це все-таки щось, що вам потрібно зробити, і я відчуваю, що це не набагато простіше, ніж коли-небудь. Але тоді створення генератора для хорошого і простого DSL - це одна з найпростіших частин вправи.

Читаючи це, я б сказав, що дні написання власного аналізатора закінчились, і краще скористатися однією з наявних бібліотек. Після того, як ви освоїли бібліотеку, всі ці DSL, які ви створюєте в майбутньому, виграють від цих знань. Крім того, інші не повинні вивчати ваш підхід до розбору.

Редагувати, щоб висвітлити коментар (і переглянути питання)

Переваги прокатки самостійно

  1. Ви володієте парсером і отримаєте весь цей прекрасний досвід мислення через складну низку проблем
  2. Ви можете придумати щось особливе, про що ніхто і не думав (малоймовірно, але ви здаєтеся розумним хлопцем)
  3. Це дозволить вам зайнятися цікавою проблемою

Отже, коротше кажучи, ви повинні закатати свою власну, коли хочете по-справжньому вибити глибоко в недрах серйозно складну проблему, яку ви відчуваєте сильною мотивацією до оволодіння.

Переваги використання чужої бібліотеки

  1. Ви уникнете повторного винайдення колеса (поширена проблема в програмуванні, погодьтесь)
  2. Ви можете зосередитись на кінцевому результаті (ви блискучі новою мовою) і не надто хвилюватися про те, як він розбирається тощо
  3. Ви побачите свою мову в дії набагато швидше (але ваша винагорода буде меншою, тому що це були не всі ви)

Тому, якщо ви хочете швидкого кінцевого результату, використовуйте чужу бібліотеку.

Загалом, це зводиться до вибору того, наскільки ви хочете володіти проблемою, а отже, і рішенням. Якщо ви хочете все це, тоді згортайте своє.


Це чудова альтернатива мисленню.
Маньєро

1
@bigown Відредаговано, щоб краще відповісти на ваше запитання
Gary Rowe

2

Великою перевагою в написанні свого є те, що ви знаєте, як написати своє. Великою перевагою використання такого інструменту, як yacc, є те, що ви знаєте, як користуватися інструментом. Я фанат верхівки дерев для початкових розвідок.


Не особливо корисно. Ви також можете сказати: «Перевага навчитися керувати автомобілем полягає в тому, що ти можеш керувати автомобілем. Переваги навчитися їздити на велосипеді полягає в тому, що ви можете їздити на велосипедах ».
Zearin

1

Чому б не роздрібнити генератор аналізатора з відкритим кодом та зробити його власним? Якщо ви не використовуєте генератори парсеру, код буде важко підтримувати, якщо ви змінили синтаксис своєї мови.

У своїх аналізаторах я використовував регулярні вирази (я маю на увазі стиль Perl) для токенізації та використання деяких зручних функцій для підвищення читабельності коду. Однак, генерований парсером код може бути швидшим, створюючи таблиці стану та long switch- cases, що може збільшити розмір вихідного коду, якщо ви не .gitignoreїх.

Ось два приклади моїх написаних на замовлення аналізаторів:

https://github.com/SHiNKiROU/DesignScript - БАЗОВИЙ діалект, тому що я був ледачий, щоб писати лукади в нотації масиву, я пожертвував якістю повідомлень про помилки https://github.com/SHiNKiROU/ExprParser - калькулятор формул. Зауважте дивні хитрощі метапрограмування


0

"Чи варто використовувати це перевірене" колесо "або винаходити його знову?"


1
Про що це «колесо» ви говорите? ;-)
Джейсон Уайтхорн

ІМО це не гарна думка з цього питання. Це лише загальна порада, не підходяща до конкретного випадку. Я починаю підозрювати, що пропозиція area51.stackexchange.com/proposals/7848 була закрита передчасно.
Маньєро

2
Якби колесо ніколи не було винайдено, ми б не їздили зі швидкістю 100 км / год щодня - якщо тільки ви не запропонуєте великих важких грудочок обертання скелі на дерев'яних осях краще, ніж багато багатьох варіантів сучасних шин, що використовуються в стільки транспортних засобів?
Пітер Бауфтон

Це обгрунтована думка, і це правильна інтуїція. Я думаю, що ця відповідь може бути кориснішою, якщо ви могли б перерахувати конкретні переваги чи недоліки, тому що подібні речі повністю залежать від обставин.
Macneil

@Peter: Одне з них - щось винаходити (мається на увазі зробити це зовсім інакше), але краще уточнити існуюче рішення для задоволення додаткових вимог. Я все за «покращення», але повернення до креслярської дошки для вже вирішеної проблеми здається неправильним.
JBRWilkinson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.