Переключатель или если заявления в письменном виде переводчика в Java

Текущее назначение требует, чтобы я написал программу для чтения файла с инструкциями на очень крошечном и базовом языке программирования (ведет себя немного как FORTRAN) и выполнил эти инструкции. По сути, это простой интерпретатор языка, который я предполагаю. Он полностью линейный, все операторы определены в последовательности и содержат только строковые и целочисленные переменные. Есть 8 ключевых слов и 4 арифметических оператора, которые мне нужно найти и определить, существуют ли они в исходном файле, и каждая строка должна начинаться с одного из зарезервированных слов. Программа на этом языке может выглядеть примерно так:

#COMMENTS
LET.... (declares variables with values)
INTEGER myINT
STRING myString
CALCULATE...
PRINT
PRINTLN
END

Могу ли я использовать блок переключателей вместо if-циклов, чтобы найти и затем выполнить все это? Меня беспокоит то, что переключатели не работают со строками в Java 6, что я и должен использовать, но я не вижу, как легко назначить различные значения int, чтобы блок переключателей работал. Заранее спасибо за любые предложения и советы!

2 ответа

Решение

Если ваш язык настолько прост, что каждое утверждение начинается в отдельной строке и идентифицируется только одним словом, то (как указал Грей в другом комментарии) вы можете разбить слова в каждой строке, а затем сравнить первое слово с картой. Тем не менее, я бы предложил вместо отображения слов в целые, а затем сделать одно большое переключение, вместо этого сопоставить их с объектами, как показано ниже (предложено Дейвом Ньютоном):

interface Directive {
    public void execute(String line);
}

class LetDirective implements Directive {
    public void execute(String line) { ...handle LET directive here... }
}

...define other directives in the same way...

Затем определите карту:

private Map<String, Directive> directives = new HashMap<String, Directive>();
directives.put("LET", new LetDirective());
...

Тогда в вашем методе разбора:

int firstSpace = line.indexOf(' ');
String command = line;
if (firstSpace > 0)
    command = line.substring(0, firstSpace);
Directive directive = directives.get(command.toUpperCase());
if (directive != null)
    directive.execute(line);
else
    ...show some error...

Каждая директива должна была бы самостоятельно проанализировать остальную часть строки и правильно обработать ее в своем методе execute().

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

Если вы говорите о преобразовании строк в целые числа, вы можете сделать это с помощью перечислимого типа Java:

private enum ReservedWord {
   LET,
   ...
}

// skip blank lines and comments
String[] tokens = codeLine.split(" ");
ReservedWord keyword;
try {
   keyword = ReservedWord.valueOf(tokens[0]);
} catch (IllegalArgumentException e) {
   // spit out nice syntax error message
}

Вы также можете поместить обработку строки внутри перечисления как метод, если хотите. Вы также можете сделать это с Map:

private final Map<String, Integer> reservedWords = new HashMap<String, Integer>();
private final int RESERVED_WORD_LET 1
...
{
   reservedWords.put("LET", RESERVED_WORD_LET);
   ...
}

// skip blank lines and comments
String[] tokens = codeLine.split(" ");
Integer value = reservedWords.get(tokens[0]);
if (value == null) // handle error... ;
switch (value) {
   case 1:
       // LET
       ...
}
Другие вопросы по тегам