Як мені реалізувати додаток для обробки команд?


9

Я хочу зробити просту програму із підтвердженням концепції (REPL), яка приймає число, а потім обробляє команди на це число.

Приклад: я починаю з 1. Потім я пишу " add 2", це дає мені 3. Потім я пишу " multiply 7", це дає мені 21. Потім я хочу знати, чи це просто, тому я пишу " is prime" (на поточний номер - 21), це дає мені хибність. " is odd" дав би мені правду. І так далі.

Тепер для простого додатка з декількома командами навіть switchобробку команд зробить навіть проста . Але якщо я хочу розширити, як мені потрібно реалізувати функціонал? Чи використовую я шаблон команди? Чи будувати простий парсер / інтерпретатор для мови? Що робити, якщо я хочу більш складні команди, наприклад " multiply 5 until >200"? Який був би простий спосіб розширити його (додати нові команди) без перекомпіляції?

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

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

Edit2: Дякую за всі відповіді, всі мені були дуже корисні, але Еммад Карім допомагав мені найбільше, тому я обрав це як відповідь. Знову дякую!


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

2
Мені дуже подобається це питання. З нетерпінням чекаю, що дизайни пропонують люди. Ви спеціально шукаєте об'єктно-орієнтований дизайн (ви згадуєте шаблон команди, який є шаблоном ОО)?
Bjarke Freund-Hansen

дякую :) так, я б віддав перевагу OOP, але я не заперечу, якщо пропонуються інші методи!
Ніні Майклс

2
Здається, реалізація зворотної польської нотації - дуже класна тема програмування!
Альберто Де Каро

2
Ви, мабуть, збиваєтесь із статті про книгу, яку категорію питань я не повинен тут задавати? у FAQ, тобто якщо ви можете уявити всю книгу, яка відповідає на ваше запитання, ви занадто багато запитуєте .
Марк Бут

Відповіді:


5

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

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

Погляньте: ця тема стосується різних аспектів роботи, також є хороші посилання, які можуть вам допомогти (особливо відповідь RMK).: Створення перекладача мови . Ви можете побачити приклад чудового вигляду проекту, який дещо схожий на: Ultimate Programmable Scientific Calculator . Ви можете знайти вихідний код та робочу програму для інтерпретатора командного рядка тут Командний рядок-Впровадження-З-С # -Зроблено для навчання . Використання компілятора для виконання складних завдань, таких як розбір і введення змінних тощо, може бути розумним способом самостійно уникнути складностей написання всього цього. Крім того, є варіант Mono, який забезпечує функцію оболонки charp, яку ви можете поглянути: CsharpRepl .


Дякуємо, ваші посилання дуже корисні! Тому я думаю, що перекладач був би найкращим вибором, якщо я хочу його легко поширити.
Ніні Майклс

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

2

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

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


1
Проблема більшості генераторів парсеру полягає в тому, що їх артефакти є статичними і не піддаються розширенню. Я думаю, що ОП краще подавати щось подібне до двигуна правил, де "правила" (ключові слова та синтаксис) зберігаються у гнучкої структурі даних та оцінюються після кожного введення.
TMN

2

Те, що ви описуєте, дуже близьке до мови стека .

Наприклад, у " Факторі" робиться те, що ви описуєте

1
2 +
7 *
even? not

Або ви могли б визначити власні слова, а потім використовувати їх, як

: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;

З цими визначеннями стає вищенаведеним прикладом

1
2 add
7 multiply
odd?

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

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


Це звучить досить просто, і гарне місце для початку. Дякую!
Ніні Майклс

1

Але якщо я хочу розширити, як мені потрібно реалізувати функціонал?

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

Чи використовую я шаблон команди?

Можна, але це, мабуть, не доречно.

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

Чи будувати простий парсер / інтерпретатор для мови?

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

а скоріше список (чисел) процесор

Тоді, можливо, вам слід вивчити мову LISt Processing . Співставлення коду та даних має добре відповідати тому, що ви описуєте.


Дякую за пропозиції. Що стосується LISP, я з ним знайомий і ще більше знайомий з Haskell, який надихнув мене на цю ідею. Однак, хоч я, можливо, трохи винаходжую колесо, я хочу забруднити руки обробкою команд та їх інтерпретацією. Тож воно має і навчальну мету, окрім власне «обробки списків» :)
Ніні Майклз

@ NiniMichaels, звичайно, але, що стосується розробки для розширюваності, використання організації / ланцюжка коду / даних lisp - це не поганий варіант.
Теластин
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.