Изящный парсинг команды в ОСНОВАННОЙ НА ООП текстовой игре

Я играю с записью приключения MUD/текста (не смейтесь) в Ruby. Кто-либо может дать мне какие-либо подсказки к изящному, основанному на ООП решению парсинга входного текста?

Мы не говорим ни о чем более сложном, чем "помещенная палочка на таблице", здесь. Но все должно быть мягким; я хочу расширить набор команд безболезненно, позже.

Мои текущие мысли, немного упрощенные:

  1. Каждый класс объекта (поле, таблица, комната, плеер) знает, как распознать команду, которая 'принадлежит' ему.

  2. Игровой класс понимает своего рода, проблемно-ориентированный язык, включающий действия, такие как "перемещение, возражает X внутренним объектам Y", "показывают описание объекта X", и т.д.

  3. Игровой класс спрашивает каждый объект в комнате, если он распознает входную команду. Сначала сказать да победы.

  4. Это затем передает управление к методу в классе объекта, который обрабатывает команду. Этот метод перефразирует команду в DSL, пасует назад его к игровому объекту заставить его произойти.

Должны быть старые, изящные способы сделать этот материал. Может казаться, ничего не гуглит, все же.

8
задан Shadowfirebird 5 February 2010 в 14:53
поделиться

5 ответов

Паттерн проектирования Интерпретатора является самым объектно-ориентированным подходом к синтаксическому анализу, который мне известен, но я уверен, что эксперты компилятора укажут на более мощные алгоритмы.

3
ответ дан 5 December 2019 в 22:18
поделиться

Er, C++ не является SQL. В SQL нет = = , а в предложении WHERE нет назначений.

Я не уверен, что он квалифицируется как «лучшая практика», но есть соглашение, которое ставит известную ценность на правую сторону. Таким образом, с литералом, как в вашем примере, который будет

WHERE CCY = 'USD' 
-121--4667646-

, я лично не стал бы делать это путь, но поместил имя столбца в левой части, так как это мне более читаемо/легче следовать в SQL-запросе.

Я очень редко видел, как это делается противоположным образом, и не думаю, что приведенная причина действительно применима к SQL (как было указано, это «=» в SQL, а не «= =»)

-121--4667650-

Ok. Значит, тебе нужна семантика? (поворот - действие, зажечь объект, на спор... (Я отношусь к вашему комментарию к dbemerlin)).

Почему бы не определить грамматику? хумм... Полагаю, lex и yacc не вариант? (так как это вообще не ООП, а то, что вы хотите сделать, это «скомпилировать» пользовательский ввод, чтобы создать что-то - выполнить какой-то код, который изменяет данные комнаты, и вывести результат)

Можно создать проект ООП для объекта и его действия (например, все объекты имеют метод .describeMe ()..), а кроме того, входной синтаксический анализатор + компилятор.

Полностью ли я отошел от темы?

Изменить: после просмотра образца интерпретатора, на которую указал Марк Симан, кажется, что это путь, по которому вы хотите его в ООП. (но вы несколько заново изобретете колесо)

0
ответ дан 5 December 2019 в 22:18
поделиться

Я действительно не думаю, что это вопрос, на который можно объективно ответить. В конце концов речь идет о людях и о том, с чем они чувствуют себя комфортнее. Вот почему, например, Facebook разработала компилятор PHP-C + + (с помощью которого производительность Java также может стать меньше) вместо того, чтобы просто нанимать разработчиков C++ для выполнения Задания.

С другой стороны, платформа Java предлагает некоторые интересные новые подходы, такие как Grails (который в основном представляет собой обертку Groovy вокруг Spring ) и Lift , а также. Это делает разработку Frontend более быстрой и простой (я все еще нахожу, что это настоящая боль с простым Java), и вы можете объединить преимущества, которые другие языки имеют с вашей существующей Java кодовой базой и опытом (btw. большинство упомянутых рамок не нуждаются в J2EE среде выполнения, простой установки Tomcat с примерно 5M и установленной JRE должно быть достаточно). Так что речь идет не только о языке программирования Java.

И если вы действительно не можете решить, что вы просто запустить PHP на Java (работает также для Ruby , Python , Javascript ...).

-121--4557547-

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

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

Подумайте об этом пути, почему вы переносите его на .Net? Я хотел бы сказать, что вы находитесь в одной из двух ситуаций, в одной из которых вы застряли, используя .Net из-за работы (doh, sorry!) или вы , как .Net, потому что это предлагает вам некоторое преимущество. Во второй категории, которая означает, что вы выбрали его вместо Java, так что при портировании вы хотели бы воспользоваться всеми функциями, которые заставили вас выбрать .Net.

-121--4196000-

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

class Thing

  # Handle a command by calling the method "cmd_" + command.
  # Raise BadCommand exception if there is no method for that command.

  def handle_command(command, args)
    method_name = "cmd_#{command}"
    raise BadCommand, command unless respond_to?(method_name)
    send(method_name, args)
  end

  def cmd_quit(args)
    # the code for command "quit"
  end

  def cmd_list(args)
    # the code for command "list"
  end

  ...

end

В этом пути добавление новой команды означает добавление нового метода. Нет необходимости корректировать таблицы или обращения.

1
ответ дан 5 December 2019 в 22:18
поделиться

Разделите его на токены, так как формат всегда будет:
[команда] [объект1] ([ссылка] [объект2])

Вы можете вызвать метод [команда] для [объекта1 ] в вашей комнате и передайте ему [объект2], если применимо.

0
ответ дан 5 December 2019 в 22:18
поделиться

Похоже, вам нужен синтаксический анализатор.

Разделить входную строку на токены (слова). Затем подайте токены по одному в конечный автомат. Я считаю, что автоматические выталкивающие элементы - это довольно интуитивно понятный и мощный способ написать такую ​​stm.

2
ответ дан 5 December 2019 в 22:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: