Написание простого игрового интерпретатора - PullRequest
2 голосов
/ 23 января 2011

Я прочитал много записей о построении интерпретатора и компилятора на этом сайте и в новостях хакера.

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

Язык

  1. Язык основан на Герберте [Imagine Cup]
  2. Я хочу создать онлайн-версию, пользователь может отправить ее в форме и увидеть, как робот работает в веб-окне.
  3. Я могу использовать только php, python, ruby ​​или любой другой веб-язык.

Вот мой язык

Основная инструкция

  1. с - прямо
  2. л - слева
  3. r - вправо
  4. Вы можете иметь функцию здесь f: ssrl [Они поддерживают рекурсию f: ssrlf аргументы f (A): Assrl, f (A): ssrlf (A-1) (здесь A является целым числом)
  5. В программе может быть несколько функций, вызывающих друг друга. е: ssrlgf

Я хочу реализовать это как можно быстрее, что будет для меня лучшей альтернативой для выполнения этой работы. [Я знаю php, не имею опыта работы с python или ruby, но хочу выучить их для этого проекта]

Ответы [ 2 ]

2 голосов
/ 25 января 2011

Вам нужно будет написать токенизатор- (цепочку).

Жетон класса { статический анализ токена (строковая программа); void Execute (состояние CurrentProgramState); }

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

Затем, когда вызывается Program.Execute (), он отслеживает CurrentProgramState и передает это состояние своим токенам, которые изменяют состояние игры в соответствии с его параметрами.

Небольшой пример.

Скажем, у нас есть язык, в котором есть только два типа токенов

с (для прямой) номер (на сколько)

class StraightToken
{
    public StraightToken(NumberToken howFar)
    {
        this.howFar = howFar;
    }
    private NumberToken howFar;
    static Token Parse(string program)
    {
        if(program.StartsWith("s ")
        {
            NumberToken number = NumberToken.Parse(program.substring(2));
            if(howFar != null)
            {                
                return new StraightToken(number);
            }
        }
        return null;
    }

    public void Execute(ProgramState state)
    {
        state.Position += this.howFar.value;
    }
}

class NumberToken
{
    public int value;
    public NumberToken(int value;)
    {
        this.value = value;
    }

    static Token Parse(string program)
    {
        if(IsDigit(program[0]))
        {
            program = program.SubString(1);
            return new NumberToken((int)program[0])
        }
    }
}
0 голосов
/ 22 августа 2016

Извините за публикацию в старой теме, но, это интересный вопрос, и, поскольку он не решен, я бы лично использовал javascript и не стал бы писать о переводчике

Таким образом, предполагая, что все вводные данные состоят из одной строки, у вас будет следующее: [предупреждение: может содержать опечатки, я отправляю сообщение с моего телефона]

var input = "lllssrb",
      horizontal = 0, vertical = 0;
//now we'll just loop through the input
input.split("").forEach(function(char){
    switch(char){
         case "l":
              horizontal --;
              break;
         case "r"
              horizontal ++;
              break;
         case "s":
              vertical ++;
              break;
          case "b":
              vertical --;
              break;
    }
});

//now do something with our results
//function advance(horizontal, vertical)
advance(horizontal, vertical);
...