Переключатель или если заявления в письменном виде переводчика в 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
...
}